47 lines
1.6 KiB
Bash
Executable File
47 lines
1.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Default sink / source volume for the popup. Refreshes on PipeWire events
|
|
# (pactl subscribe on the pipewire-pulse socket) and every 30 s.
|
|
#
|
|
# volume status loop (deflisten)
|
|
# volume setvol SINK|SOURCE PERCENT
|
|
# volume mute SINK|SOURCE
|
|
|
|
icons=("" "" "")
|
|
|
|
level() { # prints "<percent> <muted>"
|
|
wpctl get-volume "@DEFAULT_AUDIO_$1@" 2>/dev/null \
|
|
| awk '{ printf "%d %s\n", $2 * 100 + 0.5, ($0 ~ /MUTED/) ? "true" : "false" }'
|
|
}
|
|
|
|
sink_name() {
|
|
wpctl inspect @DEFAULT_AUDIO_SINK@ 2>/dev/null \
|
|
| awk -F'"' '/node\.nick/ { n = $2 } /node\.description/ { d = $2 } END { print (n != "" ? n : d) }'
|
|
}
|
|
|
|
state() {
|
|
local vol muted mic mic_muted icon mic_icon lvl
|
|
read -r vol muted < <(level SINK)
|
|
read -r mic mic_muted < <(level SOURCE)
|
|
vol=${vol:-0} muted=${muted:-false} mic=${mic:-0} mic_muted=${mic_muted:-false}
|
|
lvl=$((vol >= 67 ? 2 : vol >= 34 ? 1 : 0))
|
|
if [[ $muted == true ]]; then icon=""; else icon=${icons[$lvl]}; fi
|
|
if [[ $mic_muted == true ]]; then mic_icon=""; else mic_icon=""; fi
|
|
printf '{"icon":"%s","percent":%d,"sink_muted":%s,"mic_icon":"%s","microphone":%d,"source_muted":%s,"sink":"%s"}' \
|
|
"$icon" "$vol" "$muted" "$mic_icon" "$mic" "$mic_muted" "$(jstr "$(sink_name)")"
|
|
}
|
|
|
|
refresh() { emit "$(state)"; }
|
|
_pw_events() { pactl subscribe 2>/dev/null | grep --line-buffered -E "on (sink|source|server) "; }
|
|
|
|
case ${1:-} in
|
|
mute) wpctl set-mute "@DEFAULT_AUDIO_$2@" toggle ;;
|
|
setvol) wpctl set-volume -l 1.0 "@DEFAULT_AUDIO_$2@" "${3%.*}%" ;;
|
|
*)
|
|
refresh
|
|
mux_init
|
|
mux_add _pw_events
|
|
mux_tick 30
|
|
mux_loop refresh
|
|
;;
|
|
esac
|