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

如何从FFmpeg RTSP流提取帧编号,监控YouTube直播状态

问题描述

我正在编写脚本维护推送到YouTube的直播流,每隔几小时FFmpeg输出会显示所有帧完全相同,说明直播已异常。我需要从FFmpeg输出中提取帧编号,与后续输出的帧号对比来检测异常。

FFmpeg的输出是连续的一行数据(示例如下),导致tail、head这类命令无法生效。我只需要最新的FFmpeg统计信息,这样就能保存到文件后提取帧号。

FFmpeg输出示例:

frame=1903903 fps= 19 q=-1.0 size=50678531kB time=28:24:20.53 bitrate=4059.8kbits/s speed=   1xframe=1903915 fps= 19 q=-1.0 size=50678759kB time=28:24:21.03 bitrate=4059.8kbits/s speed=   1xframe=1903928 fps= 19 q=-1.0 size=50679013kB time=28:24:21.55 bitrate=4059.8kbits/s speed=   1xframe=1903941 fps= 19 q=-1.0 size=50679260kB time=28:24:22.05 bitrate=4059.8kbits/s speed=   1xframe=1903953 fps= 19 q=-1.0 size=50679474kB time=28:24:22.54 bitrate=4059.8kbits/s speed=   1xframe=1903966 fps= 19 q=-1.0 size=50679709kB time=28:24:23.06 bitrate=4059.8kbits/s speed=   1xframe=1903979 fps= 19 q=-1.0 size=50679959kB time=28:24:23.57 bitrate=4059.8kbits/s speed=   1x

我的FFmpeg命令:

ffmpeg -f lavfi -i anullsrc -rtsp_transport tcp -i rtsp://192.168.51.93:554/Streaming/Channels/101 \
  -tune zerolatency -pix_fmt + -c:v copy -strict experimental -f flv -flvflags no_duration_filesize \
  rtmp://a.rtmp.youtube.com/live2/STREAM-KEY \
  2>&1

我试过tee、tail -n 1这类方法,但都无效。


解决方法

1. 让FFmpeg输出按行分隔统计信息

FFmpeg默认进度输出不带换行,直接修改命令添加-progress pipe:1参数,它会把进度信息以键值对格式每行输出一条,其中包含frame字段,后续处理会更简单。

修改后的命令:

ffmpeg -f lavfi -i anullsrc -rtsp_transport tcp -i rtsp://192.168.51.93:554/Streaming/Channels/101 \
  -tune zerolatency -pix_fmt + -c:v copy -strict experimental -f flv -flvflags no_duration_filesize \
  -progress pipe:1 \
  rtmp://a.rtmp.youtube.com/live2/STREAM-KEY

输出会变成类似:

frame=1903903
fps=19
q=-1.0
size=50678531kB
time=28:24:20.53
bitrate=4059.8kbits/s
speed=1x
frame=1903915
fps=19
...

2. 实时提取无换行输出的最新帧号

如果必须处理原来的连续无换行输出,可以用awk结合正则实时解析,提取最新帧号:

你的FFmpeg命令 2>&1 | awk '{while(match($0,/frame=[0-9]+/,a)){print a[0]; $0=substr($0,RSTART+RLENGTH)}}' | tail -n 1

该命令会持续从FFmpeg输出中提取所有frame=xxx片段,再通过tail -n 1拿到最新的帧号。

3. 脚本检测帧号停滞并自动重启

可以写一个简单的Shell脚本,定期记录最新帧号,若连续多次帧号不变则判定异常,自动重启FFmpeg:

#!/bin/bash

FFMPEG_CMD="ffmpeg -f lavfi -i anullsrc -rtsp_transport tcp -i rtsp://192.168.51.93:554/Streaming/Channels/101 \
  -tune zerolatency -pix_fmt + -c:v copy -strict experimental -f flv -flvflags no_duration_filesize \
  rtmp://a.rtmp.youtube.com/live2/STREAM-KEY 2>&1"

LAST_FRAME=0
STUCK_COUNT=0

$FFMPEG_CMD | while read -r LINE; do
  # 提取帧号(若用了-progress参数,直接匹配frame=xxx行即可)
  FRAME=$(echo "$LINE" | grep -oP 'frame=\K\d+')
  if [[ -n "$FRAME" ]]; then
    if [[ "$FRAME" -eq "$LAST_FRAME" ]]; then
      STUCK_COUNT=$((STUCK_COUNT+1))
      # 连续3次帧号不变判定异常
      if [[ "$STUCK_COUNT" -ge 3 ]]; then
        echo "直播异常,帧号停滞:$FRAME"
        pkill -f "ffmpeg.*STREAM-KEY"
        exit 1
      fi
    else
      LAST_FRAME=$FRAME
      STUCK_COUNT=0
    fi
  fi
done

内容的提问来源于stack exchange,提问作者Paweł Peterwas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 00:10:38