2022容器格式全面指南

本文是一篇介绍 2022 年容器格式的全面指南,由 Bitmovin 公司中一些世界级的视频工程师和专家创作。

我们创作这篇指南的目的是希望你能全面了解关于容器格式的所有知识:从最基本的技术术语到深入探究不同的容器格式。

编解码器(Codec)用于存储二进制格式的媒体信号,大部分编解码器都会以一种有损的方式压缩原始媒体信号。

最常见的媒体信号有视频、音频和字幕。电影包括不同的媒体信号,大部分电影除了视频外,还有音频和字幕。

单一媒体信号通常被称为 ES 流(Elementary Stream)或者数据流。通常人们会用编解码器、媒体或者 H.264 流表示视频流。

容器格式 = 描述多媒体数据流和元数据如何在文件存的元文件格式规范。

容器添加如何在一个文件中使用不同数据流的数据。比如,将视频流中的唇动与音频流中的语音同步的正确时间戳。

容器提供电影跳转到某个时间点的信息。比如,当观众想观看一部分电影内容(而非整部电影)时。

元数据有很多种。使用容器格式可以将它们添加到电影中。比如,音频流所使用的语言(中文、英文等)。

常见的容器格式包括 MP4、MPEG2-TS 和 MKV(Matroska),可以承载不同的视频和音频编解码器。每种容器格式都有其优点和缺点。这些属性与兼容性、传输和数据冗余有关。

将原始媒体信号转换为编解码器的二进制文件的过程被称为编码。比如,使用视频编码器 H.264 将一系列原始图像进行编码。编码也指将非常高质量的原始视频文件转换为更容易分享和传输的中间格式的过程:以未压缩的 RGB 16 位帧为例,它每帧大小为 12.5MB,持续时间为 60 秒(按照每秒 24 帧计算),合计为 17.9GB。现在将它压缩为 3.11MB 每帧的 8 位帧,帧率为 24fps 的 60 秒相同视频,只需 2.9GB。经过高效压缩后,视频文件大小整整少了 15GB!

解码对应上文提到的编码。解码是将二进制文件转换回媒体信号的过程。比如:H.264 编码器将数据流转换为可观看的图像。

是指将一个编码格式转换为另一个(或者相同)编码格式的过程。编码和解码是实现成功转码的必要过程。其最佳描述为:将源编码格式的数据流解码,然后编码为新的目标编码格式数据流。虽然编码通常是有损的,但插帧和上采样等技术可提升转码视频的质量。

[1] 审校者注:实际上 Muxing 是 Multiplexing 的简写,Demuxing 是 Demultiplexing 的简写,一般没有区别;但是看这里的描述有意做了细微的区分,封装 / 解封装 vs 复用 / 解复用算是符合作者表达的含义,前者强调装进去和提取出来,后者强调以何种方式混合和分离音视频。

从一个容器格式中提取数据流,然后将它们放入不同的(或者相同)容器格式中。

多路复用的反向操作。意味着从媒体容器中提取 ES 流。比如,从 MP4 音乐视频中提取 MP3 音频数据。

是指与具体时间戳相关的元数据事件。通常意味着这些事件与视频和音频流同步。比如,这些事件能够用来触发动态内容替换(广告插入)或者补充内容呈现。

几乎只要有数字媒体存在的地方,就会有容器。比如,如果你使用智能手机录制视频,采集到音频和视频就会被存储在一个容器文件中(如 MP4 文件)。

容器格式的另一个实际应用场景是网络流媒体传输领域。端到端处理媒体数据的实体就是容器。

在内容生产端,打包器会将多路编码的媒体数据打包到容器中,然后在客户端设备的请求下通过网络进行传输。

在客户端,播放器需要从容器中提取基础的媒体信息。比如,切片播放时间、时长信息和编码格式等。

比如 CEA-608/708 字幕、带内事件(fMP4 的 emsg box)等,播放器需要分析媒体容器格式中的相关数据,跟踪时间线并在正确的时间点进一步处理数据(比如在正确时间显示正确字幕)。

浏览器通常缺乏对于特定容器格式的支持。一个常见例子是,Chrome、Firefox、Edge 和 IE 没有(完整)支持 MPEG-TS 容器格式,从而引发了各种问题。

由于 MPEG-TS 现在依然是常用格式,所以唯一的解决方法便是将媒体从 MPEG-TS 转换为这些浏览器支持的容器格式(如 fMP4)。

转封装环节可以在端侧完成,在将内容发送给浏览器媒体栈进行解复用和解码之前执行。

基本上,该步骤包括多路分解 MPEG-TS,然后再一次将 ES 流多路复用到 fMP4。

MPEG 表示 Moving Pictures Experts Group(动态图像专家工作组),由 ISO(国际标准化组织)和 IEC(国际电工委员会)共同成立。MPEG 的目的是为音频、视频压缩和传输设立标准。MPEG-4 明确规定了音视频对象编码。

MP4 支持多种编码格式。H.264 和 HEVC 是最常用的视频编解码器。AAC 是最常用的音频编解码器,它是大名鼎鼎的 MP3 的继任者。

ISO 文件格式(ISOBMFF, MPEG-4 Part 12)是 MP4 容器格式的基础。ISOBMFF 标准定义了基于时间的多媒体文件 —— 通常指音频和视频,并以稳定的数据流传输。ISO 既灵活,又易于扩展。它支持多媒体数据的互操作性、管理、编辑和呈现。

构成 ISOBMFF 的基本单元是 box,也被成为 atom。该标准通过使用类和面向对象方法定义了 box。所有 box 继承自基类 Box,并通过扩展添加新的类属性以实现特定功能。

FileTypeBox 被用来识别 ISOBMFF 文件的目的和用途,通常位于文件的开头。

二进制编码数据可以被存储于 mdat(Media Data Box)中。Track 对二进制编码数据做引用 / 索引。

使用 MP4,也可以将一部电影分割成多个片段(fragment)。MP4 在此处发挥了优势:通过 DASH 或者 HLS,播放器软件只需下载观众想要观看的视频片段。

另一个优势是,这些片段可以被存储在不同的文件中。片段中包含与 Movie Box(moov)非常相似的 Movie Fragment Box(moof)。moof 用于描述片段中的媒体信息。比如,一个 10 秒的视频片段,moof 存储了这 10 秒片段的时间戳信息。每个片段都有自己的 mdat。

为了发现具体 box 的 bug 和其他不必要的配置,很有必要查看 (f) MP4 文件的 box(atom)。

这些工具并不会向你展示 (f) MP4 文件的 box 结构 [2]。你可以使用下面这些工具进行展示:

因为某些平台仅支持特定容器格式,所以作为内容发行商为每个平台提供服务无疑困难重重。

想要发行特定内容,需要生成和提供不同的容器格式(即 MPEG-TS 和 fMP4)。很明显,这会增加基础设施中内容生产的成本,以及托管相同内容的多个副本的存储成本。最重要的是,它还会降低 CDN 缓存效率。MPEG-CMAF 的目的就是解决上述问题:不是通过创建另外的容器格式,而是融合进一个已经存在的、用于 OTT 媒体传输的容器格式。CMAF 与 fMP4 紧密相关,这使得从 fMP4 到 CMAF 的过渡非常容易。除此之外,随着 Apple 支持 CMAF,将内容封装为 MPEG-TS 并提供给 Apple 设备这一方式很有可能会成为过去式,而 CMAF 将无处不在。

使用 MPEG-CMAF,DRM 解决方案在互操作性方面也会得到改进 [通过使用 MPEG-CENC(通用加密,Common Encryption)]。理论上,它可以对内容进行一次加密,然后仍然可用于其他所有先进的 DRM 系统。不过,遗憾的是,目前还没有标准化的加密方案,而且还存在竞争对手,比如 Widevine 和 PlayReady。这些 DRM 彼此并不兼容,但是整个 DRM 行业正在慢慢趋向于使用一种格式 —— 通用加密格式(Common Encryption format)。

MPEG-CMAF 的一个有趣特点是:它可以将视频切片编码为 CMAF chunk。将内容如此编码后,再使用 HTTP 中的分块传输编码(HTTP chunked transfer encoding)传输媒体文件,这样就可以降低实时流媒体场景中的延迟。

在传统的 fMP4 中,整个视频切片必须完全下载之后才能播放。使用分块编码,任何完整下载的视频切片的分块(chunk)都可以解码和播放,即使切片的其他部分还在下载。因此,能够实现的直播低延迟不受切片时长限制,因为不完整切片的分块也可以被客户端加载和播放。

MPEG-TS 由小的数据包构成,这应该是一种降低视频损坏和丢失影响的措施。除此之外,该格式使用了 FEC(前向纠错,Forward Error Correction)技术,允许在接收端更正传输错误。很明显,MPEG-TS 是为在有损传输通道使用而设计的。

来自编码器的 ES 流先被打包成 PES,添加的 PES 头包含数据流标识符、PES 包长度、媒体时间戳等信息。接下来,PES 被分成 184 字节的 chunk,然后通过为每个 chunk 添加一个 4 字节的标头,将其转换为 TS。生成的 TS 由固定长度为 188 字节的数据包组成。(同一条流的)每个 TS 数据包标头都带有相同的 PID(数据包标识符,Packet Identifier),这样就将数据包与其 ES 流相关联。

一条 ES 流既可以表示音频内容,也可以表示视频内容。拿视频 ES 流来说,我们通常还会有至少一路音频 ES 流。这些相关的 ES 会被封装进同一个 TS 流,其中不同的 ES 及其数据包有单独的 PID。

MPEG-TS 具有节目(Program)的概念。节目是集合在一起的一组相关 ES 流,如视频和相对应的音频。单一 TS 流可以传输多个节目,且每个节目都是一个不同的电视频道。

从底层的角度来看,TS 流只是一个 188 字节长的 TS 数据包序列。正如前文所提到的,可以有许多节目,每个节目都有多个 ES 流,但客户端每次只能观看一个节目。因为客户端必须知道在接收到传输流时,哪些数据包被使用,哪些被舍弃。为此,有两种特殊数据包:

PAT 数据包拥有特殊 PID 0,包内含有 TS 流中所有节目的节目映射表(PMT)的 PID 信息。

在 PAT 中找到播放器应播放节目的 PMT-PID(此处为 200)。

接收 TS 流的客户端首先会读取接收到的第一个 PAT 数据包,然后根据用户选择确定呈现的节目。

客户端会从 PAT 中获得所选节目 PMT(其提供了节目 ES 流和它们的 PID)。现在客户端只需过滤这些 PID(每个 PID 代表所选节目的一个单独 ES)并使用它们 —— 即解复用、解码然后呈现给用户。

上文的介绍主要面向广电领域。然而,OTT 领域需要另做考虑。OTT 客户端的网络连接不稳定,网络带宽只够按需加载用户要观看的内容(而不能加载全部节目)。

鉴于客户端只能一次呈现一个节目,而同一 TS 流中有多个节目,将它们全部加载将会浪费带宽,而这些带宽可以获得更好地利用,比如质量自适应。

所以对于 OTT,我们不会在一个 TS 流中包含多个节目。出于类似的考虑,对于多路音频内容的封装,各路音频应封装到各自的 TS 流中(而不是多路音频 ES 流封装到一路 TS 流)。

MPEG-TS 的一个缺陷是:与 fMP4 相比,它的封装冗余度更高(由于数据包较小和所有的数据包标头)。

MPEG-TS 是面向传输的格式,它考虑了对有损传输场景的处理,不适合与基于 HTTP 的媒体分发方式相结合,因为 HTTP 已经在网络栈上保证了传输可靠性。

Matroska 是一种自由和开放标准的容器格式,基于 EBML(可扩展二进制元语言,Extensible Binary Meta Language,基本上是 XML 的二进制形式)。得益于此,标准很容易进行扩展。它几乎可以支持任何编解格式。

WebM 是基于 Matroska 的容器格式。谷歌主导了其中的开发工作,使它成为替代 MP4 和 MPEG2-TS 的开源方案。同时,WebM 也支持谷歌的开源编解码器:如视频编解码器 VP8 和 VP9,以及音频编解码器 Opus 和 Vorbis。WebM 也可以与 DASH 一起使用 —— 在 Web 上传输 VP9 和 Opus。

非常感谢大家阅读本篇文章,想要了解有关容器格式和处理的更多信息,请加入我们的每月 Demo 和技术问答:

本文已获得作者 Armin Trattnig 授权翻译和发布,特此感谢。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注