3. FFmpeg命令行基础:命令结构、全局参数、输入输出与编码选择
说实话,我见过不少刚接触FFmpeg的朋友,一上来就复制网上的命令跑,跑通了就觉得自己会了。但一旦遇到报错,或者想改点东西,就完全懵了。这就像你只会按快门,却不懂光圈和快门速度的关系——永远拍不出想要的照片。
所以这一章,咱们把FFmpeg的命令行基础彻底搞明白。我保证,看完这章,你不仅能看懂任何一条FFmpeg命令,还能自己组装出符合需求的命令。
3.1 FFmpeg命令的骨架:一个命令是怎么组成的?
一条完整的FFmpeg命令,其实就五个部分。我习惯把它想象成「流水线」:
ffmpeg [全局参数] [输入文件参数] -i 输入文件 [输出文件参数] 输出文件
咱们拆开看:
- ffmpeg:就是启动这个工具本身,没啥好说的。
- [全局参数]:影响整个命令行为的设置,比如日志级别、覆盖文件策略等。它放在最前面。
- [输入文件参数]:针对输入文件的设置,比如指定视频轨道、设置输入格式等。它紧跟在全局参数后面,在
-i之前。 - -i 输入文件:指定输入文件路径。可以写多个
-i,实现多输入。 - [输出文件参数]:针对输出文件的设置,比如编码器、码率、分辨率等。它放在输出文件之前。
举个例子,这条命令我经常在项目里用来快速转码:
ffmpeg -y -i input.mp4 -c:v libx264 -b:v 2M output.mp4
这里 -y 是全局参数(自动覆盖输出文件),-c:v libx264 -b:v 2M 是输出文件参数,input.mp4 是输入,output.mp4 是输出。结构清晰吧?
3.2 常用全局参数:这些你每天都会用到
全局参数虽然不多,但用错了能让你抓狂。我挑几个最常用的说说:
| 参数 | 作用 | 我的经验 |
|---|---|---|
-y |
覆盖输出文件,不询问 | 脚本里必加,否则卡住 |
-n |
不覆盖输出文件,直接跳过 | 批量处理时防止误覆盖 |
-loglevel |
设置日志级别 | 调试用 debug,生产用 error |
-hide_banner |
隐藏编译信息等杂项 | 让输出更清爽,我必加 |
-stats |
显示编码进度 | 默认开启,但有时需要显式指定 |
ffmpeg -y -hide_banner -loglevel error。这样既安静又不会因为文件存在而中断。
3.3 输入输出文件指定:不只是写个路径那么简单
指定输入输出文件,最基础的就是写路径。但FFmpeg支持很多「花样」,我挑两个实用的:
3.3.1 多个输入文件
比如你要把视频和音频合并:
ffmpeg -i video.mp4 -i audio.wav -c:v copy -c:a aac output.mp4
这里两个 -i,第一个是视频,第二个是音频。FFmpeg会按顺序给它们编号:0:0 是第一个文件的第一个流,1:0 是第二个文件的第一个流。
3.3.2 使用管道(pipe)
我在做实时流处理时经常用这个。从标准输入读取:
cat input.ts | ffmpeg -i pipe:0 -c copy output.mp4
或者输出到标准输出:
ffmpeg -i input.mp4 -c copy -f mpegts pipe:1 | some_other_program
-f 指定输出格式,因为FFmpeg无法从管道中自动探测格式。我曾经在这上面栽过跟头,折腾了半天才发现是格式没指定。
3.4 -c copy 与重编码:核心区别在哪?
这是新手最容易混淆的地方。我直接说结论:
- -c copy:直接复制,不重新编码。速度快,画质无损。
- 重编码:解码后再编码。速度慢,画质有损(除非用无损编码器)。
为什么会这样?你想想看,-c copy 只是把压缩好的数据从一种容器里「搬」到另一种容器里。而重编码,是把压缩的数据先解压成原始图像/音频,再用另一种方式压缩回去。这中间的解压-再压缩过程,不仅耗时,还会引入画质损失。
我举个例子,你一看就明白:
# 直接复制(秒完成)
ffmpeg -i input.mkv -c copy output.mp4
# 重编码(可能要几分钟)
ffmpeg -i input.mkv -c:v libx264 -c:a aac output.mp4
第一条命令,如果只是改封装格式(比如从MKV到MP4),几秒钟就完事。第二条命令,同样的文件,可能要跑几分钟甚至更久。
- 只改封装格式(如 MKV → MP4)
- 只裁剪或拼接(不改变编码)
- 只提取流(如提取音频)
- 改变分辨率、帧率、码率
- 改变编码格式(如 H.264 → H.265)
- 添加滤镜、水印、字幕
我曾经有个项目,需要把一批TS流文件转成MP4。一开始我傻傻地用重编码,一个文件要跑半小时。后来发现只是容器不同,改成 -c copy,一个文件十几秒就搞定。嗯,这就是经验的价值。
3.5 知识体系总览:一张图看懂
说了这么多,咱们用一张SVG图把整个命令结构串起来。这样你以后看到任何FFmpeg命令,都能快速拆解:
3.6 实战对比:一个例子看懂所有
咱们用同一个输入文件,做三件事,你感受一下区别:
| 操作 | 命令 | 速度 | 画质 |
|---|---|---|---|
| 改封装(MKV→MP4) | ffmpeg -i input.mkv -c copy output.mp4 |
极快(几秒) | 无损 |
| 改编码(H.264→H.265) | ffmpeg -i input.mp4 -c:v libx265 output.mp4 |
慢(几分钟) | 有损(但更小) |
| 加滤镜(调亮度) | ffmpeg -i input.mp4 -vf eq=brightness=0.2 output.mp4 |
慢(需重编码) | 有损 |
-c copy。如果必须改内容,再考虑重编码。这个习惯能帮你省下大量时间。
好了,这一章的内容就这些。记住命令的骨架结构,分清全局参数和文件参数,理解 -c copy 和重编码的本质区别。这些东西看似基础,但我在工作中见过太多人在这上面翻车。打好这个基础,后面的章节你会走得很顺。