核心概念:容器格式、编码格式、码率、帧率、分辨率等基本术语

在开始使用 FFmpeg 之前,必须先厘清一组最基础、也最容易混淆的概念。很多命令行参数之所以让人困惑,根源在于没有区分“容器”与“编码”。打个比方:编码格式决定食物本身的做法(红烧、清蒸),而容器格式决定用什么盘子端上桌(瓷盘、木碗)。同一个盘子可以装不同做法的菜,同一种菜也可以换不同的盘子——但有些搭配并不合适。

1. 容器格式(Container Format)

容器格式是封装视频流、音频流、字幕流、章节信息以及元数据的“外壳”。它不关心内部数据如何压缩,只负责组织与同步。常见的容器有:

  • MP4(.mp4):最通用的网络与设备格式,支持 H.264/H.265/AAC,适合流媒体与移动端。
  • MKV(.mkv):Matroska,开源且几乎支持一切编码,适合多音轨、多字幕的本地收藏。
  • AVI(.avi):老牌容器,兼容性好但索引机制落后,损坏后难修复。
  • MOV(.mov):Apple 生态常用,与 MP4 同源但支持更多高级特性。
  • TS(.ts):MPEG-TS,用于广播电视与实时流,支持拼接与断点续传。

FFmpeg 中通过文件扩展名或 -f 参数指定容器。例如将裸 H.264 码流封装为 MP4:

ffmpeg -i video.h264 -c copy output.mp4

这里 -c copy 表示不重新编码,仅改变封装,速度极快且无损。

2. 编码格式(Codec)

编码格式负责压缩原始视频/音频数据,消除空间与时间冗余。编码决定了文件大小、画质与解码兼容性。核心编码包括:

编码类型典型用途FFmpeg 名称
H.264 (AVC)有损兼容性最强,网络视频首选libx264
H.265 (HEVC)有损4K/8K,比 H.264 节省约 50% 码率libx265
AV1有损开源免专利费,新一代流媒体libaom-av1
ProRes有损/近无损专业后期剪辑中间格式prores_ks
FFV1无损数字档案保存ffv1

编码与容器是正交的。例如 MKV 里可以装 H.264、HEVC、VP9 甚至无损 FFV1;MP4 则对编码有更严格的限制(通常只允许 H.264/H.265 + AAC)。

3. 码率(Bitrate)

码率表示单位时间内传输的数据量,单位通常为 kbps(千比特/秒)或 Mbps。码率直接决定体积与画质上限:码率越高,每帧可用的数据越多,细节保留越好,但文件也越大。

码率分为两种设置方式:

  • 固定码率(CBR):全程保持恒定,适合实时流媒体,但复杂场景容易产生块效应。
  • 可变码率(VBR):根据画面复杂度动态调整,简单场景用低码率,复杂场景用高码率,效率更高。

FFmpeg 中通过 -b:v 设置视频码率,-b:a 设置音频码率。例如输出 2Mbps 视频 + 128kbps 音频:

ffmpeg -i input.mp4 -c:v libx264 -b:v 2000k -c:a aac -b:a 128k output.mp4

更推荐使用 两次编码(2-pass) 来精确控制目标文件大小:第一次扫描分析,第二次按分配码率编码,画质比单次 VBR 更稳定。

4. 帧率(Frame Rate)

帧率指每秒显示的静止画面数,单位 fps(frames per second)。帧率影响运动流畅度:24fps 是电影标准,30fps 用于电视与网络,60fps 适合体育与游戏。高帧率能减少拖影,但会显著增加编码压力与文件体积。

FFmpeg 中通过 -r 设置输出帧率,或通过 fps 滤镜进行更精细的转换:

# 将 60fps 视频降为 30fps
ffmpeg -i input.mp4 -vf "fps=30" -c:v libx264 output.mp4

# 查看视频实际帧率
ffprobe -v error -select_streams v:0 -show_entries stream=avg_frame_rate -of default=noprint_wrappers=1 input.mp4

注意:改变帧率不会加速或减速视频,只是丢弃或复制帧。若想改变播放速度,应使用 setpts 滤镜。

5. 分辨率(Resolution)

分辨率指视频的像素尺寸,如 1920×1080(1080p)、3840×2160(4K)。分辨率决定画面细节总量,但并非越高越好——它必须与码率匹配。低码率下强行拉高分辨率,只会得到模糊且充满噪点的画面。

FFmpeg 中缩放分辨率使用 scale 滤镜:

# 将视频缩放到 1280x720,保持宽高比
ffmpeg -i input.mp4 -vf "scale=-2:720" -c:v libx264 output.mp4

-2 表示自动计算宽度并保证偶数(H.264 要求宽高为偶数)。若需裁剪而非缩放,可使用 crop 滤镜。

6. 核心概念关系图

下面这张图展示了从原始信号到最终文件的完整链路,以及各参数在链路中的位置:

FFmpeg 核心概念链路图 原始信号 未压缩 PCM/YUV 编码格式 H.264 / H.265 / AV1 码率控制 CBR / VBR / 2-pass 容器格式 MP4 / MKV / TS 压缩 量化 封装 时空采样参数(影响编码输入) 帧率 (fps) 24 / 30 / 60 分辨率 1920×1080 / 3840×2160 像素格式 yuv420p / yuv444p 最终输出文件 video.mp4 (H.264 + AAC) FFmpeg 命令行中:-c:v 选编码,-b:v 设码率,-r 设帧率,-vf scale 调分辨率,-f 指定容器 常用 FFmpeg 参数映射 -c:v libx264 | -b:v 2000k | -r 30 | -vf scale=1920:1080 | -f mp4

7. 综合案例:从参数到命令

假设你有一个 4K 60fps 的原始视频,需要发布到视频网站,目标为 1080p 30fps,码率上限 4Mbps。完整命令如下:

ffprobe -v error -show_entries stream=codec_name,width,height,r_frame_rate -of default=noprint_wrappers=1 input.mkv

ffmpeg -i input.mkv \
  -vf "scale=-2:1080,fps=30" \
  -c:v libx264 -preset slow -b:v 4000k -maxrate 4500k -bufsize 8000k \
  -c:a aac -b:a 128k -ac 2 \
  -movflags +faststart \
  output.mp4

参数解读:scale=-2:1080 保持宽高比缩放到高 1080;fps=30 降低帧率;preset slow 提高压缩效率;maxrate/bufsize 限制码率波动;+faststart 将 moov 元数据移到文件头部,便于网络播放。

8. 常见误区与复盘

误区一:把容器扩展名当作编码。 看到 .mp4 就认为一定是 H.264,实际上 MP4 也可以封装 MPEG-2 或 H.263。务必用 ffprobe 确认真实编码。
误区二:盲目追求高码率。 对于 1080p 视频,10Mbps 与 20Mbps 的视觉差异极小,但文件体积翻倍。应根据内容类型选择:静态画面(讲座)用低码率,快速运动(体育)用高码率。
实践建议: 使用 ffprobe 分析任何陌生视频时,先查看 codec_name、width×height、avg_frame_rate、bit_rate 四个字段,即可快速判断文件规格。若 bit_rate 显示为 N/A,说明是可变码率,需用 -show_entries stream=bit_rate 查看具体流信息。

理解这五个核心概念后,FFmpeg 的绝大多数参数都能找到对应位置。编码格式决定压缩算法,容器决定封装结构,码率控制数据量,帧率与分辨率定义时空采样密度。实际工作中,这些参数相互制约:分辨率越高、帧率越高,就需要越高的码率来维持画质;而容器则决定了这些参数能否被目标播放器正确识别。掌握它们之间的关系,是编写高效、可靠 FFmpeg 命令的第一步。