如何在耳机断开连接时暂停 VLC 播放?

Her*_*Hde 12 headphones video-player vlc playback

当我的耳机被拔掉时,如何暂停 VLC 的播放?我可以通过 ALSA 将扬声器静音,但我想使用插头触发器来停止播放,这在智能手机中很常见。

Stu*_*nts 9

好的,因此您需要为此做一些事情:

  1. 检测耳机何时拔下;
  2. 在(1)中的事件发生后,向VLC发送“暂停”命令;
  3. 检测耳机何时重新插入;
  4. 在(3)中的事件之后,向VLC发送“播放”命令;

对于 (1) 和 (3):您可以使用此处显示的内容。此答案包含一个小程序,用于查找插入式和未插入式插孔之间的区别,以及您可以修改以符合您的情况的脚本。

对于 (2) 和 (4):您应该使用 VLC 的 Dbus 接口。相关代码应该是这样的:

dbus-send --print-reply --session --dest=org.mpris.vlc /Player org.freedesktop.MediaPlayer.Pause

dbus-send --print-reply --session --dest=org.mpris.vlc /Player org.freedesktop.MediaPlayer.Play

分别用于暂停和播放。

现在,关于脚本。在你的情况下,它应该是这样的:

#!/bin/bash
# This scripts detecs unplugging headphones.

oldstatus="unrelated string"
while [ 1 ]; do
    # The following line has to be changed depending on the difference (use diff) in '/proc/asound/card0/code#0'
    status=$(grep -A 4 'Node 0x16' '/proc/asound/card0/codec#0' |  grep 'Amp-Out vals:  \[0x80 0x80\]')
    if [ "$status" != "$oldstatus" ]; then
        if [ -n "$status" ]; then
            echo "Plugged in"
             dbus-send --print-reply --session --dest=org.mpris.vlc /Player org.freedesktop.MediaPlayer.Play
            oldstatus="$status"
        else
            echo "Unplugged"
            dbus-send --print-reply --session --dest=org.mpris.vlc /Player org.freedesktop.MediaPlayer.Pause
            oldstatus="$status"
        fi
    fi
    # Now sleep for 250 milli-seconds as per @Serg's request (who learnt if from @Fabby)
    # sleep is timer-based so doesn't use *any* processor cycles while sleeping.
    sleep 0.25
done
Run Code Online (Sandbox Code Playgroud)

将此修改后的脚本添加到您的启动应用程序中,您就完成了。我认为它应该做你想做的。

PS - 请注意,有更有效的方法可以做到这一点,例如inotify用于检测事件更改(甚至可能是其他方法),但这应该可以帮助您入门(其他方法都高于我的技能水平和经验)。我想你可以从这种“hackish”方法开始,然后从这里开始。

  • 你可以在最后添加一个 `sleep 0.25`,这是四分之一秒的延迟。这减轻了 CPU 的负担,并且仍然足够快。我有时也在自己的脚本中使用它 (3认同)
  • ACPI 处理拔下耳机,您会将其添加到您的答案中吗?http://askubuntu.com/a/642404/20275 (2认同)

Stu*_*nts 5

好的,根据我从这里学到的知识,我正在尝试使用 ACPI 的新方法。

  1. 创建一个脚本,用于暂停和取消暂停 VLC:

    sudo touch /etc/acpi/headphone_jack.sh
    sudo chmod +x /etc/acpi/headphone_jack.sh
    
    Run Code Online (Sandbox Code Playgroud)

    并将以下内容放在此文件中:

    _pid=`pgrep vlc`
    _pid="${_pid% *}"
    DBUS_SESSION_BUS_ADDRESS=`grep -z DBUS_SESSION_BUS_ADDRESS /proc/$_pid/environ | sed -e 's/DBUS_SESSION_BUS_ADDRESS=//'`
    _username=`grep -z USER= /proc/$_pid/environ |sed 's/.*=//'`
    
    if [ "$3" = unplug ]; then
        su $_username -c "DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS dbus-send --print-reply --session --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Pause"
    else
        su $_username -c "DBUS_SESSION_BUS_ADDRESS=$DBUS_SESSION_BUS_ADDRESS dbus-send --print-reply --session --dest=org.mpris.MediaPlayer2.vlc /org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.Play"
    fi
    
    Run Code Online (Sandbox Code Playgroud)
  2. 现在让我们创建一个事件触发器(替换vim为您最喜欢的文本编辑器):

    sudo vim /etc/acpi/events/headphones
    
    Run Code Online (Sandbox Code Playgroud)

    并添加以下内容:

    event=jack/headphone
    action=/etc/acpi/headphone_jack.sh %e
    
    Run Code Online (Sandbox Code Playgroud)
  3. 最后,重启 ACPI 守护进程:

    sudo service acpid restart
    
    Run Code Online (Sandbox Code Playgroud)

我认为这应该正是您所需要的,不涉及投票。我在这个实现中发现的唯一缺点是,如果您有多个用户同时运行 VLC。我想在这种情况下,可能发生的情况是这种方法会随机暂停并恢复其中之一(或者它可能根本不起作用)。

感谢@int_ua 和@Sneetsher 为我提供了有关 ACPI 事件处理的重要知识。还要感谢@user3073656 帮助简化程序。