2. 音视频基础概念:封装格式、编码格式、码率、帧率、分辨率
做流媒体开发,说白了就是在跟这几个参数打交道。我见过不少新手,一上来就急着调 FFmpeg 命令行,结果出来的文件要么播放器不认,要么画质惨不忍睹。原因很简单——没搞懂这些基础概念。
今天咱们就把这几个核心概念掰开揉碎。你理解了它们,后面学 FFmpeg 的封装、解析、转码,才会顺手。
2.1 封装格式:视频的“容器”
封装格式,你可以把它想象成一个“行李箱”。里面装着视频流、音频流、字幕、元数据。播放器打开文件时,先读这个行李箱的目录,找到对应的轨道,再解码播放。
我遇到过最典型的坑:有人把 .mp4 文件直接改成 .mkv,以为这样就能兼容某个老旧播放器。结果当然不行——改后缀不改变内部结构,播放器还是按 MP4 的规则去解析,自然报错。
2.1.1 常见封装格式对比
| 格式 | 全称 | 特点 | 典型场景 |
|---|---|---|---|
| MP4 | MPEG-4 Part 14 | 兼容性最好,流式播放支持好 | 网络视频、移动端、通用分发 |
| MKV | Matroska | 开源、灵活、支持多轨/章节/附件 | 高清电影、多音轨、字幕封装 |
| AVI | Audio Video Interleave | 老格式、无 B 帧支持、索引结构脆弱 | 老旧设备、Windows 兼容 |
| TS | MPEG-2 Transport Stream | 支持实时流、容错强、分段传输 | 数字电视、直播、HLS 切片 |
2.1.2 封装格式的内部结构
以 MP4 为例,它由一个个 Box(也叫 Atom)组成。核心的 Box 包括:
- ftyp:文件类型标识,告诉播放器“我是 MP4”
- moov:元数据区,存放时长、分辨率、轨道信息
- mdat:实际的音视频数据
我记得有一次做点播系统,用户上传的 MP4 文件播放时总是先黑屏几秒。排查后发现是 moov box 放在了文件末尾——播放器必须下载完整个文件才能读到元数据。解决方案很简单:用 FFmpeg 的 faststart 参数把 moov 移到文件头部。
ffmpeg -i input.mp4 -movflags faststart output.mp4
2.2 编码格式:视频的“压缩算法”
封装格式管的是“怎么装”,编码格式管的是“怎么压缩”。原始视频数据量巨大——一帧 1080p 的 RGB 图像大约 6MB,30fps 的话一秒就是 180MB。不压缩,谁也存不下、传不动。
2.2.1 H.264:目前最通用的视频编码
H.264(也叫 AVC)是当前兼容性最好的视频编码。从老旧的 MP4 播放器到最新的手机,几乎都支持。它的核心思路是:
- 帧内预测:利用同一帧内相邻像素的相似性压缩
- 帧间预测:利用前后帧的差异来压缩(P 帧、B 帧)
- 变换编码:把残差数据从像素域变换到频域,丢掉人眼不敏感的高频信息
关键概念:I 帧、P 帧、B 帧
- I 帧:关键帧,完整编码,不依赖其他帧。可以理解为“快照”。
- P 帧:向前参考帧,只记录与前一帧的差异。
- B 帧:双向参考帧,参考前后帧,压缩率最高但解码最复杂。
我曾经在直播项目中遇到过 B 帧导致的延迟问题。解码器需要等后面的帧到了才能解码 B 帧,这在低延迟场景下很致命。后来我强制设置了 -bf 0 禁用 B 帧,延迟从 3 秒降到了 500 毫秒。
2.2.2 AAC:音频编码的“默认选项”
AAC(Advanced Audio Coding)是 MP4 最常用的音频编码。相比 MP3,它在相同码率下音质更好。FFmpeg 中常用的 AAC 编码器有:
- libfdk_aac:质量最好,但需要单独编译
- aac:FFmpeg 内置编码器,兼容性好
- libmp3lame:MP3 编码器,兼容老旧设备
2.3 码率:决定文件大小和画质
码率(Bitrate)就是每秒传输的数据量,单位是 bps(bit per second)。码率越高,画质越好,文件也越大。
2.3.1 固定码率 vs 可变码率
| 类型 | 说明 | 适用场景 |
|---|---|---|
| CBR(固定码率) | 整个视频码率恒定 | 直播、网络带宽受限的场景 |
| VBR(可变码率) | 根据画面复杂度动态调整码率 | 本地存储、点播,画质优先 |
| CRF(恒定质量) | 设定质量等级,让编码器自动分配码率 | 个人收藏、后期处理 |
我个人习惯用 CRF 模式做本地转码。CRF 值范围是 0-51,值越小质量越高。一般 18-28 之间比较常用:
# CRF 23,画质和体积比较均衡
ffmpeg -i input.mp4 -crf 23 output.mp4
# CRF 18,接近无损,适合存档
ffmpeg -i input.mp4 -crf 18 output.mp4
2.4 帧率:视频的“流畅度”
帧率(Frame Rate)就是每秒显示多少帧画面,单位是 fps。常见的帧率有:
- 24fps:电影标准,有“胶片感”
- 25fps:PAL 制式电视标准
- 30fps:NTSC 制式电视标准,也是网络视频常用
- 60fps:高帧率,适合体育、游戏直播
帧率不是越高越好。人眼对 30fps 以上的流畅度提升感知有限,但码率会成倍增加。我做过一个测试:同样一段 1080p 视频,30fps 码率 5Mbps 画质很好,60fps 要 8Mbps 才能达到同等画质。
2.5 分辨率:视频的“清晰度”
分辨率就是视频的宽高像素数。常见的有:
| 名称 | 分辨率 | 宽高比 |
|---|---|---|
| SD(标清) | 720×576 | 4:3 |
| HD(高清) | 1280×720 | 16:9 |
| Full HD(全高清) | 1920×1080 | 16:9 |
| 4K UHD | 3840×2160 | 16:9 |
分辨率越高,细节越丰富,但码率需求也越大。4K 视频的码率通常是 1080p 的 4 倍左右。做转码时,我一般会根据目标带宽来降分辨率:
# 将 4K 视频降为 1080p
ffmpeg -i input_4k.mp4 -vf scale=1920:1080 output_1080p.mp4
2.6 知识体系总览
下面这张图把本章的核心概念串起来了。你可以看到:原始音视频数据经过编码压缩,再封装成容器格式,最终通过码率、帧率、分辨率这三个参数来平衡画质和文件大小。
2.7 小结
这一章的内容,说白了就是四个字:选对工具。
- 封装格式选 MP4 还是 MKV,看你的分发场景
- 编码格式选 H.264 还是 H.265,看你的兼容性要求
- 码率、帧率、分辨率这三个参数,永远在画质和体积之间做权衡
我刚开始做流媒体时,也踩过不少坑。比如用 AVI 封装 H.264,结果播放器不支持;或者把 4K 视频直接压成 1Mbps 的码率,画面全是马赛克。这些教训让我明白:基础概念不扎实,后面调 FFmpeg 参数就是瞎蒙。