Существует ли модное вертикальное экранное уведомление, которое работает как для ALSA, так и для pulseaudio?

15

Есть ли причудливый способ заставить OSD уведомлений о громкости работать с pulseaudio и ALSA? Прямо сейчас стандартные настольные работают только с pulseaudio для меня. Как насчет вертикального OSD, которое я могу использовать для замены или вызова из командной строки, чтобы графически сообщать об изменениях в произвольных процентах, в виде полосы, которая перемещается вверх и вниз?

Причина, по которой он мне нужен для работы как с ALSA, так и с pulseaudio, заключается в том, что я использую приложение WINE, которое не очень хорошо работает с импульсами, поэтому я отключаю импульс перед запуском приложения Windows, чтобы использовать ALSA без дополнительного уровня абстракции. Когда я понял, что клавиши регулировки громкости на моей клавиатуре не работают без импульса, я написал несколько сценариев bash, которые я вызываю с помощью Compiz или Openbox (настроенных через CCSM и lxde-rc.xml соответственно), чтобы перехватить сигнал выхода из pulseaudio --checkи затем отрегулируйте громкость соответственно:

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

Сценарии отлично работают и отображаются на кнопки просто отлично, но у меня больше нет возможности видеть визуальную обратную связь - даже с импульсами, так как я перехватываю события кнопок (XF86AudioLowerVolume и т. Д.). Очевидно, я мог бы просто сопоставить клавиши регулировки громкости ALSA с чем-то другим, но нет смысла дублировать сочетания клавиш.

Я нашел регулятор громкости python, который я могу вызвать в приведенных выше скриптах:
https://github.com/fishman/utils/blob/master/pvol.py

pvol.py -s показывает текущий уровень громкости на экране для ALSA и pulseaudio, но он ужасно крошечный по сравнению с OSD гнома, который я использовал, и он не вертикальный (столбец сверху, старый OSD снизу):

Сравнение размеров стандартных OSD и pvol.py

Итак, я сделал это больше и шлепнул вокруг:

введите описание изображения здесь

Но, даже с переключением ориентации на вертикальную, синяя тема GTK по умолчанию не такая гладкая, как VLC (см. Ниже).

Многое из того, что я нашел при поиске реализаций OSD, - это сообщения о командах notify-send, в которых отсутствует вся концепция индикатора выполнения. В противном случае это в основном горизонтальные столбцы (и большое количество подсчитываемых заполнителей в скриптах bash). На самом деле все, что мне нужно сделать, это вызвать amix & pactl, так что было бы замечательно что-то простое, например, индикатор выполнения gtk в pvol.py - просто не такой синий и не прямо в середине экрана.

VLC имеет хороший пример того, что я имею в виду, когда вы прокручиваете колесо мыши в полноэкранном режиме:

VLC вертикальная шкала громкости

Это намного менее мешает, чем обычные окна, которые находятся в центре экрана:

Горизонтальное уведомление об объеме OSD

Вся аналогия с горизонтальным слайдером никогда не имела для меня большого смысла, кроме панорамирования звука между левой и правой колонками.

В любом случае, как получаются уведомления рабочего стола по умолчанию (особенно LXDE)? Я вижу много сообщений о настройке событий нажатия клавиш, но не много о том, какие сценарии запускают эти события. Какие еще варианты есть в вертикально-модном отделе?

Кроме того, есть ли какой-нибудь пакет, который я должен удалить, чтобы предотвратить возникновение конфликтов между событиями, которые я обрабатываю с помощью сценариев и команд compiz или openbox?

Обновление: чтобы выяснить, какое OSD я сейчас использую, я не сразу изменил способ обработки кнопки отключения звука. Если убить xfce4-notifyd, а затем нажать кнопку отключения звука, будет запущен новый процесс xfce4-notifyd, поэтому я предположил, что значок большого динамика произошел из-за чего-то вроде xfce4-Volumed, но на самом деле у меня не установлен этот пакет ... Ах, ха! Убийство gnome-settings-daemon останавливает большое OSD в центре экрана.

Адам
источник
1
ПРИМЕЧАНИЕ: с LXDE вы должны убить панель и перезапустить ее, когда вы остановите pulseaudio, или lxpanel начнет загружать процессор.
Адам
5
Ух ты какой классный и продуманный вопрос! +1
Сет

Ответы:

10

Хорошо, рискуя ответить на мой собственный вопрос, я придумал немного взломанную версию Pyqt pvol по ссылке в вопросе выше. Если ничего другого, возможно, кто-то еще может улучшить мой код. В конце концов, я планирую либо избавиться от частей в скрипте ниже, которые остаются неиспользованными, либо убрать скрипты bash из уравнения и сделать так, чтобы один скрипт pyqt обрабатывал все события кнопки. Прямо сейчас экранное меню истекает с постоянной скоростью с первого нажатия кнопки вместо того, чтобы оставаться включенным в течение фиксированного периода времени после последнего нажатия кнопки.

Просто скопируйте, вставьте и сохраните файлы (с именами, выделенными жирным шрифтом), поместите их все в один каталог, установите исполняемые биты и измените системные вызовы в скрипте pyqt в соответствии с тем, где вы их сохраните, или поместите их все в каталог, который находится на вашем пути. Затем сопоставьте сценарии оболочки с командами Compiz, ярлыками Openbox или чем-то подобным и измените сценарий pyqt, если вы не используете кнопки громкости на мультимедийной клавиатуре.

Примечание: имя класса Qvol было рабочим названием, и я не стал его менять. Также обратите внимание, что кнопка отключения звука остается необработанной - это всего лишь прототип для выражения возможного пути выполнения запрошенных функций, и в настоящее время он не связан с каким-либо размещенным проектом или стандартной моделью разработки. Любые существенные разработки, полученные из приведенного ниже кода, вероятно, должны принадлежать Sourceforge, GitHub или веб-сайту проекта. Тем не менее, не стесняйтесь редактировать этот ответ или предложить существующий проект, который позволяет схожи по функциям и дизайну.

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()  
Адам
источник
«Безмолвные» аргументы для сценариев bash с шагом шага - это своего рода фиктивный хак - сценарии фактически ничего не делают с аргументом, кроме проверки его существования. Таким образом, вы можете подключить все что угодно с тем же эффектом.
Адам