自动在内部和HDMI扬声器之间切换


18

您知道将耳机插入笔记本电脑的aux插孔时如何将内部扬声器自动静音并且声音从耳机中发出吗?我想要HDMI正是这样。

我有时将带有内置扬声器的显示器连接到笔记本电脑上,以观看视频。当视频放在显示器上(离我的桌子3 m远)时,这很奇怪,但是声音来自笔记本电脑的内置扬声器(笔记本电脑坐在桌子上)。

当然,我可以转到声音设置,然后将输出通道切换为HDMI。但是后来,当我几个小时前拔下HDMI电缆,甚至可能在一个完全不同的位置时,声音将无法播放,因为声音服务器仍尝试通过HDMI播放它,但是没有任何连接。

在没有通过HDMI连接任何设备时自动切换回内部扬声器更为重要,但是在连接有设备时通过HDMI切换到声音输出仍然非常好。

这显然适用于11.10,但不适用于16.04。


使用快捷键切换声音可能对您来说是一个很好的解决方案。此线程的第二个答案是这样的:askubuntu.com/questions/41858/…–
WinEunuuchs2Unix

我仍在寻找解决方案(在16.04;建议的解决方案均无效)。这个问题也在薄荷论坛上讨论
hiro主角

@hiroprotagonist是的,我也是。似乎这里的答案在大多数情况下都有效,但并非全部。
UTF-8

实际上,自动切换在Ubuntu 14.04中有效,除非已被更新禁用。
BurninLeo

Answers:


8

背景

当声音从HDMI电视切换到笔记本电脑扬声器时,在暂停/恢复过程中我遇到了类似的问题。恢复后,声音将留在笔记本电脑扬声器上,我必须在System Settings->中手动将输出设备重置为电视Sound

这是我最初从Ubuntu 14.04升级到16.04的烦人经历之一,其根源是升级到16.04 LTS附带的PulseAudio 8

经过大量搜索之后,我创建了一个名为的脚本TV-sound。尽管我不像自己那样插拔电视,但我进行了一些Google搜索并创建了变体脚本以适合您的情况。我已经对其进行了测试,并且可以正常工作。

步骤1:创建脚本以在连接的设备之间切换音频

我们将创建一个称为hotplugtvudev调用的脚本。尽管可以在许多地方调用同一脚本。例如,在测试期间,我lock-screen-timer在屏幕锁定期间将声音恢复为笔记本电脑的情况下使用了它。

cd /usr/local/bin
sudo touch hotplugtv
sudo chmod +x hotplugtv
gksu gedit hotplugtv

当编辑器打开并显示空白屏幕时,将以下内容复制并粘贴到其中:

#! /bin/bash

# NAME: hotplugtv
# PATH: /usr/local/bin
# DESC: Update pulseaudio output device when HDMI TV plugged / unplugged
# CALL: called from /etc/udev/rules.d/99-monitor-hotplug.rules
# DATE: Created Nov 26, 2016.
# NOTE: logs output using log-file
# UPDT: Dec 14, 2016 - Sometimes /sys/class/drm/card0 & sometimes /sys/class/drm/card1
#       so use /sys/class/dmcard* instead.

if [[ $(cat /sys/class/drm/card*-HDMI-A-1/status | grep -Ec "^connected") -eq 1 ]]; then
#        log-file "HDMI TV connected" ~/bin/log-hotplugtv;
        /bin/sleep 2;
        export PULSE_RUNTIME_PATH="/run/user/1000/pulse/";
        sudo -u rick -E pacmd set-card-profile 0 output:hdmi-stereo;
else
#        log-file "HDMI TV disconnected" ~/bin/log-hotplugtv;
        export PULSE_RUNTIME_PATH="/run/user/1000/pulse/";
        sudo -u rick -E pacmd set-card-profile 0 output:analog-stereo;
fi

exit 0

您将需要rick用自己的用户ID(例如)替换两次出现的UTF-8

我知道通过自动将用户名设置为bash变量可以更加专业,但是我还不熟练:(无论如何,保存文件并退出gedit

步骤2:建立udev规则

当您插入和拔下HDMI监视器时,udev会监视热插拔事件。键入以下内容以创建新规则。

cd /etc/udev/rules.d
sudo cp 70-persistent-net.rules 99-hotplugtv.rules
gksu gedit 99-hotplugtv.rules

注意:如果目录70-persistent-net.rules中不存在该文件,请在该目录中复制任何其他文件。我们不需要文件内容,仅需要文件许可权即可确保文件权限相同。

编辑器将显示一堆不相关的文本,突出显示并删除它。然后突出显示下面的代码并将其粘贴到编辑器中:

# NAME: 99-hotplugtv.rules
# PATH: /etc/udev/rules.d
# DESC: Update pulseaudio output device when HDMI TV plugged / unplugged
# CALL: automatically called on system events
# DATE: Created Nov 26, 2016.
# NOTE: in future may requre systemd service hooks

ACTION=="change", SUBSYSTEM=="drm", ENV{HOTPLUG}=="1", RUN+="/usr/local/bin/hotplugtv"

保存文件并退出。

要启用该规则(不重新启动),我们需要重新加载udev:

sudo udevadm control --reload-rules

现在,您可以插入和拔下HDMI监视器/电视,并相应地切换声音。

警告

在我的系统上,拔下HDMI时,声音会自动恢复为笔记本电脑的扬声器。在您的系统上没有。如果在拔下HDMI时声音没有传到笔记本电脑扬声器上,则可能需要进一步增强代码。请通过下面的评论回复,看看事情如何/不成功。

在CLI中进行快速测试

您可以使用以下命令在终端上快速测试代码:

    export PULSE_RUNTIME_PATH="/run/user/1000/pulse/";
  • 切换至HDMI /电视:

        sudo -u rick -E pacmd set-card-profile 0 output:hdmi-stereo;
  • 切换回内置扬声器:

        sudo -u rick -E pacmd set-card-profile 0 output:analog-stereo;
  • 请记住rick用您的用户名替换。

  • 最初的export行可能不是必需的,但为了安全起见,我已将其包括在内。
  • 如果您有多个声卡,或者hdmi-stereo在编写脚本之前显然需要进行其他调整才能找出正确的参数。

在PulseAudio中解密设备名称

下面的代码两次使用同一命令。声音设置为外部HDMI电视时一次。第二次将声音设置为笔记本电脑的内置扬声器时。每次您看到名称PulseAudio都会使用:

$ pacmd list-sinks | grep -e 'name:' -e 'index'
  * index: 28
    name: <alsa_output.pci-0000_00_1b.0.hdmi-stereo>
───────────────────────────────────────────────────────────────────────────────
$ pacmd list-sinks | grep -e 'name:' -e 'index'
  * index: 30
    name: <alsa_output.pci-0000_00_1b.0.analog-stereo>

当您有多个声卡时

使用命令aplay -l查看卡号是否大于0。如果是,则需要在脚本中使用适当的卡号。例如:

$ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: PCH [HDA Intel PCH], device 0: 92HD91BXX Analog [92HD91BXX Analog]
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 0: PCH [HDA Intel PCH], device 3: HDMI 0 [HDMI 0]
  Subdevices: 0/1
  Subdevice #0: subdevice #0

在上面的示例中,具有不同输出源的所有卡号均为0。如果您有USB扬声器,则它们的卡号可以不同于0。

编辑2016年12月2日

由于某种未知的原因,该脚本今天已被破坏。上面的代码用来读取:“ $(cat / sys / class / drm / card0-HDMI-A-1 / status”,但是我不得不更改card0card1上面的代码,因此无法修改。自2016年11月26日起在我的系统上运行,而不是常规Ubuntu更新。

编辑2016年12月14日

上面的代码需要再次切换回:“ $(cat / sys / class / drm / card0-HDMI-A-1 / status”。而不是根据启动之间card0或之间的修改代码,而是card1修改程序以引用card*这两种情况。


我无法复制,70-persistent-net.rules因为它不存在。/etc/udev/rules.d仅包含一个名为的文件39-smfp_samsung.rules
UTF-8

哦,好复制30-smfp_samsung.rules,我们不需要文件内容只是为了确保我们对新文件拥有正确的权限。复制现有文件是最简单的方法(无论如何对我来说)。
WinEunuuchs2Unix

1
它在我的系统上不起作用。@已经对此答案表示支持的人:它对您有用吗?| 我首先尝试了它,但没有重新启动,但没有成功。重新启动后,它也不起作用。重新启动之前,我断开了HDMI并将声音设置为内置扬声器。重新启动后,我播放了一些音乐并连接了HDMI电缆。音乐仍然(仅)来自内置扬声器。除了两次出现的用户名外,您是否还需要更改其他任何内容?cat /sys/class/drm/card0-HDMI-A-1/status显示正确的状态(我尝试了几次)。
UTF-8

@ UTF-8我添加了一个新部分,您可以在其中测试命令行的切换。您可以运行此命令,看看是否会出现错误吗?
WinEunuuchs2Unix

似乎没有output:analog-stereopastebin.com/n5bHyhCm这使它变得更加奇怪,因为那时我希望声音总是通过HDMI播放。连接HDMI未连接HDMI 我的声音设置的屏幕截图。编辑:我已经尝试过了,但是花了我几分钟才发布此评论,因为我必须上传屏幕截图。
UTF-8
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.