Skip to content

Instantly share code, notes, and snippets.

@fstanis
Created July 8, 2024 14:43
Show Gist options
  • Save fstanis/686c7904c0b600743906ae6ceecef4db to your computer and use it in GitHub Desktop.
Save fstanis/686c7904c0b600743906ae6ceecef4db to your computer and use it in GitHub Desktop.
pactl with extensions
#!/bin/bash
# Copyright 2024 Google LLC.
# SPDX-License-Identifier: Apache-2.0
# This script provides a few extensions to pactl, the tool used to reconfigure
# a running PulseAudio sound server during runtime.
# Added commands:
# exists-card Checks if card exists (args: name)
# exists-sink Checks if sink exists (args: name)
# exists-source Checks if source exists (args: name)
# await-card Blocks until card exists (args: name)
# move-all-to-sink Set the default sink and move all sink inputs to it (args: index|name)
# move-all-to-source Set the default source and move all source outputs to it (args: index|name)
# sinks-muted Checks if all sinks are muted
# sources-muted Checks if all sources are muted
# toggle-sinks-mute Mutes or unmutes all sinks
# toggle-sources-mute Mutes or unmutes all sources
# bluez-card-name Generates card name used by bluez (args: mac)
# bluez-a2dp-sink-name Generates an A2DP sink name used by bluez (args: mac)
# Unrecognized commands are passed to pactl.
pactl_exists() {
[[ "${2}" ]] || die "Must specify ${1} name"
pactl list "${1}s" | grep -Fqw -e "Name: ${2}"
}
pactl_await() {
while ! pactl_exists "${1}" "${2}"; do
sleep 1
done
}
pactl_indexes() {
pactl list "${1}s" | grep -oP '^\S[a-zA-Z #]+\K\d+'
}
pactl_move_all_to() {
pactl "set-default-${1}" "${3}" || exit 1
for index in $(pactl_indexes "${1}-${2}"); do
pactl "move-${1}-${2}" "$index" "${3}"
done
}
pactl_is_muted() {
! pactl list "${1}s" | grep -Pq 'Mute:\s+no'
}
pactl_mute() {
for index in $(pactl_indexes ${1}); do
pactl "set-${1}-mute" "$index" "${2}"
done
}
pactl_mute_toggle() {
if pactl_is_muted "${1}"; then
pactl_mute "${1}" false
else
pactl_mute "${1}" true
fi
}
bluez_card_name() {
[[ "${1}" ]] || die "Must specify mac address"
local address="${1//:/_}"
local card="bluez_card.${address}"
echo "$card"
pactl_exists card "$card"
}
bluez_sink() {
pactlx list sinks | grep -Po 'Name: \Kbluez_output.\S+'
}
die() {
echo "$1" >&2 && exit 1
}
main() {
case "$1" in
exists-card)
pactl_exists card "$2"
;;
exists-sink)
pactl_exists sink "$2"
;;
exists-source)
pactl_exists source "$2"
;;
await-card)
pactl_await card "$2"
;;
move-all-to-sink)
pactl_move_all_to sink input "$2"
;;
move-all-to-source)
pactl_move_all_to source output "$2"
;;
sinks-muted)
pactl_is_muted sink
;;
sources-muted)
pactl_is_muted source
;;
toggle-sinks-mute)
pactl_mute_toggle sink
;;
toggle-sources-mute)
pactl_mute_toggle source
;;
bluez-card-name)
bluez_card_name "$2"
;;
bluez-sink)
bluez_sink
;;
*)
pactl "$@"
;;
esac
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment