How to achieve (automated) simultaneous outputs with Pipewire?
I’d like to have my system automatically output to all available sound devices (preferably using a sink in Pulseaudio Volume Control). This was possible when using Pulseaudio alone.
Is it possible with Pipewire? If yes, how would you achieve this?
Is it possible to set this up to be available automatically?
I finally found the answer after reporting a bug and getting a response to my question. The solution is so amazingly simple:
Run:
pactl load-module module-combine-sink
And you get the same functionality with PipeWire.
If I’m understanding these instructions correctly, you can make this permanent by copying /usr/share/pipewire/pipewire-pulse.conf
to ~/.config/pipewire/pipewire-pulse.conf
and adding:
context.exec = [
{ path = "pactl" args = "load-module module-combine-sink" }
]
Then saving the file. Alternatively, you can add the first command to your startup applications.
You can check with helvum
if sinks and sources are properly connected.
This is to supplement OP’s answer:
According to man pipewire.conf
(and a bit of inferencing), you can use drop-in files to the same effect, so this should be the preferred way to do it IMO.
The directories are /etc/pipewire/pipewire-pulse.conf.d/
for global and $XDG_CONFIG_HOME/pipewire/pipewire-pulse.conf.d/
for user (which defaults to ~/.config/pipewire/pipewire-pulse.conf.d/
if $XDG_CONFIG_HOME
is unset).
So just create this file (mkdir -p
if directory does not exist):
$XDG_CONFIG_HOME/pipewire/pipewire.conf.d/add-combined-sink.conf
context.exec = [
{ path = "pactl" args = "load-module module-combine-sink" }
]
Note that in my testing, if I put the drop-in file in /etc/pipewire/pipewire-pulse.conf.d/
, something weird happens to the combined output (pitch becomes higher and introduces regular stutters).
If I have to guess, it’s probably something related to the modules’ loading order: most likely there is a way to fix it, but I haven’t bothered to investigate. Putting it in $XDG_CONFIG_HOME/pipewire/pipewire-pulse.conf.d/
works just fine though, so that’s what I did.
With PipeWire version 0.3.65, we have a native module available as well: module-combine-stream
.
For the simultaneous output configuration, you’ll want to use something like the following in pipewire.conf
, adapted from the example in the documentation:
context.modules = [
{ name = libpipewire-module-combine-stream
args = {
combine.mode = sink
node.name = "my_combined_sink"
node.description = "My Combined Sink"
combine.props = {
audio.position = [ FL FR ]
}
stream.rules = [
{
matches = [
{
media.class = "Audio/Sink"
}
]
actions = {
create-stream = {
}
}
}
]
}
}
]
If you only want to combine specific sinks, you can of course add more entries to the matches
array and specify node.name
instead of matching all sinks.
If you don’t know their names already, you can get all available sink names via pw-link -o
.