我想将我的树莓派上录制的声音通过管道传输到我的 MacBook 上进行现场播放。我尝试过以下方法:
在我的树莓派上:
我尝试在端口3333上建立数据流
arecord -D plughw:3,0 -f S16_LE 44100 -t raw | nc -l -p 3333
在我的 MacBook 上:
nc 10.10.1.1 3333 | play -t raw -b 16 -e signed-integer -r 44100 -c 1 -V1 -
有了这个,我在 Mac 上听不到任何声音,但在终端中得到以下输出:
-: (raw)
File Size: 0
Encoding: Signed PCM
Channels: 1 @ 16-bit
Samplerate: 44100Hz
Replaygain: off
Duration: unknown
In:0.00% 00:00:00.00 [00:00:00.00] Out:0 [ | ] Clip:0
Done.
答案1
我无法真正告诉您在您的具体情况下您的设置出了什么问题;您想要检查您是否nc
实际接收数据(例如,通过写入文件,或通过管道传输pv
),以及您是否arecord
实际捕获声音(通过写入文件而不是通过管道传输到nc
)。
另外,不确定 44100 Hz 是否是一个优雅的采样率;如今大多数硬件本身的频率为 48000 Hz,您只需让 ALSA 将其转换为 44100 Hz。
更重要的是,您应该使用合理的传输成帧器,以允许接收端正确对齐时间、补偿丢失、延迟丢失或重新排序数据包,了解流格式本身。我使用 MPEG 传输流作为流格式,用于数字视频广播和其他多媒体流平台。
因此,使用 TCP 进行低延迟传输可能也不是一个好主意。您还需要限制网络接收器使用的传输缓冲区大小(在本例中为nc
RPi 上的)。总而言之,这arecord | nc
可能不是最好的流媒体方法。此外,在您的方法中,您获得的延迟至少与发送方启动并准备好连接后接收端启动所需的延迟相同
当我快速捕获一些音频并需要将其传输到另一台机器时(主要是出于网络会议的原因),我所做的就是在“麦克风机器”上执行以下操作:
ffmpeg \
-f alsa -channels 1 -sample_rate 24000 -i pipewire \
-f mpegts -max_packet_size 1024 \
-c:a libopus -b:a 64k -vbr off -packet_loss 10 -fec on \
udp://127.0.0.1:1234
让我们把它拆开:
ffmpeg
:我们正在运行的程序,FFmpeg。几乎是大多数平台上的标准转码/流媒体/解码解决方案。
输入选项:
-f alsa
:输入类型(“格式”)是 alsa,即我们从 alsa 声音系统获取声音-channels 1
:选修的我只想要单声道声音。忽略使用声音设备提供的任何内容(可能是立体声?),或者如果您想特别想要捕获不同数量的通道,则设置为不同的值-sample_rate 24000
:选修的我最关心的是语音,在这种情况下,24 kHz 采样率足以获得出色的音频质量(我不是蝙蝠,我的声音不会高于 1.2 kHz……)。-i pipewire
:从 ALSA 设备捕获pipewire
。就你而言,plughw:3,0
似乎。 (使用 检查可用的捕获设备arecord -L
)
输出格式选项:
-f mpegts
:在-i
我们描述完输入之后,这就-f
描述了输出格式。我们正在传输 MPEG 传输流。-max_packet_size 1024
:选修的我们强制流媒体每 1024 字节发出一个数据包。这限制了发送端延迟
音频编解码器选项:选修的
-c:a libopus
:选修的c
是编解码器的缩写,a
用于音频, and here we use the
libopus 编码器。 OPUS 是一个成熟的、网络标准的音频编码器,具有低复杂度和高质量设置。-b:a 64k
:选修的,但我们将编码比特率设置为 64kb/s。这是相当高质量的,但计算能力相当不错(最多考虑一个核心的 5% 到 20%)-vbr off
:选修的力常数(与v
可变比特率相对)。如果您计划通过有限带宽链路进行流式传输并且不能进行具有高速率短峰值的编码,那么这是有意义的。在 LAN 上省略。-packet_loss 10
:选修的设置数据包冗余,即使十分之一的数据包丢失也没关系。使其在偶尔出现数据包丢失的连接(例如某些互联网连接、某些无线连接等)上保持稳健。在 LAN 上忽略。-fec on
:选修的在设置了冗余量之后,我们还希望实际启用该冗余的发送功能F向前e错误C矫正目的。仅当 > 0 时才有意义-packet_loss
。
输出选项:
udp://127.0.0.1:1234
要流式传输的 IP 地址和端口。注意力!这里接收器是监听部分,发送器是UDP套接字,因此它只是将音频流推出,而不关心是否有人接听。这样做的优点是您可以根据需要随时连接和断开接收器。
在接收端,我们将打开一个监听套接字:
ffplay -f mpegts -nodisp -fflags nobuffer udp://127.0.0.1:1234
-nodisp
轮流显示(我们不是流式传输视频),-fflags nobuffer
使输入流解析器不会尝试赶上旧的东西(即,避免“迟到的听众”延迟)。
请注意,在这种情况下,玩end 是服务器,它打开侦听套接字(就像您nc -l
所做的那样)。如果您愿意,您还可以使用之前在两侧zmq:tcp://
使用的位置来扭转这一局面udp://
,并能够将多个侦听器连接到您的服务“记录器”pi。
nc -u -l -p 1234 | …
当然,如果…
是一个能够理解 MPEG TS 的程序,您也可以完全自由地使用。