我正在尝试在服务器上接收 udp 流并将其写入 mp4 文件。这很好用:
ffmpeg -i udp://127.0.0.1:12345 -codec copy out.mp4
如果我按 CTRL+C (或向进程发送 SIGINT),ffmpeg 将退出,并且我有一个工作的 mp4 文件。
但是,如果数据停止进入 udp 端口(例如,流式传输 10 分钟后)并且我尝试停止 ffmpeg,则需要 2 个中断信号,此时 ffmpeg 会突然退出并导致无法播放的 mp4 文件。
有谁知道如何防止 ffmpeg 在没有输入数据时挂起或强制其写出 mp4 标头?
我知道我可以指定一个网址选项
udp://127.0.0.1:12345?timeout=<microseconds>
但是,我需要能够忽略录制过程中偶尔(5-10分钟长)的停顿,只在最后退出。 因此,即使我设置 timeout=60000000,当我想停止流时(例如,如果没有数据),它也会导致我的应用程序等待 10 分钟,并且当我向它发送 SIGINT 时,我需要它立即退出
您可以添加movflags,即使您强制停止ffmpeg,您仍然会有可播放的mp4文件。
ffmpeg -i input -movflags +frag_keyframe+separate_moof+omit_tfhd_offset+empty_moov output
更多详细信息请参见此处(Gyan 的回答):
https://video.stackexchange.com/a/18179/33701
最好使用其他格式录制直播视频。我用的是MKV,它不像MP4那么严格,可以容忍一些错误。 另外,添加像
-reconnect_streamed 1
这样的标志,如果发生错误,ffmpeg将尝试重新连接。
示例:
ffmpeg -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 3 -i input -c copy out.mkv
找到了解决方法:如果没有数据传入,则将图像(例如绿屏)作为视频转发到所需的端口。例如
ffmpeg -loop 1 -y -re -i greenscreen.jpg -r 30 -vcodec libx264 -an -f h264 udp://127.0.0.1:12345
这样,ffmpeg 写入 mp4 文件将正常停止,但最后您可能会看到 1-2 秒的绿屏视频。
问题是,我不确定如何自动检测“无数据”
向 ffmpeg 进程发送 SIGINT 会通过正确保存标头来温和地杀死它。 至少2.5.7之后的版本是这样的