Skip to content

Instantly share code, notes, and snippets.

@omgmog
Last active October 11, 2025 19:14
Show Gist options
  • Save omgmog/5bb66598c792f98ccdbe39cfd503488c to your computer and use it in GitHub Desktop.
Save omgmog/5bb66598c792f98ccdbe39cfd503488c to your computer and use it in GitHub Desktop.
SwiftBar audio device switcher
#!/usr/bin/env bash
# <bitbar.title>Audio Output Switcher</bitbar.title>
# <bitbar.version>2.7</bitbar.version>
# <bitbar.author>Your Name</bitbar.author>
# <bitbar.desc>SwiftBar-only output switcher using SF Symbols and UID matching. Active item tinted blue.</bitbar.desc>
# <bitbar.dependencies>bash,SwitchAudioSource</bitbar.dependencies>
# <swiftbar.hideAbout>true</swiftbar.hideAbout>
# <swiftbar.hideRunInTerminal>true</swiftbar.hideRunInTerminal>
# <swiftbar.hideLastUpdated>true</swiftbar.hideLastUpdated>
# <swiftbar.hideDisablePlugin>true</swiftbar.hideDisablePlugin>
# <swiftbar.hideSwiftBar>true</swiftbar.hideSwiftBar>
SWITCH_AUDIO_BIN="${SWITCH_AUDIO_BIN:-SwitchAudioSource}"
# ---- Config: one per line: Label|UID|SF Symbol ----
DEVICES='G635 Gaming Headset|AppleUSBAudioEngine:Logitech:G635 Gaming Headset:00000000:2|headphones
Stage V2|00-02-3C-99-0B-7C:output|speaker.wave.2.fill
MacBook Pro Speakers|BuiltInSpeakerDevice|laptopcomputer'
trim(){ sed 's/^[[:space:]]*//; s/[[:space:]]*$//'; }
die(){ echo "⚠️"; echo "---"; echo "$1"; exit 0; }
command -v "$SWITCH_AUDIO_BIN" >/dev/null 2>&1 || die "SwitchAudioSource not found. Install: brew install switchaudio-osx"
# Click handler
if [ "${1-}" = "set" ] && [ -n "${2-}" ]; then
"$SWITCH_AUDIO_BIN" -t output -u "$2" >/dev/null 2>&1
exit 0
fi
# SF Icon config
SFCONFIG="$(printf '%s' '{"renderingMode":"Hierarchical","scale":"medium", "colors":[]}' | base64 | tr -d '\n\r' | trim)"
# echo "$SFCONFIG" | base64 -d
# Current device UID (JSON)
CURRENT_JSON="$("$SWITCH_AUDIO_BIN" -c -t output -f json 2>/dev/null)"
CUR_UID="$(printf '%s\n' "$CURRENT_JSON" | sed -n 's/.*"uid"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | tr -d '\r' | trim)"
# Menubar icon (active device’s symbol, tinted blue)
ACTIVE_SYMBOL="speaker.wave.2.fill"
while IFS='|' read -r LABEL DEV_UID SYMBOL; do
[ -z "$LABEL$DEV_UID$SYMBOL" ] && continue
DEV_UID="$(printf '%s' "$DEV_UID" | trim)"
SYMBOL="$(printf '%s' "$SYMBOL" | trim)"
if [ -n "$CUR_UID" ] && [ "$DEV_UID" = "$CUR_UID" ]; then
ACTIVE_SYMBOL="$SYMBOL"
break
fi
done <<< "$DEVICES"
echo "| sfimage=$ACTIVE_SYMBOL sfconfig=$SFCONFIG"
echo "---"
# Device rows
while IFS='|' read -r LABEL DEV_UID SYMBOL; do
[ -z "$LABEL$DEV_UID$SYMBOL" ] && continue
LABEL="$(printf '%s' "$LABEL" | trim)"
DEV_UID="$(printf '%s' "$DEV_UID" | trim)"
SYMBOL="$(printf '%s' "$SYMBOL" | trim)"
line="$LABEL | bash='$0' param1=set param2='$DEV_UID' terminal=false refresh=true sfimage=$SYMBOL sfconfig=$SFCONFIG"
if [ -n "$CUR_UID" ] && [ "$DEV_UID" = "$CUR_UID" ]; then
# Tick it, tint the icon and text blue
line="$line checked=true"
fi
echo "$line"
done <<< "$DEVICES"
echo "---"
echo "Sound Settings… | bash='/usr/bin/open' param1='x-apple.systempreferences:com.apple.preference.sound' terminal=false sfimage=gearshape sfconfig=$SFCONFIG"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment