如何让ffmpeg在输入分辨率变化时自动退出?
解决输入分辨率变化时FFmpeg自动停止的问题
因为你使用-c:v copy直接复制视频流,无法通过编码环节强制分辨率恒定,所以可以通过以下两种方法让FFmpeg在分辨率变化时自动退出:
方法1:提前获取初始分辨率,用滤镜检测并触发退出
这个方法先通过ffprobe获取直播流的初始分辨率,再让FFmpeg在转推时实时检测分辨率,一旦不匹配就抛出错误并退出。
- 先获取初始分辨率:
# 获取初始分辨率(格式如1920x1080) INIT_RES=$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 "http://mpegts-live-stream") # 拆分宽和高 INIT_W=$(echo "$INIT_RES" | cut -d'x' -f1) INIT_H=$(echo "$INIT_RES" | cut -d'x' -f2)
- 修改FFmpeg转推命令,添加检测滤镜:
ffmpeg -i "http://mpegts-live-stream" \ -vf "if(neq(width,$INIT_W)||neq(height,$INIT_H),error=Input resolution changed from ${INIT_W}x${INIT_H},null)" \ -c:v copy -c:a aac -ac 2 -f flv \ -xerror \ "rtmp://nginxserver/live/streamname"
-vf中的滤镜会实时对比当前分辨率和初始值,不匹配时抛出错误-xerror参数让FFmpeg遇到任何错误时立即退出,触发你的重启脚本
方法2:利用FFmpeg元数据监控(无需提前获取分辨率)
如果不想提前获取分辨率,可以让FFmpeg实时打印视频元数据,配合简单的脚本监控分辨率变化并杀死FFmpeg进程:
- 启动FFmpeg并将元数据输出到临时文件:
ffmpeg -i "http://mpegts-live-stream" \ -filter:v "metadata=print:key=width,height:file=/tmp/stream_res.log" \ -c:v copy -c:a aac -ac 2 -f flv \ "rtmp://nginxserver/live/streamname" & FFMPEG_PID=$!
- 同时运行监控脚本(可整合到你的重启脚本中):
# 获取初始分辨率 INIT_W=$(grep -m1 "width" /tmp/stream_res.log | awk -F'=' '{print $2}') INIT_H=$(grep -m1 "height" /tmp/stream_res.log | awk -F'=' '{print $2}') # 实时监控分辨率变化 tail -f /tmp/stream_res.log | while read line; do if echo "$line" | grep -q "width"; then CURRENT_W=$(echo "$line" | awk -F'=' '{print $2}') if [ "$CURRENT_W" != "$INIT_W" ]; then kill $FFMPEG_PID exit 0 fi elif echo "$line" | grep -q "height"; then CURRENT_H=$(echo "$line" | awk -F'=' '{print $2}') if [ "$CURRENT_H" != "$INIT_H" ]; then kill $FFMPEG_PID exit 0 fi fi done
注意事项
- 方法1更简洁,依赖FFmpeg内置滤镜和参数,无需额外监控脚本
- 两种方法都能让FFmpeg在分辨率变化时停止,触发你的重启脚本
- 确保你的设备上安装了
ffprobe(通常和FFmpeg一起打包)
内容的提问来源于stack exchange,提问作者rednine
相关产品推荐
相关产品推荐

