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

15

Existe-t-il un moyen sophistiqué de faire fonctionner l'OSD de notification de volume avec pulseaudio et ALSA? Pour le moment, les ordinateurs de bureau standard ne fonctionnent qu'avec pulseaudio pour moi. Que diriez-vous d'un OSD vertical que je peux utiliser comme remplacement de remplacement ou appeler à partir de la ligne de commande pour signaler graphiquement les changements de pourcentages arbitraires, comme une barre qui monte et descend?

La raison pour laquelle j'en ai besoin pour travailler avec ALSA et pulseaudio est que j'utilise une application WINE qui ne fonctionne pas bien avec pulse, donc je tue pulse avant de démarrer 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 impulsion, j'ai écrit des 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 --checket puis réglez 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 mappent très bien sur les boutons, mais je n'ai plus de bon moyen de voir les commentaires visuels - pas même avec ceux pulseaudio puisque j'attrape les événements de bouton (XF86AudioLowerVolume, etc.). Évidemment, je pourrais simplement mapper les touches de volume ALSA à autre chose, mais il n'y a aucun sens à dupliquer les touches de raccourci.

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 affiche le niveau de volume actuel à l'écran pour ALSA et pulseaudio, mais il est terriblement petit par rapport à l'OSD gnome que j'avais utilisé, et il n'est pas vertical (barre en haut, ancien OSD en bas):

Comparaison de taille de l'OSD standard et de pvol.py

Donc, je l'ai agrandi et l'ai floppé:

entrez la description de l'image ici

Mais, même en changeant l'orientation en verticale, le thème GTK par défaut bleu 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 qui manquent de tout le 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). Vraiment tout ce que je dois faire est d'appeler amix & pactl, donc quelque chose de simple comme la barre de progression gtk dans pvol.py serait génial - juste pas si bleu et pas juste au milieu de l'écran.

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

Barre de volume verticale VLC

C'est beaucoup moins obstructif que les cases habituelles qui se trouvent au centre de l'écran:

Notification de volume OSD horizontal

Toute l'analogie avec le curseur horizontal n'a jamais eu beaucoup de sens pour moi en dehors du panoramique 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 de messages sur la configuration des événements de presse clés, mais pas beaucoup sur les scripts que ces événements déclenchent. Quelles sont les autres options disponibles dans le département verticalement fantaisie?

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

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

Adam
la source
1
REMARQUE: Avec LXDE, vous devez tuer le panneau et le réapparaître lorsque vous arrêtez pulseaudio ou lxpanel commencera à consommer le CPU.
Adam
5
Wow quelle question géniale et bien pensée! +1
Seth

Réponses:

10

D'accord, au risque de répondre à ma propre question, j'ai trouvé un peu une version piratée pyqt ensemble de pvol à partir du lien dans la question ci-dessus. Si rien d'autre, peut-être que quelqu'un d'autre peut améliorer mon code. Finalement, je prévois de me débarrasser des parties du script ci-dessous qui ne sont pas utilisées ou de retirer les scripts bash de l'équation et d'avoir un script pyqt qui gère tous les événements de bouton. À l'heure actuelle, l'OSD expire à un taux constant à partir de la première pression sur un bouton au lieu de rester allumé pendant une durée fixe après la dernière pression sur un bouton.

Copiez, collez et enregistrez simplement les fichiers (avec les noms en gras), placez-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 placez-les tous dans répertoire qui se trouve sur 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 de sourdine n'est pas géré - Ce n'est qu'un prototype pour exprimer une avenue possible pour remplir les fonctionnalités 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 de projet. Cela dit, n'hésitez pas à modifier cette réponse ou à suggérer un projet existant qui permet est similaire dans la fonction et la conception.

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 __name__ == '__main__':
    main()  
Adam
la source
Les arguments "silencieux" pour les scripts bash de l'étape de volume sont une sorte de hack factice - Les scripts ne font rien d'autre avec l'argument que de tester s'il existe. Vous pouvez donc y brancher n'importe quoi avec le même effet.
Adam