如何通过Windows Batch实时提取FFmpeg的frame与fps值到变量
实时提取FFmpeg转码输出中的frame和fps值(Windows批处理方案)
你遇到的核心问题是FFmpeg的状态输出走的是STDERR,而且是实时流,没法直接用常规的文件读取方式处理。其实不用拆分批处理或者依赖临时文件,我们可以通过STDERR重定向+管道+实时解析的方式,直接把输出抓出来并存入变量,完全适配实时场景。
实现思路
- 把FFmpeg的STDERR输出重定向到STDOUT(用
2>&1),这样管道能捕获到转码状态信息; - 用
findstr过滤出包含frame=的行,只处理我们关心的状态行; - 用
for /f解析每行内容,提取frame=和fps=对应的值,存入变量; - 启用变量延迟扩展,确保循环内的变量能实时更新。
完整可运行的批处理代码
@echo off setlocal enabledelayedexpansion :: 替换成你的FFmpeg转码命令 set "FFMPEG_CMD=ffmpeg -i "D:\Videos\youtube.mp4" -c:v libx265 -c:a copy "D:\Videos\youtube.mkv"" :: 提前用ffprobe获取原视频总帧数(用于后续进度计算) for /f %%f in ('ffprobe -v error -select_streams v:0 -show_entries stream=nb_frames -of default=nokey=1:noprint_wrappers=1 "D:\Videos\youtube.mp4"') do set "TOTAL_FRAMES=%%f" :: 实时捕获并解析FFmpeg输出 %FFMPEG_CMD% 2>&1 | findstr "frame=" | ( :: 记录转码开始时间 set "START_TIME=%time%" :PROCESS_LINE set "CURRENT_LINE=" set /p CURRENT_LINE= if not defined CURRENT_LINE goto :END_PROCESS :: 提取frame值(tokens=2对应frame=后面的数值) for /f "tokens=2 delims== " %%a in ("!CURRENT_LINE!") do set "CURRENT_FRAME=%%a" :: 提取fps值(tokens=4对应fps=后面的数值) for /f "tokens=4 delims== " %%b in ("!CURRENT_LINE!") do set "CURRENT_FPS=%%b" :: 这里可以加入你的进度计算和ETA逻辑,示例如下 if not "!TOTAL_FRAMES!"=="" ( set /a "PROGRESS=CURRENT_FRAME*100/TOTAL_FRAMES" echo 当前进度: !PROGRESS!%, 已处理帧: !CURRENT_FRAME!, 当前帧率: !CURRENT_FPS! :: ETA计算可以基于已用时间和进度,这里省略具体实现,你可以用时间差来计算 ) else ( echo 已处理帧: !CURRENT_FRAME!, 当前帧率: !CURRENT_FPS! ) goto :PROCESS_LINE ) :END_PROCESS echo 转码完成! endlocal
关键细节解释
- STDERR重定向:
2>&1是Windows批处理中把错误输出(FFmpeg的状态信息默认走这里)转到标准输出的语法,这样管道才能捕获到内容; - 变量延迟扩展:
setlocal enabledelayedexpansion必须开启,否则循环内的变量无法实时更新(要用!变量!代替%变量%来引用); - 解析参数调整:如果你的FFmpeg输出行格式有变化(比如
frame=和fps=的位置不同),需要调整for /f里的tokens参数。比如原输出行是frame= 19 fps=0.0 q=-0.0 ...,tokens=2对应frame值,tokens=4对应fps值; - 总帧数获取:用
ffprobe(FFmpeg套件自带工具)提前获取原视频的总帧数,这是计算进度百分比的基础,如果没有ffprobe,也可以通过视频时长×帧率估算总帧数。
关于周期性检查
如果不需要每一行都处理,而是想固定间隔(比如每1秒)检查一次状态,可以在goto :PROCESS_LINE前加入timeout /t 1 /nobreak >nul,但要注意这可能会错过部分输出行,所以优先推荐实时捕获的方式,因为FFmpeg的状态输出本身就是周期性的(默认大概每秒几次)。
内容的提问来源于stack exchange,提问作者HASJ
相关产品推荐
相关产品推荐

