The bare $HOME repo is gone. This is now the rice: install.sh, rice-* scripts in bin/, configs in home/ linked into $HOME, theme templates, st and the particle wallpaper. Clone to ~/rice and run install.sh.
61 lines
2.8 KiB
Bash
Executable file
61 lines
2.8 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# rice-audio - audio state for the eww panel, and the actions it runs.
|
|
#
|
|
# rice-audio watch JSON on every change (eww deflisten)
|
|
# rice-audio sink <name> default output; playing streams move with it
|
|
# rice-audio source <name> default input
|
|
# rice-audio app-volume <index> <pct> volume of one playing app
|
|
# rice-audio app-mute <index>
|
|
# rice-audio mic <pct> | mic-mute
|
|
set -uo pipefail
|
|
|
|
snapshot() {
|
|
jq -cn \
|
|
--arg dsink "$(pactl get-default-sink 2>/dev/null)" \
|
|
--arg dsrc "$(pactl get-default-source 2>/dev/null)" \
|
|
--argjson sinks "$(pactl -f json list sinks 2>/dev/null || echo '[]')" \
|
|
--argjson sources "$(pactl -f json list sources 2>/dev/null || echo '[]')" \
|
|
--argjson apps "$(pactl -f json list sink-inputs 2>/dev/null || echo '[]')" '
|
|
def pct: [.volume[]?.value_percent | rtrimstr("%") | tonumber] | if length > 0 then (add / length | round) else 0 end;
|
|
def level: {name: (.description // ""), vol: pct, muted: (.mute // false)};
|
|
{
|
|
sink: (($sinks | map(select(.name == $dsink)) | .[0]) // {} | level),
|
|
source: (($sources | map(select(.name == $dsrc)) | .[0]) // {} | level),
|
|
sinks: [ $sinks[] | {index, name, desc: .description, default: (.name == $dsink)} ],
|
|
sources: [ $sources[] | select(.name | endswith(".monitor") | not)
|
|
| {index, name, desc: .description, default: (.name == $dsrc)} ],
|
|
apps: [ $apps[] | {id: .index,
|
|
name: (.properties["application.name"] // .properties["media.name"] // "app"),
|
|
vol: pct, muted: .mute} ]
|
|
}'
|
|
}
|
|
|
|
watch() {
|
|
snapshot
|
|
pactl subscribe 2>/dev/null |
|
|
grep --line-buffered -E "'(change|new|remove)' on (sink|source|sink-input|server)" |
|
|
while read -r _; do
|
|
# A slider drag fires dozens of events; wait for the burst to end.
|
|
while read -r -t 0.08 _; do :; done
|
|
snapshot
|
|
done
|
|
}
|
|
|
|
# Panel buttons pass numeric indexes, never device names, so nothing a
|
|
# device reports about itself ends up inside a shell command.
|
|
num() { [[ ${1:-} =~ ^[0-9]+$ ]] || { echo "rice-audio: expected a number, got '${1:-}'" >&2; exit 2; }; }
|
|
|
|
case "${1:-}" in
|
|
watch) watch ;;
|
|
sink)
|
|
num "${2:-}"
|
|
pactl set-default-sink "$2"
|
|
pactl -f json list sink-inputs | jq -r '.[].index' | while read -r i; do pactl move-sink-input "$i" "$2"; done
|
|
;;
|
|
source) num "${2:-}"; pactl set-default-source "$2" ;;
|
|
app-volume) num "${2:-}"; num "${3:-}"; pactl set-sink-input-volume "$2" "$3%" ;;
|
|
app-mute) num "${2:-}"; pactl set-sink-input-mute "$2" toggle ;;
|
|
mic) num "${2:-}"; wpctl set-volume -l 1.0 @DEFAULT_AUDIO_SOURCE@ "$2%" ;;
|
|
mic-mute) rice-volume mic-mute ;;
|
|
*) sed -n '2,10p' "$0" | sed 's/^# \{0,1\}//'; exit 2 ;;
|
|
esac
|