如何在电脑和电视机之间切换音频?

如何在电脑和电视机之间切换音频?

我创建了一个脚本,用于在通过 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_idtarget_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

相关内容