You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

优化检测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:让脚本后台运行并开机自启

  1. 给脚本添加执行权限:
chmod +x monitor_ffmpeg.sh
  1. 后台启动脚本(退出终端也能继续运行):
nohup ./monitor_ffmpeg.sh &
  1. 开机自启(以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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:03:06