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

您知道当您将耳机插入笔记本电脑的辅助插孔时,内置扬声器会自动静音并且耳机会发出声音吗? 我想要的是HDMI。

我有时将带有内置扬声器的显示器连接到笔记本电脑上观看video。 video在显示器上(距离我的桌子3米远)时非常奇怪,但声音来自笔记本电脑的内置扬声器(笔记本电脑放在桌面上)。

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

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

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

背景

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

这是我从Ubuntu 14.04升级到16.04的第一次烦人体验之一,根本升级到Pulse Audio 8,它带有16.04 LTS

经过多次搜索,我创建了一个名为TV-sound的脚本。 虽然我没有像你一样插拔电视,但我做了一些谷歌搜索并创建了一个脚本的变体,以适应你的情况。 我测试了它,它的工作原理。

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

我们将创建一个名为hotplugtv的脚本,udev调用该脚本。 但是,在许多地方可以调用相同的脚本。 例如,在测试期间,我在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 

您需要使用自己的用户ID替换两次出现的rick ,即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 / TV:

      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:  ─────────────────────────────────────────────────────────────────────────────── $ pacmd list-sinks | grep -e 'name:' -e 'index' * index: 30 name:  

当你有多张声卡时

使用命令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”但我不得不将card0更改为card0 ,上面的代码已经修改过了。我无法解释自2016年11月26日以来,除了常规Ubuntu更新之外,我的系统发生了哪些变化。

编辑2016年12月14日

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