![在多宿主 Linux 主机上录制多播流](https://linux22.com/image/1358007/%E5%9C%A8%E5%A4%9A%E5%AE%BF%E4%B8%BB%20Linux%20%E4%B8%BB%E6%9C%BA%E4%B8%8A%E5%BD%95%E5%88%B6%E5%A4%9A%E6%92%AD%E6%B5%81.png)
我有一个听起来最简单的用例,但没有什么令人满意的。
我有一个多宿主主机,我想在 eth1 上监听多播,并将所有有效负载(不包括 UDP 数据包头,只是有效负载)推送到一个文件中。以下是我已经尝试过的一些方法,
- socat。这听起来像是一个完美的工具,但我不知道该使用什么语法,而且我找到的所有示例都是针对更复杂的用例。我真的无法理解我看到的示例。如果有人知道,我该如何让 socat 做到这一点?请随意叫我白痴,因为我没有弄清楚。
- vlc。偶尔会丢包,这是不可接受的。我需要它长时间运行而不丢掉一个数据包。我在多个平台上的许多 vlc 版本上都看到这种偶尔丢包的情况,我根本不相信它。
- wireshark。它确实有效,并且永远不会像 vlc 那样丢弃数据包(即使同时运行),但我实际上不需要数据包转储,只需要有效载荷。我可以事后使用 wireshark 将所有有效载荷写入文件,使用“跟随 UDP 流”功能,但这需要大量时间,并且无法实时保存有效载荷。此外,这似乎只能在 wireshark gui 中实现。如果没有 GUI,我的工作流程会容易得多。
- netcat。听起来像是正确的工具,但在接收多播时却无能为力。不知道如何调试,或者它是否不适用于多播。此外,我正在运行 nemesis 来强制 igmp 加入,我可以使用 tcpdump 看到它有效。如果我遗漏了一些愚蠢的东西,请提出建议。
- nc6。与 netcat 相同的结果。
答案1
socat -u UDP4-RECV:6666,ip-add-membership=224.1.0.1:0.0.0.0 CREATE:test.out
也许不是最佳的,但应该可行。
答案2
您可以使用ffmpeg
、multicat
和tsudpreceive
:tsp
ffmpeg -i udp://<multicast_ip>:<port_number> -c copy -f mpegts test.ts
请记住,ffmpeg 会删除 NULL PID,但它会将所有其他 PID 复制到test.ts
文件中。
另一个选择是使用multicat
:
multicat -u -U @<multicast_ip>:<port_number> test.ts
默认情况下,mutlticat
期望 RTP 流作为输入,这就是为什么您需要定义-u
并-U
告知源和目标不包含 RTP 标头。
您可以安装露天矿并使用tsudpreceive
:
tsudpreceive <multicast_ip> <port_number> > test.ts
你也可以尝试使用TS鸭子和tsp
:
tsp -rtrue -I ip <multicast_ip>:<port_number> --buffer-size-mb 50 -O file test.ts
rtrue
告诉tsp
使用实时处理
-I ip
- 定义输入是 IP 流,
--buffer-size-mb
指定缓冲区大小(以兆字节为单位),默认为 16MB,所以这只是可选参数,
-O file
定义输出到文件的类型。
FFmpeg
您可以通过传递来定义录音的持续时间-t <seconds>
。您可以对 multicat 执行相同操作,但这次您需要以 27MHz 为单位定义持续时间,这意味着如果您想要进行 30 秒的录音,您需要传递:-d 810000000
(27E+6 * 30 = 81E+7)。对于其余选项,您可以使用timeout --foreground 30
作为命令的前缀,这将精确地将录音剪切到 30 秒。
您很可能可以使用 等执行相同的操作gstreamer
,cvlc
但我不熟悉它们的语法。