web-dev-qa-db-fra.com

Existe-t-il un OSD de notification verticale sophistiqué qui fonctionne à la fois pour ALSA et pulseaudio?

Existe-t-il un moyen élégant de faire en sorte que l’OSD de notification de volume fonctionne à la fois avec pulseaudio et avec ALSA? À l'heure actuelle, les ordinateurs de bureau standard ne fonctionnent qu'avec pulseaudio pour moi. Qu'en est-il d'un OSD vertical que je peux utiliser comme remplacement immédiat ou appeler à partir de la ligne de commande pour signaler graphiquement les changements en pourcentage arbitraires, comme une barre qui se lève et s'abaisse?

La raison pour laquelle j'ai besoin de travailler avec ALSA et pulseaudio est que j'utilise une application WINE qui ne fonctionne pas bien avec Pulse. Je tue donc Pulse avant de lancer l'application Windows pour utiliser ALSA sans la couche d'abstraction supplémentaire. Quand j'ai réalisé que les touches de volume de mon clavier ne fonctionnaient pas sans Pulse, j'ai écrit quelques scripts bash que j'appelle avec Compiz ou Openbox (configurés via CCSM et lxde-rc.xml, respectivement) pour capter le signal de sortie de pulseaudio --check puis ajustez le volume en conséquence:

vol_step_up

#!/bin/bash
pulseaudio --check
if [ $? -eq 0 ] ; then
        pactl set-sink-volume 0 -- +3db
    else
        amixer -c0 set Master playback 3+
fi

vol_step_down

#!/bin/bash
pulseaudio --check
if [ $? -eq 0 ] ; then
        pactl set-sink-volume 0 -- -3db
    else
        amixer -c0 set Master playback 3-
fi

Les scripts fonctionnent très bien et correspondent parfaitement aux boutons, mais je n’ai plus de moyen de voir le retour visuel, même pas avec celui en pulseaudio puisque je saisis les événements des boutons (XF86AudioLowerVolume, etc.). Évidemment, je pourrais simplement mapper les touches de volume d'ALSA sur quelque chose d'autre, mais dupliquer les touches de raccourci n'a aucun sens.

J'ai trouvé un contrôle de volume python que je peux appeler dans les scripts ci-dessus:
https://github.com/fishman/utils/blob/master/pvol.py

pvol.py -s indique le niveau de volume actuel à l'écran pour ALSA et pulseaudio, mais il est terriblement minime comparé au gnome OSD que j'utilisais et il n'est pas vertical (barre en haut, ancien OSD en bas):

Size comparison of Standard OSD and pvol.py

Donc, je l'ai fait plus gros et je l'ai floppé:

enter image description here

Cependant, même avec le basculement de l'orientation sur une orientation verticale, le thème GTK bleu par défaut n'est pas aussi lisse que VLC (voir ci-dessous).

Une grande partie de ce que j'ai trouvé en recherchant des implémentations OSD sont des publications sur les commandes notify-send (envoi de notifications-envoi), qui manquent du concept de barre de progression. Sinon, il s'agit principalement de barres horizontales (et de nombreux espaces réservés de comptage dans les scripts bash). Tout ce dont j'ai besoin, c’est d’appeler amix & pactl, ce qui est génial, comme la barre de progression de gtk dans pvol.py;.

VLC a un bon exemple de ce que j'ai en tête lorsque vous faites défiler la molette de la souris en mode plein écran:

VLC Vertical Volume Bar

C'est beaucoup moins gênant que les boîtes habituelles situées au centre de l'écran:

Horizontal OSD Volume Notification

L'analogie avec le curseur horizontal n'a jamais eu de sens pour moi en dehors du balayage audio entre les haut-parleurs gauche et droit.

Quoi qu'il en soit, comment se fait-il que les notifications de bureau par défaut soient appelées (en particulier LXDE)? Je vois beaucoup d'articles sur la configuration d'événements de presse clés, mais pas beaucoup sur les scripts que ces événements déclenchent. Quelles autres options existe-t-il dans le département à la mode verticale?

De plus, y a-t-il un paquet à désinstaller pour éviter des conflits entre les événements que je gère via les scripts et les commandes compiz ou openbox?

Mise à jour: Afin de déterminer quel OSD j'utilise actuellement, je n'ai pas changé la façon dont j'ai géré le bouton de désactivation du son tout de suite. Tuer xfce4-notifyd, puis appuyer sur le bouton muet génère un nouveau processus xfce4-notifyd, alors je devinais que la grosse icône de haut-parleur venait de quelque chose comme xfce4-volumed, mais je n'ai pas ce paquet installé ... Ah, ah! Tuer gnome-settings-daemon arrête le gros OSD au centre de l'écran.

15
Adam

Très bien, au risque de répondre à ma propre question, j'ai proposé une version piratée de pvol à partir du lien de la question ci-dessus. Si rien d'autre, peut-être que quelqu'un d'autre peut améliorer mon code. Finalement, je prévois soit de supprimer les parties du script ci-dessous qui restent inutilisées, soit de supprimer les scripts bash de l'équation et de laisser un script pyqt gérer tous les événements de bouton. Pour le moment, le menu OSD expire à un rythme constant depuis la première pression sur un bouton au lieu de rester allumé pendant une durée déterminée après la dernière pression sur un bouton.

Copiez, collez et enregistrez les fichiers (avec les noms en gras), mettez-les tous dans le même répertoire, définissez les bits exécutables et modifiez les appels système dans le script pyqt en fonction de l'endroit où vous les enregistrez, ou mettez-les tous dans répertoire qui est dans votre chemin. Mappez ensuite les scripts Shell aux commandes Compiz, aux raccourcis Openbox ou à quelque chose de similaire, et modifiez le script pyqt si vous n'utilisez pas les boutons de volume du clavier multimédia.

Remarque: le nom de classe Qvol était un titre de travail et je n'ai pas pris la peine de le changer. Veuillez également noter que le bouton muet n'est pas géré - Il s'agit simplement d'un prototype exprimant un moyen possible de remplir les fonctions demandées, et il n'est actuellement associé à aucun type de projet hébergé ou de modèle de développement standard. Tout type de développement significatif dérivé du code ci-dessous devrait probablement appartenir à Sourceforge, à GitHub ou à un site Web du projet. Cela dit, n'hésitez pas à éditer cette réponse ou à suggérer un projet existant qui permet une fonction et une conception similaires.

pqvol

vol_step_down

#!/bin/bash
pulseaudio --check
#if [ $? -ne 0 ] ; then
if [ $? -eq 0 ] ; then
        pactl set-sink-volume 0 -- -3db
    else
        amixer -c0 set Master playback 3-
fi

if [ -z "$1" ] ; then
        pqvol -s
fi

vol_step_up

#!/bin/bash
pulseaudio --check
#if [ $? -ne 0 ] ; then
if [ $? -eq 0 ] ; then
        pactl set-sink-volume 0 -- +3db
    else
        amixer -c0 set Master playback 3+
fi

if [ -z "$1" ] ; then
    pqvol -s
fi

pqvol

#!/usr/bin/env python2

# pvol -- Commandline audio volume utility
#         with an optional GTK progressbar
# Copyright (C) 2009 Adrian C. <anrxc_sysphere_org>
# Modified by 2011 Reza Jelveh
# Ported to pyqt and renamed to pqvol 2013 by Adam R.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.


import os.path
import optparse
import alsaaudio
import sys
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import QTimer

appname = "Qvol"
#appicon = "/usr/share/icons/ubuntu-mono-light/status/24/audio-volume-high-panel.svg"

DEFAULT_STYLE = """
QProgressBar{
    border: 2px solid grey;
    border-radius: 5px;
    background-color: transparent;
}

QProgressBar::chunk {
    background-color: Gainsboro;
}
"""

class AlsaMixer():
    def __init__(self, pcm=False, mute=False, arg=None):
        self.mixer = alsaaudio.Mixer()
        self.percent = self.mixer.getvolume()[0]
        print self.percent
        self.label = "dB" #% name
        if arg:
            self.percent = min(100, max(0, self.percent + int(arg)))
            self.mixer.setvolume(self.percent)
        if mute:
            mutestate = self.mixer.getmute()[0]
            if mutestate:
                self.label = "Unmuted: "
            else:
                self.label = "Muted: "

            self.mixer.setmute(mutestate^1)
 #     self.label = self.label + "%.0f%%" % self.percent

class Qvol(QtGui.QWidget):

    def __init__(self):
        super(Qvol, self).__init__()
#       self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
        self.setWindowFlags(QtCore.Qt.Popup)
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
        self.setWindowTitle("Qvol")
        self.initUI()

    def initUI(self):     

        self.pbar = QtGui.QProgressBar(self)
        self.pbar.setGeometry(5, 5, 20, 470)
        self.pbar.setOrientation(QtCore.Qt.Vertical)
        self.pbar.setRange(0,100)
        volume = AlsaMixer()
        self.pbar.setValue(volume.percent)
        self.pbar.setTextVisible(False)
        self.setStyleSheet(DEFAULT_STYLE)

        self.setGeometry(1260, 180, 30, 480)
        self.setWindowTitle('QtGui.QProgressBar')
        self.show()


        QTimer.singleShot(2000, finished)

    def keyPressEvent(self, event):
        if event.key()==QtCore.Qt.Key_VolumeMute:
#           QtGui.QWidget.paintEvent()
            finished()
        Elif event.key()==QtCore.Qt.Key_VolumeDown:
            launch_process ("vol_step_down silent")
            volume=AlsaMixer()
            self.pbar.setValue(volume.percent)
#           finished()
        Elif event.key()==QtCore.Qt.Key_VolumeUp:
            launch_process ("vol_step_up silent")
            volume=AlsaMixer()
            self.pbar.setValue(volume.percent)
#           finished()

#       else:
#           QtGui.QWidget.keyPressEvent(self, event)


processes = set([])

def launch_process(process):
    # Do something asynchronously
    proc = QtCore.QProcess()
    processes.add(proc)
    proc.start(process)
    proc.waitForFinished(-1)

def finished():
    print "The process is done!"
    # Quit the app
    QtCore.QCoreApplication.instance().quit()


def main():

    app = QtGui.QApplication(sys.argv)
    ex = Qvol()
    sys.exit(app.exec_())


if __== '__main__':
    main()  
10
Adam