You are not logged in.
As per the pipewire wiki page says, first I determine the node number of the 2 concerned sinks using wpctl status:
...
Audio
├─ Devices:
│ 48. Navi 10 HDMI Audio [alsa]
│ 62. JDS Labs Atom DAC+ [alsa]
│ 64. Starship/Matisse HD Audio Controller [alsa]
│
├─ Sinks:
│ * 32. JDS Labs Atom DAC+ Analog Stereo [vol: 1.00]
│ 46. Starship/Matisse HD Audio Controller Digital Stereo (IEC958) [vol: 1.00]
│ 70. Navi 10 HDMI Audio Digital Stereo (HDMI 4) [vol: 0.40]
...
I determined that node 32 and node 46 are 2 sinks that I want to switch on-the-fly
After that, this script is what i have so far:
pipewire-switch-default
#!/bin/sh
# Script to switch between speaker and headphones using wireplumber
# assumed IDs are 32 (for headphones) and 46 (for speakers)
TOGGLE=$HOME/.toggle
if [ ! -e $TOGGLE ]; then
touch $TOGGLE
wpctl set-default 32
else
rm $TOGGLE
wpctl set-default 46
fi
Now normally this would work as I tested it multiple times, but after a reboot, the nodes numbers randomized and mess up my script. Is there a way to set a default sink in WirePlumber using something more permanent across system reboots? I have an idea to write 2 Lua scripts that sets the nodes priority, but i am not sure how to make WirePlumber loads the correct one on-the-fly as I understand it, policies and configs are loaded at startup time.
Offline
See this feature request for WirePlumber: https://gitlab.freedesktop.org/pipewire … issues/395
For now, we can parse pw-dump (JSON) and find the IDs of sinks by searching their names.
Offline
Are you deathly averse to using pactl for this? It supports sink names, getting the default sink as a name and a bunch of other stuff that will have the same end goal.
Offline
@minh2134 I'm using this script. It's not really toggling like yours, but achieves the same goal.
Get the sink names:
$ wpctl status --name
├─ Sinks:
│ 51. alsa_output.pci-0000_03_00.1.hdmi-stereo [vol: 0.35]
│ * 52. alsa_output.pci-0000_00_1f.3.analog-stereo [vol: 0.70 MUTED]
wireplumber-set-sink.sh:
#!/bin/sh
speaker_id=$(pw-cli info alsa_output.pci-0000_03_00.1.hdmi-stereo | head -n 1 | awk '{print $2}')
headset_id=$(pw-cli info alsa_output.pci-0000_00_1f.3.analog-stereo | head -n 1 | awk '{print $2}')
if [ "$1" = 'speaker' ]; then
wpctl set-default "$speaker_id"
elif [ "$1" = 'headset' ]; then
wpctl set-default "$headset_id"
else
echo 'Unrecognized device name' >&2
exit 2
fi
Usage:
wireplumber-set-sink headset|speaker
@V1del I haven't tried pactl myself, but maybe I should — it doesn't look like WirePlumber intends to make its tool easier for us. But I mean, we're running PipeWire, not Pulseaudio; that doesn't sound right.
Offline
It is right because the entire volume/sink/sources logic is absolutely intended - and directly copied from - to be handled via existing pulseaudio means. 99% of the clients you're using talks to pipewire via pulseaudio anyway, it's crucial that pipewire/wireplumber support this properly, I'd not make this a hill to die on.
Last edited by V1del (2024-09-03 08:34:55)
Offline