#!/bin/sh # cycle between wireplumber(pipewire) audio sinks parse_sinks() { isaudio= isadsink= while read -r line do case "$line" in Audio) isaudio=true ;; ├─\ Sinks:) [ "$isaudio" = true ] && isadsink=true ;; ├─*:) [ "$isadsink" = true ] && break ;; *) # skip if not inside audio sink [ "$isadsink" != true ] && continue # skip "blank" lines [ -z "${line#│}" ] && continue # clean up input line="${line#│ }" line="${line%%.*}" sinks="${sinks}${line}:" ;; esac done printf "%s" "${sinks%:}" unset isaudio isadsink } cycle_sink() { read -r sinks default_sink= next_sink= IFS=: for sink in $sinks do case "$sink" in \**) default_sink="${sinks#* }" ;; *) if [ -n "$default_sink" ] then next_sink="${sink# }" break fi ;; esac done # if default sink is last one use first sink : "${next_sink:="${sinks%%:*}"}" wpctl set-default "$next_sink" } wpctl status | parse_sinks | cycle_sink