使用FFmpeg录制监控流的systemd服务终止异常求助
解决systemd终止FFmpeg录制服务时视频文件损坏的问题
问题根源
当systemd停止服务时,默认会向FFmpeg发送SIGTERM信号,FFmpeg收到该信号后会立即终止进程,导致MP4文件的关键索引信息(moov原子)未写入完成,最终生成的文件无法正常播放。
解决方案
1. 修改systemd服务配置,实现优雅停止
编辑你的服务文件(例如/etc/systemd/system/camera-record.service),在[Service]段添加以下配置:
[Service] # 替换默认终止信号为SIGINT,让FFmpeg优雅完成文件收尾 KillSignal=SIGINT # 延长停止超时时间,给FFmpeg足够时间写入文件索引 TimeoutStopSec=10 # 仅终止FFmpeg进程,避免误杀相关进程组 KillMode=process
修改后重新加载systemd配置:
sudo systemctl daemon-reload
2. 优化FFmpeg录制命令(可选)
在录制脚本中,移除-nostdin参数(无特殊需求时无需保留),同时可添加-y参数自动覆盖同名文件(避免启动时因文件存在报错),修改后的命令:
ffmpeg -i "$url" -acodec copy -vcodec copy -y $out
3. 验证效果
启动服务后执行停止命令:
sudo systemctl stop camera-record.service
查看日志确认无Error closing file报错,尝试播放生成的MP4文件,此时文件应能正常播放。
额外优化:让FFmpeg自动重连流(减少systemd重启次数)
如果希望FFmpeg在流中断时自动重连,无需依赖systemd重启,可在FFmpeg命令中添加重连参数:
ffmpeg -reconnect 1 -reconnect_at_eof 1 -reconnect_streamed 1 -reconnect_delay_max 20 -i "$url" -acodec copy -vcodec copy $out
这些参数会让FFmpeg在流断开时自动尝试重连,最长等待20秒,减少服务重启频次。
内容的提问来源于stack exchange,提问作者Transporter
相关产品推荐
相关产品推荐

