Created
March 9, 2023 16:14
-
-
Save neogeographica/bd6279a8c9562b04263a5812df3448b3 to your computer and use it in GitHub Desktop.
switch audio output (PipeWire... and maybe PulseAudio too?)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# For PipeWire. Based on my previous script for PulseAudio. This one might | |
# also work with PulseAudio since it only uses pactl... haven't tested that. | |
# Unlike on my older PulseAudio system, I didn't need to edit any config file | |
# to disable per-application persistence of sink assignments. | |
# The grepping/sed-ing patterns for various bits of command output may need | |
# to be tweaked to work with other systems or audio devices. | |
# Create an array of sink names. | |
sink_names=() | |
mapfile -t sink_names < <(pactl list short sinks | cut -f2) | |
# Get the name of the default sink. | |
default_sink_name=$(pactl info | grep -oP '^Default Sink:[[:space:]]*\K.+') | |
# Get the last index in the array. | |
final_sink_index=$((${#sink_names[@]} - 1)) | |
# Create a list of the sink descriptions. | |
sink_descriptions=() | |
mapfile -t sink_descriptions < <(pactl list sinks | sed -n -e 's/.*device\.description[[:space:]]=[[:space:]]"\(.*\)"/\1/p') | |
# OK we want to cycle to a new sink that should become the default sink. We | |
# don't want to just "pick the next one" because some sinks are not hooked up | |
# to anything in reality. | |
# Ideally I'd support a list of sinks-to-skip here, but in practice right now | |
# there's only one that I need to skip. | |
blacklisted_sink_desc="HDA NVidia" | |
# Start our search for next-sink-to-use at the current default sink. | |
for index in "${!sink_names[@]}"; do | |
if [[ "${sink_names[$index]}" == "$default_sink_name" ]]; then | |
next_sink_index=$index | |
fi | |
done | |
# Begin the search. | |
looping=true | |
while [[ $looping == true ]] ; do | |
# Choose the next sink in the array. Wrap around to the beginning if needed. | |
if [[ $next_sink_index -ne $final_sink_index ]] ; then | |
next_sink_index=$((next_sink_index + 1)) | |
else | |
next_sink_index=0 | |
fi | |
next_sink_name=${sink_names[$next_sink_index]} | |
# Terminate the search if we've come back to our original starting point. | |
if [[ "$next_sink_name" == "$default_sink_name" ]] ; then | |
looping=false | |
fi | |
# Terminate the search if we found a non-blacklisted sink. | |
if [[ "${sink_descriptions[$next_sink_index]}" != "$blacklisted_sink_desc" ]] ; then | |
looping=false | |
fi | |
done | |
# Change the default sink. | |
pactl set-default-sink $next_sink_name | |
# Move all current inputs to the new default sink. | |
for input_id in $(pactl list short sink-inputs | cut -f1); | |
do | |
pactl move-sink-input $input_id $next_sink_name | |
done | |
# And notify! | |
notify-send -i audio-volume-high "Sound output switched to ${sink_descriptions[$next_sink_index]}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment