Check PulseAudio sink volume

You can use pactl list sinks to get info on the current state of your sinks. This returns a lot of information, including the volume. So, to get only the volume of sink 1, you can use:

pactl list sinks | perl -000ne 'if(/#1/){/(Volume:.*)/; print "$1\n"}'

This will return something like:

Volume: 0:  50% 1:  50%

The above perl command will print the details of sink 1. To use a different sink, change the #1 to another number, for example #0.

I am not sure what the two 50% mean, I assume they are the left and right speaker volumes. So, in order to check if they are above or below a specific value, (assuming that the balance is set to "center", that both left and right volumes are identical so only one needs to be checked), you can do:

pactl list sinks | perl -000lne 'if(/#1/){/Volume:.*?(\d+)%/; $1 >= 50 ? (print "y\n") : (print "n\n")}'

The above will print a y if the volume is greater than or equal to 50 and an n otherwise. This is all getting a bit complex though, so I would simplify by creating a script:



    #!/usr/bin/env perl 
    
    ## The sink we are interested in should be given as the 
    ## 1st argument to the script.
    die("Need a sink number as the first argument\n") if @ARGV < 1;
    my $sink=$ARGV[0];
    
    ## If the script has been run with a second argument,
    ## that argument will be the volume threshold we are checking
    my $volume_limit=$ARGV[1]||undef;
    
    ## Run the pactl command and save the output in 
    ## ther filehandle $fh
    open(my $fh, '-|', 'pactl list sinks');
    
    ## Set the record separator to consecutive newlines (same as -000)
    ## this means we read the info for each sink as a single "line".
    $/="\n\n";
    
    ## Go through the pactl output
    while (<$fh>) {
        ## If this is the sink we are interested in
        if (/#$sink/) {
            ## Extract the current colume of this sink
            /Volume:.*?(\d+)%/;
            my $volume=$1;
            ## If the script has been run with a second argument,
            ## check whether the volume is above or below that
            if ($volume_limit) {
                ## If the volume os greater than or equal to the
                ## value passed, print "y"
                if ($volume >= $volume_limit) {
                   print "y\n";
                    exit 0;
                }
                else {
                    print "n\n";
                    exit 1;
                }
            }   
            ## Else, if the script has been run with just one argument,
            ## print the current volume.
            else {
                print "$volume%\n";
            }
        }
}

Save the script above as check_volume.pl in a directory in your $PATH (for example, /usr/local/bin), make it executable, chmod +x check_volume.pl and then run it giving the sink you are interested as the first argument:

$ check_volume.pl 1
50%

To check whether the volume is above a given threshold, give the threshold as a second argument:

$ check_volume.pl 1 50
y
$ check_volume.pl 1 70
n

Note that this assumes your system language is English. If it isn't run the script with a changed locale:

LC_ALL=C check_volume.pl 1 50

You can use amixer to read the pulseaudio volume by using the mixer option like this.

$ amixer -c $CARD -M -D $MIXER get $SCONTROL
# CARD is your sound card number, mixer is either alsa or pulse and scontrol is the alsa device name, Master if you want to use pulse.
$ amixer -c 1 -M -D pulse get Master

Simple mixer control 'Master',0
  Capabilities: pvolume pswitch pswitch-joined
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 65536
  Mono:
  Front Left: Playback 27662 [42%] [on]
  Front Right: Playback 27662 [42%] [on]

Now we can parse it using grep or sed or perl.

$ amixer -c 1 -M -D pulse get Master | grep -o -E [[:digit:]]+%