第三章 命令行核心语法:ffmpeg 命令结构解析
说实话,我见过不少刚接触 FFmpeg 的同事,上来就复制粘贴网上的命令。能跑通还好,一旦报错就完全懵了。为什么?因为根本不知道这条命令在说什么。
这一章,我们就来彻底拆解 ffmpeg 的命令结构。你搞懂了骨架,以后不管多复杂的命令,在你眼里都是一块块积木。
3.1 命令的“骨架”:一个公式搞定
FFmpeg 的命令行,本质上就一个公式:
ffmpeg [全局参数] [输入文件参数] -i 输入文件 [输出文件参数] 输出文件
嗯,就这么简单。你仔细看,它只有四个核心部分:
- ffmpeg:调用程序本身
- [全局参数]:影响整个命令行为的开关
- [输入文件参数]:针对输入文件的设置
- [输出文件参数]:针对输出文件的设置
我刚开始用的时候,总喜欢把所有参数堆在一起。后来踩了几次坑才发现,参数放错位置,结果天差地别。
核心原则:参数的位置决定了它的作用范围。放在 -i 前面,影响输入;放在 -i 后面、输出文件前面,影响输出。
3.2 输入文件(-i):告诉 FFmpeg 读什么
-i 是 input 的缩写。它的后面跟着你要处理的文件路径或 URL。
ffmpeg -i input.mp4 output.avi
这条命令很简单:读取 input.mp4,输出成 output.avi。
但实际项目中,输入往往不止一个。比如你要给视频加字幕、混音,就需要多个输入:
ffmpeg -i video.mp4 -i subtitle.srt -i audio.mp3 output.mkv
这里我用了三个 -i。FFmpeg 会按顺序给它们编号:0:0 是第一个文件的第一个流,1:0 是第二个文件的第一个流,以此类推。
我的习惯:在复杂命令里,我会在注释里写明每个输入文件的用途。虽然命令行不支持注释,但我会在笔记里记清楚,避免搞混流索引。
3.3 输出文件:不止是文件名
输出文件写在命令的最后。FFmpeg 会根据文件扩展名自动猜测封装格式。比如 .mp4 就是 MP4,.mkv 就是 Matroska。
但输出文件前面可以跟一堆参数,用来控制编码器、码率、分辨率等等。这些就是输出文件参数。
ffmpeg -i input.mp4 -c:v libx264 -b:v 2M -c:a aac output.mp4
这条命令里:
-c:v libx264:视频编码器用 H.264-b:v 2M:视频码率设为 2 Mbps-c:a aac:音频编码器用 AAC
这些参数只作用于输出文件,不会影响输入文件的读取方式。
3.4 全局参数 vs 流参数:别放错位置
这是新手最容易搞混的地方。我当年也犯过这个错。
全局参数:放在最前面,影响整个命令。比如日志级别、覆盖输出文件等。
ffmpeg -y -loglevel debug -i input.mp4 output.avi
-y 表示覆盖输出文件而不询问,-loglevel debug 表示输出调试信息。这两个都是全局的。
流参数:针对某个特定的流。比如只处理视频流,或者只处理音频流。
ffmpeg -i input.mp4 -c:v libx264 -an output.mp4
-an 表示禁用音频流。它属于输出文件参数,只影响输出。
| 参数类型 | 位置 | 作用范围 | 示例 |
|---|---|---|---|
| 全局参数 | 所有 -i 之前 | 整个命令 | -y, -loglevel, -stats |
| 输入文件参数 | 紧跟对应的 -i 之后 | 该输入文件 | -ss, -t, -f |
| 输出文件参数 | 输出文件之前 | 该输出文件 | -c:v, -b:a, -s |
我曾经踩过的坑:有一次我想裁剪视频的前 10 秒,把 -ss 10 放在了输出参数的位置。结果 FFmpeg 先解码再裁剪,速度慢得要命。后来我才知道,-ss 放在输入参数位置是“快进”模式,效率高得多。
3.5 流选择器:精准控制每个流
有时候你只想处理视频里的某一条流。比如一个文件里有两条音轨,你只想保留第二条。
ffmpeg -i input.mkv -c:v copy -c:a:1 copy output.mkv
-c:a:1 表示只复制第二个音频流。流选择器的语法是 流类型:索引。
常用的流类型:
v:视频a:音频s:字幕d:数据
索引从 0 开始。所以 v:0 是第一个视频流,a:1 是第二个音频流。
3.6 知识体系总览
下面这张图,是我自己整理的命令结构。每次写复杂命令前,我都会在脑子里过一遍这个流程。
3.7 实战:从命令到理解
我们来看一个真实项目中的命令。这是我去年帮一个客户处理视频时写的:
ffmpeg -y -ss 00:01:00 -i source.mp4 -t 30 -c:v libx264 -preset fast -crf 23 -c:a aac -b:a 128k output.mp4
我们来逐段拆解:
-y:全局参数,自动覆盖已有文件。-ss 00:01:00:输入参数,从第 1 分钟开始读取。放在-i前面,是快速定位模式。-i source.mp4:输入文件。-t 30:输出参数,只输出 30 秒。-c:v libx264:输出参数,视频编码器。-preset fast:输出参数,编码速度预设。-crf 23:输出参数,视频质量。-c:a aac:输出参数,音频编码器。-b:a 128k:输出参数,音频码率。output.mp4:输出文件。
你看,一旦你掌握了骨架,再长的命令也能一眼看穿。
我的建议:刚开始练习时,每次写完命令,都手动标注一下每个参数属于哪一类。坚持两周,你就能形成条件反射。
3.8 常见误区
最后,我总结几个我见过最多的错误:
- 参数顺序搞反:把输出参数写在
-i前面,导致参数被忽略。 - 忘记
-i:直接写文件名,FFmpeg 会把它当成输出文件。 - 流索引搞错:多输入时,流索引从 0 开始,不是从 1 开始。
- 全局参数放错位置:比如把
-y放在-i后面,虽然有时也能用,但不符合规范。
嗯,这一章的内容就到这里。你把这些基础打牢了,后面学滤镜、学复杂转码,都会轻松很多。