优化检测FFmpeg推流IP摄像头RTSP至YouTube挂死的Bash脚本
解决IP摄像头RTSP推YouTube时FFmpeg卡帧无法自动恢复的问题
我之前帮朋友处理过一模一样的场景——用FFmpeg推花园IP摄像头的RTSP流到YouTube直播,碰到摄像头重启或断网后,FFmpeg直接卡死在最后一帧,哪怕摄像头恢复也不会自动续推。下面是我验证过的可行方案,核心思路是通过监控FFmpeg的输出日志,检测帧号停滞来判断推流状态,异常时自动重启FFmpeg:
步骤1:配置FFmpeg输出含帧号的日志
首先要让FFmpeg把详细的处理日志写入文件,这样我们才能追踪帧号变化。修改你的推流命令,加上日志重定向:
ffmpeg -i rtsp://你的摄像头IP/流路径 -c:v libx264 -preset veryfast -maxrate 2500k -bufsize 5000k -vf "format=yuv420p" -g 50 -c:a aac -b:a 128k -f flv rtmp://a.rtmp.youtube.com/live2/你的YouTube直播密钥 2>&1 >> /var/log/ffmpeg_stream.log
这里的2>&1是把FFmpeg的错误输出(里面包含帧处理信息)重定向到标准输出,再追加到日志文件里,确保我们能抓到每一步的帧号数据。
步骤2:编写自动监控重启脚本
写一个shell脚本(命名为monitor_ffmpeg.sh),每隔几秒检查日志里的帧号是否停滞:
#!/bin/bash LOG_FILE="/var/log/ffmpeg_stream.log" LAST_FRAME="" CHECK_INTERVAL=5 # 检查间隔,单位:秒 while true; do # 从日志最后10行提取最新的帧号(适配FFmpeg默认日志格式) CURRENT_FRAME=$(tail -n 10 "$LOG_FILE" | grep -oP 'frame=\K\d+' | tail -n 1) if [[ -n "$CURRENT_FRAME" ]]; then if [[ "$CURRENT_FRAME" == "$LAST_FRAME" ]]; then # 帧号未变化,判定推流异常,执行重启 echo "$(date '+%Y-%m-%d %H:%M:%S'): 检测到帧号停滞,重启FFmpeg..." >> "$LOG_FILE" pkill ffmpeg sleep 2 # 留一点时间让进程完全退出 # 替换成你的实际推流命令 ffmpeg -i rtsp://你的摄像头IP/流路径 -c:v libx264 -preset veryfast -maxrate 2500k -bufsize 5000k -vf "format=yuv420p" -g 50 -c:a aac -b:a 128k -f flv rtmp://a.rtmp.youtube.com/live2/你的YouTube直播密钥 2>&1 >> "$LOG_FILE" & fi LAST_FRAME="$CURRENT_FRAME" fi sleep "$CHECK_INTERVAL" done
脚本说明:
- 每次检查会从日志最后10行里捞取最新的帧号(避免日志里的旧数据干扰)
- 如果连续两次检查到的帧号相同,就判定推流异常,杀死FFmpeg进程后重新启动推流
- 你可以根据摄像头的稳定性调整
CHECK_INTERVAL,比如如果摄像头偶尔会卡顿3秒,就把间隔设为10秒,减少误判
步骤3:让脚本后台运行并开机自启
- 给脚本添加执行权限:
chmod +x monitor_ffmpeg.sh
- 后台启动脚本(退出终端也能继续运行):
nohup ./monitor_ffmpeg.sh &
- 开机自启(以systemd为例):
创建一个ffmpeg-monitor.service文件:
[Unit] Description=FFmpeg Stream Monitor After=network.target [Service] Type=simple ExecStart=/path/to/your/monitor_ffmpeg.sh Restart=always User=root # 根据你的实际用户调整 [Install] WantedBy=multi-user.target
然后执行命令启用服务:
sudo systemctl daemon-reload sudo systemctl enable ffmpeg-monitor.service sudo systemctl start ffmpeg-monitor.service
注意事项
- 确保日志文件所在目录有足够的写入权限,避免FFmpeg无法生成日志导致脚本失效
- 如果你的FFmpeg日志格式和默认不同(比如自定义了日志级别),需要调整
grep提取帧号的正则表达式,保证能正确匹配到frame=XXX格式的内容 - 可以定期清理日志文件,避免日志过大占用磁盘空间
内容的提问来源于stack exchange,提问作者shakespeare
相关产品推荐
相关产品推荐

