4. FFmpeg命令行入门

FFmpeg 的命令行看似参数繁多,但它的核心模型非常稳定:输入(Input)→ 解码(Decode)→ 滤镜(Filter)→ 编码(Encode)→ 输出(Output)。理解这条数据通路,就能把绝大多数命令拆解成“读什么、怎么处理、写什么”三个问题。本节围绕输入输出、转码、复用、解复用、滤镜与流映射六个基础操作展开,为后续 RTP 推流与性能调优打下命令行基础。

一、核心原理:一条命令就是一张处理图

FFmpeg 把每个输入文件视为一个“输入流集合”,把每个输出文件视为一个“输出流集合”。命令行中的 -i 负责声明输入,输出文件名负责声明输出,中间的 -c、-vf、-map 等参数则描述如何处理。FFmpeg 内部会为每个输出构建一张有向图:解复用器(Demuxer)拆出音视频包,解码器还原成帧,滤镜处理帧,编码器再压缩成包,最后由复用器(Muxer)写入容器。

这里有两个关键概念:复用(Mux)是把多路编码流按容器规范交织写入一个文件,例如把 H.264 视频和 AAC 音频写进 MP4;解复用(Demux)则是反向操作,从容器中分离出独立的流。转码(Transcode)是“解码 + 编码”的组合,而流复制(Stream Copy)只做复用/解复用,不重新编码,因此速度极快、画质无损。

FFmpeg 命令行处理通路:输入 → 解复用 → 解码 → 滤镜 → 编码 → 复用 → 输出 输入文件 -i input.mp4 解复用 Demuxer 解码 Decoder 滤镜 Filter Graph 编码 Encoder 复用 Muxer 输出文件 output.mp4 流复制 Stream Copy -c copy:跳过解码与编码 转码路径:解码 → 滤镜 → 编码,可改变分辨率、码率、编码格式; 流复制路径:仅解复用 → 复用,不改变编码数据,速度快、无画质损失,适合封装格式转换与切片。

二、方法流程:从一条最小命令开始

最基础的转码命令只包含输入、输出和编码器选择。下面把 MP4 转为 H.264 + AAC 的 MP4,并指定视频码率与音频采样率:

ffmpeg -i input.mp4 \
  -c:v libx264 -b:v 2000k -preset medium \
  -c:a aac -b:a 128k -ar 44100 \
  -movflags +faststart output.mp4

如果只想换容器而不重新编码,使用流复制即可,速度通常提升数十倍:

ffmpeg -i input.mkv -c copy output.mp4

解复用与提取流是常见需求。例如只提取视频流、只提取音频流,或把音频转成 WAV:

ffmpeg -i input.mp4 -map 0:v -c copy video.h264
ffmpeg -i input.mp4 -map 0:a -c copy audio.aac
ffmpeg -i input.mp4 -vn -c:a pcm_s16le audio.wav

滤镜通过 -vf(视频)和 -af(音频)指定。下面把视频缩放到 1280×720、裁剪为 16:9,并叠加时间戳:

ffmpeg -i input.mp4 \
  -vf "scale=1280:720,crop=1280:720,drawtext=text='%{pts\\:hms}':x=10:y=10:fontsize=24:fontcolor=white" \
  -c:a copy output.mp4

三、流映射:-map 决定“谁进谁出”

当输入包含多路音视频或字幕时,FFmpeg 默认只挑选“最佳”的一路视频和一路音频。要精确控制输出包含哪些流,必须使用 -map。它的语法是 -map 输入索引:流类型:流索引,例如 -map 0:v:0 表示第 0 个输入的第 0 路视频,-map 1:a:1 表示第 1 个输入的第 1 路音频。负映射 -map -0:a:1 则用于排除某一路流。

使用 -map 后,FFmpeg 不再自动选择流,所有需要的流都必须显式映射,否则输出可能缺少音频或字幕。

下面这条命令把两个输入合并:主视频来自 input1.mp4,背景音乐来自 input2.mp3,并保留原视频编码:

ffmpeg -i input1.mp4 -i input2.mp3 \
  -map 0:v:0 -map 1:a:0 \
  -c:v copy -c:a aac -shortest output.mp4

四、常用参数与场景对照

操作目标 关键参数 典型命令片段
转码视频编码 -c:v libx264 ffmpeg -i in.mp4 -c:v libx264 out.mp4
仅换容器 -c copy ffmpeg -i in.mkv -c copy out.mp4
提取音频 -vn -c:a ffmpeg -i in.mp4 -vn -c:a copy out.aac
缩放与裁剪 -vf scale,crop ffmpeg -i in.mp4 -vf "scale=1280:720" out.mp4
精确选流 -map ffmpeg -i in.mp4 -map 0:v:0 -map 0:a:1 out.mp4
快速起播 -movflags +faststart ffmpeg -i in.mp4 -c copy -movflags +faststart out.mp4

五、误区与复盘

误区一:把 -c copy 当成万能转码。流复制不能改变编码格式、分辨率或码率。若目标容器不支持源编码(例如把 H.265 直接复制进某些旧设备只认 H.264 的 MP4),播放器会黑屏或报错,此时必须真正转码。

误区二:忽略 -map 的排他性。一旦使用 -map,自动流选择失效。只映射了视频却忘记音频,输出就会静音。

误区三:滤镜顺序随意。滤镜按逗号从左到右依次执行,scale 后再 crop 与先 crop 再 scale 结果不同,需按目标分辨率反推顺序。

误区四:忽视时间戳与同步。合并多输入时若不加 -shortest,输出时长可能被最长流拉长,出现尾部黑屏或静音。

复盘时建议养成固定排查顺序:先用 ffprobe 查看输入流布局,确认有几路视频、几路音频、编码格式与分辨率;再决定是流复制还是转码;然后显式写出 -map;最后检查输出容器是否支持所选编码。掌握这套流程后,无论是本地转码、切片还是后续 RTP 推流,命令行都会变得可预测、可复现。