如何从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
相关产品推荐
相关产品推荐

