This was harder to find out how to do than I'd expected, which may, of course, be due to my lack of web skills, but at any rate, I'm putting this up so I don't have to look again.
This was done on a minimal Fedora install, a small Arch install, a Voidlinux install, and FreeBSD. All used openbox as the window manager, I suspect that it may be even simpler in desktop environments like Gnome.
My use case is occasionally connecting a laptop, through an HDMI cable, to a large TV. I wanted it to automatically use the TV's speaker when connected and the laptop's speakers when not. I only connect it to the TV infrequently, say for a maximum of an hour or so, a few times a week.
First, you need pipewire and wireplumber. Once you have these installed, you can hook the laptop up to the TV and type, as the user who will be doing this
wpctl status |more |
This will give output that will contain, among other things, something like
Audio Devices: 40. Built-in Audio [alsa] 41. Built-in Audio [alsa] Sinks: 44. Built-in Audio Digital Stereo (HDMI) [vol: 0.74] * 45. Built-in Audio Analog Stereo [vol: 0.72] |
You'll want to pipe it through more or less as I did in the example as there will be a lot of output. Anyway, in that example, you see that the HDMI sink is number 44. Now set it as default.
wpctl set-default 44 |
It will now use the HDMI when it is plugged in. If it's not attached to the TV it will use the laptop speakers. In my experience, once I unplug it, I have to get out of X and restart it, for the sound to change. But for my needs, this isn't a big deal.
Aside from pipewire and wireplumber, you'll need to install rtkit. Otherwise, it seems to keep changing. For example, at one point, you had to set XDG_RUNTIME_DIR, but now it seems automatic. I use it by either starting X or labwc, a Wayland version of openbox, then starting pipewire in dmenu, which I use with openbox and fluxbox, or bemenu which I use with labwc. See the VoidLinux news article. Void has been problematic for me. It seems to change frequently and as I don't use pipewire often, it seems that after a few months, I have to trouble shoot agian. However, as of August, 2024, it seems to be working without too much effort. Install it, it pulls in wireplumber, start it with whatever you use to run programs, and you can use wpctl status to see where your HDMI device is. I then run wpctl set-default 44 (for example). It will then use the HDMI speaker from the TV. Sometimes, I have to raise the volume with something like wpctl set-volume 44 85. This will set the volume on device 44 (the HDMI speaker) to 85%.
For my use, when I don't have it hooked to the TV, I don't even need pipewire. So, I can, if just running the laptop, not even use the pipewire command and get sound through the speakers. Therefore, I only run pipewire when hooked up to the TV.
What I do find with VoidLinux, however, is that this sometimes stops working after an upgrade, then starts working again after another upgrade. Or sometimes, I can fix it by just uninstalling and reinstalling pipewire and wireplumber. I haven't looked too deeply into it, as the uninstall reinstall of pipewire and wireplumber has usually fixed it for me.
Installed devices: pcm0: <ATI R6xx (HDMI)> (play) pcm1: <ATI R6xx (HDMI)> (play) pcm2: <ATI R6xx (HDMI)> (play) pcm3: <Realtek ALC257 (Analog 2.0+HP/2.0)> (play/rec) default pcm4: <Realtek ALC257 (Right Analog Mic)> (rec) No devices installed from userspace. |
Note that the default is pcm3, which refers to the laptop speakers. To get it to use HDMI, I can edit it on the fly with
sysctl hw.snd.default_unit=1 |
This switches the default to HDMI. Once disconnected from the TV, I can go back to the laptop speakers with
sysctl hw.snd.default_unit=3 |
If you use this frequently, it might be worth making a shell script.
Vermaden's incredibly useful blog has a section on using pactl (pulse audio control) to switch output on the fly. I haven't had a chance to try it yet, but it seems as if it may be a good solution.
I hope that this helps the reader to quickly and easily use pipewire with HDMI speakers. Some of the docs that I found were lacking in information while others seemed to overcomplicate it. I hope this strikes a happy medium.