这是一个老问题,也许你已经解决了你的问题。但是如果你还没有解决,或者其他人遇到了这个问题并且找不到适合他们的解决方案(就像我最近遇到的情况一样),那么这里有另一种可以尝试的方法。
这主要是从
这里的建议中提取出来的,但稍微扩展/修改了一下。似乎PulseAudio存在一个bug,可能导致它无法自动检测hdmi音频输出(在其语言中称为“sinks”),因此您可以通过手动告诉它您的hdmi设备来修复问题。
步骤1:确保PulseAudio没有检测到您的hdmi sink
您可以使用
pactl list short sinks
列出加载到PulseAudio中的所有sink。这应该会产生一系列形式的东西。
0 alsa_output.pci-0000_06_00.6.HiFi__hw_Generic__sink module-alsa-card.c s16le 2ch 48000HzIDLE
如果您的HDMI音频在列表中没有显示出来,那么我们可能已经找到了问题,请继续阅读。如果您不确定是否有显示,您也可以运行
pactl list sinks | grep description
以获取更多可读性强的设备描述信息。我认为HDMI输出将具有形如"blah High Definition Audio Controller"的描述,而非HDMI输出可能会有类似"blah blah blah Speaker + Headphone"的描述。
第二步:确保您的计算机能够将音频输出到HDMI
运行
aplay -l
以获取硬件播放设备列表。对我来说,输出看起来像是这样的:
**** List of PLAYBACK Hardware Devices ****
card 0: NVidia [HDA NVidia], device 3: HDMI 0 [HDMI 0]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: NVidia [HDA NVidia], device 7: HDMI 1 [HDMI 1]
Subdevices: 0/1
Subdevice #0: subdevice #0
card 0: NVidia [HDA NVidia], device 8: HDMI 2 [HDMI 2]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: NVidia [HDA NVidia], device 9: HDMI 3 [HDMI 3]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: NVidia [HDA NVidia], device 10: HDMI 4 [HDMI 4]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 0: NVidia [HDA NVidia], device 11: HDMI 5 [HDMI 5]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: Generic [HD-Audio Generic], device 0: ALC245 Analog [ALC245 Analog]
Subdevices: 0/1
Subdevice #0: subdevice #0
特别是,有许多种类的HDMI设备可供选择。我们想找到与您插入电缆的HDMI端口实际对应的设备。
首先要做的是运行“alsamixer”以确保您的HDMI设备没有静音。您应该会看到一个类似下面的屏幕。
![enter image description here](https://istack.dev59.com/kFoPK.webp)
使用
F6
选择正确的声卡。如果在任何插槽中看到
MM
,那意味着它被静音了。选择它并按下
M
取消静音。完成后按下
Esc
。
实际上,你可能只需要取消静音其中一个插槽(与你的 HDMI 端口相关联的插槽,通常是第一个),但取消静音所有插槽也无妨。
处理完这些后,我们现在可以测试你的音频。运行
speaker-test --channels 2 --test wav --device hw:[card],[device]
其中 [card],[device] 是指从 aplay -l
的输出中得到的数字,例如,我会首先使用 hw:0,3
。你需要对之前列出的每个 HDMI 硬件设备都进行这样的操作,直到其中一个能够发出可听的声音为止。
第三步:将 HDMI 输出添加到 PulseAudio 并确保其正常工作(如果不需要可以跳过)
现在,你已经确定了与你的 HDMI 端口相关联的卡和设备号码,只需运行以下命令:
pactl load-module module-alsa-sink device=hw:[card],[device]
你现在应该能够进入声音设置并看到一个新的可选输出设备(我的叫做“TU116高清音频控制器”)。选择它,然后查看你的HDMI音频是否正常工作。如果不行,我无法帮助你。但如果可以,恭喜你。
第四步:使这个更改(几乎)永久化
目前,如果你重新启动电脑,你需要再次运行这个“load_module”命令才能让HDMI再次工作。为了让事情变得更好一点,以root身份编辑“/etc/pulse/default.pa”文件,并在文件末尾添加以下行:
load-module module-alsa-sink device=hw:[card],[device]
在这之后(尤其是如果你跳过了第三步),你可能想要运行。
rm -r ~/.config/pulse
killall pulseaudio
pulseaudio --start
重新启动PulseAudio。
最后,有几个小问题/备注
- 对我来说,即使在执行此操作之后,重启计算机后仍然需要运行
killall pulseaudio; pulseaudio --start
才能加载hdmi音频输出。我不知道如何解决这个问题。
- 对我来说,即使没有插入HDMI线缆,Ubuntu的声音设置中仍然会列出HDMI设备作为选项。我不知道如何解决这个问题。
- 本答案开头的链接提到了一个脚本,可以在插入HDMI线缆时自动切换到HDMI音频输出。我对Linux了解不多,无法理解该脚本的具体内容,所以我自己没有尝试过。
编辑:一个执行本答案的Bash脚本
针对上面的最后一个要点,我最近写了一个bash脚本,可以自动执行这里描述的步骤。你可以在
github上找到它。与
参考链接中的脚本相比,我写的这个脚本(尝试)对运行它的机器做出更少的假设;特别是,它不假设PulseAudio已经(手动)配置好以检测你的HDMI电缆。如果还没有进行这样的配置,它会运行上述过程,然后将音频切换到HDMI。
这个脚本可以通过使用udev在插入或拔出HDMI电缆时自动运行。要实现这一点,在文件夹
/etc/udev/rules.d
中添加一个包含以下行的文件。
KERNEL=="card*", SUBSYSTEM=="drm", ACTION=="change", RUN+="[path-to-script]"
(在我的机器上,我将脚本保存在
/usr/local/bin/hdmi.sh
中)。创建完这个文件后,运行
udevadm control --reload-rules
。完成这些步骤后,你只需插入HDMI电缆,一切应该正常工作。当你拔掉电缆时,音频应该自动切换回电脑。
新的问题/备注
在第一次添加此udev规则后,您可能需要重新启动计算机一次,然后更改才能生效。
如果udev规则表现不佳,您可以始终手动运行脚本。这样做虽然需要花费更多的精力,但更加可靠。
对于我来说,如果我连续插拔HDMI电缆5次而不重新启动,则音频变得极度失真。我不知道是什么原因。
该脚本实际上只是执行上述过程。特别是,在某些时候,它会运行speaker-test
以确定要在PulseAudio中加载哪个卡/设备。因此,当运行时,您可能会听到可听的“左侧/右侧”声音(或speaker-test
默认的任何声音)。
在脚本中,有一个ENABLE_DESKTOP_NOTIFICATIONS
变量。如果要每次运行时收到通知,请将其设置为1。