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.