1、封装格式基础:什么是封装格式、常见封装格式对比(MP4/TS/MKV/FLV)、封装与编码的关系

1.1 封装格式到底是什么?

先问个问题:你拿到一个 .mp4 文件,把它重命名为 .mkv,它还能正常播放吗?

大概率不能。为什么?因为封装格式不是简单的文件后缀,它是一套严格的容器规范。

我个人习惯把封装格式比作「快递箱」。视频编码(H.264、HEVC)是箱子里的货物,音频编码(AAC、MP3)是另一件货物,字幕、时间戳、章节信息是填充物和标签。封装格式就是那个箱子——它规定了货物怎么摆放、标签贴在哪、怎么保证运输途中不散架。

说白了,封装格式解决的是「如何把视频、音频、字幕、元数据打包成一个文件,并且让播放器能准确拆开」的问题。

核心定义:封装格式(Container Format)是一种文件结构规范,定义了如何将编码后的视频流、音频流、字幕流以及元数据(如时长、分辨率、语言)组织在一个文件中,并提供同步播放所需的索引和时间戳信息。

我在项目中遇到过不少新手,以为「封装就是编码」。其实差远了。编码决定画质和码率,封装决定兼容性和功能。你编码出再好的 H.265 视频,塞进一个过时的封装里,播放器不认识,照样白搭。

1.2 封装与编码的关系

这里必须理清一个关键概念:封装 ≠ 编码。

编码是压缩算法,把原始图像数据变成 H.264 或 HEVC 码流。封装是容器,把码流打包成文件。两者是独立的——同一个 H.264 视频流,可以放进 MP4,也可以放进 TS 或 MKV。

举个例子:

原始视频 → H.264 编码器 → 裸 H.264 码流(.h264)
裸 H.264 码流 + AAC 音频 → MP4 封装 → 最终文件(.mp4)
裸 H.264 码流 + AAC 音频 → TS 封装 → 最终文件(.ts)
裸 H.264 码流 + AAC 音频 → MKV 封装 → 最终文件(.mkv)

你看,编码器输出的是同一份码流,封装器不同,出来的文件格式就不同。这就是封装与编码的解耦关系。

经验之谈:转码流程中,解封装(Demux)和封装(Mux)是两个独立步骤。解封装是从容器里提取裸码流,封装是把裸码流重新打包。我经常看到有人把「转码」和「重新封装」搞混——转码会改变编码格式,重新封装只换容器,不碰码流。

1.3 常见封装格式对比

做流媒体这行,天天跟封装格式打交道。下面这四种是我工作中最常碰到的。

特性 MP4 TS MKV FLV
全称 MPEG-4 Part 14 MPEG Transport Stream Matroska Flash Video
诞生时间 2001 1995 2002 2003
流式支持 支持(需分段) 原生支持 不支持原生 支持
容错性 低(损坏难恢复) 高(可分段播放) 中(有恢复机制) 低
字幕支持 有限(需特定规范) 有限(DVB字幕) 强大(SRT/ASS/PGS) 不支持
多音轨 支持 支持 支持 不支持
元数据 有限 有限 丰富 极少
浏览器兼容 极好 差(需插件) 差 已淘汰
主要场景 点播、移动端 直播、广电 本地存储、高清 早期直播

MP4

MP4 是目前最通用的封装格式。几乎所有浏览器、手机、电视都支持。它的结构基于 ISO Base Media File Format(ISOBMFF),用 box 结构组织数据。

但 MP4 有个硬伤:它的 moov box(元数据)通常放在文件头部或尾部。如果放在尾部,必须下载完整个文件才能开始播放。这就是为什么有些 MP4 在网页上要等很久才出画面——moov box 在文件末尾,播放器得先下载整个文件才能读到索引。

避坑指南:我曾经在点播平台上线前发现,用户播放 MP4 视频要缓冲 10 秒才出画面。排查后发现是编码器把 moov box 放在了文件末尾。解决方案是用 qt-faststart 或 FFmpeg 的 -movflags faststart 参数把 moov box 挪到文件头部。这个操作叫「moov 前置」,做点播的同学一定要记住。

TS

TS 是广电和直播领域的「老兵」。它设计之初就是为了应对不稳定的传输环境——数据包固定 188 字节,每个包都有同步头,即使丢了一部分,后面的包还能正常解析。

我做过一个直播项目,用 HLS 协议分发视频。HLS 的切片格式就是 TS。为什么?因为 TS 支持边下载边播放,而且容错性好。网络抖动丢几个包,播放器不会崩,最多花屏一下。

TS 的缺点也很明显:文件体积大(固定包结构导致开销高),元数据支持弱,不适合做本地存储。

MKV

MKV 是「全能型选手」。它基于 EBML(Extensible Binary Meta Language),结构灵活,几乎什么都能装——H.264、HEVC、VP9、FLAC、DTS、ASS 字幕、章节信息……

我个人非常喜欢 MKV 的字幕支持。ASS 字幕的特效(滚动、渐变、卡拉OK)在 MKV 里可以完美保留。MP4 就不行,它只支持 timed text 这种简陋的字幕格式。

但 MKV 不适合流媒体。它的索引结构复杂,播放器需要先解析整个文件才能定位到指定时间点。而且浏览器原生不支持 MKV,得靠 MSE 或 WebAssembly 才能播放。

FLV

FLV 是 Flash 时代的产物。当年直播平台几乎清一色用 FLV + RTMP。结构简单,头部 + body + tag 三段式,解析起来非常快。

现在 FLV 基本被淘汰了。浏览器不再支持 Flash,直播也转向了 HLS 和 WebRTC。不过有些老系统还在用 FLV,我去年还帮一个客户迁移过 FLV 直播流到 HLS。

注意:FLV 不支持 HEVC 编码(虽然有民间扩展,但非标准)。如果你要处理 4K 或 HDR 视频,别碰 FLV。另外 FLV 没有字幕轨道,多语言场景直接 pass。

1.4 封装格式的核心结构

不管哪种封装格式,核心结构都包含以下几部分:

  • 文件头(Header):标识文件类型、版本号、文件大小等基本信息。
  • 索引(Index):记录每个关键帧的位置和时间戳,用于快进快退。
  • 媒体数据(Media Data):视频、音频、字幕的裸码流,按时间顺序交错存放。
  • 元数据(Metadata):时长、分辨率、码率、语言、创建时间等描述信息。
  • 同步信息(Sync Info):时间戳(PTS/DTS)、帧率、采样率等,保证音画同步。

下面这张图展示了封装格式的通用结构:

封装格式通用结构 文件头(Header)— 标识、版本、文件大小 元数据(Metadata)— 时长、分辨率、码率、语言 索引(Index)— 关键帧位置、时间戳映射 媒体数据(Media Data) 视频帧(H.264/HEVC) | 音频帧(AAC/MP3) | 字幕(SRT/ASS) 同步信息(Sync Info)— PTS/DTS 时间戳、帧率、采样率 不同封装格式对这五部分的组织方式不同,但核心逻辑一致

1.5 封装格式的选择策略

工作中怎么选封装格式?我一般按场景来:

  • 点播 + 浏览器:无脑选 MP4。兼容性最好,HLS 的 fMP4 也是基于 MP4 的。
  • 直播 + HLS:TS 或 fMP4。TS 是老牌选择,fMP4 是趋势(苹果从 iOS 10 开始支持)。
  • 本地存储 + 多字幕:MKV。尤其是做蓝光原盘或高清收藏,MKV 是首选。
  • 老系统兼容:FLV。但建议尽快迁移,别在新项目里用。

一句话总结:封装格式是视频文件的「骨架」,编码是「血肉」。骨架决定了文件怎么被解析和播放,血肉决定了画质和码率。做转码流程,先搞清楚你的目标场景需要什么骨架,再谈怎么优化血肉。