是否有适用于 ALSA 和 pulseaudio 的精美垂直通知 OSD?

是否有适用于 ALSA 和 pulseaudio 的精美垂直通知 OSD?

有没有一种奇特的方法可以让音量通知 OSD 与 pulseaudio 和 ALSA 兼容?目前,标准桌面版仅适用于 pulseaudio。我可以使用垂直 OSD 作为替代品,或者从命令行调用它,以图形方式报告任意百分比的变化,就像上下移动的条一样,怎么样?

我需要它与 ALSA 和 pulseaudio 一起工作的原因是我正在使用一个与 pulse 配合不好的 WINE 应用程序,所以我在启动 Windows 应用程序之前杀死了 pulse,以便在没有额外抽象层的情况下使用 ALSA。当我意识到没有 pulse 键盘上的音量键就无法工作时,我编写了一些 bash 脚本,我使用 Compiz 或 Openbox(分别通过 CCSM 和 lxde-rc.xml 配置)调用这些脚本来捕获退出信号,pulseaudio --check然后相应地调整音量:

音量升高

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

音量降低

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

脚本运行良好,可以很好地映射到按钮,但我没有很好的方法来查看视觉反馈——即使是使用 pulseaudio 脚本,因为我正在捕捉按钮事件(XF86AudioLowerVolume 等)。显然,我可以将 ALSA 音量键映射到其他东西上,但复制快捷键是没有意义的。

我确实找到了一个可以在上面的脚本中调用的 python 音量控制:
https://github.com/fishman/utils/blob/master/pvol.py

pvol.py -s在屏幕上显示 ALSA 和 pulseaudio 的当前音量级别,但与我一直使用的 gnome OSD 相比,它非常小,并且不是垂直的(栏在顶部,旧 OSD 在底部):

标准OSD和pvol.py的大小比较

因此,我将其放大并翻转:

在此处输入图片描述

但是,即使将方向切换为垂直方向,蓝色的默认 GTK 主题也不像 VLC 那样流畅(见下文)。

在搜索 OSD 实现时,我发现很多都是关于通知发送命令的帖子,这些命令缺乏完整的进度条概念。否则,它主要是水平条(以及 bash 脚本中的大量计数占位符)。实际上我需要做的就是调用 amix 和 pactl,所以像 pvol.py 中的 gtk 进度条这样简单的东西就很好了——只是不要太蓝,也不在屏幕中间。

VLC 有一个很好的例子来说明我在全屏模式下滚动鼠标滚轮时想到的内容:

VLC 垂直音量条

它比通常位于屏幕中央的框的阻碍要小得多:

水平OSD音量通知

除了在左右扬声器之间平移音频之外,整个水平滑块类比对我来说没有多大意义。

无论如何,默认桌面通知是如何调用的(尤其是 LXDE)?我看到很多关于配置按键事件的帖子,但关于这些事件触发什么脚本的帖子却不多。在垂直花哨部门还有哪些其他选择?

此外,我是否应该卸载某些软件包以防止我通过脚本和 compiz 或 openbox 命令处理的事件之间发生冲突?

更新:为了弄清楚我当前正在使用什么 OSD,我没有立即改变处理静音按钮的方式。杀死 xfce4-notifyd 然后按下静音按钮会生成一个新的 xfce4-notifyd 进程,所以我猜测大扬声器图标来自 xfce4-volumed 之类的东西,但我实际上没有安装该软件包……啊哈!杀死 gnome-settings-daemon 会停止屏幕中心的大 OSD。

答案1

好吧,冒着回答自己问题的风险,我从上面问题的链接中想出了一个 pvol 的 pyqt 版本。如果没有别的办法,也许其他人可以改进我的代码。最终,我计划要么删除下面脚本中未使用的部分,要么将 bash 脚本从等式中移除,让一个 pyqt 脚本处理所有按钮事件。现在,OSD 从第一次按下按钮开始以恒定的速率超时,而不是在最后一次按下按钮后保持固定的时间。

只需复制、粘贴并保存文件(名称以粗体显示),将它们全部放在同一目录中,设置可执行位,并根据保存位置修改 pyqt 脚本中的系统调用,或将它们全部放在路径中的目录中。然后将 shell 脚本映射到 Compiz 命令、Openbox 快捷方式或类似内容,如果您不使用多媒体键盘音量按钮,请更改 pyqt 脚本。

注意:类名 Qvol 是一个工作标题,我没有费心去更改它。还请注意,静音按钮未处理 - 这只是一个原型,用于表达实现所请求功能的可能途径,并且它目前不与任何类型的托管项目或标准开发模型相关联。从以下代码派生的任何重要开发都应该属于 Sourceforge、GitHub 或项目网站。也就是说,请随意编辑此答案或建议允许在功能和设计上相似的现有项目。

流量

音量降低

#!/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

音量升高

#!/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

流量

#!/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()  

相关内容