You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							200 lines
						
					
					
						
							5.5 KiB
						
					
					
				
			
		
		
	
	
							200 lines
						
					
					
						
							5.5 KiB
						
					
					
				#!/bin/bash -eu | 
						|
 | 
						|
# --------------------------------------------------------- | 
						|
# Lazy Variables | 
						|
__save() { | 
						|
    local name=$1 | 
						|
    shift | 
						|
    declare -g $name="$*" | 
						|
} | 
						|
 | 
						|
require() { | 
						|
    for name in $@; do | 
						|
        if [ -z "${!name+x}" ]; then | 
						|
            get_$name "__save $name" "require_for $name" | 
						|
        fi | 
						|
    done | 
						|
} | 
						|
 | 
						|
shopt -s expand_aliases | 
						|
alias greq='$2 ' | 
						|
alias gsave='$1 ' | 
						|
 | 
						|
typeset -gA require_depends=() | 
						|
 | 
						|
invalidate() { | 
						|
    for name in $@; do | 
						|
        unset -v $name | 
						|
        if [ -n "${require_depends[$name]:-""}" ]; then | 
						|
            local tmp="${require_depends[$name]}" | 
						|
            unset -v require_depends[$name] | 
						|
            invalidate $tmp | 
						|
        fi | 
						|
    done | 
						|
} | 
						|
 | 
						|
require_for() { | 
						|
    local self_name=$1 | 
						|
    shift | 
						|
    require $@ | 
						|
    for name in $@; do | 
						|
        require_depends[$name]="${require_depends[$name]-""} $self_name" | 
						|
    done | 
						|
} | 
						|
 | 
						|
# --------------------------------------------------------- | 
						|
# Lazy variables | 
						|
get_ponymix_prog() { | 
						|
    gsave $(which ponymix 2>/dev/null) | 
						|
} | 
						|
 | 
						|
get_pacmd_prog() { | 
						|
    # May be unavailable if only pulse clients installed | 
						|
    gsave $(which pacmd 2>/dev/null) | 
						|
} | 
						|
 | 
						|
get_default_sink() { | 
						|
    gsave $(pactl info | grep 'Default Sink' | cut -d: -f2) | 
						|
} | 
						|
 | 
						|
# There doesn't seem to be a better way to get a sink volume right now | 
						|
get_pacmd_dump() { | 
						|
    greq pacmd_prog | 
						|
    [ -n "$pacmd_prog" ] || { echo "ERROR: \$pacmd_dump requires available pacmd which is part of the pulseaudio server package"; exit 44; } | 
						|
    gsave "$(pacmd dump)" | 
						|
} | 
						|
 | 
						|
get_pacmd_default_sink_config() { | 
						|
    greq pacmd_dump default_sink | 
						|
    gsave "$(echo "$pacmd_dump" | grep "$default_sink")" | 
						|
} | 
						|
 | 
						|
get_pacmd_default_volume() { | 
						|
    greq pacmd_default_sink_config | 
						|
    gsave $[$(echo "$pacmd_default_sink_config" | grep "set-sink-volume" | cut -d' ' -f3)] | 
						|
} | 
						|
 | 
						|
get_default_volume_percent() { | 
						|
    greq ponymix_prog | 
						|
    if [ -n "$ponymix_prog" ]; then | 
						|
        gsave $($ponymix_prog get-volume) | 
						|
    else | 
						|
        greq pacmd_default_volume | 
						|
        gsave $[(100*$pacmd_default_volume+32768)/65535] | 
						|
    fi | 
						|
} | 
						|
 | 
						|
get_default_mute() { | 
						|
    greq ponymix_prog | 
						|
    if [ -n "$ponymix_prog" ]; then | 
						|
        $ponymix_prog is-muted && gsave yes || gsave no | 
						|
    else | 
						|
        greq pacmd_default_sink_config | 
						|
        gsave $(echo "$pacmd_default_sink_config" | grep "set-sink-mute" | cut -d' ' -f3) | 
						|
    fi | 
						|
} | 
						|
 | 
						|
# --------------------------------------------------------- | 
						|
# Operations | 
						|
do_vol() { | 
						|
    # Set default sink volume | 
						|
    require default_sink | 
						|
    local offset | 
						|
    case "$1" in | 
						|
        m|mute) | 
						|
            pactl set-sink-mute $default_sink true | 
						|
            ;; | 
						|
        u|unmute) | 
						|
            pactl set-sink-mute $default_sink false | 
						|
            ;; | 
						|
        t|toggle|toggle-mute) | 
						|
            pactl set-sink-mute $default_sink toggle | 
						|
            ;; | 
						|
        \+) : ${offset:=+5%};& | 
						|
        \-) : ${offset:=-5%};& | 
						|
        *)  : ${offset:=$1} | 
						|
            pactl set-sink-mute $default_sink false | 
						|
            pactl set-sink-volume $default_sink $offset | 
						|
            ;; | 
						|
    esac | 
						|
    invalidate pacmd_dump default_volume_percent default_mute | 
						|
} | 
						|
 | 
						|
do_notify() { | 
						|
    # Notification | 
						|
    if which dunstify >/dev/null 2>&1 && [ -n "`pgrep --ns $$ -u $(id -u) dunst`" ]; then | 
						|
        require default_sink default_volume_percent default_mute | 
						|
        dunst_id=6533319 | 
						|
        if [ $default_mute = yes ]; then | 
						|
            icon=audio-volume-muted | 
						|
            text="Volume muted" | 
						|
        else | 
						|
            text="Volume $default_volume_percent%" | 
						|
            if [ $default_volume_percent -lt 35 ]; then | 
						|
                icon=audio-volume-low | 
						|
            elif [ $default_volume_percent -lt 75 ]; then | 
						|
                icon=audio-volume-medium | 
						|
            else | 
						|
                icon=audio-volume-high | 
						|
            fi | 
						|
        fi | 
						|
        if echo $default_sink | grep -q bluez; then | 
						|
            text="Bluetooth $text" | 
						|
        fi | 
						|
        bar_size=20 | 
						|
        filled=$[(($bar_size * $default_volume_percent) + (100 / (2 * $bar_size)))/100] | 
						|
        bar= | 
						|
        if [ $filled -gt 0 ]; then | 
						|
            bar="`printf %.s● $(seq $filled)`" | 
						|
        fi | 
						|
        if [ $filled -lt $bar_size ]; then | 
						|
            bar="$bar`printf %.s○ $(seq $[$bar_size-$filled])`" | 
						|
        fi | 
						|
        dunstify -a "PA Volume" -u low -i $icon -r $dunst_id "$text" "$bar" | 
						|
    fi | 
						|
} | 
						|
 | 
						|
do_print() { | 
						|
    require default_sink default_volume_percent default_mute | 
						|
    [ $default_mute = yes ] && muted=muted || muted=unmuted | 
						|
    echo "$default_sink $default_volume_percent% $muted" | 
						|
} | 
						|
 | 
						|
# --------------------------------------------------------- | 
						|
# Main | 
						|
 | 
						|
while [ $# -gt 0 ]; do | 
						|
    verb=$1; shift | 
						|
 | 
						|
    case $verb in | 
						|
        v|vol|volume) | 
						|
            do_vol "$1"; shift | 
						|
            do_notify | 
						|
            do_print | 
						|
            ;; | 
						|
        set-volume) | 
						|
            do_vol "$1"; shift | 
						|
            ;; | 
						|
        n|notify) | 
						|
            do_notify | 
						|
            ;; | 
						|
        p|print) | 
						|
            do_print | 
						|
            ;; | 
						|
        get-default-sink) | 
						|
            require default_sink | 
						|
            echo $default_sink | 
						|
            ;; | 
						|
        *) | 
						|
            echo "Available verbs:" | 
						|
            echo "  set-volume <[+-]n%|mute|unmute|toggle>  Change default sink volume" | 
						|
            echo "  notify                                  Display a notification with current default sink volume" | 
						|
            echo "  print                                   Print the default sink and it's volume" | 
						|
            echo "  volume <see set-volume>                 Short for \"set-volume <...> notify print\"" | 
						|
            echo "  get-default-sink                        Print default sink name" | 
						|
            echo | 
						|
            echo " verbs can be chained by separating them with space. Note that some have additional arguments" | 
						|
            exit 1 | 
						|
            ;; | 
						|
    esac | 
						|
done
 | 
						|
 |