Rewrite select-sound-output.sh
This commit is contained in:
28
old/pulse/select-sound-output-pulse.sh
Executable file
28
old/pulse/select-sound-output-pulse.sh
Executable file
@ -0,0 +1,28 @@
|
|||||||
|
#!/usr/bin/env zsh
|
||||||
|
local info="$(pactl list sinks)"
|
||||||
|
local default_name="$(pactl info | grep -Po '(?<=Default Sink: ).+')"
|
||||||
|
local ids=(${(@f)"$(echo "${info}" | grep -Po '(?<=Sink #).+')"})
|
||||||
|
local names=(${(@f)"$(echo "${info}" | grep -Po '(?<=Name: ).+')"})
|
||||||
|
local descs=(${(@f)"$(echo "${info}" | grep -Po '(?<=Description: ).+')"})
|
||||||
|
local default_id=""
|
||||||
|
local query_string=""
|
||||||
|
for ((i = 1; i <= "${#ids}"; ++i)); do
|
||||||
|
if [[ "${names[${i}]}" == "${default_name}" ]]; then
|
||||||
|
default_id="${ids[${i}]}"
|
||||||
|
fi
|
||||||
|
query_string+="${ids[${i}]}: ${descs[${i}]} (${names[${i}]})\n"
|
||||||
|
done
|
||||||
|
[[ -v WAYLAND_DISPLAY ]] \
|
||||||
|
&& prompt_cmd=("fuzzel" "-dp" "${default_id}> ") \
|
||||||
|
|| prompt_cmd=("dmenu" "-p" "${default_id}:")
|
||||||
|
local choice
|
||||||
|
choice="$(echo "${query_string%"\n"}" | ${prompt_cmd})"
|
||||||
|
if (( "${?}" != 0 )); then
|
||||||
|
exit
|
||||||
|
fi
|
||||||
|
local selected_id="$(echo "${choice}" | grep -Eo '^[0-9]+')"
|
||||||
|
pactl set-default-sink "${selected_id}"
|
||||||
|
local selected_name="$(echo "${choice}" \
|
||||||
|
| cut -c "$(("${#selected_id}" + 3))-" \
|
||||||
|
| grep -Po '^.+(?= \()')"
|
||||||
|
notify-send 'Output Device' "${selected_name} (${selected_id})"
|
||||||
@ -1,28 +1,78 @@
|
|||||||
#!/usr/bin/env zsh
|
#!/usr/bin/env zsh
|
||||||
local info="$(pactl list sinks)"
|
|
||||||
local default_name="$(pactl info | grep -Po '(?<=Default Sink: ).+')"
|
setopt pipefail typeset_silent
|
||||||
local ids=(${(@f)"$(echo "${info}" | grep -Po '(?<=Sink #).+')"})
|
|
||||||
local names=(${(@f)"$(echo "${info}" | grep -Po '(?<=Name: ).+')"})
|
get_default_sink() {
|
||||||
local descs=(${(@f)"$(echo "${info}" | grep -Po '(?<=Description: ).+')"})
|
local -a first_line
|
||||||
local default_id=""
|
first_line=${${(f)"$(wpctl inspect @DEFAULT_AUDIO_SINK@)"}[1]}
|
||||||
local query_string=""
|
if (( ${?} )); then
|
||||||
for ((i = 1; i <= "${#ids}"; ++i)); do
|
echo "error: getting default sink with wpctl failed with error code ${?}" >&2
|
||||||
if [[ "${names[${i}]}" == "${default_name}" ]]; then
|
exit 1
|
||||||
default_id="${ids[${i}]}"
|
elif [[ ${first_line} =~ '^id ([0-9]+), ' ]]; then
|
||||||
|
printf '%s' "${match}"
|
||||||
|
else
|
||||||
|
echo "error: getting default sink with wpctl failed" >&2
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
query_string+="${ids[${i}]}: ${descs[${i}]} (${names[${i}]})\n"
|
}
|
||||||
|
|
||||||
|
let current_sink="$(get_default_sink)"
|
||||||
|
|
||||||
|
local JQ_SCRIPT=$(<<'EOF'
|
||||||
|
.[] | select(.type == "PipeWire:Interface:Node"
|
||||||
|
and .info.props.["media.class"] == "Audio/Sink")
|
||||||
|
| "\(.id)\u0000\(.info.props.["node.nick"]) - \(.info.props.["node.description"]) (\(.id))\u0000\(.info.props.["device.icon-name"])\u0000"
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
local -a id_desc_pairs
|
||||||
|
|
||||||
|
id_desc_pairs=(${(0)"$(pw-dump | jq -rj "${JQ_SCRIPT}")"})
|
||||||
|
if (( ${?} )); then
|
||||||
|
echo "error: pw-dump or jq failed with error code ${?}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
generate_icon_names() {
|
||||||
|
# I got this idea from the pavucontrol source
|
||||||
|
# - First try the icon name as is
|
||||||
|
# - Then concatenate "-symbolic"
|
||||||
|
# - Then remove the last dash (-) character and everything after it
|
||||||
|
# - Then again try that with "-symbolic"
|
||||||
|
local nonl="${1//%'\n'/}"
|
||||||
|
printf '%s,%s' "${nonl}" "${nonl}-symbolic"
|
||||||
|
if [[ ${1} = *-* ]]; then
|
||||||
|
printf ',%s,%s' "${nonl%-*}" "${nonl%-*}-symbolic"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
local -a ids descs fuzzel_ents
|
||||||
|
|
||||||
|
for id desc icon in ${id_desc_pairs}; do
|
||||||
|
ids+=("${id}")
|
||||||
|
descs+=("${desc}")
|
||||||
|
fuzzel_ents+=("${desc//$'\n'/}" "$(generate_icon_names "${icon}")")
|
||||||
done
|
done
|
||||||
[[ -v WAYLAND_DISPLAY ]] \
|
|
||||||
&& prompt_cmd=("fuzzel" "-dp" "${default_id}> ") \
|
local fuzzel_index
|
||||||
|| prompt_cmd=("dmenu" "-p" "${default_id}:")
|
|
||||||
local choice
|
fuzzel_index="$(printf '%s\0icon\x1f%s\n' ${fuzzel_ents} \
|
||||||
choice="$(echo "${query_string%"\n"}" | ${prompt_cmd})"
|
| fuzzel -p "Cur: ${current_sink}> " --dmenu --index)"
|
||||||
if (( "${?}" != 0 )); then
|
if (( ${?} )); then
|
||||||
exit
|
echo "Canceled by user" >&2
|
||||||
|
exit 0
|
||||||
|
elif [[ ${fuzzel_res} = -1 ]]; then
|
||||||
|
echo "User selected non-existant entry" >&2
|
||||||
|
exit 0
|
||||||
fi
|
fi
|
||||||
local selected_id="$(echo "${choice}" | grep -Eo '^[0-9]+')"
|
|
||||||
pactl set-default-sink "${selected_id}"
|
let new_id=$(( ids[fuzzel_index + 1] ))
|
||||||
local selected_name="$(echo "${choice}" \
|
|
||||||
| cut -c "$(("${#selected_id}" + 3))-" \
|
wpctl set-default ${new_id}
|
||||||
| grep -Po '^.+(?= \()')"
|
if (( ${?} )); then
|
||||||
notify-send 'Output Device' "${selected_name} (${selected_id})"
|
echo 'error: wpctl failed with exit code ${?}' >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
notify-send -t 5000 'Default audio sink changed' \
|
||||||
|
"${descs[${fuzzel_index} + 1]}"
|
||||||
|
|||||||
Reference in New Issue
Block a user