Files
arch-i3/dotfiles/local/bin/volume
T
2026-09-14 15:31:20 -05:00

67 lines
1.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# Volume / mic control with a dunst OSD. usage: volume up|down|mute|micmute|set <n>
set -uo pipefail
STEP="${VOLUME_STEP:-5}"
MAX="${VOLUME_MAX:-100}"
SINK="@DEFAULT_AUDIO_SINK@"
SOURCE="@DEFAULT_AUDIO_SOURCE@"
ID=2593 # fixed notification id => the OSD replaces itself instead of stacking
have() { command -v "$1" >/dev/null 2>&1; }
have wpctl || { echo "wpctl (wireplumber) not found" >&2; exit 1; }
get_volume() {
wpctl get-volume "$SINK" | awk '{printf "%d", $2 * 100}'
}
is_muted() {
wpctl get-volume "$SINK" | grep -q MUTED
}
osd() {
have dunstify || return 0
local icon="$1" text="$2" value="$3"
dunstify -a osd -u low -r "$ID" -h "int:value:$value" -i "$icon" "$text"
}
case "${1:-}" in
up)
wpctl set-mute "$SINK" 0
wpctl set-volume -l "$(awk "BEGIN{print $MAX/100}")" "$SINK" "${STEP}%+"
;;
down)
wpctl set-mute "$SINK" 0
wpctl set-volume "$SINK" "${STEP}%-"
;;
set)
wpctl set-volume -l "$(awk "BEGIN{print $MAX/100}")" "$SINK" "${2:?need a percentage}%"
;;
mute)
wpctl set-mute "$SINK" toggle
;;
micmute)
wpctl set-mute "$SOURCE" toggle
if wpctl get-volume "$SOURCE" | grep -q MUTED; then
osd microphone-sensitivity-muted "Microphone muted" 0
else
osd microphone-sensitivity-high "Microphone live" 100
fi
exit 0
;;
""|-h|--help)
echo "usage: volume up|down|mute|micmute|set <percent>"; exit 0 ;;
*)
echo "unknown action: $1" >&2; exit 2 ;;
esac
vol="$(get_volume)"
if is_muted; then
osd audio-volume-muted "Muted" 0
elif (( vol >= 66 )); then osd audio-volume-high "Volume ${vol}%" "$vol"
elif (( vol >= 33 )); then osd audio-volume-medium "Volume ${vol}%" "$vol"
else osd audio-volume-low "Volume ${vol}%" "$vol"
fi
# Nudge polybar so the bar updates instantly rather than on its 5s poll
pkill -RTMIN+1 polybar 2>/dev/null || true