我创建了一个脚本,用于在通过 HDMI 连接的 PC 和电视机之间切换音频输出。看起来是这样的:
inactive_sink_id=$(pacmd list-sinks | grep -E "[^*] index: [0-9]+" | sed -r -e "s/.*([0-9]+)/\1/g")
pacmd set-default-sink $inactive_sink_id
move_sink_to_id=$(pacmd list-sink-inputs | grep -E "index: [0-9]+" | sed -r -e "s/.* ([0-9]+)/\1/g")
pacmd move-sink-input $move_sink_to_id $inactive_sink_id
但有时有效,有时无效。
例如,当 YouTube 视频正在播放时,我可以在我的电脑上听到声音。当我切换到视频中的另一个位置后,就听不到声音了。我打开“音频和视频设置”,注意到电视机 HDMI 位于“设备首选项”列表的顶部。
切换音频输出的可靠方法是什么?
我注意到虽然我的脚本做了一些更改,但“音频和视频设置”保持不变:
$ pacmd list-sinks | grep index
* index: 0
index: 1
$ toggle-audio-between-pc-and-tv.sh # My script
$ pacmd list-sinks | grep index
index: 0
* index: 1
播放视频。没有声音。
但是,当我多次执行脚本时,声音会切换到电视机。
操作和“音频和视频设置”对话框似乎pacmd
不同步。
答案1
从你的变量名得出结论,你不明白这里发生了什么。
这条线很好。 (但如果您有两个以上的接收器,则不会。)您正在寻找没有的接收器*
并将其分配给inactive_sink_id
。
inactive_sink_id=$(pacmd list-sinks | grep -E "[^*] index: [0-9]+" | sed -r -e "s/.*([0-9]+)/\1/g")
这个也不错啊只要你只有两个水槽。如果有更多,将会出现错误,因为变量将包含许多数字。
pacmd set-default-sink $inactive_sink_id
这个也可能没问题,但只有一个输入。而且这里的变量名也不行。
move_sink_to_id=$(pacmd list-sink-inputs | grep -E "index: [0-9]+" | sed -r -e "s/.* ([0-9]+)/\1/g")
您没有将接收器移动到 id。您正在将输入移动到由 id 标识的接收器。 (id 不会改变。为什么会改变?)如果有更多输入,此行将不起作用,因为将move_sink_to_id
包含许多整数:
pacmd move-sink-input $move_sink_to_id $inactive_sink_id
尝试使用这个构造:
for input in $(pactl list short sink-inputs | awk '{print $1}'); do
pacmd move-sink-input $input $inactive_sink_id
done
现在您确定每个输入都已移动到目标接收器。这很重要,因为即使您暂停一个 YouTube 视频,它仍然会在输入列表中停留一段时间。你可以做一些实验
pactl list short sink-inputs
看看 PulseAudio 是如何看待它的。
另外,我会将名称更改inactive_sink_id
为target_sink_id
,并针对有两个以上接收器的情况引入覆盖范围。这可能是基于接收器名称的硬编码。您不仅可以通过 id 引用接收器,还可以通过名称引用接收器,例如。
pactl move-sink-input 65 alsa_output.pci-0000_00_1b.0.analog-stereo
或者您可以引入一个可能可选的选择列表,让您选择要将输入移动到的位置。
此命令会生成一个清晰的接收器列表,其名称位于第二列中:
pactl list short sinks
并确保在 PulseAudio 可以看到您的电视接收器之前运行您的脚本!
最终的脚本可能如下所示:
#!/bin/bash
target_sink=alsa_output.pci-0000_00_1b.0.analog-stereo
pactl list short sinks | grep -- "$target_sink" || {
echo Sink "$target_sink" not found! >&2
exit 1
}
pacmd set-default-sink "$target_sink"
for input in $(pactl list short sink-inputs | awk '{print $1}'); do
pacmd move-sink-input "$input" "$target_sink"
done