封装格式与传输容器:流媒体的“包装盒”
各位同学,欢迎来到第四章。前面我们聊了编码,把视频压成了 H.264 或 AAC 的裸流。但裸流就像散装的零件,没法直接运输。你得找个盒子把它们装起来,贴上标签,写上播放顺序——这就是封装格式干的事。
我入行那会儿,最头疼的就是不同平台对封装格式的支持千差万别。PC 上好好的 MP4,放到老款机顶盒上就黑屏。后来才明白,不是编码有问题,是容器没选对。今天我们就来拆解几个最主流的封装格式:MP4、FLV、TS、fMP4/CMAF 和 WebM。
核心观点:封装格式决定了你的流媒体系统能支持多低的延迟、多广的兼容性。选错了,后面全白搭。
MP4 格式详解:ftyp、moov、mdat
MP4 是基于 ISO Base Media File Format(ISOBMFF)的容器。说白了,它由一系列 Box(也叫 Atom)组成。每个 Box 有类型、长度和数据。最核心的三个 Box 是:ftyp、moov 和 mdat。
- ftyp(File Type Box):文件类型标识。告诉播放器“我是 MP4,兼容哪个版本”。
- moov(Movie Box):元数据。包含时长、分辨率、编码参数、关键帧索引等。没有它,播放器不知道怎么看。
- mdat(Media Data Box):真正的音视频数据。裸流就塞在这里。
我的经验:早期做点播系统时,我发现 MP4 文件如果 moov 在末尾,用户必须等整个文件下载完才能播放。后来我把 moov 挪到文件头部(使用 qt-faststart 工具),首屏加载时间从 8 秒降到了 1.5 秒。这个优化,成本几乎为零,效果立竿见影。
MP4 的典型结构如下:
ftyp box → moov box → mdat box
(moov 前置时)
但默认编码器生成的 MP4,moov 往往在 mdat 之后。你需要后处理把它挪到前面。我建议在服务端上传完成后自动执行这个操作。
FLV 格式详解
FLV 是 Adobe 的格式,当年 Flash 时代的老将。现在它主要活在 RTMP 推流场景里。结构很简单:文件头 + 一系列 Tag。
每个 Tag 包含:
- Tag 类型(音频、视频、脚本)
- 数据大小
- 时间戳
- 数据体
FLV 最大的优点是结构极简,解析开销小。RTMP 推流时,数据直接封装成 FLV Tag 发送,延迟可以做到 1 秒以内。
注意:FLV 不支持 H.265 和 AAC 的某些高级特性。如果你要用 HEVC 推流,FLV 不是好选择。我曾经在一个项目中硬塞 H.265 进 FLV,结果播放器各种花屏。后来换了 fMP4 才搞定。
TS 格式详解
TS(Transport Stream)是 MPEG-2 标准的一部分,最初为数字电视设计。它的核心特点是固定长度包——每个包 188 字节。这个设计是为了在容易丢包的信道上传输,比如卫星、有线电视。
TS 的结构:
TS 包(188 字节):
- 同步头(0x47)
- PID(包标识)
- 载荷(PES 包或 PSI/SI 信息)
每个 TS 包可以携带视频、音频或元数据。播放器通过 PID 区分。HLS 最初就是基于 TS 分片的,每个 .ts 文件包含几秒的数据。
TS 的缺点也很明显:冗余大。188 字节里有一部分是包头,而且为了抗丢包,经常要重复发送 PAT/PMT 表。带宽利用率不高。
什么时候用 TS?如果你的目标平台是老旧机顶盒、IPTV 系统,或者你需要极致的抗丢包能力,TS 仍然是可靠选择。但做互联网直播,我建议优先考虑 fMP4。
fMP4 与 CMAF 标准
fMP4(Fragmented MP4)是 MP4 的进化版。传统 MP4 的 moov 在文件头,mdat 在后面。fMP4 把数据切成多个片段(Segment),每个片段有自己的 moof(Movie Fragment Box)和 mdat。
结构示意:
ftyp | moov | moof+mdat | moof+mdat | moof+mdat | ...
这样做的好处是:
- 支持流式播放:不需要等整个文件下载完。
- 支持分片索引:配合 MPEG-DASH 或 HLS,可以动态切换码率。
- 低延迟:每个片段可以很短(比如 1 秒),播放器收到一个片段就能播。
CMAF(Common Media Application Format) 是苹果和微软联合推动的标准。它统一了 HLS 和 DASH 的底层格式——都用 fMP4。也就是说,你只需要存一份 fMP4 文件,同时生成 .m3u8 和 .mpd 索引,就能同时服务 HLS 和 DASH 客户端。
我建议:新项目直接上 CMAF。我在去年重构直播系统时,从 TS 切到 CMAF,存储成本降了 30%,CDN 回源率也明显下降。而且延迟从 6 秒降到了 2 秒以内。这笔账怎么算都划算。
WebM 格式
WebM 是 Google 推的开源容器,基于 Matroska(MKV)的子集。它只支持 VP8/VP9 视频和 Opus/Vorbis 音频。结构上也是 EBML 元素嵌套,类似 Box 但更灵活。
WebM 的核心优势:
- 完全开源:没有专利授权问题。
- 浏览器原生支持:Chrome、Firefox、Edge 都直接支持
<video>标签播放。 - WebRTC 标配:WebRTC 的默认编码 VP8/VP9 就用 WebM 封装。
但 WebM 也有短板:硬件解码支持不如 H.264 广泛。老款手机、电视盒子可能不支持 VP9 硬解,播放时 CPU 飙升、发热严重。
避坑:我曾经在一个 OTT 项目里全量用 WebM,结果用户反馈播放卡顿。排查后发现,超过 40% 的设备不支持 VP9 硬解。后来我加了 H.264 降级方案才解决。所以,WebM 适合你能控制客户端环境的场景,比如内部系统或 WebRTC 通话。
格式对比一览
| 格式 | 适用场景 | 延迟 | 兼容性 | 带宽效率 |
|---|---|---|---|---|
| MP4 | 点播、文件分发 | 高(需完整下载) | 极高 | 高 |
| FLV | RTMP 推流、低延迟直播 | 低(1-3 秒) | 中(Flash 生态) | 中 |
| TS | HLS 传统方案、IPTV | 中(4-8 秒) | 高(老旧设备) | 低(包头冗余) |
| fMP4/CMAF | 低延迟 HLS/DASH、统一分发 | 低(1-3 秒) | 高(现代设备) | 高 |
| WebM | WebRTC、开源生态 | 低 | 中(硬解支持有限) | 高 |