Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 15/08/2009, à 12:17

Elzen

[Script Python] Visualiser le niveau sonore lors de la modification.

Salut les gens ! Comme promis, voici l'engin wink

Pour ceux qui n'auraient pas suivi la discussion préalable : lorsque l'on utilise un environnement alternatif, on se passe généralement du daemon de Gnome qui contrôle notamment certains raccourcis claviers, comme ceux pour contrôler le volume sur un ordinateur portable. Il existe en effet un certain nombre d'autres moyens d'associer une commande à certaines touches (le via rc.xml d'Openbox, les panneaux de configuration de CompizStandalone ou Enlightenment, l'utilisation du programme xbinkeys, etc...).
Cependant, pour ce qui est du contrôle du volume, la solution habituelle (passer par la commande amixer, présente dans le paquet alsa-utils sous Debian et Ubuntu) se déclenche de manière "invisible" : l'effet est bien appliqué, mais aucun rendu visuel ne nous le signale. C'est pour cette raison que j'ai créé ce script, qui lance les mêmes commandes, mais affiche en plus une petite popup conçue sur le modèle de celle affichée par le daemon de Gnome.

Je vous livre ce script tel quel : c'est encore un travail en cours, et il y a certainement pas mal de choses à corriger. Notamment, ce script ouvre une nouvelle pop-up (par dessus l'ancienne) à chaque fois que l'on lui demande un affichage. Il serait beaucoup plus élégant de récupérer la dernière pop-up ouverte, si elle est toujours affichée, pour modifier son contenu, mais ça, ça dépasse pour l'instant mes compétences.

Niveau paquets, en dehors d'alsa-utils pour la commande sus-citée, python-gtk2 est requis, mais je ne sais plus exactement quels sont les autres concernés. Par contre, il va falloir retoucher quelques variables que j'ai placé en début de script pour adapter ça à votre configuration wink
Je suis ouvert à toute suggestion concernant l'amélioration, notamment au niveau de la récupération automatique des images. Pour l'instant, il faut les indiquer manuellement : elles doivent être en 48x48, normalement.

Le script requiert un paramètre, et un seul : "up" pour augmenter le volume, "down" pour le diminuer", "toggle" pour passer de muet à sonore et réciproquement, et "show" (ou n'importe quoi d'autre qui ne soit aucun des trois précédents) pour juste afficher le volume, sans rien modifier.

#! /usr/bin/python
# -*- coding:Utf-8 -*-

## Script réalisé par ArkSeth/Elzen sous GNU GPL v3.

import os
import sys
import gtk
import time
import gobject
import commands

##Icônes à utiliser. Modifier l'adresse pour faire pointer sur celles que vous voulez.
IMG_VOL_MUT = "/usr/share/icons/VOTRE_THEME/48x48/stock/media/stock_volume-mute.png" #Image à afficher lorsque volume coupé
IMG_VOL_NUL = "/usr/share/icons/VOTRE_THEME/48x48/stock/media/stock_volume-0.png" #Image à afficher lorsque volume à zéro
IMG_VOL_MIN = "/usr/share/icons/VOTRE_THEME/48x48/stock/media/stock_volume-min.png" #Image à afficher lorsque volume faible
IMG_VOL_MED = "/usr/share/icons/VOTRE_THEME/48x48/stock/media/stock_volume-med.png" #Image à afficher lorsque volume moyen
IMG_VOL_MAX = "/usr/share/icons/VOTRE_THEME/48x48/stock/media/stock_volume-max.png" #Image à afficher lorsque volume fort

##Commandes à utiliser. À modifier si nécessaire
CMD_VOL_UP = "amixer -q set Master 5%+"
CMD_VOL_DWN = "amixer -q set Master 5%-"
CMD_VOL_TOG = "amixer -q set Master toggle"

##Géométrie de la fenêtre. Celle-ci est pour un écran en 1024x600.
GEOMETRY = "178x102+423+399"

##début du script d'affichage.
class Volume:
	def __init__(self, path, level):
		##Création de la pop-up.
		self.win = gtk.Window()
		self.win.set_title("Volume")
		self.win.parse_geometry(GEOMETRY)
		self.win.set_property("skip-taskbar-hint", True)
		self.win.set_property("skip-pager-hint", True)
		self.win.connect("destroy", self.destroy)
		self.win.set_keep_above(True)
		self.win.set_decorated(False)
		self.win.stick()
		##Bord en relief.
		self.brd = gtk.Frame()
		self.brd.set_shadow_type(gtk.SHADOW_OUT)
		self.win.add(self.brd)
		##Création et placement des composants.
		self.box = gtk.VBox(False, 10)
		self.box.set_border_width(10)
		self.brd.add(self.box)
		self.img = gtk.Image()
		self.img.set_from_file(path)
		self.box.add(self.img)
		self.bar = gtk.ProgressBar()
		self.bar.set_fraction(level/100.0)
		self.box.add(self.bar)
		##Durée d'affichage de la popup.
		self.timer = time.time()+2
	
	def destroy(self, widget, data=None):
		gtk.main_quit()
	
	##Ferme la fenêtre après le délai requis.
	def delay(self):
		if self.timer < time.time():
			gtk.main_quit()
		return True
	
	##Affichage de la fenêtre.
	def main(self):
		gobject.idle_add(self.delay)
		self.img.show()
		self.bar.show()
		self.box.show()
		self.brd.show()
		self.win.show()
		gtk.main()

##le programme attend un argument exactement.
if len(sys.argv) != 2:
	quit()

##Augmentation du volume.
if sys.argv[1] == "up":
	os.system(CMD_VOL_UP)

##Diminution du volume.
if sys.argv[1] == "down":
	os.system(CMD_VOL_DWN)

##Passage à muet ou à sonore.
if sys.argv[1] == "toggle":
	os.system(CMD_VOL_TOG)

##Récupération du niveau actuel pour affichage.
off = commands.getoutput("amixer get Master | cut -d'\n' -f5 | grep off")
if off == "":
	vol = int(commands.getoutput("amixer get Master | cut -d'\n' -f5 | cut -d'[' -f2 | cut -d'%' -f1"))
	if vol == 0:
		Volume(IMG_VOL_NUL, 0).main()
	elif vol < 34:
		Volume(IMG_VOL_MIN, vol).main()
	elif vol > 66:
		Volume(IMG_VOL_MAX, vol).main()
	else: Volume(IMG_VOL_MED, vol).main()
else: Volume(IMG_VOL_MUT, 0).main()

Enjoy ! big_smile

Hors ligne

#2 Le 15/08/2009, à 12:28

Кຼزດ

Re : [Script Python] Visualiser le niveau sonore lors de la modification.

Ok, je vais tester ça smile
(visiblement awesome n'aime pas ça big_smile)


dou

Hors ligne

#3 Le 15/08/2009, à 12:47

Kookaburra

Re : [Script Python] Visualiser le niveau sonore lors de la modification.

A noter qu'il existe un paquet pratique pour ceux qui veulent contrôler le son simplement à partir du Systray : VolWheel

http://www.gnomefiles.org/app.php/VolWheel
minimixer.png

Cela fonctionne parfaitement sous Crunchbang-Openbox wink


Portable17p : CrunchBangLinux // EeePC : ArchLinux
Openbox Addict : http://kookadimi.deviantart.com
Mes photos : http://www.fluidr.com/photos/kookadimi/sets
Votre téléphone mobile dispose de plus de puissance que l'ensemble des ordinateurs de la NASA en 1969. La NASA a lancé un homme sur la Lune. Vous lancez un oiseau sur des cochons...

Hors ligne

#4 Le 15/08/2009, à 13:08

Elzen

Re : [Script Python] Visualiser le niveau sonore lors de la modification.

Certes, mais ça ne s'applique pas au même usage : VolWheel est prévu pour une gestion à la souris depuis le SysTray, le miens est prévu pour être déclenché par un raccourcis clavier wink Les deux peuvent donc être parfaitement complémentaires.

Mais c'est vrai, je n'avais pas pensé que les gestionnaires en tiling pouvaient ne pas apprécier... éventuellement, ce que tu peux faire, c'est modifier temporairement certains paramètres (passer le délai à +10 ou  +60 au lieu de +2, par exemple, pour avoir un peu plus de temps d'action), afin de pouvoir modifier les règles pour que le gestionnaire de fenêtres oublie cette fenêtre-là.

Hors ligne

#5 Le 15/08/2009, à 13:21

Кຼزດ

Re : [Script Python] Visualiser le niveau sonore lors de la modification.

ArkSeth a écrit :

Certes, mais ça ne s'applique pas au même usage : VolWheel est prévu pour une gestion à la souris depuis le SysTray, le miens est prévu pour être déclenché par un raccourcis clavier wink Les deux peuvent donc être parfaitement complémentaires.

Mais c'est vrai, je n'avais pas pensé que les gestionnaires en tiling pouvaient ne pas apprécier... éventuellement, ce que tu peux faire, c'est modifier temporairement certains paramètres (passer le délai à +10 ou  +60 au lieu de +2, par exemple, pour avoir un peu plus de temps d'action), afin de pouvoir modifier les règles pour que le gestionnaire de fenêtres oublie cette fenêtre-là.

Bof, suffit de définir une règle, mais ça surprend tongue
Edit : tiens, sinon je viens de trouver ça, c'est du bash : http://bbs.archlinux.org/viewtopic.php?id=46608

Dernière modification par mathieuI (Le 15/08/2009, à 13:32)


dou

Hors ligne

#6 Le 15/08/2009, à 13:44

Elzen

Re : [Script Python] Visualiser le niveau sonore lors de la modification.

Le mien est plus agréable à l'œil, quand même, non ? ^^

En fait, je l'ai copié l'apparence sur celle de la popup qui s'affiche pour augmenter/diminuer la luminosité de l'écran, et qui elle n'a pas l'air de dépendre du daemon (elle s'affiche même sur une session hyper-minimale, chez moi)

Hors ligne

#7 Le 15/08/2009, à 16:43

Kookaburra

Re : [Script Python] Visualiser le niveau sonore lors de la modification.

ArkSeth a écrit :

En fait, je l'ai copié l'apparence sur celle de la popup qui s'affiche pour augmenter/diminuer la luminosité de l'écran, et qui elle n'a pas l'air de dépendre du daemon (elle s'affiche même sur une session hyper-minimale, chez moi)

Même chose chez moi : sur mon portable, la gestion de la luminosité est automatiquement gérée avec les cessions minimales, mais pour le son c'est une autre histoire roll:mad:

Dernière modification par Kookaburra (Le 15/08/2009, à 16:43)


Portable17p : CrunchBangLinux // EeePC : ArchLinux
Openbox Addict : http://kookadimi.deviantart.com
Mes photos : http://www.fluidr.com/photos/kookadimi/sets
Votre téléphone mobile dispose de plus de puissance que l'ensemble des ordinateurs de la NASA en 1969. La NASA a lancé un homme sur la Lune. Vous lancez un oiseau sur des cochons...

Hors ligne

#8 Le 12/09/2009, à 10:08

Elzen

Re : [Script Python] Visualiser le niveau sonore lors de la modification.

Victory ! big_smilecool

Je viens de me repencher sur ce petit script, et j'ai réussi trois opérations notables :
1/ Diminuer un peu la consommation de l'engin en utilisant un vrai délai et pas un test continuel (y a quelqu'un qui m'avait suggéré une mauvaise solution au début ^^).
2/ Lui faire accepter un signal pour que la fenêtre en cours se redessine plutôt que d'en ouvrir une nouvelle.
3/ Récupérer automatiquement les icônes du thème gtk, sans avoir besoin d'indiquer manuellement leur emplacement.

La nouvelle version nécessite l'installation d'un paquet supplémentaire, wmctrl, qui permet la manipulation des fenêtres en consoles. Je l'utilise pour vérifier si la fenêtre est déjà ouverte ou pas.
Notez que l'on peut aussi (pour éviter le problème évoqué par mathieuI) remplacer le "self.win = gtk.Window()" par "self.win = gtk.Window(gtk.WINDOW_POPUP)", et ainsi obtenir une fenêtre surgissante (comme celle d'un menu, par exemple) qui ne dérangera pas le gestionnaire de fenêtre, mais si on fait ça, wmctrl non plus ne reconnaît plus la fenêtre, et donc l'envoi de signal ne pourra pas se faire.

Bref, ce truc me semble tout à fait fonctionnel, il ne vous reste plus qu'à brancher vos raccourcis claviers. Je reste cependant ouvert à toute suggestion d'amélioration wink

#! /usr/bin/python
# -*- coding:Utf-8 -*-

## Script réalisé par ArkSeth/Elzen sous GNU GPL v3.

import os
import sys
import gtk
import time
import gobject
import commands

##Commandes à utiliser. À modifier selon votre convenance.
CMD_VOL_UP = "amixer -q set Master 5%+"
CMD_VOL_DWN = "amixer -q set Master 5%-"
CMD_VOL_TOG = "amixer -q set Master toggle"

##Géométrie de la fenêtre. Celle-ci est pour un écran en 1024x600.
GEOMETRY = "178x102+423+399"

class Volume:
	##Création de la fenêtre
	def __init__(self):
		self.win = gtk.Window()
		self.win.set_title("Visualisation du volume")
		self.win.parse_geometry(GEOMETRY)
		self.win.set_property("skip-taskbar-hint", True)
		self.win.set_property("skip-pager-hint", True)
		self.win.set_property("accept-focus", False)
		self.win.set_property("focus-on-map", False)
		self.win.connect("destroy", self.destroy)
		self.win.set_keep_above(True)
		self.win.set_decorated(False)
		self.win.stick()
		self.brd = gtk.Frame()
		self.brd.set_shadow_type(gtk.SHADOW_OUT)
		self.win.add(self.brd)
		self.box = gtk.VBox(False, 10)
		self.box.set_border_width(10)
		self.brd.add(self.box)
		self.img = gtk.Image()
		self.box.add(self.img)
		self.bar = gtk.ProgressBar()
		self.box.add(self.bar)
		self.glimpse()
		
	##Réglage de l'affichage en fonction du volume et du thème GTK.
	def glimpse(self):
		self.timer = time.time()+2
		gobject.timeout_add_seconds(2, self.delay)
		off = commands.getoutput("amixer get Master | cut -d'\n' -f5 | grep off")
		theme = gtk.icon_theme_get_default()
		if off == "":
			vol = int(commands.getoutput("amixer get Master | cut -d'\n' -f5 | cut -d'[' -f2 | cut -d'%' -f1"))
			if vol == 0:
				self.img.set_from_pixbuf(theme.load_icon("audio-volume-zero", 48, gtk.ICON_LOOKUP_USE_BUILTIN))
				self.bar.set_fraction(0)
			elif vol < 34:
				self.img.set_from_pixbuf(theme.load_icon("audio-volume-low", 48, gtk.ICON_LOOKUP_USE_BUILTIN))
				self.bar.set_fraction(vol/100.0)
			elif vol > 66:
				self.img.set_from_pixbuf(theme.load_icon("audio-volume-high", 48, gtk.ICON_LOOKUP_USE_BUILTIN))
				self.bar.set_fraction(vol/100.0)
			else:
				self.img.set_from_pixbuf(theme.load_icon("audio-volume-medium", 48, gtk.ICON_LOOKUP_USE_BUILTIN))
				self.bar.set_fraction(vol/100.0)
		else:
			self.img.set_from_pixbuf(theme.load_icon("audio-volume-muted", 48, gtk.ICON_LOOKUP_USE_BUILTIN))
			self.bar.set_fraction(0)
	
	##En cas de fermeture explicite.
	def destroy(self, widget, data=None):
		gtk.main_quit()
	
	##Vérification du délai de disparition.
	def delay(self):
		if self.timer < time.time():
			gtk.main_quit()
		return True
	
	##Actualisation au signal reçu.
	def handler(self, signum, frame):
		self.glimpse()
	
	##Branchement et affichage de la fenêtre.
	def main(self):
		signal.signal(signal.SIGUSR1, self.handler)
		gobject.timeout_add_seconds(2, self.delay)
		self.img.show()
		self.bar.show()
		self.box.show()
		self.brd.show()
		self.win.show()
		gtk.main()

##Un paramètre est requis.
if len(sys.argv) != 2:
	quit()

##Augmentation du volume.
if sys.argv[1] == "up":
    os.system(CMD_VOL_UP)

##Diminution du volume.
if sys.argv[1] == "down":
    os.system(CMD_VOL_DWN)

##Passage à muet ou à sonore.
if sys.argv[1] == "toggle":
    os.system(CMD_VOL_TOG)

##Si la fenêtre existe déjà, on envoie un signal à l'autre processus pour actualiser
pid = commands.getoutput('wmctrl -pl | grep "Visualisation du volume" | tr -s " " | cut -d" " -f3')
if (pid != ""):
	os.system('kill -s USR1 '+pid)
else: Volume().main()

Hors ligne

#9 Le 05/06/2010, à 09:31

Elzen

Re : [Script Python] Visualiser le niveau sonore lors de la modification.

J'remonte le sujet juste pour dire que voici une petite version un peut retouchée... la fenêtre n'a maintenant plus besoin qu'on lui définisse de règles spécialement pour elle, et il n'y a plus besoin d'installer wmctrl, je repère ça directement avec les PIDs. N'hésitez pas à donner votre avis wink

#! /usr/bin/python
# coding: Utf-8

##########################################################
###          Affichage et réglagle du volume.          ###
### Réalisé sous licence GNU GPL v3 par ArkSeth/Elzen. ###
##########################################################

import os, sys, gtk, time, signal, gobject, commands

class Volume:
	def __init__(self):
		self.win = gtk.Window(gtk.WINDOW_POPUP)
		#self.win.set_title("Visualisation du volume")
		self.win.parse_geometry("178x102+423+399")
		#self.win.set_property("skip-taskbar-hint", True)
		#self.win.set_property("skip-pager-hint", True)
		#self.win.set_property("accept-focus", False)
		#self.win.set_property("focus-on-map", False)
		self.win.connect("destroy", self.destroy)
		self.win.set_keep_above(True)
		self.win.set_decorated(False)
		self.win.stick()
		self.brd = gtk.Frame()
		self.brd.set_shadow_type(gtk.SHADOW_OUT)
		self.win.add(self.brd)
		self.box = gtk.VBox(False, 10)
		self.box.set_border_width(10)
		self.brd.add(self.box)
		self.img = gtk.Image()
		self.box.add(self.img)
		self.bar = gtk.ProgressBar()
		self.box.add(self.bar)
		self.glimpse()
	
	def glimpse(self):
		self.timer = time.time()+2
		gobject.timeout_add_seconds(2, self.delay)
		off = commands.getoutput("amixer get Master | cut -d'\n' -f5 | grep off")
		theme = gtk.icon_theme_get_default()
		if off == "":
			vol = int(commands.getoutput("amixer get Master | cut -d'\n' -f5 | cut -d'[' -f2 | cut -d'%' -f1"))
			if vol == 0:
				self.img.set_from_pixbuf(theme.load_icon("audio-volume-zero", 48, gtk.ICON_LOOKUP_USE_BUILTIN))
				self.bar.set_fraction(0)
			elif vol < 34:
				self.img.set_from_pixbuf(theme.load_icon("audio-volume-low", 48, gtk.ICON_LOOKUP_USE_BUILTIN))
				self.bar.set_fraction(vol/100.0)
			elif vol > 66:
				self.img.set_from_pixbuf(theme.load_icon("audio-volume-high", 48, gtk.ICON_LOOKUP_USE_BUILTIN))
				self.bar.set_fraction(vol/100.0)
			else:
				self.img.set_from_pixbuf(theme.load_icon("audio-volume-medium", 48, gtk.ICON_LOOKUP_USE_BUILTIN))
				self.bar.set_fraction(vol/100.0)
		else:
			self.img.set_from_pixbuf(theme.load_icon("audio-volume-muted", 48, gtk.ICON_LOOKUP_USE_BUILTIN))
			self.bar.set_fraction(0)
	
	def destroy(self, widget, data=None):
		gtk.main_quit()
	
	def delay(self):
		if self.timer < time.time():
			gtk.main_quit()
		return True
	
	def handler(self, signum, frame):
		self.glimpse()
	
	def main(self):
		signal.signal(signal.SIGUSR1, self.handler)
		gobject.timeout_add_seconds(2, self.delay)
		self.img.show()
		self.bar.show()
		self.box.show()
		self.brd.show()
		self.win.show()
		gtk.main()

if len(sys.argv) != 2:
	quit()

if sys.argv[1] == "up":
	os.system("amixer -q set Master 5%+")

if sys.argv[1] == "down":
	os.system("amixer -q set Master 5%-")

if sys.argv[1] == "toggle":
	os.system("amixer -q set Master toggle")

pids = commands.getoutput('ps -ef -U $USER | grep -v grep | grep "'+sys.argv[0]+'" | tr -s " " | cut -d" " -f2').split("\n")
if (len(pids) > 1):
	for pid in pids: os.system('kill -s USR1 '+pid)
else: Volume().main()

Edit : erratum rectifié dans le code.

Dernière modification par ArkSeth (Le 05/06/2010, à 18:47)

Hors ligne