As you know I mainly use Fluxbox on a minimal Ubuntu installation without access to all the every-day functionality provided by panel applets in Gnome, including volume control. Therefore, I have been using pavucontrol for controlling Pulseaudio. It is a really nice application that gives you very finegrained control, for instance over which application should be how loud. Lately I have been annoyed with opening a whole application just for the sake of adjusting volume a little bit, so I set out to find a way to control it via shell. Turns out there is no convenient interface to pulseaudio at all, leaving me to script something together, this time in Ruby. It uses a very unwieldy interface to Pulseaudio named pacmd, contained in Ubuntu package pulseaudio-utils.
#!/usr/bin/ruby def current c = IO::popen("pacmd \"list-sinks\" | grep volume | head -1").readlines[0] return c.split(" ").last.sub("%", "").strip.to_i end def max c = IO::popen("pacmd \"list-sinks\" | grep \"volume steps\" | head -1").readlines[0] return c.split(" ").last.strip.to_i - 1 end def index c = IO::popen("pacmd \"list-sinks\" | grep index | head -1").readlines[0] return c.split(" ").last.strip.to_i end def set(v) IO::popen("pacmd \"set-sink-volume #{index} #{v}\"").readlines end def muted c = IO::popen("pacmd \"list-sinks\" | grep muted | head -1").readlines[0] return c.split(" ").last.strip == "yes" end def toggle t = 1 if ( muted ) t = 0 end IO::popen("pacmd \"set-sink-mute #{index} #{t}\"").readlines end interval = 5 if ( ARGV.size == 0 ) puts current elsif (ARGV[0] == "?" ) puts muted elsif ( ARGV[0] == "+" ) set([current + interval, 100].min * (max / 100.0).round) elsif ( ARGV[0] == "-" ) set([current - interval, 0].max * (max / 100.0).round) elsif ( ARGV[0] == "!" ) toggle end
This is certainly not the most efficient way to do it, retrieving all the info multiple times, but it works and I do not perceive any delays. Note that the script will just use the first sink that pacmd prints, so if you have a setup with multiple sinks you will have to be more clever.
Of course, the obligatory Fluxbox key bindings
None XF86AudioLowerVolume :execCommand pavol - None XF86AudioRaiseVolume :execCommand pavol + None XF86AudioMute :execCommand pavol !
and conky volume display:
Vol: ${exec if [ `pavol ?` != 'true' ]; then echo `pavol`%; else echo 'Muted'; fi}
Update: The script now has a home on GitHub.