Improve audio output selector

9490234f03b29e981cfb4899a0eb26f9069046bf
Work with bluetooth speakers.
Alexis Sellier committed ago 1 parent aacdce45
bin/waybar-audio-output-selector +69 -10
1 1
#!/bin/sh
2 2
3 3
sinks=$(pactl -f json list sinks | jq -r '.[] | [.name, .description] | @tsv')
4 -
5 -
[ -n "$sinks" ] || exit 1
6 -
7 4
default=$(pactl get-default-sink)
8 -
sink=$(
5 +
choices=$(
9 6
  printf '%s\n' "$sinks" |
10 -
    awk -F '\t' -v current="$default" '{
7 +
    awk -F '\t' -v current="$default" 'NF {
11 8
      marker = ($1 == current) ? "* " : "  "
12 -
      printf "%s\t%s%s\n", $1, marker, $2
13 -
    }' |
14 -
      fuzzel --dmenu --hide-prompt --lines=6 --width=64 \
9 +
      icon = index($1, "bluez_output.") == 1 ? "󰂯" : "󰕾"
10 +
      printf "sink:%s\t%s%s %s\n", $1, marker, icon, $2
11 +
    }'
12 +
)
13 +
14 +
while read -r prefix address name; do
15 +
  [ "$prefix" = Device ] || continue
16 +
17 +
  info=$(bluetoothctl info "$address")
18 +
  case "$info" in
19 +
    *"UUID: Audio Sink"*) ;;
20 +
    *) continue ;;
21 +
  esac
22 +
23 +
  device_key=$(printf '%s' "$address" | tr ':' '_')
24 +
  case "$sinks" in
25 +
    *"bluez_output.$device_key."*) continue ;;
26 +
  esac
27 +
28 +
  choices="${choices}${choices:+
29 +
}bluetooth:$address	  󰂲 $name"
30 +
done <<EOF
31 +
$(bluetoothctl devices Paired)
32 +
EOF
33 +
34 +
[ -n "$choices" ] || exit 1
35 +
36 +
selection=$(
37 +
  printf '%s\n' "$choices" |
38 +
    fuzzel --dmenu --hide-prompt --lines=6 --width=64 \
15 39
      --with-nth=2 --accept-nth=1 --only-match --no-run-if-empty
16 -
    ) || exit 0
40 +
) || exit 0
41 +
42 +
[ -n "$selection" ] || exit 1
43 +
44 +
case "$selection" in
45 +
  sink:*)
46 +
    sink=${selection#sink:}
47 +
    case "$sink" in
48 +
      bluez_output.*)
49 +
        device_key=${sink#bluez_output.}
50 +
        device_key=${device_key%%.*}
51 +
        address=$(printf '%s' "$device_key" | tr '_' ':')
52 +
        bluetoothctl connect "$address" || exit 1
53 +
        ;;
54 +
    esac
55 +
    ;;
56 +
  bluetooth:*)
57 +
    address=${selection#bluetooth:}
58 +
    bluetoothctl connect "$address" || exit 1
17 59
18 -
[ -n "$sink" ] || exit 1
60 +
    device_key=$(printf '%s' "$address" | tr ':' '_')
61 +
    attempts=0
62 +
    while [ "$attempts" -lt 20 ]; do
63 +
      sink=$(
64 +
        pactl -f json list sinks |
65 +
          jq -r --arg prefix "bluez_output.$device_key." \
66 +
            'first(.[] | select(.name | startswith($prefix)) | .name) // empty'
67 +
      )
68 +
      [ -n "$sink" ] && break
69 +
      sleep 0.25
70 +
      attempts=$((attempts + 1))
71 +
    done
72 +
    [ -n "$sink" ] || exit 1
73 +
    ;;
74 +
  *)
75 +
    exit 1
76 +
    ;;
77 +
esac
19 78
20 79
pactl set-default-sink "$sink"
21 80
pactl list sink-inputs short | awk '{ print $1 }' | while read -r input; do
22 81
  pactl move-sink-input "$input" "$sink"
23 82
done