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 是最实用的,尤其是在分析性能问题时,能看到每个步骤花了多长时间。

实战:日志系统的知识体系

说了这么多,我们来画一张图,把整个日志系统的脉络理清楚:

FFmpeg 日志系统知识体系 FFmpeg 日志系统 日志级别 颜色控制 格式定制 quiet/panic fatal/error warning info verbose debug trace panic/fatal → 红色 warning → 黄色 info → 绿色 debug/trace → 蓝色/灰色 +time 时间戳 +pid 进程ID +level 级别名称 +file 文件行号 实战建议 生产环境:-loglevel warning 或 error 调试环境:-loglevel debug+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 的问题,别急着搜百度。先看看日志级别对不对,颜色有没有开,格式是不是够详细。很多时候,答案就在日志里,只是你没看到而已。