Czy istnieje fantazyjne OSD z powiadomieniem wertykalnym, które działa zarówno dla ALSA, jak i pulseaudio?

15

Czy jest jakiś wymyślny sposób, aby OSD powiadomienia głośności działało zarówno z pulseaudio, jak i ALSA? W tej chwili standardowe komputery stacjonarne działają tylko dla mnie z pulseaudio. Co powiesz na pionowe menu OSD, którego mogę użyć jako kropli zastępowania lub wywołania z wiersza poleceń, aby graficznie zgłaszać zmiany w dowolnych procentach, jako pasek, który przesuwa się w górę i w dół?

Powodem, dla którego muszę pracować zarówno z ALSA, jak i pulseaudio, jest to, że używam aplikacji WINE, która nie działa dobrze z pulsem, więc zabijam puls przed uruchomieniem aplikacji Windows, aby korzystać z ALSA bez dodatkowej warstwy abstrakcji. Kiedy zdałem sobie sprawę, że klawisze głośności na mojej klawiaturze nie działają bez pulsu, napisałem kilka skryptów bash, które wywołuję za pomocą Compiz lub Openbox (skonfigurowanych odpowiednio za pomocą CCSM i lxde-rc.xml), aby przechwycić sygnał wyjścia z pulseaudio --checki następnie odpowiednio dostosuj głośność:

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

Skrypty działają świetnie i mapowanie przycisków jest w porządku, ale nie mam już dobrego sposobu na zobaczenie wizualnej informacji zwrotnej - nawet w przypadku pulseaudio, ponieważ łapię zdarzenia przycisków (XF86AudioLowerVolume itp.). Oczywiście mogę po prostu zmapować klawisze głośności ALSA na coś innego, ale powielanie klawiszy skrótów nie ma sensu.

Znalazłem regulator głośności Pythona, który mogę wywołać w powyższych skryptach:
https://github.com/fishman/utils/blob/master/pvol.py

pvol.py -s pokazuje aktualny poziom głośności na ekranie zarówno dla ALSA, jak i pulseaudio, ale jest okropnie mały w porównaniu do OSD gnome, którego używałem, i nie jest pionowy (pasek u góry, stary OSD u dołu):

Porównanie wielkości standardowego OSD i pvol.py

Więc powiększyłem go i sflopowałem:

wprowadź opis zdjęcia tutaj

Ale nawet po zmianie orientacji na pionową niebieski domyślny motyw GTK nie jest tak gładki jak VLC (patrz poniżej).

Wiele z tego, co znalazłem w poszukiwaniu implementacji OSD, to posty dotyczące poleceń powiadomień i wysyłania, w których brakuje całej koncepcji paska postępu. W przeciwnym razie są to głównie poziome paski (i wiele liczących symboli zastępczych w skryptach bash). Naprawdę wszystko, co muszę zrobić, to zadzwonić do amix i pactl, więc coś prostego, jak pasek postępu gtk w pvol.py, byłoby świetne - po prostu nie tak niebieskie i nie na środku ekranu.

VLC ma dobry przykład tego, co mam na myśli, gdy przewijasz kółko myszy w trybie pełnoekranowym:

Pionowy pasek głośności VLC

Jest o wiele mniej przeszkadzający niż zwykłe pudełka, które znajdują się na środku ekranu:

Powiadomienie o poziomie głośności OSD

Cała analogia suwaka poziomego nigdy nie miała dla mnie większego sensu poza przesuwaniem dźwięku między lewym i prawym głośnikiem.

W każdym razie, w jaki sposób wywoływane są domyślne powiadomienia na pulpicie (zwłaszcza LXDE)? Widzę wiele postów na temat konfigurowania kluczowych zdarzeń prasowych, ale niewiele na temat skryptów, które te zdarzenia uruchamiają. Jakie inne opcje są dostępne w dziale fantazyjnym?

Czy jest też jakiś pakiet, który powinienem odinstalować, aby zapobiec powstawaniu konfliktów między zdarzeniami, które obsługuję za pomocą skryptów i poleceń compiz lub openbox?

Aktualizacja: Aby dowiedzieć się, z którego obecnie korzystam OSD, nie zmieniłem od razu sposobu obsługi przycisku wyciszenia. Zabicie xfce4-notifyd, a następnie naciśnięcie przycisku wyciszenia powoduje pojawienie się nowego procesu xfce4-notifyd, więc zgadywałem, że ikona dużego głośnika pochodzi z czegoś takiego jak xfce4-volumed, ale tak naprawdę nie mam zainstalowanego tego pakietu ... Ach, ha! Zabicie gnome-settings-demona zatrzymuje duży OSD na środku ekranu.

Adam
źródło
1
UWAGA: W LXDE musisz zabić panel i odrodzić go, gdy zatrzymasz pulseaudio lub lxpanel zacznie pochłaniać procesor.
Adam
5
Wow, co za niesamowite i dobrze przemyślane pytanie! +1
Seth

Odpowiedzi:

10

W porządku, ryzykując odpowiedzieć na moje pytanie, wymyśliłem trochę zhakowanej pyqt wersji pvol z linku w powyższym pytaniu. Jeśli nic więcej, może ktoś inny może poprawić mój kod. W końcu planuję albo pozbyć się części skryptu, które nie są używane, albo usunąć skrypty bash z równania i mieć jeden skrypt pyqt obsługujący wszystkie zdarzenia przycisku. W tej chwili limit czasu OSD jest stały od pierwszego naciśnięcia przycisku, zamiast pozostać włączony przez określony czas po ostatnim naciśnięciu przycisku.

Po prostu skopiuj, wklej i zapisz pliki (z pogrubionymi nazwami), umieść je wszystkie w tym samym katalogu, ustaw bity wykonywalne i zmodyfikuj wywołania systemowe w skrypcie pyqt zgodnie z miejscem, w którym je zapisałeś, lub umieść je wszystkie w katalog, który znajduje się na twojej ścieżce. Następnie zamapuj skrypty powłoki na polecenia Compiz, skróty Openbox lub coś podobnego i zmień skrypt pyqt, jeśli nie używasz przycisków głośności klawiatury multimedialnej.

Uwaga: nazwa klasy Qvol była działającym tytułem i nie zadałem sobie trudu, aby go zmienić. Należy również pamiętać, że przycisk wyciszenia nie jest obsługiwany - jest to tylko prototyp wyrażający możliwą drogę do spełnienia żądanych funkcji i nie jest obecnie powiązany z żadnym hostowanym projektem ani standardowym modelem programistycznym. Wszelkie znaczące zmiany wynikające z poniższego kodu powinny prawdopodobnie należeć do Sourceforge, GitHub lub strony internetowej projektu. To powiedziawszy, nie krępuj się edytować tej odpowiedzi lub zasugerować istniejący projekt, który pozwala na podobne działanie i wygląd.

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
źródło
„Ciche” argumenty dla skryptów bashowych zwiększania głośności są swego rodzaju manekinem - skrypty nie robią nic z argumentem poza testowaniem, czy on istnieje. Możesz więc podłączyć tam wszystko z tym samym efektem.
Adam