Switch audio output device per application
Pipewire: Change per-application output sink
I wanted the comfort of switching the audio output for running application through a custom keyboard shortcut.
For that I looked into the abyss of Pipewire, PulseAudio and wireplumber applications.
By looking through the output of different tools, like pactl
, pw-cli
, … and finally wpctl
.
The easiest way to achieve this could be by parsing the output of wpctl
provided by wireplumber.
For my solution you need:
- wireplumber (
wpctl
) rofi
pactl
Shell script: pw-change-sink
#!/bin/bash
set -euo pipefail
rofi_cmd() {
rofi "$@"
}
outputs="$(pactl list sinks \
| awk '/Sink/ {sink=$2} /Description:/ {desc=substr($0, length($1)+3, length($0)-length($1)) ; print sink ";" desc}' \
| sed -n -E 's/^#([0-9]+);(.*)/\1\t\2/p' \
| tr -d '"')"
streams="$(pactl list sink-inputs \
| awk '/Sink Input/ {sink=$3} /application.name =/ {print sink ";" $3}' \
| tr -d '#' \
| tr -d '"' \
| tr ';' '\t')"
selected_stream="$(echo "$streams" | rofi_cmd -dmenu -i -p "Active Audio Streams" | awk '{print $1}')"
selected_output="$(echo "$outputs" | rofi_cmd -dmenu -i -p "Available Output Devices" | awk '{print $1}')"
pactl move-sink-input "$selected_stream" "$selected_output"
notify-send -u low --icon=speaker "Audio" "Output for applicationchanged."
The rofi_cmd
is a placeholder for future features, like overwriting the configuration.
When executed only active audio streams are shown. If you are not running an application outputting audio at the moment, you will not see any “Active Audio Stream”.