How do you programmatically change volume in Gnome on Ubuntu, either from the command line or an API (Python preferrably)?

The only answers I found to similar questions use amixer, which seems to have no effect on Ubuntu 12.04. Running:

amixer set Headphone 10-

shows:

Simple mixer control 'Headphone',0
  Capabilities: pvolume pswitch penum
  Playback channels: Front Left - Front Right
  Limits: Playback 0 - 115
  Mono:
  Front Left: Playback 0 [57%] [-57.50dB] [on]
  Front Right: Playback 0 [57%] [-57.50dB] [on]

The x% changes each time I run it. Unfortunately, it has no effect on the actual volume. Eventually it says 0%, but volume is still at full blast.

The other downside is I have to specify the exact active output device, which I might not know if there are multiple devices. For example, if I have a “Master” and “Headphone”, how do I determine which one is the active device?

Ubuntu uses pulseaudio as sounderver. It can be controlled from the command line using the pactl and pacmd utilities, for example:

pactl set-sink-volume 0 20%

would set the volume of the sink #0 to 20%.

see: man pactl and pacmd help


edit:

to avoid -xx being interpreted as command line option you must prefix it with --. That stops option parsing from that point:

pactl set-sink-volume 0 -- -20%    # or:
pactl -- set-sink-volume 0 -20%    # doesn't matter where the `--` goes

I do it using ALSA mixer. You probably need to download python-alsaaudio

sudo apt-get install python-alsaaudio

Then to control volume,

import alsaaudio
m = alsaaudio.Mixer()   # defined alsaaudio.Mixer to change volume
m.setvolume(50) # set volume
vol = m.getvolume() # get volume float value

Read http://pyalsaaudio.sourceforge.net/libalsaaudio.html to know about alsaaudio library in details.

amixer command worked in Ubuntu 13.04,

Increase volume by 5%
amixer -D pulse sset Master 5%+

Decrease volume by 5%
amixer -D pulse sset Master 5%-

pactl or pacmd did not work for me correctly in Ubuntu 13.04.

Dirty snippet to read volume (don’t forget volume goes past “100%” on ubuntu – at which point this returns ~0.66).

#!/usr/bin/python
import subprocess

vol = int(filter(lambda l: l.startswith('set-sink-volume'),
          subprocess.check_output(["pacmd","dump"])
          .split('\n'))[0]
          .split()[-1],16)/100000.

print vol

You could also try the simple and elegant ponymix utill. It makes it very easy to increase/decrease the volume, toggle (mute/unmute) the audio, etc.

First get a list of available audio sources with ponymix

In my case, I can see both a sink 0 and a source 0. I can use either the number 0 or the full name, Built-in Audio Digital Stereo (HDMI), to control the audio.

Increase the volume of card 0 by 5%: ponymix -c 0 increase 5

Decrease the volume of card 0 by 5%: ponymix -c 0 decrease 5

I can recommend this tool that controls pulseaudio:
https://github.com/graysky2/pulseaudio-ctl

[email protected] ~ $ pulseaudio-ctl
pulseaudio-ctl v1.63

/usr/bin/pulseaudio-ctl {up,down,mute,mute-input,set,atmost,full-status} [n]

Where up and down adjust volume in ±5 % increments
Where up and down [n] adjust volume in ±n % increments
Where mute toggles the mute status on/off
Where mute-input toggles the input status on/off
Where set set the volume to [n] %
Where atmost only takes effect if current volume is higher than [n]
Where full-status prints volume level, sink and source mute state to stdout

Optionally, redefine an upper threshold in /home/me/.config/pulseaudio-ctl/config

Volume level     : 80 %
Is sink muted    : no
Is source muted  : no
Detected sink    : 1
Detected source  : 3
Pulse version    : 8.0
[email protected] ~ $