带有 Kodi 的 Ubuntu - 如何根据音频输出暂停?

带有 Kodi 的 Ubuntu - 如何根据音频输出暂停?

好的,我在 HTPC 上运行 Ubuntu 15.04 和 Kodi 15.2。由于这两个系统的电源管理似乎会引起一些冲突,因此我一直遇到挂起和休眠问题。当我在 Kodi 上看电影时,Ubuntu 会让我的系统进入睡眠状态,所以我禁用了电源管理。当我在观看 Netflix 时,Kodi 会让我的系统进入睡眠状态(使用 Advanced Launcher 或 Chrome Launcher),所以我禁用了该功能(目前我的 HTPC 全天候运行)。我正在尝试编写某种脚本,不仅可以测量不活动状态,还可以测量音频输出。在编写脚本方面,我完全是个菜鸟,但这是我目前想到的:

    LOG=/var/log/sleepcounter.log
    sound=0 > /var/log/sleepcounter.log

    while true: do
        sleep 1

        # check if sound is sent to speakers, add 1 if not
        if pactl list | grep -v RUNNING > /dev/null; then
            echo sound=$((sound += 1)) > /var/log/sleepcounter.log;
        fi
    done

这实际上是对音频未播放的秒数进行计数。问题是,当音频播放时,它不会将计数器重置为“0”。我尝试将其切换过来,并想出了一个略有不同的脚本,但它不起作用:

    LOG=/var/log/sleepcounter.log
    sound=0 > /var/log/sleepcounter.log
    read -d $'\x04' sound < "$LOG"


    while true; do
            sleep 1

            # check if sound is sent to speakers, add 1 if not
            if pactl list | grep  RUNNING > /dev/null; then
                    echo sound=0 > /var/log/sleepcounter.log
            else echo sound=$((sound += 1)) > /var/log/sleepcounter.log;

            fi
    done

这个脚本并没有向 sleepcounter.log 文件写入任何内容,当我检查它时,它是空白的。我不知道如何让它默认为 sound=0,并在播放声音时保持 0,在声音停止时开始计数,然后在声音再次开始时从 0 重新开始……

我将其与另一个脚本配对:

    LOG=/var/log/sleepcounter.log
    read -d $'\x04' sound < $LOG

    while true; do
            sleep 30
            # check if there is any system activity
            if [[ `xprintidle` > 600000 && "$sound" -ge 600 ]]; then
                    (sudo pm-suspend-hybrid);
            fi
    done

这个确实有效。如果我手动将 sleepcounter.log 设置为 sound=600(或更大),系统会在 10 分钟不活动时进入睡眠状态。虽然这个有效,但我想也许还有一种方法可以将两个脚本合并为一个,只是为了让它更简单一些。

我知道我在引用变量时遇到了问题,这是我第一次尝试编写脚本。如果有人能帮助我,我将不胜感激。

答案1

经过一些测试,我发现 Kodi 在空闲几分钟后关闭了其 Pulseaudio 客户端。这使得这个问题变得非常简单。在关闭脚本中,您需要测试的(除了时间)就是没有 Kodi 或 Chrome 客户端。这很简单:

DISPLAY=:0 pactl list clients | grep -E 'kodi|chrome'

编辑:说实话,在写这个答案之前,我并没有读过标题。设置DISPLAY似乎是关键元素,至少在这里,以便pactl查看正确的 Pulseaudio 会话。

如果您要将此脚本编写到某个程序中,请记住grep匹配时返回 0。并且您可以使用-q参数,而不是重定向到/dev/null

然而如果你也关闭了导航声音,用户可能只是在菜单中。你可能需要做另一种检查,也许挂接到输入或检查平均屏幕色彩(将屏幕保护程序设置为黑屏,如果屏幕是黑的,并且没有声音,则暂停)。

答案2

我会在这里发布此信息,以便其他寻求简单解决方案的人使用。我最担心的是,很多时候我们在看电影时睡着了,醒来后发现电视仍然开着。我是 Linux 新手,我们之前的系统是 Windows XP(没有 Kodi),所以 10 分钟后屏幕被禁用是没有问题的(尽管它偶尔会出现故障,并在 Netflix 电影中途关闭)。我过去曾有两台不同的戴尔 Windows 系统因进入睡眠状态而死机,从未唤醒,所以我从未使用过 Windows 内置的睡眠/挂起功能。我认为 Kodi 是一个很棒的界面,比尝试使用无线迷你键盘/触控板控制 Windows 桌面要好得多。

我终于搞清楚了这一点,当然我把它弄得比实际复杂得多。我最终做的是将两个不同的脚本重写为一个脚本:

    while true; do
            sleep 1     # wait for 1 second to continue loop

            # check for sound output, if yes clear variable, if no then count +1
            if pactl list | grep RUNNING > /dev/null; then
                unset sound; echo $sound; else
                echo sound=$((sound++))
            fi

            # check idle time and no-sound time, if yes then suspend and exit loop
            if [[ `xprintidle` > 600000000 && "$sound" -ge 600 ]]; then
                (sudo pm-suspend); exit 0
            fi
    done

保存脚本后,我必须执行一些其他命令才能使其正常工作:

    chmod x+ /path/to/filename.sh #to make it executable
    chmod 555 /path/to/filename.sh #had a problem with permissions and ownership

然后修改/etc/sudoers文件以便能够pm-suspend在没有 root 权限或要求输入密码的情况下进行调用,方法是在文件末尾添加以下内容:

    username  ALL = NOPASSWD: /usr/sbin/pm-hibernate
    username  ALL = NOPASSWD: /usr/sbin/pm-suspend

替换username为我用于登录系统的实际用户名。

到目前为止,无论是什么在产生声音(我通过 Kodi 的 Chrome Launcher 测试了 Netflix,直接从桌面测试了 Chrome 中的 YouTube,以及直接从 Kodi 播放电影),只要我不做其他事情,它就会在声音停止后大约 10 分钟暂停。我说“大约”是因为我相信xprintidle这里和那里会产生一些随机数,但到目前为止它总是处于睡眠状态。我不得不添加命令exit,否则它会产生难以摆脱的睡眠/唤醒循环。然后我通过添加 cron 作业添加了要在启动时运行的脚本@reboot /path/to/filename.sh。这很有效,但我还不确定是否会cron在恢复时重新启动(我不相信它会重新启动,还没有能够测试),或者我是否必须在系统唤醒时从其他地方调用脚本。

我想我需要在另一个线程中询问,但这个项目的下一部分是确保该脚本在恢复时重新启动,并让系统识别我的 Rii Mini i28 无线键盘(带 USB 加密狗)作为唤醒设备。

相关内容