FFmpeg 日志系统:从入门到实战调优
日志,说白了就是程序的「黑匣子」。你想想看,一个流媒体管道跑起来,里面几十个 filter 在干活,突然画面卡了、声音断了、推流失败了——你靠什么定位问题?靠猜吗?
我个人习惯,不管写什么工具,第一件事就是把日志系统摸透。FFmpeg 的日志系统其实不复杂,但很多人只停留在 -loglevel debug 这个层面,遇到问题还是一头雾水。今天我们就把它彻底讲清楚。
日志级别:从安静到话痨
FFmpeg 定义了 9 个日志级别,从最安静到最话痨,依次是:
| 级别名称 | 数值 | 含义 | 典型场景 |
|---|---|---|---|
quiet |
-8 | 完全静默,什么都不输出 | 生产环境、脚本批量处理 |
panic |
0 | 仅输出导致进程崩溃的致命错误 | 最简错误报告 |
fatal |
8 | 致命错误,进程即将退出 | 关键故障上报 |
error |
16 | 一般性错误,不影响继续运行 | 日常错误监控 |
warning |
24 | 警告,可能存在问题但不一定出错 | 潜在风险提示 |
info |
32 | 常规信息,默认级别 | 日常运行状态 |
verbose |
40 | 详细信息,比 info 更啰嗦 | 调试初期 |
debug |
48 | 调试信息,包含内部状态 | 深入排查问题 |
trace |
56 | 最详细,包含函数调用轨迹 | 开发阶段、极难复现的 bug |
核心要点:数值越大,输出越多。默认是 info 级别(32)。生产环境我一般用 warning 或 error,开发调试才开 debug 或 trace。
怎么设置日志级别?
最常用的方式就是命令行参数 -loglevel,或者它的简写 -v:
# 只显示错误
ffmpeg -v error -i input.mp4 output.mp4
# 显示调试信息
ffmpeg -loglevel debug -i input.mp4 output.mp4
# 完全静音
ffmpeg -loglevel quiet -i input.mp4 output.mp4
嗯,这里要注意:quiet 级别是真的什么都不输出,连错误都不报。我曾经在自动化脚本里用过 quiet,结果转码失败了三天我才发现——从那以后,生产环境我至少留个 error 级别。
日志颜色:让重点一目了然
FFmpeg 默认会根据日志级别给输出上色。这个功能默认是开启的,但如果你把输出重定向到文件,颜色信息会被剥离。
颜色映射规则是这样的:
| 日志级别 | 颜色 | 效果 |
|---|---|---|
panic / fatal |
红色 | 刺眼醒目,一眼就能看到 |
error |
亮红色 | 明显但不刺眼 |
warning |
黄色 | 警示感,但不紧急 |
info |
绿色 | 正常状态,让人安心 |
verbose / debug |
蓝色 | 调试信息,不干扰视线 |
trace |
灰色 | 最不显眼,需要时才看 |
你可以通过 -color 参数控制颜色行为:
# 强制开启颜色(即使输出到文件)
ffmpeg -color always -i input.mp4 output.mp4
# 强制关闭颜色
ffmpeg -color never -i input.mp4 output.mp4
# 自动模式(默认):终端输出有颜色,文件重定向无颜色
ffmpeg -color auto -i input.mp4 output.mp4
我的习惯:调试时用 -color always 配合 -loglevel debug,红色错误和黄色警告在终端里特别显眼,扫一眼就能定位问题。但如果你要把日志保存到文件,记得用 -color never,否则文件里会塞满转义字符,看着像乱码。
日志格式定制:按你的方式输出
FFmpeg 的日志格式可以通过 -loglevel 的 + 后缀来微调。比如:
# 显示时间戳
ffmpeg -loglevel debug+time -i input.mp4 output.mp4
# 显示进程 PID
ffmpeg -loglevel debug+pid -i input.mp4 output.mp4
# 同时显示时间和 PID
ffmpeg -loglevel debug+time+pid -i input.mp4 output.mp4
支持的格式修饰符有:
+time:在每行日志前加上时间戳+pid:显示进程 ID+level:显示日志级别名称(默认就有)+file:显示源代码文件名和行号
举个例子,加了 +time+pid 后,输出会变成这样:
[2025-01-15 14:23:45] [pid=12345] [info] Input #0, mp4, from 'input.mp4':
[2025-01-15 14:23:45] [pid=12345] [debug] Parsing group of pictures...
[2025-01-15 14:23:46] [pid=12345] [error] Could not find codec parameters for stream 0
我个人觉得 +time 是最实用的,尤其是在分析性能问题时,能看到每个步骤花了多长时间。
实战:日志系统的知识体系
说了这么多,我们来画一张图,把整个日志系统的脉络理清楚:
避坑指南:我踩过的那些坑
做流媒体调试这些年,日志系统帮我省了不少时间,但也坑过我几次。分享几个真实案例:
坑1:日志级别太低,错过关键信息
我曾经排查一个推流断连的问题,开了 -loglevel error,结果只看到「Connection reset by peer」,完全不知道前面发生了什么。后来改成 debug 才发现,原来是某个 filter 在 30 秒后超时了。所以我的原则是:第一次排查问题,至少开到 verbose。
坑2:颜色信息污染日志文件
有一次我把日志重定向到文件,忘了加 -color never,结果文件里全是 \033[31m 这样的转义字符。用 cat 看还好,用 less 看就是一堆乱码。后来写了个脚本自动过滤颜色码,但总归是多此一举。
坑3:trace 级别输出量太大
开 trace 级别调试一个 4K 视频转码,5 分钟生成了 2GB 的日志文件。磁盘直接写满了,转码进程也挂了。所以 trace 级别我建议只在开发环境用,而且最好配合 -max_log_size 限制日志文件大小。
总结一下
FFmpeg 的日志系统其实就三件事:选对级别、用好颜色、定制格式。级别决定了你看多少信息,颜色帮你快速定位重点,格式让你知道每条日志的上下文。这三者配合好了,调试效率能翻一倍。
下次遇到 FFmpeg 的问题,别急着搜百度。先看看日志级别对不对,颜色有没有开,格式是不是够详细。很多时候,答案就在日志里,只是你没看到而已。