我正在尝试将两个 UDP 视频流传输到 LAN 多播
让一台计算机接收这些多播流,
将它们并排组合并将它们作为单个流重新传输
出于测试目的,我按如下方式传输两个测试文件
ffmpeg -re -i testfile1.mp4 -c copy -f mpegts udp://239.0.0.1:9991
ffmpeg -re -i testfile2.mp4 -c copy -f mpegts udp://239.0.0.1:9992
在另一台计算机上,我可以使用此测试命令在输出时观看这些流中的任何一个
ffplay -hide_banner -fflags nobuffer -flags low_delay -probesize 32 -analyzeduration 0 -max_delay 0 "udp://239.0.0.1:9991"
ffplay -hide_banner -fflags nobuffer -flags low_delay -probesize 32 -analyzeduration 0 -max_delay 0 "udp://239.0.0.1:9992"
流式传输时两个视频都会在第二台计算机上播放
我还在网络上的几台主机上运行wirehack和tcpdump,所有主机都可以看到239.0.0.1:9991和239.0.0.1:9992上的多播数据包
现在我尝试“接收、组合、重新传输”命令如下
ffmpeg -i "udp://239.0.0.1:9991" -i "udp://239.0.0.1:9992" -filter_complex "[0:v:0][1:v:0]hstack=inputs=2" -c:v libx264 -preset ultrafast -f mpegts "udp://239.0.0.1:9990"
这是此过程的视频截图
在所有主机上,从未收到发往 UDP 端口 239.0.0.1:9990 的数据包
这个方法有什么问题吗?
回答我自己的问题,
这是正确的方法,但是,ffmpeg 需要大量输入数据才能开始接收流,而测试文件根本不够长。
因此,为了进行测试,我已将测试文件更改为测试桌面捕获。
我现在将描述新流程。
在我的显示器上,我有两个网页,其中循环播放着 gif。
我使用 ffmpeg ddagrab 功能示例捕获这些:-filter_complex "ddagrab=...
并且使用裁剪函数示例对它们进行裁剪:crop=649:461:16:475
这是两个完整的发送器命令行,传输到 udp://239.0.0.1:9991 和 udp://239.0.0.1:9992
ffmpeg -hide_banner -filter_complex "ddagrab=framerate=30:output_idx=1:video_size=3840x2160,hwdownload,format=bgra,crop=649:461:16:475,scale=1280:720[out]" -map "[out]" -colorspace bt709 -chroma_sample_location left -c:v h264_nvenc -preset p1 -tune ull -bufsize 600k -g 15 -pix_fmt nv12 -flags low_delay -f mpegts udp://239.0.0.1:9991
ffmpeg -hide_banner -filter_complex "ddagrab=framerate=30:output_idx=1:video_size=3840x2160,hwdownload,format=bgra,crop=649:461:16:1500,scale=1280:720[out]" -map "[out]" -colorspace bt709 -chroma_sample_location left -c:v h264_nvenc -preset p1 -tune ull -bufsize 600k -g 15 -pix_fmt nv12 -flags low_delay -f mpegts udp://239.0.0.1:9992
我还使用ffplay准备了两个接收器测试窗口,如下
ffplay -hide_banner -fflags nobuffer -flags low_delay -probesize 32 -analyzeduration 0 -max_delay 0 "udp://239.0.0.1:9991
ffplay -hide_banner -fflags nobuffer -flags low_delay -probesize 32 -analyzeduration 0 -max_delay 0 "udp://239.0.0.1:9992
最后是前面描述的 ffmpeg 连接命令
ffmpeg -hide_banner -i "udp://239.0.0.1:9991" -i "udp://239.0.0.1:9992" -filter_complex "[0:v:0][1:v:0]hstack=inputs=2" -c:v libx264 -preset ultrafast -f mpegts "udp://239.0.0.1:9990"
此命令正在同一 LAN、L2 网段的单独计算机上运行
最后,另一个监听 udp://239.0.0.1:9990 的 ffplay 命令将收到最终产品
可以在此处观察此过程的演示
以下是一些观察结果
1 需要一段时间才能开始
2 延迟很高(几秒)
3 启动后,如果任何一个流熄灭,则整个流也熄灭
4 如果你不小心在端口 9991 发送两个流,就像我一开始所做的那样,流将交替但仍然可以工作一点并且不会崩溃,令人印象深刻!
5 最糟糕的是,当流因一个输入停止而停止时,工作流将保留在缓冲区中。这将增加延迟,并且流将永久不同步,因为缓冲区永远不会被丢弃
请提供替代答案以减轻这些缺点
谢谢!