Gibt es ein ausgefallenes vertikales Benachrichtigungs-OSD, das sowohl für ALSA als auch für pulseaudio funktioniert?

15

Gibt es eine ausgefallene Möglichkeit, das Volume-Benachrichtigungs-OSD sowohl mit pulseaudio als auch mit ALSA zusammenarbeiten zu lassen? Momentan funktionieren die Standard-Desktops nur mit pulseaudio für mich. Wie wäre es mit einem vertikalen OSD, das ich als Ersatz verwenden oder über die Befehlszeile aufrufen kann, um Änderungen in willkürlichen Prozentsätzen grafisch als Balken anzuzeigen, der sich nach oben und unten bewegt?

Der Grund, warum ich es für die Arbeit mit ALSA und pulseaudio benötige, ist, dass ich eine WINE-Anwendung verwende, die mit pulse nicht gut funktioniert. Daher bringe ich pulse zum Erliegen, bevor ich die Windows-App starte, um ALSA ohne die zusätzliche Abstraktionsebene zu verwenden. Als ich feststellte, dass die Lautstärketasten auf meiner Tastatur nicht ohne Puls arbeiteten, schrieb ich einige Bash-Skripte, die ich entweder mit Compiz oder Openbox (konfiguriert über CCSM bzw. lxde-rc.xml) aufrief, um das Ausgangssignal von pulseaudio --checkund abzufangen Stellen Sie dann die Lautstärke entsprechend ein:

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

Die Skripte funktionieren hervorragend und die Zuordnung zu den Schaltflächen ist in Ordnung, aber ich kann das visuelle Feedback nicht mehr gut sehen - nicht einmal bei den pulseaudio-Skripten, da ich die Schaltflächenereignisse (XF86AudioLowerVolume usw.) abfange. Natürlich könnte ich die ALSA-Lautstärketasten auch einer anderen Funktion zuordnen, aber es macht keinen Sinn, Tastenkombinationen zu duplizieren.

Ich habe eine Python-Lautstärkeregelung gefunden, die ich in den obigen Skripten aufrufen kann:
https://github.com/fishman/utils/blob/master/pvol.py

pvol.py -s zeigt den aktuellen Lautstärkepegel auf dem Bildschirm für ALSA und pulseaudio an, aber er ist im Vergleich zu dem von mir verwendeten Gnome-OSD schrecklich winzig und nicht vertikal (Balken oben, altes OSD unten):

Größenvergleich von Standard OSD und pvol.py

Also habe ich es größer gemacht und herumgeworfen:

Bildbeschreibung hier eingeben

Aber selbst wenn Sie die Ausrichtung in eine vertikale ändern, ist das blaue Standard-GTK-Design nicht ganz so schick wie VLC (siehe unten).

Vieles, was ich bei der Suche nach OSD-Implementierungen gefunden habe, sind Posts über Benachrichtigungssendebefehle, denen das gesamte Fortschrittsbalkenkonzept fehlt. Ansonsten sind es meist horizontale Balken (und viele Platzhalter in Bash-Skripten). Eigentlich muss ich nur amix & pactl aufrufen, also wäre etwas Einfaches wie der gtk-Fortschrittsbalken in pvol.py großartig - nur nicht so blau und nicht genau in der Mitte des Bildschirms.

VLC hat ein gutes Beispiel dafür, was ich denke, wenn Sie im Vollbildmodus mit dem Mausrad scrollen:

VLC Vertikaler Lautstärkeregler

Es ist viel weniger störend als die üblichen Kisten in der Mitte des Bildschirms:

Horizontale OSD-Volumenbenachrichtigung

Die gesamte Analogie der horizontalen Schieberegler hat für mich nie viel Sinn gemacht, wenn ich den Ton zwischen dem linken und dem rechten Lautsprecher verschoben habe.

Wie kommt es, dass die Standard-Desktop-Benachrichtigungen aufgerufen werden (insbesondere LXDE)? Ich sehe viele Beiträge über das Konfigurieren von Tastendruckereignissen, aber nicht viel darüber, welche Skripte diese Ereignisse auslösen. Welche anderen Optionen gibt es in der Abteilung für vertikale Phantasie?

Gibt es auch ein Paket, das ich deinstallieren sollte, um zu verhindern, dass Konflikte zwischen den Ereignissen entstehen, die ich durch Skripten und Compiz- oder Openbox-Befehle bearbeite?

Update: Um herauszufinden, welches OSD ich gerade verwende, habe ich die Art und Weise, wie ich mit der Stummschalttaste umgehe, nicht sofort geändert. Wenn Sie xfce4-notifyd beenden und dann die Stummschalttaste drücken, wird ein neuer xfce4-notifyd-Prozess ausgelöst. Ich habe also vermutet, dass das große Lautsprechersymbol von xfce4-volumed stammt, aber ich habe dieses Paket nicht installiert ... Ah ha! Durch das Beenden des Gnome-Settings-Daemons wird das große OSD in der Mitte des Bildschirms angehalten.

Adam
quelle
1
ANMERKUNG: Mit LXDE müssen Sie das Panel beenden und es erneut starten, wenn Sie pulseaudio beenden, oder lxpanel beginnt, die CPU zu verschlingen.
Adam
5
Wow was für eine tolle und durchdachte Frage! +1
Seth

Antworten:

10

Okay, auf die Gefahr hin, meine eigene Frage zu beantworten, habe ich über den Link in der obigen Frage eine etwas zerhackte pyqt-Version von pvol gefunden. Wenn nichts anderes, kann vielleicht jemand anderes meinen Code verbessern. Schließlich plane ich, entweder die nicht verwendeten Teile im Skript zu entfernen oder die Bash-Skripte aus der Gleichung zu entfernen und ein Pyqt-Skript alle Schaltflächenereignisse behandeln zu lassen. Derzeit wird das OSD ab dem ersten Tastendruck mit einer konstanten Geschwindigkeit abgebrochen, anstatt nach dem letzten Tastendruck für eine feste Zeitdauer eingeschaltet zu bleiben.

Kopieren Sie einfach die Dateien, fügen Sie sie ein und speichern Sie sie (mit fettgedruckten Namen), legen Sie sie alle im selben Verzeichnis ab, setzen Sie die ausführbaren Bits und ändern Sie die Systemaufrufe im pyqt-Skript, je nachdem, wo Sie sie speichern, oder fügen Sie sie alle ein Verzeichnis, das sich in Ihrem Pfad befindet. Ordnen Sie dann die Shell-Skripte Compiz-Befehlen, Openbox-Verknüpfungen oder Ähnlichem zu und ändern Sie das Pyqt-Skript, wenn Sie keine Multimedia-Tastaturlautstärketasten verwenden.

Hinweis: Der Klassenname Qvol war ein Arbeitstitel, und ich habe mich nicht darum gekümmert, ihn zu ändern. Bitte beachten Sie auch, dass die Stummschaltfläche nicht bearbeitet wird. Dies ist nur ein Prototyp, der einen möglichen Weg zur Erfüllung der angeforderten Funktionen beschreibt, und er ist derzeit keinem gehosteten Projekt oder Standardentwicklungsmodell zugeordnet. Jede bedeutende Entwicklung, die sich aus dem folgenden Code ableitet, sollte wahrscheinlich auf Sourceforge, GitHub oder einer Projektwebsite zu finden sein. Trotzdem können Sie diese Antwort gerne bearbeiten oder ein vorhandenes Projekt vorschlagen, das in Funktion und Design ähnlich ist.

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
quelle
Die "stillen" Argumente für die Volume-Step-Bash-Skripte sind eine Art Dummy-Hack - Die Skripte machen eigentlich nichts mit dem Argument, außer zu testen, ob es existiert. Sie können also alles mit dem gleichen Effekt anschließen.
Adam