getting default audio/video input and ouput devices with rust and pipewire-rs

134 Views Asked by At

I Created a code in rust with pipewire-rs that lists all the devices and ports. i don't see any information about what's the default audio input and output device and default video output device.

use std::thread;
use std::thread::JoinHandle;
use gtk::glib::ExitCode;
use pipewire::{Context, Core, MainLoop};
use pipewire::spa::ReadableDict;
use pipewire::types::ObjectType;

pub fn mypipewrite_spawn_mainloop() -> JoinHandle<ExitCode> {

    let pw_thread = thread::spawn(|| {
        // Initialize PipeWire and run the main loop
        // ...
        let mainloop = MainLoop::new().expect("failed to get mail loop");
        let context = Context::new(&mainloop).expect("failed to get context");
        let core = context.connect(None).expect("failed to get core");
        let registry = core.get_registry().expect("failed to get registry");
   
        let _listener = registry
            .add_listener_local()
            .global(|global|
                {
                    if global.type_ == ObjectType::Port {
                        let props = global.props.as_ref().unwrap();
                        let port_name = props.get("port.name");
                        let port_alias = props.get("port.alias");
                        let object_path = props.get("object.path");
                        let format_dsp = props.get("format.dsp");
                        let audio_channel = props.get("audio.channel");
                        let port_id = props.get("port.id");
                        let port_direction = props.get("port.direction");
                        println!("Port: Name: {:?} Alias: {:?}  Id: {:?} Direction: {:?} AudioChannel: {:?} Object Path: {:?} FormatDsp: {:?}",
                        port_name,
                        port_alias,
                            port_id,port_direction,audio_channel,object_path,format_dsp
                            );
                    } else if global.type_ == ObjectType::Device {
                            let props = global.props.as_ref().unwrap();
                            let device_name = props.get("device.name");
                            let device_nick = props.get("device.nick");
                            let device_description = props.get("device.description");
                            let device_api = props.get("device.api");
                            let media_class = props.get("media.class");
                            println!("Device: Name: {:?} Nick: {:?} Desc: {:?} Api: {:?} MediaClass: {:?}",
                                     device_name, device_nick, device_description, device_api, media_class);
                    }
                }
                            )
            .register();

        // Calling the `destroy_global` method on the registry will destroy the object with the specified id on the remote.
        // We don't have a specific object to destroy now, so this is commented out.
        // registry.destroy_global(313).into_result()?;


        mainloop.run();
        return ExitCode::FAILURE; // not sure
    });
    return pw_thread;
}

it lists everything beautifully, in my case this is the output:

Port: Name: Some("Midi Through:(playback_0) Midi Through Port-0") Alias: Some("Midi Through:Midi Through Port-0")  Id: Some("0") Direction: Some("in") AudioChannel: None Object Path: Some("alsa:seq:default:client_14:playback_0") FormatDsp: Some("8 bit raw midi")
Port: Name: Some("Midi Through:(capture_0) Midi Through Port-0") Alias: Some("Midi Through:Midi Through Port-0")  Id: Some("0") Direction: Some("out") AudioChannel: None Object Path: Some("alsa:seq:default:client_14:capture_0") FormatDsp: Some("8 bit raw midi")
Device: Name: Some("v4l2_device.pci-0000_00_14.0-usb-0_10_1.0") Nick: None Desc: Some("HD Pro Webcam C920") Api: Some("v4l2") MediaClass: Some("Video/Device")
Device: Name: Some("v4l2_device.pci-0000_00_14.0-usb-0_10_1.0.2") Nick: None Desc: Some("HD Pro Webcam C920") Api: Some("v4l2") MediaClass: Some("Video/Device")
Device: Name: Some("alsa_card.pci-0000_01_00.1") Nick: Some("HDA NVidia") Desc: Some("GA106 High Definition Audio Controller") Api: Some("alsa") MediaClass: Some("Audio/Device")
Device: Name: Some("alsa_card.usb-046d_HD_Pro_Webcam_C920_B71E5BFF-02") Nick: Some("HD Pro Webcam C920") Desc: Some("HD Pro Webcam C920") Api: Some("alsa") MediaClass: Some("Audio/Device")
Device: Name: Some("alsa_card.pci-0000_00_1f.3") Nick: Some("HDA Intel PCH") Desc: Some("Built-in Audio") Api: Some("alsa") MediaClass: Some("Audio/Device")
Port: Name: Some("capture_1") Alias: Some("HD Pro Webcam C920:capture_1")  Id: Some("0") Direction: Some("out") AudioChannel: None Object Path: Some("v4l2:/dev/video0:capture_0") FormatDsp: None
Port: Name: Some("capture_FL") Alias: Some("HD Pro Webcam C920:capture_FL")  Id: Some("0") Direction: Some("out") AudioChannel: Some("FL") Object Path: Some("alsa:pcm:0:front:0:capture:capture_0") FormatDsp: Some("32 bit float mono audio")
Port: Name: Some("capture_FR") Alias: Some("HD Pro Webcam C920:capture_FR")  Id: Some("1") Direction: Some("out") AudioChannel: Some("FR") Object Path: Some("alsa:pcm:0:front:0:capture:capture_1") FormatDsp: Some("32 bit float mono audio")
Port: Name: Some("playback_FL") Alias: Some("ALC897 Analog:playback_FL")  Id: Some("0") Direction: Some("in") AudioChannel: Some("FL") Object Path: Some("alsa:pcm:1:front:1:playback:playback_0") FormatDsp: Some("32 bit float mono audio")
Port: Name: Some("monitor_FL") Alias: Some("ALC897 Analog:monitor_FL")  Id: Some("0") Direction: Some("out") AudioChannel: Some("FL") Object Path: Some("alsa:pcm:1:front:1:playback:monitor_0") FormatDsp: Some("32 bit float mono audio")
Port: Name: Some("playback_FR") Alias: Some("ALC897 Analog:playback_FR")  Id: Some("1") Direction: Some("in") AudioChannel: Some("FR") Object Path: Some("alsa:pcm:1:front:1:playback:playback_1") FormatDsp: Some("32 bit float mono audio")
Port: Name: Some("monitor_FR") Alias: Some("ALC897 Analog:monitor_FR")  Id: Some("1") Direction: Some("out") AudioChannel: Some("FR") Object Path: Some("alsa:pcm:1:front:1:playback:monitor_1") FormatDsp: Some("32 bit float mono audio")
Port: Name: Some("capture_FL") Alias: Some("ALC897 Analog:capture_FL")  Id: Some("0") Direction: Some("out") AudioChannel: Some("FL") Object Path: Some("alsa:pcm:1:front:1:capture:capture_0") FormatDsp: Some("32 bit float mono audio")
Port: Name: Some("capture_FR") Alias: Some("ALC897 Analog:capture_FR")  Id: Some("1") Direction: Some("out") AudioChannel: Some("FR") Object Path: Some("alsa:pcm:1:front:1:capture:capture_1") FormatDsp: Some("32 bit float mono audio")
Port: Name: Some("playback_FL") Alias: Some("34GL750:playback_FL")  Id: Some("0") Direction: Some("in") AudioChannel: Some("FL") Object Path: Some("alsa:pcm:2:hdmi:2:playback:playback_0") FormatDsp: Some("32 bit float mono audio")
Port: Name: Some("monitor_FL") Alias: Some("34GL750:monitor_FL")  Id: Some("0") Direction: Some("out") AudioChannel: Some("FL") Object Path: Some("alsa:pcm:2:hdmi:2:playback:monitor_0") FormatDsp: Some("32 bit float mono audio")
Port: Name: Some("playback_FR") Alias: Some("34GL750:playback_FR")  Id: Some("1") Direction: Some("in") AudioChannel: Some("FR") Object Path: Some("alsa:pcm:2:hdmi:2:playback:playback_1") FormatDsp: Some("32 bit float mono audio")
Port: Name: Some("monitor_FR") Alias: Some("34GL750:monitor_FR")  Id: Some("1") Direction: Some("out") AudioChannel: Some("FR") Object Path: Some("alsa:pcm:2:hdmi:2:playback:monitor_1") FormatDsp: Some("32 bit float mono audio")
Port: Name: Some("output_FL") Alias: Some("speech-dispatcher-dummy:output_FL")  Id: Some("0") Direction: Some("out") AudioChannel: Some("FL") Object Path: Some("speech-dispatcher-dummy:output_0") FormatDsp: Some("32 bit float mono audio")
Port: Name: Some("output_FR") Alias: Some("speech-dispatcher-dummy:output_FR")  Id: Some("1") Direction: Some("out") AudioChannel: Some("FR") Object Path: Some("speech-dispatcher-dummy:output_1") FormatDsp: Some("32 bit float mono audio")
Port: Name: Some("input_FL") Alias: Some("GNOME Settings:input_FL")  Id: Some("0") Direction: Some("in") AudioChannel: Some("FL") Object Path: Some("GNOME Settings:input_0") FormatDsp: Some("32 bit float mono audio")
Port: Name: Some("monitor_FL") Alias: Some("GNOME Settings:monitor_FL")  Id: Some("0") Direction: Some("out") AudioChannel: Some("FL") Object Path: Some("GNOME Settings:monitor_0") FormatDsp: Some("32 bit float mono audio")
Port: Name: Some("input_FR") Alias: Some("GNOME Settings:input_FR")  Id: Some("1") Direction: Some("in") AudioChannel: Some("FR") Object Path: Some("GNOME Settings:input_1") FormatDsp: Some("32 bit float mono audio")
Port: Name: Some("monitor_FR") Alias: Some("GNOME Settings:monitor_FR")  Id: Some("1") Direction: Some("out") AudioChannel: Some("FR") Object Path: Some("GNOME Settings:monitor_1") FormatDsp: Some("32 bit float mono audio")
Port: Name: Some("input_FL") Alias: Some("GNOME Settings:input_FL")  Id: Some("0") Direction: Some("in") AudioChannel: Some("FL") Object Path: Some("GNOME Settings:input_0") FormatDsp: Some("32 bit float mono audio")
Port: Name: Some("monitor_FL") Alias: Some("GNOME Settings:monitor_FL")  Id: Some("0") Direction: Some("out") AudioChannel: Some("FL") Object Path: Some("GNOME Settings:monitor_0") FormatDsp: Some("32 bit float mono audio")
Port: Name: Some("input_FR") Alias: Some("GNOME Settings:input_FR")  Id: Some("1") Direction: Some("in") AudioChannel: Some("FR") Object Path: Some("GNOME Settings:input_1") FormatDsp: Some("32 bit float mono audio")
Port: Name: Some("monitor_FR") Alias: Some("GNOME Settings:monitor_FR")  Id: Some("1") Direction: Some("out") AudioChannel: Some("FR") Object Path: Some("GNOME Settings:monitor_1") FormatDsp: Some("32 bit float mono audio")

out of these devices i want to know what's the default input/output devices for audio and video, how can i do that ?

1

There are 1 best solutions below

0
On

Infomation about default sinks and sources is contained in "PipeWire:Interface:Metadata" objects. One of them contains a "metadata" key which has a dictionary with default.video.source, default.audio.sink and default.audio.source values.

Here's the output of pw-dump showing the relevant entries for my setup:

$ pw-dump
[
  {
    "id": 36,
    "type": "PipeWire:Interface:Metadata",
    "version": 3,
    "permissions": [ "r", "w", "x" ],
    "props": {
      "client.id": 34,
      "factory.id": 6,
      "metadata.name": "default",
      "module.id": 5,
      "object.serial": 36
    },
    "metadata": [
      { "subject": 0, "key": "default.video.source", "type": "Spa:String:JSON", "value": { "name": "v4l2_input.pci-0000_00_1a.0-usb-0_1.6_1.0" } },
      { "subject": 0, "key": "default.audio.sink", "type": "Spa:String:JSON", "value": { "name": "alsa_output.pci-0000_00_1b.0.analog-stereo" } },
      { "subject": 0, "key": "default.audio.source", "type": "Spa:String:JSON", "value": { "name": "alsa_input.pci-0000_00_1b.0.analog-stereo" } }
    ]
  }