我将音乐从一台控制 PC(“发送器”)流式传输到 LAN 上的多台 PC(接收器),如下所述:
https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Network/#index2h3
如何在控制 PC(发送者)上播放相同的音乐?
我当前的设置对于现在的测试来说非常简单:
发件人
pactl load-module module-null-sink sink_name=rtpsink1
pactl load-module module-rtp-send source=rtpsink1.monitor
接收器
pactl load-module module-rtp-recv
答案1
这是我首选的可行解决方案。它基于:pulsertp-multiroom
https://github.com/mada3k/pulsertp-multiroom/blob/master/scripts/pulsertpm-start.sh
我用它来将音频发送到多个接收器(不同的房间)。有两行,如下所示,使发送者也成为接收者并解决了这个问题。他们是:
- module-rtp-send 带有发送者的唯一 IP 地址
- module-rtp-recv 带有发送者的唯一 IP 地址
这种方法的优点是所有接收器(包括发送器上的接收器)保持同步。正如我的其他答案中那样,组合同步时情况并非如此。
编辑输入正确的 IP 地址后,当准备启动 RTP 单播时,我在发送方上运行此脚本:
#!/bin/bash
#
# PulseRTP-multiroom
# Loads RTP sender modules to setup multiroom audio at request
#
# Notes
# * If you have issues, and have multiple network interfaces, add source_ip= with you prefered local IP
# * mtu=1408 is good initial value. It makes room for 352 PCM frames in 16/44.1k.
#
pa_rtp_mtu=1408
pa_sink="rtpsink1"
echo "timedatectl status:"
timedatectl status --no-pager | grep 'NTP service: active'
if [[ $? -ne 0 ]]; then
timedatectl set-ntp true
sleep 2
timedatectl status --no-pager | grep 'NTP service: active'
if [[ $? -ne 0 ]]; then
echo "WARNING: NTP service not active"
else
echo "timedatectl status OK"
fi
fi
pacmd list-modules | grep module-native-protocol-unix
if [ $? -ne 0 ]; then
pactl load-module module-native-protocol-unix
fi
pacmd list-modules | grep module-default-device-restore
if [ $? -ne 0 ]; then
pactl load-module module-default-device-restore
fi
pacmd list-modules | grep module-rescue-streams
if [ $? -ne 0 ]; then
pactl load-module module-rescue-streams
fi
pacmd list-modules | grep module-always-sink
if [ $? -ne 0 ]; then
pactl load-module module-always-sink
fi
pacmd list-modules | grep module-intended-roles
if [ $? -ne 0 ]; then
pactl load-module module-intended-roles
fi
pacmd list-modules | grep module-suspend-on-idle
if [ $? -ne 0 ]; then
load-module module-suspend-on-idle
fi
#hardcoded addresses of each receiver:
pactl load-module module-rtp-send source=${pa_sink}.monitor mtu=${pa_rtp_mtu} destination_ip=192.168.0.1 #this is the sender's IP address (see below)
pactl load-module module-rtp-send source=${pa_sink}.monitor mtu=${pa_rtp_mtu} destination_ip=192.168.0.2
pactl load-module module-rtp-send source=${pa_sink}.monitor mtu=${pa_rtp_mtu} destination_ip=192.168.0.3
pactl load-module module-rtp-send source=${pa_sink}.monitor mtu=${pa_rtp_mtu} destination_ip=192.168.0.4
pactl load-module module-rtp-send source=${pa_sink}.monitor mtu=${pa_rtp_mtu} destination_ip=192.168.0.5
在每个接收器上:
pactl load-module module-rtp-recv sap_address=192.168.0.X
使用接收者的实际IP地址,例如192.168.0.2
最后,在发送方上,也将其设为接收方:
pactl load-module module-rtp-recv sap_address=192.168.0.1
您可以通过编辑 /etc/pulse/default.pa 使接收器上的配置永久化
要停止向接收者进行 RTP 投射,请在发送者上运行以下脚本:
#!/bin/bash
#
# PulseRTP-Multiroom
# Unloads RTP sender modules to avoid unnecessary bandwidth hogging
#
pa_sink="rtpsink1"
IFS=$'\n'
for rtpn in `pactl list modules short|grep ${pa_sink}`; do
PAM_ID=`echo $rtpn|awk '{print $1}'`
pactl unload-module $PAM_ID
echo " * unload-module id $PAM_ID done"
done
对于开始和停止音乐播放,无需对接收器进行任何更改。他们的配置可以永久化。我不需要使用上面启动脚本的修改版本对发送者进行任何永久配置更改。
答案2
使用模块组合接收器。
在发件人上:
pacmd list-sinks
使用每个接收器的值组合在下面的从站列表中:
pactl load-module module-combine-sink sink_name=rtp1combined slaves=abcd,wxyz
其中abcd
和wxyz
是要组合的两个接收器的名称。就我而言,这将是slaves=rtpsink1,alsa_output.pci-0000_02_00.1.hdmi-stereo
更新:这种方法显然有一个缺点,即发送者与节点不同步。