#!/bin/sh set -e [ -n "$DEBUG" ] && set -x DEFAULT_PROFILE="output:analog-stereo+input:analog-stereo" HDMI_PROFILE="output:hdmi-stereo" export MENU_PROMPT="soundswitch" global= focused= profile= hdmi= reset= output= input= usage() { printf "usage: %s [-gfhr]\n" "$(basename "$0")" printf "\n" printf " -O \t(manipulate pulseaudio sinks)\n" printf " -I \t(manipulate pulseaudio sources)\n" printf " -g \t(set default sink and switch global output)\n" printf " -f \t(switch focused container output)\n" printf " -p \t(switch card profile)\n" printf " -H \t(switch card to HDMI profile)\n" printf " -R \t(switch card to default profile)\n" printf "\n" printf "Needs swq(1) to work.\n" exit 2 } while getopts OIfgpHRh name; do case ${name} in g) global=1 ;; f) focused=1 ;; p) profile=1 ;; H) hdmi=1 ;; R) reset=1 ;; O) output=1 ;; I) input=1 ;; h|?) usage ;; esac done if [ "$#" -lt 1 ]; then printf "global\nfocused\ncard profile\nhdmi profile\nreset profile\n" | menu | { read -r line case ${line} in global) exec "$0" -g ;; focused) exec "$0" -f ;; "card profile") exec "$0" -p ;; "hdmi profile") exec "$0" -H ;; "reset profile") exec "$0" -R ;; *) usage ;; esac } exit $? fi if [ -n "$global" ] || [ -n "$focused" ]; then if [ -z "$output" ] && [ -z "$input" ]; then printf "output\ninput\n" | menu | { read -r line case ${line} in output) exec "$0" -O "$*" ;; input) exec "$0" -I "$*" ;; *) usage ;; esac } exit $? fi fi [ -n "$output" ] && keyword="sink" && what="sink-input" [ -n "$input" ] && keyword="source" && what="source-output" # returns the sink_id selects() { pactl list short "${keyword}s" | awk '{print $2}' | menu } if [ -n "${global}" ] then target=$(selects) notify-send -a soundswitch "soundswitch: global" "switch to ${target}" # set new default pactl "set-default-${keyword}" "${target}" # move all attached to the new target pactl list "${what}s" short | cut -f1 \ | xargs -i pactl "move-${what}" "{}" "${target}" elif [ -n "${focused}" ] then # parse pid of currently focused container # then get the sink-inputs for it and parse the sink-input-id focused_binary=$(swq current con | jq -r '.pid' | xargs ps -o comm=) what_id=$(printf "%s\n" "${focused_binary}" \ | xargs pacmd "list-${what}s" \ | tr '\n' '\r' \ | perl -pe 's/[^\r]*index: ([0-9]+).+?application\.process\.binary = "([^\r]+)"\r.+?(?=index:|$)/\2=\1\r/g' \ | tr '\r' '\n' \ | grep "^{}" \ | cut -d'=' -f2) [ -z "${what_id}" ] && exit 1 # select where to switch to target=$(selects) [ -z "${what_id}" ] && exit 1 notify-send -a soundswitch "soundswitch: ${focused_binary}" "switch to ${target}" pacmd move-sink-input "${what_id}" "${target}" elif [ -n "${profile}" ] then target_card=$(pactl list short cards | awk '{print $2}' | menu) target_profile=$(pacmd list-cards \ | tr '\n' '\r' \ | perl -pe 's/[^\r]index: ([0-9]+).+?name: \r.+profiles:\r(.+)sinks:.*?(?=index:|$)/\2\r/g' \ | tr -d '\t' \ | tr '\r' '\n' \ | tail -n+2 \ | menu \ | perl -pe 's/^\s*([^\s]+):\s.*$/\1/') notify-send -a soundswitch "soundswitch: profile" "switch ${target_card} to ${target_profile} profile" pactl set-card-profile "${target_card}" ${target_profile} elif [ -n "${hdmi}" ] then target_card=$(pactl list short cards | awk '{print $2}' | menu) notify-send -a soundswitch "soundswitch: hdmi" "switch ${target_card} to HDMI profile" pactl set-card-profile "${target_card}" ${HDMI_PROFILE} exit $? elif [ -n "${reset}" ] then target_card=$(pactl list short cards | awk '{print $2}' | menu) notify-send -a soundswitch "soundswitch: reset" "switch ${target_card} to default profile" pactl set-card-profile "${target_card}" ${DEFAULT_PROFILE} fi