在純 ALSA 中複製音頻以在本地設備上播放並通過 trx 流式傳輸
我正在嘗試使用 Raspberry Pis 在我家中實現多房間音頻設置。如何讓 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 程序的 niceness 更改為 -10 可以輕鬆解決。
renice -n -10 {process_id}
問題:
我希望能夠將音頻從 VLC 播放到網路上偵聽多播 239.0.0.99 的設備,也可以從傳輸設備的耳機/線路輸出插座播放音頻。
我不知道如何在 ~/.asoundrc 中設置一個插頭、路由和多路,以便有一個 ALSA 設備 cvlc 可以播放,其中音頻被饋送到本地 hw:1(耳機插座)和 plug:tx (通過 tx 傳輸音頻的輸入)。
ALSA 合理的配置文件非常糟糕。我嘗試了以下對 .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 的音頻路由?
我終於解決了多房間音頻 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 -司機/。
在本地和通過 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 loopback 模組:
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 設備的預設音頻輸出從 rx 端播放。
要在 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 &