You are not logged in.

#1 2007-12-29 21:56:11

bruenig
Member
Registered: 2007-05-20
Posts: 175

changevol - volume management (good for binding multimedia keys)

I wrote this script to work with my laptop's multimedia keys. It requires python, pygtk, and alsa-utils. It is a non-interactive program that modifies the volume and then pops up a little gui notifier similar to programs like keytouch (but much simpler and less bloated). It was designed to work by binding multimedia keys (using programs like xbindkeys or any WM's/DE's keybinding apps) to the script and that is probably the only real convenient use.

Here is what it looks like (pops up in the middle of the desktop on top of everything else). Don't worry about the color of the bar and such, it is programmed with gtk2, so it will inherit whatever your gtk theme looks like:
6nrr3va.png

Here is the script. To use: just dump into a text file called "changevol", chmod +x it, and put it in the PATH somewhere:

#!/usr/bin/env python

import pygtk
import gtk
import gobject
import commands
import sys
import os
import re
import getopt

def err(msg):
  print msg
  sys.exit(1)

def usage():
  print '''
Usage: changevol [options] [argument]

Options:
  -i, --increase  increase volume by `argument'
  -d, --decrease  decrease volume by `argument'
  -c, --control   specify the mixer control by `argument' (default Master)
                  use only to modify a mixer other than Master

  -t, --toggle    toggle mute on and off
  -s, --status    display current volume status without modifying it
  -q, --quiet     don't display the gtk progressbar, just change the volume
  -b, --backlight adjust the backlight using xbacklight
  -h, --help      display this help message

Note:
  Volume increases and decreases won't be exact due to amixer oddities.
'''
  sys.exit(0)

class GetVolInfo():

  def __init__(self, command):
    self.amixeroutput = commands.getoutput(command)

    if re.compile("off]$", re.M).search(self.amixeroutput, 1):
      self.realvol = "0"
      self.endlabel = "Mute"
    else:
      self.tempvolarray1 = self.amixeroutput.split("[")
      self.tempvolarray2 = self.tempvolarray1[1].split("%")
      self.realvol = self.tempvolarray2[0]
      self.endlabel = self.realvol + " %"

    self.percent = float(self.realvol)/100
    self.label = "Volume " + self.endlabel

class ProgressBar:
  
  def timeout_callback(self):
    gtk.main_quit()
    return False

  def __init__(self, fraction, label):
    self.window = gtk.Window(gtk.WINDOW_POPUP)
    self.window.set_border_width(0)
    self.window.set_default_size(180, -1)
    self.window.set_position(gtk.WIN_POS_CENTER)

    timer = gobject.timeout_add(1000, self.timeout_callback)

    self.bar = gtk.ProgressBar()
    self.bar.set_fraction(fraction)
    self.bar.set_orientation(gtk.PROGRESS_LEFT_TO_RIGHT)
    self.bar.set_text(label)
    self.bar.show()

    self.window.add(self.bar)
    self.window.show()


#Run through parameters, set variables and such
CONTROL = "Master"
AMIXEROPTION = "unset"
QUIET = "NO"
BACKLIGHT = "NO"

if (len(sys.argv) < 2):
  usage()

try:
  opts, args = getopt.getopt(sys.argv[1:], "bqhtsc:i:d:", ["backlight" "quiet", "help", "toggle", "status", "control=", "increase=", "decrease="])
except getopt.GetoptError:
  err("Incorrect usage, see changevol --help.")

if (len(opts) == 0):
  err("Incorrect usage, see --help.")

for opt, arg in opts:
  if opt in ("-h", "--help"):
    usage()
  elif opt in ("-q", "--quiet"):
    QUIET = "YES"
  elif opt in ("-b", "--backlight"):
    BACKLIGHT = "YES"
  elif opt in ("-t", "--toggle"):
    AMIXEROPTION = "toggle"
  elif opt in ("-s", "--status"):
    INCREMENT = "0"
    AMIXEROPTION = INCREMENT + "%+"
  elif opt in ("-c", "--control"):
    CONTROL = arg
  elif opt in ("-i", "--increase"):
    INCREMENT = arg
    AMIXEROPTION = INCREMENT + "%+"
  elif opt in ("-d", "--decrease"):
    INCREMENT = arg
    AMIXEROPTION = INCREMENT + "%-"
  else:
    err("Incorrect usage, see --help")

if (AMIXEROPTION == "unset"):
  err("No volume changing action has been dictated. See changevol --help.")

command = "amixer set " + CONTROL + " " + AMIXEROPTION

#Execution
volume = GetVolInfo(command)
if (QUIET == "NO"):
  ProgressBar(volume.percent, volume.label)
  gtk.main()

if (BACKLIGHT == "YES"):
  os.execv('/usr/bin/xbacklight', ['placeholder', '-set', volume.realvol])

Here is the usage synopsis (it can be accessed with changevol --help):

Usage: changevol [options] [argument]

Options:
  -i, --increase  increase volume by `argument'
  -d, --decrease  decrease volume by `argument'
  -c, --control   specify the mixer control by `argument' (default Master)
                  use only to modify a mixer other than Master

  -t, --toggle    toggle mute on and off
  -s, --status    display current volume status without modifying it
  -q, --quiet     don't display the gtk progressbar, just change the volume
  -b, --backlight adjust the backlight using xbacklight
  -h, --help      display this help message

Note:
  Volume increases and decreases won't be exact due to amixer oddities.

Edit: Changed mute handling a bit.
Edit2: Added a -c, --control option for an amixer interface other than Master
Edit3: Added a -s, --status option to just display the current volume status without modifying it
Edit4: Added a -q, --quiet option to not show the progress bar and just change the volume
Edit5: Added a -b, --backlight option to adjust the backlight along with the volume change (someone asked for it, so why the hell not right?)

Last edited by bruenig (2008-02-03 06:43:07)

Offline

#2 2007-12-29 22:26:00

rson451
Member
From: Annapolis, MD USA
Registered: 2007-04-15
Posts: 1,233
Website

Re: changevol - volume management (good for binding multimedia keys)

very nice. as soon as a boot up my laptop tonight i'll be playin with this. thanks bruenig


archlinux - please read this and this — twice — then ask questions.
--
http://rsontech.net | http://github.com/rson

Offline

#3 2007-12-30 17:57:50

sergejx
Member
From: Czechoslovakia
Registered: 2006-10-24
Posts: 9
Website

Re: changevol - volume management (good for binding multimedia keys)

Thank you for great script. Maybe you should make name of mixer control configurable. For example I don't have 'Master' control, instead I use 'Front'.

Offline

#4 2007-12-30 19:04:26

thayer
Fellow
From: Vancouver, BC
Registered: 2007-05-20
Posts: 1,560
Website

Re: changevol - volume management (good for binding multimedia keys)

Great stuff... thanks!


thayer williams ~ cinderwick.ca

Offline

#5 2007-12-30 20:22:10

bruenig
Member
Registered: 2007-05-20
Posts: 175

Re: changevol - volume management (good for binding multimedia keys)

sergejx wrote:

Thank you for great script. Maybe you should make name of mixer control configurable. For example I don't have 'Master' control, instead I use 'Front'.

I have changed the script in the first post to provide that option, tell me if it works.

Last edited by bruenig (2007-12-30 20:43:54)

Offline

#6 2007-12-30 20:29:44

cu3edweb
Member
From: USA
Registered: 2007-10-07
Posts: 291

Re: changevol - volume management (good for binding multimedia keys)

very awesome!!

Thanks

Offline

#7 2007-12-31 01:47:57

delaril
Member
Registered: 2007-02-11
Posts: 9

Re: changevol - volume management (good for binding multimedia keys)

A handy script, thanks!

Offline

#8 2007-12-31 02:36:19

ralvez
Member
From: Canada
Registered: 2005-12-06
Posts: 1,694
Website

Re: changevol - volume management (good for binding multimedia keys)

I gave it a spin but every time I get the same answer: "No volume changing action has been dictated."
Can you provide an example of issuing the command using xbindkeys? or even what I should be issuing on the command line? I must be doing something wrong ... and I do not feel like studying the code to figure it out since you can give me the answer just as fast smile

Offline

#9 2007-12-31 03:17:22

bruenig
Member
Registered: 2007-05-20
Posts: 175

Re: changevol - volume management (good for binding multimedia keys)

ralvez wrote:

I gave it a spin but every time I get the same answer: "No volume changing action has been dictated."
Can you provide an example of issuing the command using xbindkeys? or even what I should be issuing on the command line? I must be doing something wrong ... and I do not feel like studying the code to figure it out since you can give me the answer just as fast smile

The usage synopsis is in the first post or available by just doing "changevol" or changevol -h|--help.

But to increase the volume by 5:

changevol -i 5

To decrease the volume by 5:

changevol -d 5

To toggle mute on and off:

changevol -t

If you need to specify a mixer other than "Master" which is the default mixer, you use the -c flag, so say you needed to use the mixer "Front" to increase by 5:

changevol -c Front -i 5

I see there is a problem in the code where it says No volume changing action has been dictated when I want it to say Incorrect usage, see changevol --help. I will try to fix that. Still learning python.

Edit: I have changed it to see if getopts returns no options and then if so print back the Incorrect usage error message. That should do a lot to direct people to the right, direction. I have also, changed the No volume changing action one, to also direct to --help.

Last edited by bruenig (2007-12-31 03:27:37)

Offline

#10 2007-12-31 03:23:34

ralvez
Member
From: Canada
Registered: 2005-12-06
Posts: 1,694
Website

Re: changevol - volume management (good for binding multimedia keys)

Thanks for the reply.
Well ... this is most interesting. I issued the command: changevol -c Front -i 1 and what I got was the message I posted.
I executed the script on the command line like this: python volctl.py changevol -c -i 1
where volctl.py is the file where I saved your script, but no joy. sad

p.s. I just did another test with volctl.py -c -i 1 and that works just fine. Thanks!
smile /happy camper/

Last edited by ralvez (2007-12-31 03:26:32)

Offline

#11 2007-12-31 03:29:23

bruenig
Member
Registered: 2007-05-20
Posts: 175

Re: changevol - volume management (good for binding multimedia keys)

ralvez wrote:

Thanks for the reply.
Well ... this is most interesting. I issued the command: changevol -c Front -i 1 and what I got was the message I posted.
I executed the script on the command line like this: python volctl.py changevol -c -i 1
where volctl.py is the file where I saved your script, but no joy. sad

p.s. I just did another test with volctl.py -c -i 1 and that works just fine. Thanks!
smile /happy camper/

Oh see, the initial post assumes that you actually name the script "changevol" on your system. But also, you should be able to leave the "-c" flag out unless you need some other mixer than "Master". And according to your last post you are just doing -c but without specifying another mixer. So just volctl.py -i 1 (or changevol -i 5) would be identical.

Last edited by bruenig (2007-12-31 03:30:53)

Offline

#12 2007-12-31 03:31:51

ralvez
Member
From: Canada
Registered: 2005-12-06
Posts: 1,694
Website

Re: changevol - volume management (good for binding multimedia keys)

Yes. I realized that afterwards. roll
Thanks again. Wonderful program. I have been about to code something like that for awhile ... good timing!!


R

Offline

#13 2007-12-31 10:09:40

sergejx
Member
From: Czechoslovakia
Registered: 2006-10-24
Posts: 9
Website

Re: changevol - volume management (good for binding multimedia keys)

bruenig wrote:
sergejx wrote:

Thank you for great script. Maybe you should make name of mixer control configurable. For example I don't have 'Master' control, instead I use 'Front'.

I have changed the script in the first post to provide that option, tell me if it works.

Yes, it works. Thank you.

Offline

#14 2008-01-11 00:09:24

zenix
Member
From: Earth - Save it!
Registered: 2007-08-05
Posts: 104
Website

Re: changevol - volume management (good for binding multimedia keys)

hm, Is there a way to call amixer to definitely set the volume to a certain percent? This works almost as I expect it to, bruenigvol -i increases, bruenigvol -d decreases but it changes not in units of 1 or 5 but in units of 3, so "bruenigvol -i 1" would increase from 87 to 90, or "bruenigvol -d 5" would decrease from 90 to 81 or 86, it seems kinda random. The volume of the music coming out the speakers is only slightly decreased, but the actual percentage fluctuates a bit.

PS: Could you please add some type of status message? Maybe changevol -s/--status would popup with the volume bar and display the current volume, etc but not modify it smile

EDIT: I should read more roll seeing as you said that it wouldn't be exact, right there in the help! Silly me...

Last edited by zenix (2008-01-11 00:11:13)


I made an AUR helper once.
I also go by evaryont and nogweii elsewhere on the internet.
Check out my projects and packages.

Offline

#15 2008-01-12 05:36:56

bruenig
Member
Registered: 2007-05-20
Posts: 175

Re: changevol - volume management (good for binding multimedia keys)

zenix wrote:

hm, Is there a way to call amixer to definitely set the volume to a certain percent? This works almost as I expect it to, bruenigvol -i increases, bruenigvol -d decreases but it changes not in units of 1 or 5 but in units of 3, so "bruenigvol -i 1" would increase from 87 to 90, or "bruenigvol -d 5" would decrease from 90 to 81 or 86, it seems kinda random. The volume of the music coming out the speakers is only slightly decreased, but the actual percentage fluctuates a bit.

PS: Could you please add some type of status message? Maybe changevol -s/--status would popup with the volume bar and display the current volume, etc but not modify it smile

EDIT: I should read more roll seeing as you said that it wouldn't be exact, right there in the help! Silly me...

Ha yeah, amixer is weird. Someone explained to me at one point why for some reason it is unable to change precisely but I have forgotten why.

Also, I modified the script in the first post to work with -s, --status. Tell me if it works.

Last edited by bruenig (2008-01-12 05:37:46)

Offline

#16 2008-01-12 23:15:24

zenix
Member
From: Earth - Save it!
Registered: 2007-08-05
Posts: 104
Website

Re: changevol - volume management (good for binding multimedia keys)

I'm happy to report that it works just as expected. I did a bit of searching yesterday, why didn't you use something like pyalsa or pyalsaaudio?


I made an AUR helper once.
I also go by evaryont and nogweii elsewhere on the internet.
Check out my projects and packages.

Offline

#17 2008-01-14 22:00:05

bruenig
Member
Registered: 2007-05-20
Posts: 175

Re: changevol - volume management (good for binding multimedia keys)

zenix wrote:

I'm happy to report that it works just as expected. I did a bit of searching yesterday, why didn't you use something like pyalsa or pyalsaaudio?

No idea such a thing existed. I will look into it.

Edit: Adding another library for a script as trivial as this seems unnecessary. Because I am not doing anything really complex with alsa, the pyalsa wrapper would just be unneeded bloat really.

Last edited by bruenig (2008-01-15 17:53:46)

Offline

#18 2008-01-28 01:51:06

cu3edweb
Member
From: USA
Registered: 2007-10-07
Posts: 291

Re: changevol - volume management (good for binding multimedia keys)

I don't know when this started but I am getting this error now when trying to use the -t mute option.

Traceback (most recent call last):
  File "/home/bmartin/.bin/changevol", line 116, in <module>
    volume = GetVolInfo(command)
  File "/home/bmartin/.bin/changevol", line 45, in __init__
    self.tempvolarray2 = self.tempvolarray1[1].split("%")
IndexError: list index out of range

Offline

#19 2008-01-30 19:55:50

rson451
Member
From: Annapolis, MD USA
Registered: 2007-04-15
Posts: 1,233
Website

Re: changevol - volume management (good for binding multimedia keys)

request fulfilled. thanks again!

Last edited by rson451 (2008-01-31 00:19:49)


archlinux - please read this and this — twice — then ask questions.
--
http://rsontech.net | http://github.com/rson

Offline

#20 2008-01-30 21:30:42

zyghom
Member
From: Poland/currently Africa
Registered: 2006-05-11
Posts: 432
Website

Re: changevol - volume management (good for binding multimedia keys)

cu3edweb wrote:

I don't know when this started but I am getting this error now when trying to use the -t mute option.

Traceback (most recent call last):
  File "/home/bmartin/.bin/changevol", line 116, in <module>
    volume = GetVolInfo(command)
  File "/home/bmartin/.bin/changevol", line 45, in __init__
    self.tempvolarray2 = self.tempvolarray1[1].split("%")
IndexError: list index out of range

change the channel from Master to PCM or Front


Zygfryd Homonto

Offline

#21 2008-02-01 00:42:09

semperfiguy
Member
Registered: 2007-12-03
Posts: 224

Re: changevol - volume management (good for binding multimedia keys)

I have the same error.. tried changing to PCM but no luck

Offline

#22 2008-02-01 14:59:29

cu3edweb
Member
From: USA
Registered: 2007-10-07
Posts: 291

Re: changevol - volume management (good for binding multimedia keys)

semperfiguy wrote:

I have the same error.. tried changing to PCM but no luck

Same problem here also. I have mine set to PCM.

Offline

#23 2008-02-01 21:53:38

bruenig
Member
Registered: 2007-05-20
Posts: 175

Re: changevol - volume management (good for binding multimedia keys)

To the people with problems: I don't know a lick about python. I actually wrote this trying to make myself learn it, but got bored of it. If someone else knows what the hell is going on, please fix it.

Offline

#24 2008-02-01 23:51:10

mfolnovic
Member
From: Zagreb, Croatia
Registered: 2008-01-03
Posts: 104

Re: changevol - volume management (good for binding multimedia keys)

great script, worked for me without problem, tnx!

Offline

#25 2008-02-03 07:00:59

ruinevil
Member
Registered: 2008-01-15
Posts: 11

Re: changevol - volume management (good for binding multimedia keys)

    if (BACKLIGHT == "YES"): 
      self.label = "Backlight " + self.endlabel
    else:
      self.label = "Volume " + self.endlabel

I added that where you had

self.label = "Volume " + self.endlabel

and it worked...

Offline

Board footer

Powered by FluxBB