Skip to content

Instantly share code, notes, and snippets.

@jkcdarunday
Last active April 2, 2024 07:24
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jkcdarunday/617a0f6662726bd85a71e72969c54128 to your computer and use it in GitHub Desktop.
Save jkcdarunday/617a0f6662726bd85a71e72969c54128 to your computer and use it in GitHub Desktop.
A shell script that switches to the next available Pulseaudio/Pipewire Pulse output device/sink
#!/bin/bash
# Author: Jan Keith Darunday <github@jkcdarunday.mozmail.com>
# Description: A shell script that switches to the next available Pulseaudio output device/sink
# Note: This uses pactl instead of pacmd since pacmd is not available in pipewire
function get_current_sink() {
pactl info | sed -En 's/Default Sink: (.*)/\1/p'
}
SINKS=$(pactl list short sinks | grep -v easyeffects)
SINK_COUNT=$(echo "$SINKS" | wc -l)
CURRENT_SINK=$(get_current_sink)
CURRENT_SINK_INDEX=$(echo "$SINKS" | grep -n "$CURRENT_SINK" | grep -Eo '^[0-9]+')
MAX_RETRIES=6
RETRIES=0
while true; do
[ "$RETRIES" -ge "$MAX_RETRIES" ] && echo "Reached retry limit of $MAX_SINK_SKIPS, giving up." && break
NEW_SINK_INDEX=$(((CURRENT_SINK_INDEX + $RETRIES) % $SINK_COUNT + 1))
NEW_SINK=$(echo "$SINKS" | sed "${NEW_SINK_INDEX}q;d" | awk '{ print $2 }')
echo "Switching to sink: $NEW_SINK"
pactl set-default-sink "$NEW_SINK"
[ "$(get_current_sink)" = "$NEW_SINK" ] && break
# Note: switching could fail if, for example, the new sink does not have any available output port
echo "Failed to switch to sink: $NEW_SINK, skipping to next sink..."
RETRIES=$((RETRIES + 1))
done
# Forward all playing audio (sink inputs) to the new sink (Uncomment if your system does not automatically do this)
#SINK_INPUTS=($(pactl list short sink-inputs | grep -Eo '^[0-9]+'))
#for SINK_INPUT in ${SINK_INPUTS[*]}; do pactl move-sink-input $SINK_INPUT $NEW_SINK; done
@Merrit
Copy link

Merrit commented Oct 21, 2022

Exactly what I needed, the streams I previously moved manually weren't switching automatically. Thanks! 💙

@celgit
Copy link

celgit commented Dec 14, 2022

Wow, thank you!
I was fiddling with a similiar solution and was thinking about how to "capture" the ever changing sink id's, but this works like a charm!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment