我正在尝试使用 Raspberry Pi 在我的房子里实现多房间音频设置。如何让 VLC 在本地耳机端口上同时播放,同时通过 trx 将其流式传输到其他设备?
背景:
我发现了一个名为 trx 的奇妙软件包,它允许在 LAN 上使用 Opus 编解码器进行低延迟流传输:http://www.pogo.org.uk/~mark/trx/streaming-desktop-audio.html
我已成功安装 trx 并使用以下内容:
sudo modprobe snd-aloop
传输端~/.asoundrc
# TX device catches played audio from a player (e.g. VLC)
# point vlc to this device:
# cvlc --alsa-audio-device="tx" <file_or_stream>
pcm.tx {
type plug
slave.pcm {
type dmix
ipc_key 2867
slave {
pcm "hw:Loopback,0,0"
rate 48000
format S16_LE
channels 2
period_size 256
buffer_size 8192
}
}
}
# Hubcap ensures 48000Hz sample rate (Opus compatible)
pcm.hubcap {
type plug
slave {
pcm "hw:Loopback,1,0"
rate 48000
format S16_LE
}
}
传输侧:
tx -d hubcap -m 64 -h 239.0.0.99 &
cvlc --alsa-audio-device="tx" {source_file_path_or_url}
接收方:
rx -m 64 -h 239.0.0.99
偶尔会出现缓冲区不足的情况,通过将 tx 进程的良好度更改为 -10 可以轻松修复。
renice -n -10 {process_id}
问题:
我希望能够将音频从 VLC 播放到网络上侦听多播 239.0.0.99 的设备,以及从传输设备的耳机/线路输出插座播放音频。
我不知道如何在 ~/.asoundrc 中设置插头、路由和多重,以便有一个 ALSA 设备 cvlc 可以播放,其中音频被馈送到本地 hw:1 (耳机插座)和plug:tx (通过 tx 传输音频的输入)。
ALSA asound 配置文档非常糟糕。我尝试向 .asoundrc 添加以下内容,但没有成功:
pcm.headphones_dmix {
type dmix
slave {
pcm "hw:Headphones"
}
}
pcm.localandtx {
type plug
slave {
format S16_LE
pcm {
type multi
slaves.tx.pcm "tx"
slaves.tx.channels 2
slaves.local.pcm "headphones_dmix"
slaves.local.channels 2
bindings.0.slave tx
bindings.0.channel 0
bindings.1.slave tx
bindings.1.channel 1
bindings.2.slave local
bindings.2.channel 0
bindings.3.slave local
bindings.3.channel 1
}
}
route_policy duplicate
ttable {
0.0 1
1.1 1
0.2 1
1.3 1
}
hint {
show on
description "Play both locally and via TX."
}
}
与上述:
vlc 会很高兴地用本地耳机播放 --alsa-audio-device="hw:Headphones"
vlc 将很乐意在运行 rx 的设备上播放--alsa-audio-device="tx"
但是,vlc 无法与--alsa-audio-device="localandtx"
.我想让两者都玩。 (我知道通过 trx 发送音频时会产生额外的延迟)。
vlc 错误是:
ALSA lib pcm_direct.c:2031:(snd1_pcm_direct_parse_open_conf) Unique IPC key is not defined
[015a4ac8] alsa audio output error: cannot open ALSA device "localandtx": Invalid argument
[015a4ac8] main audio output error: Audio output failed
[015a4ac8] main audio output error: The audio device "localandtx" could not be used: Invalid argument.
[015a4ac8] main audio output error: module not functional
[71b7a980] main decoder error: failed to create audio output
是否有任何有用的(健全的)工具来调试 ALSA asound 配置文件?
我如何确定 localandtx 中的哪个 .asoundrc 参数是“无效的”?
如何在不使用 PulseAudio 的情况下在 ALSA 中实现到 hw:Headphones 和 tx 的音频路由?
答案1
我终于解决了 Raspberry Pi 多房间音频难题!
解决方案是引入 PulseAudio。由于 Raspberry Pi 的 ALSA bcm2835 驱动程序限制,ALSA 无法单独完成此操作。由于我不太明白的原因,驱动程序无法使用 mmap 将数据从一个流复制到另一个流。即使专门启用 mmap 并使用 mmap 模拟 (mmap_emul),情况也是如此 - 请参阅:https://blog.dowhile0.org/2013/04/27/mmap-support-for-raspberry-pi-bcm2835-alsa-driver/。
Raspberry Pi 音频流本地复制和通过 trx 复制的完整解决方案:
传输端-安装包:
sudo su sudo apt install alsa-utils opus-tools lame vlc cmake libasound2-dev libortp-dev libopus-dev pulseaudio mkdir ~/Installers cd ~/Installers git clone http://www.pogo.org.uk/~mark/trx.git make sudo make install
传输端 - 将用户添加到音频组:
sudo usermod -a -G audio your_username
传输端-激活alsa环回模块:
modprobe snd-aloop echo "snd-aloop" | sudo tee -a /etc/modules
传输端 - 设置 ALSA 设备以支持 trx:
如果您只想为一个用户执行此操作,您应该编辑 ~/.asoundrc,或者编辑 /etc/asound.conf 为所有用户执行此操作。
# nano /etc/asound.conf
或者
# nano ~/asoundrc:
文件内容:
# /etc/asound.conf OR ~/asoundrc: # tx_dmix ensures audio sent to tx gets resampled properly pcm.tx_dmix { type dmix ipc_key 2867 ipc_perm 0666 # allow other users slave { pcm "hw:Loopback,0,0" rate 48000 format S16_LE channels 2 period_size 256 buffer_size 8192 } } # tx is the entry point for anything that wants to play down the TX link pcm.tx { type plug slave.pcm "tx_dmix" hint.description "Audio input for TX transmission." } # Hubcap is used by TX to resample audio into Opus-friendly sample rate pcm.hubcap { type plug slave { pcm "hw:Loopback,1,0" rate 48000 format S16_LE } hint.description "Internal loopback capture and resampler for TX. Only TX should use." } # Headphones (3.5mm jack) playback pcm.headphones_hw { type hw card Headphones sync_ptr_ioctl 1 } pcm.headphones { type plug slave.pcm "headphones_hw" } pcm.!default { type plug slave.pcm "headphones" }
传输端 - 设置 PulseAudio 连接
# nano /etc/pulse/default.pa
或者
# nano ~/.pulse/default.pa:
文件内容:
# PulseAudio config - duplicates audio for local playback and network playback .include /etc/pulse/default.pa # Set up Pulse sinks to connect to our ALSA devices we configured in .asoundrc load-module module-alsa-sink device="tx" sink_name=tx load-module module-alsa-sink device="headphones" sink_name=headphones # Create stream duplicator load-module module-null-sink sink_name=localandtx load-module module-loopback source=localandtx.monitor sink=tx load-module module-loopback source=localandtx.monitor sink=headphones set-default-sink localandtx
创建此文件后重新启动脉冲
pulseaudio -k
传输端 - 创建 tx 初始化脚本:
nano ~/run_tx.sh
文件内容
#!/bin/bash # Fires up the TX transmission # Usage: # sudo run_tx.sh [ip] [latency in ms] # sudo run_tx.sh 239.0.0.99 64 # Defaults DEFAULT_TX_IP="239.0.0.99" DEFAULT_LATENCY_BUFFER_MS="64" # Resolve from args CHOSEN_TX_IP=${$1:-$DEFAULT_TX_IP} CHOSEN_LATENCY_BUFFER_MS=${$2:-$DEFAULT_LATENCY_BUFFER_MS} echo "Launching TX on ${CHOSEN_TX_IP} with ${CHOSEN_LATENCY_BUFFER_MS} ms buffer." # Start TX, using hubcap ALSA device tx -d hubcap -m $(($CHOSEN_LATENCY_BUFFER_MS)) -h $CHOSEN_TX_IP & # Boost priority of all TX threads (necessary to prevent buffer underruns) TX_PIDS=$(ps -L -C tx -o lwp=) for TX_PID in TX_PIDS do sudo renice -10 $(($TX_PID)) done
传输端 - 运行 tx 发送器:
chmod +x ~/run_tx.sh sudo ~/run_tx.sh
接收端 - 安装软件包(仅运行 ALSA,不需要 PulseAudio):
sudo su sudo apt install alsa-utils opus-tools lame vlc cmake libasound2-dev libortp-dev libopus-dev mkdir ~/Installers cd ~/Installers git clone http://www.pogo.org.uk/~mark/trx.git make sudo make install
接收方 - 创建 rx 初始化脚本:
nano ~/run_rx.sh
文件内容
#!/bin/bash # Fires up the RX Reception side # Usage: # sudo run_rx.sh [ip] [latency in ms] # sudo run_rx.sh 239.0.0.99 64 # Defaults DEFAULT_RX_IP="239.0.0.99" DEFAULT_LATENCY_BUFFER_MS="64" # Resolve from args CHOSEN_RX_IP=${$1:-$DEFAULT_RX_IP} CHOSEN_LATENCY_BUFFER_MS=${$2:-$DEFAULT_LATENCY_BUFFER_MS} echo "Launching RX receiver, listening on ${CHOSEN_RX_IP} with ${CHOSEN_LATENCY_BUFFER_MS} ms buffer." # Start RX, using default ALSA device rx -m $(($CHOSEN_LATENCY_BUFFER_MS)) -h $CHOSEN_RX_IP & # Boost priority of all RX threads (necessary to prevent buffer underruns) RX_PIDS=$(ps -L -C rx -o lwp=) for RX_PID in RX_PIDS do sudo renice -10 $(($RX_PID)) done
接收端 - 运行 rx 监听器:
chmod +x ~/run_rx.sh sudo ~/run_rx.sh
将 tx 端的某些内容播放到 PulseAudio 默认接收器 (localandtx) 中。它将通过接收设备的默认音频输出从接收端播放。
要指定在 rx 中播放的不同音频设备,请将该-d "alsa_device_name"
选项添加到该rx -m $(($CHOSEN_LATENCY_BUFFER_MS)) -h $CHOSEN_RX_IP &
行,例如rx -m $(($CHOSEN_LATENCY_BUFFER_MS)) -h $CHOSEN_RX_IP -d Headphones &