3、FFmpeg命令行基础:命令结构、全局参数、输入输出与日志控制
说实话,我见过不少刚接触FFmpeg的朋友,一上来就复制粘贴网上的命令。跑通了还好,一旦报错就完全懵了。为什么?因为根本不知道这条命令在说什么。
这一章,我们就把它彻底拆开。你以后看到任何FFmpeg命令,都能一眼看出它的骨架。
3.1 命令的骨架:ffmpeg到底在干什么?
一条完整的FFmpeg命令,说白了就三部分:工具名 + 参数 + 输入输出。我习惯把它想象成一条流水线:
ffmpeg [全局参数] [输入文件参数] -i 输入文件 [输出文件参数] 输出文件
嗯,就这么简单。但这里有个坑——参数的顺序是有讲究的。全局参数必须放在最前面,输入参数紧跟着对应的 -i,输出参数则放在输出文件之前。我曾经见过有人把输出参数写在输入前面,结果FFmpeg直接忽略了它。
核心原则:参数作用于它后面遇到的第一个文件。全局参数作用于整个命令。
举个例子,下面这条命令,你能看出它的结构吗?
ffmpeg -y -v quiet -i input.mp4 -b:v 2M output.mp4
我来拆解一下:
-y和-v quiet是全局参数,一上来就生效。-i input.mp4指定输入文件。-b:v 2M是输出参数,作用于后面的output.mp4。
3.2 全局参数:那些一开始就要定好的事
全局参数,就是那些不针对某个具体文件,而是影响整个处理流程的设置。我个人最常用的就这几个:
| 参数 | 作用 | 我的使用场景 |
|---|---|---|
-y |
覆盖输出文件,不询问 | 批量处理时必加,不然每跑一个文件都要按一次y |
-n |
不覆盖输出文件,直接跳过 | 做增量处理时用,防止误覆盖已有结果 |
-v / -loglevel |
控制日志输出级别 | 调试时用 debug,上线脚本用 error |
-stats |
显示编码进度统计 | 默认就开着,但如果你关了日志,记得手动加上 |
-progress |
将进度信息输出到指定文件或URL | 写自动化脚本时,用来实时监控转码进度 |
小技巧:在写自动化脚本时,我习惯把 -y -v error 作为固定前缀。这样既不会因为文件存在而卡住,也不会被海量日志刷屏。
3.3 输入输出文件:-i 和 裸文件名的秘密
输入文件用 -i 指定,这个好理解。但输出文件为什么没有 -o 呢?
其实FFmpeg的设计哲学是:最后一个没有 -i 前缀的参数,就是输出文件。你想想看,这样设计是不是很简洁?
但这里有个容易翻车的地方——多个输入文件。比如你要拼接视频,或者混音,就需要多个 -i:
ffmpeg -i video.mp4 -i audio.mp3 -c:v copy -c:a aac output.mp4
这个命令里,video.mp4 是第一个输入,audio.mp3 是第二个输入。它们通过 -map 参数(后面章节会细讲)来指定如何混合。我曾经在做一个多轨录音项目时,因为搞混了输入文件的顺序,结果音频和视频对不上,排查了半天才发现是 -i 的顺序问题。
注意:输入文件可以有多个,但输出文件通常只有一个(除非你用了 -map 输出多个流)。多个输入时,它们的索引从0开始:0:0 表示第一个输入文件的第一个流。
3.4 日志级别控制:别让信息淹了你
FFmpeg默认的日志输出,说实话,有点啰嗦。跑一个简单的转码任务,它能给你刷好几屏。我刚开始学的时候,经常在满屏的 frame= 和 fps= 里找真正的错误信息。
日志级别由 -loglevel 或 -v 控制,从安静到详细,一共8个级别:
| 级别 | 值 | 什么时候用 |
|---|---|---|
| quiet | -8 | 生产环境脚本,完全不想看到任何输出 |
| panic | 0 | 只显示导致进程崩溃的错误 |
| fatal | 8 | 只显示致命错误 |
| error | 16 | 只显示错误信息,我写脚本时最常用 |
| warning | 24 | 显示警告和错误,日常手动操作推荐 |
| info | 32 | 默认级别,显示基本信息 |
| verbose | 40 | 比info更详细,适合初步调试 |
| debug | 48 | 显示所有信息,包括每个数据包的细节 |
举个例子,你写了一个批量转码的脚本,不想被日志刷屏,可以这样:
ffmpeg -v error -i input.mp4 output.mp4
这样只有真正的错误才会出现在屏幕上。如果一切顺利,它就安安静静地跑完。
避坑指南:我曾经在调试一个诡异的音画不同步问题时,把日志级别设成了 quiet,结果完全看不到FFmpeg给出的警告信息。后来改成 warning,才发现是输入文件的采样率不匹配。所以,调试时别偷懒,至少用 warning 级别。
3.5 一张图看懂FFmpeg命令结构
说了这么多,我们来画一张图,把整个命令结构串起来。这张图我每次给团队新人培训时都会用,看完基本就理解了。
这张图从左到右,就是FFmpeg处理一条命令的完整流程。你以后看到任何命令,都可以按这个结构去拆解:先找全局参数,再找输入,最后看输出。
3.6 实战:从零写一条完整的命令
光说不练假把式。我们拿一个真实场景来试试:把一个视频文件转成音频,同时控制日志输出。
需求很简单:把 lecture.mp4 转成 lecture.mp3,只保留音频,比特率设成192k,并且不要看到一堆无关信息。
按照我们刚才学的结构,一步步来:
- 全局参数:加
-y覆盖输出,加-v error只显示错误。 - 输入文件:
-i lecture.mp4。 - 输出参数:
-vn(不要视频),-b:a 192k(音频比特率)。 - 输出文件:
lecture.mp3。
组合起来就是:
ffmpeg -y -v error -i lecture.mp4 -vn -b:a 192k lecture.mp3
你看,是不是很清晰?就算这条命令跑失败了,你也能根据结构快速定位问题——是输入文件不存在?还是输出参数写错了?