2022容器格式全面指南
at 2年前 ca 音视频 pv 414 by touch
作者:Armin Trattnig
翻译:Alex
技术审校:赵志立
特别说明:This article was originally published by our friends/colleagues at Bitmovin on June 14, 2022. A copy of the original article can be found here:
https://bitmovin.com/container-formats-fun-1/
本文是一篇介绍 2022 年容器格式的全面指南,由 Bitmovin 公司中一些世界级的视频工程师和专家创作。
我们创作这篇指南的目的是希望你能全面了解关于容器格式的所有知识:从最基本的技术术语到深入探究不同的容器格式。
你可以从头开始阅读本篇文章,也可以跳到自己感兴趣的章节阅读。
让我们开始吧!
在正式开始之前,让我们先来了解一些技术术语。
编解码器(Codec)用于存储二进制格式的媒体信号,大部分编解码器都会以一种有损的方式压缩原始媒体信号。
最常见的媒体信号有视频、音频和字幕。电影包括不同的媒体信号,大部分电影除了视频外,还有音频和字幕。
常见的视频编解码器有:H.264、HEVC、VP9 和 AV1。音频编解码器有:AAC、MP3 和 Opus。
每种媒体信号都可以使用多种不同的编解码器。
编解码器类型
单一媒体信号通常被称为 ES 流(Elementary Stream)或者数据流。通常人们会用编解码器、媒体或者 H.264 流表示视频流。
01
什么是媒体容器?
容器格式 = 描述多媒体数据流和元数据如何在文件中共存的元文件格式规范。
容器格式提供如下功能:
数据流封装(Stream Encapsulation)
单一文件可以包含一个或者多个媒体数据流。
定时 / 同步(Timing/Synchronization)
容器添加如何在一个文件中使用不同数据流的数据。比如,将视频流中的唇动与音频流中的语音同步的正确时间戳。
跳转播放(Seeking)
容器提供电影跳转到某个时间点的信息。比如,当观众想观看一部分电影内容(而非整部电影)时。
元数据(Metadata)
元数据有很多种。使用容器格式可以将它们添加到电影中。比如,音频流所使用的语言(中文、英文等)。
有时字幕也被认为是元数据。
常见的容器格式包括 MP4、MPEG2-TS 和 MKV(Matroska),可以承载不同的视频和音频编解码器。每种容器格式都有其优点和缺点。这些属性与兼容性、传输和数据冗余有关。
02
容器格式技术术语
编码(Encoding)
将原始媒体信号转换为编解码器的二进制文件的过程被称为编码。比如,使用视频编码器 H.264 将一系列原始图像进行编码。编码也指将非常高质量的原始视频文件转换为更容易分享和传输的中间格式的过程:以未压缩的 RGB 16 位帧为例,它每帧大小为 12.5MB,持续时间为 60 秒(按照每秒 24 帧计算),合计为 17.9GB。现在将它压缩为 3.11MB 每帧的 8 位帧,帧率为 24fps 的 60 秒相同视频,只需 2.9GB。经过高效压缩后,视频文件大小整整少了 15GB!
解码(Decoding)
解码对应上文提到的编码。解码是将二进制文件转换回媒体信号的过程。比如:H.264 编码器将数据流转换为可观看的图像。
转码(Transcoding)
是指将一个编码格式转换为另一个(或者相同)编码格式的过程。编码和解码是实现成功转码的必要过程。其最佳描述为:将源编码格式的数据流解码,然后编码为新的目标编码格式数据流。虽然编码通常是有损的,但插帧和上采样等技术可提升转码视频的质量。
封装(Muxing)[1]
是指将一个或多个编解码器数据流添加到一个容器格式的过程。
[1] 审校者注:实际上 Muxing 是 Multiplexing 的简写,Demuxing 是 Demultiplexing 的简写,一般没有区别;但是看这里的描述有意做了细微的区分,封装 / 解封装 vs 复用 / 解复用算是符合作者表达的含义,前者强调装进去和提取出来,后者强调以何种方式混合和分离音视频。
解封装(Demuxing)
从容器格式中提取编解码器数据流。
转封装(Transmuxing)
从一个容器格式中提取数据流,然后将它们放入不同的(或者相同)容器格式中。
多路复用(Multiplexing)
是指将音频和视频混合为一个数据流的过程。比如,来自编码器的 ES 流被转换为 PES 流(Packetized Elementary Stream),再被转换为 TS 流(Transport Stream)。
解复用(Demultiplexing)
多路复用的反向操作。意味着从媒体容器中提取 ES 流。比如,从 MP4 音乐视频中提取 MP3 音频数据。
带内事件(In-Band Events)
是指与具体时间戳相关的元数据事件。通常意味着这些事件与视频和音频流同步。比如,这些事件能够用来触发动态内容替换(广告插入)或者补充内容呈现。
03
OTT 媒体传输中的容器格式
几乎只要有数字媒体存在的地方,就会有容器。比如,如果你使用智能手机录制视频,采集到音频和视频就会被存储在一个容器文件中(如 MP4 文件)。
容器格式的另一个实际应用场景是网络流媒体传输领域。端到端处理媒体数据的实体就是容器。
在内容生产端,打包器会将多路编码的媒体数据打包到容器中,然后在客户端设备的请求下通过网络进行传输。
然后容器被解复用,其中的内容被解码并最终呈现给终端用户。
在线媒体分发工作流程
04
播放器对容器格式的处理
提取元数据
在客户端,播放器需要从容器中提取基础的媒体信息。比如,切片播放时间、时长信息和编码格式等。
除此之外,大部分浏览器通常不会直接提取和处理容器中的元数据。
这就要求播放器实现能够妥善处理元数据。
比如 CEA-608/708 字幕、带内事件(fMP4 的 emsg box)等,播放器需要分析媒体容器格式中的相关数据,跟踪时间线并在正确的时间点进一步处理数据(比如在正确时间显示正确字幕)。
fMP4 切片的 EMSG box
客户端转封装
浏览器通常缺乏对于特定容器格式的支持。一个常见例子是,Chrome、Firefox、Edge 和 IE 没有(完整)支持 MPEG-TS 容器格式,从而引发了各种问题。
MPEG-TS 格式是专为 DVB(数字视频广播,Digital Video Broadcasting)应用设计的。
由于 MPEG-TS 现在依然是常用格式,所以唯一的解决方法便是将媒体从 MPEG-TS 转换为这些浏览器支持的容器格式(如 fMP4)。
转封装环节可以在端侧完成,在将内容发送给浏览器媒体栈进行解复用和解码之前执行。
基本上,该步骤包括多路分解 MPEG-TS,然后再一次将 ES 流多路复用到 fMP4。
这个过程通常被称为 Transmuxing,即转封装。
05
MP4 容器格式
标准概览
MPEG-4 Part 14(MP4)是最常用的容器格式,通常以.mp4 作为文件后缀名。它可以用于 DASH,也可以用于 Apple 的 HLS。
MP4 基于 ISO 基础媒体文件格式(MPEG-4 Part 12),该格式以 QuickTime 文件格式为基础。
MPEG 表示 Moving Pictures Experts Group(动态图像专家工作组),由 ISO(国际标准化组织)和 IEC(国际电工委员会)共同成立。MPEG 的目的是为音频、视频压缩和传输设立标准。MPEG-4 明确规定了音视频对象编码。
MP4 支持多种编码格式。H.264 和 HEVC 是最常用的视频编解码器。AAC 是最常用的音频编解码器,它是大名鼎鼎的 MP3 的继任者。
ISO 基础媒体文件格式(ISO Base Media File Format)
ISO 文件格式(ISOBMFF, MPEG-4 Part 12)是 MP4 容器格式的基础。ISOBMFF 标准定义了基于时间的多媒体文件 —— 通常指音频和视频,并以稳定的数据流传输。ISO 既灵活,又易于扩展。它支持多媒体数据的互操作性、管理、编辑和呈现。
构成 ISOBMFF 的基本单元是 box,也被成为 atom。该标准通过使用类和面向对象方法定义了 box。所有 box 继承自基类 Box,并通过扩展添加新的类属性以实现特定功能。
基类:
示例 FileTypeBox:
FileTypeBox 被用来识别 ISOBMFF 文件的目的和用途,通常位于文件的开头。
box 也可以有子 box,并形成 box 树。比如,MovieBox(moov)就有多个 TrackBox(trak)。ISOBMFF 中的 track 就是单一媒体流。如 MovieBox 可以包含一个视频 track box 和一个音频 track box。
二进制编码数据可以被存储于 mdat(Media Data Box)中。Track 对二进制编码数据做引用 / 索引。
Fragmented MP4 (fMP4)
使用 MP4,也可以将一部电影分割成多个片段(fragment)。MP4 在此处发挥了优势:通过 DASH 或者 HLS,播放器软件只需下载观众想要观看的视频片段。
fMP4(fragmented MP4)文件包含普通的 MovieBox 和 TrackBox,用以表示哪些媒体流可用。Movie Extends Box (mvex) 用于指示后面跟随着 MP4 片段。
另一个优势是,这些片段可以被存储在不同的文件中。片段中包含与 Movie Box(moov)非常相似的 Movie Fragment Box(moof)。moof 用于描述片段中的媒体信息。比如,一个 10 秒的视频片段,moof 存储了这 10 秒片段的时间戳信息。每个片段都有自己的 mdat。
调试 (f) MP4 文件
为了发现具体 box 的 bug 和其他不必要的配置,很有必要查看 (f) MP4 文件的 box(atom)。
查看媒体文件内容的最佳工具包括:
MediaInfo (https://mediaarea.net/en/MediaInfo/Download)
ffprobe(ffmpeg 工具集的一部分)(https://ffbinaries.com/downloads)
这些工具并不会向你展示 (f) MP4 文件的 box 结构 [2]。你可以使用下面这些工具进行展示:
[2] 审校者注:此处为原文技术疏漏,mediainfo 可以展示 box 结构,例如,命令行执行 mediainfo 可通过添加 --Details=1 参数来实现。
Boxdumper (https://github.com/l-smash/l-smash)
IsoViewer (https://github.com/sannies/isoviewer)
MP4Box.js (http://download.tsi.telecom-paristech.fr/gpac/mp4box.js/filereader.html)
Mp4dump (https://www.bento4.com/)
Isoviewer 的截图
06
CMAF 容器格式
MPEG-CMAF
因为某些平台仅支持特定容器格式,所以作为内容发行商为每个平台提供服务无疑困难重重。
想要发行特定内容,需要生成和提供不同的容器格式(即 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)。
Chunked CMAF
MPEG-CMAF 的一个有趣特点是:它可以将视频切片编码为 CMAF chunk。将内容如此编码后,再使用 HTTP 中的分块传输编码(HTTP chunked transfer encoding)传输媒体文件,这样就可以降低实时流媒体场景中的延迟。
在传统的 fMP4 中,整个视频切片必须完全下载之后才能播放。使用分块编码,任何完整下载的视频切片的分块(chunk)都可以解码和播放,即使切片的其他部分还在下载。因此,能够实现的直播低延迟不受切片时长限制,因为不完整切片的分块也可以被客户端加载和播放。
07
MPEG-TS 容器格式
MPEG-TS(MPEG Transport Stream)在 MPEG-2 Part 1 中被标准化,并专门用于 DVB(数字视频广播,Digital Video Broadcasting)应用场景。与其对应的 MPEG Program Stream(目的在于存储媒体以及在 DVD 等应用中的使用)相比,MPEG-TS 更倾向于是一种面向传输的格式。
MPEG-TS 由小的数据包构成,这应该是一种降低视频损坏和丢失影响的措施。除此之外,该格式使用了 FEC(前向纠错,Forward Error Correction)技术,允许在接收端更正传输错误。很明显,MPEG-TS 是为在有损传输通道使用而设计的。
封装:ES → PES → TS
来自编码器的 ES 流先被打包成 PES,添加的 PES 头包含数据流标识符、PES 包长度、媒体时间戳等信息。接下来,PES 被分成 184 字节的 chunk,然后通过为每个 chunk 添加一个 4 字节的标头,将其转换为 TS。生成的 TS 由固定长度为 188 字节的数据包组成。(同一条流的)每个 TS 数据包标头都带有相同的 PID(数据包标识符,Packet Identifier),这样就将数据包与其 ES 流相关联。
封装多个 ES 流
一条 ES 流既可以表示音频内容,也可以表示视频内容。拿视频 ES 流来说,我们通常还会有至少一路音频 ES 流。这些相关的 ES 会被封装进同一个 TS 流,其中不同的 ES 及其数据包有单独的 PID。
封装多个节目
MPEG-TS 具有节目(Program)的概念。节目是集合在一起的一组相关 ES 流,如视频和相对应的音频。单一 TS 流可以传输多个节目,且每个节目都是一个不同的电视频道。
节目关联
从底层的角度来看,TS 流只是一个 188 字节长的 TS 数据包序列。正如前文所提到的,可以有许多节目,每个节目都有多个 ES 流,但客户端每次只能观看一个节目。因为客户端必须知道在接收到传输流时,哪些数据包被使用,哪些被舍弃。为此,有两种特殊数据包:
节目关联表(PAT,Program Association Table)
PAT 数据包拥有特殊 PID 0,包内含有 TS 流中所有节目的节目映射表(PMT)的 PID 信息。
节目映射表(PMT,Program Map Table)
PMT 代表单一节目,并包含节目所有 ES 流的 PID。
查看 PID 为 0 的 TS 数据包,内部包含 PAT 信息。
在 PAT 中找到播放器应播放节目的 PMT-PID(此处为 200)。
使用相关 PMT-PID(其中包含 PMT,此处为 PID 200)获取 TS 数据包。
PMT 包含所有媒体轨道的 PID,它们是播放节目的一部分。
接收 TS 流的客户端首先会读取接收到的第一个 PAT 数据包,然后根据用户选择确定呈现的节目。
客户端会从 PAT 中获得所选节目 PMT(其提供了节目 ES 流和它们的 PID)。现在客户端只需过滤这些 PID(每个 PID 代表所选节目的一个单独 ES)并使用它们 —— 即解复用、解码然后呈现给用户。
OTT 具体方面和总结
上文的介绍主要面向广电领域。然而,OTT 领域需要另做考虑。OTT 客户端的网络连接不稳定,网络带宽只够按需加载用户要观看的内容(而不能加载全部节目)。
鉴于客户端只能一次呈现一个节目,而同一 TS 流中有多个节目,将它们全部加载将会浪费带宽,而这些带宽可以获得更好地利用,比如质量自适应。
所以对于 OTT,我们不会在一个 TS 流中包含多个节目。出于类似的考虑,对于多路音频内容的封装,各路音频应封装到各自的 TS 流中(而不是多路音频 ES 流封装到一路 TS 流)。
MPEG-TS 依然广泛用于 OTT,尤其是面向 Apple 生态系统时。
MPEG-TS 的一个缺陷是:与 fMP4 相比,它的封装冗余度更高(由于数据包较小和所有的数据包标头)。https://www.slideshare.net/bitmovin/bitmovin-segmentlength-50056628/11
MPEG-TS 是面向传输的格式,它考虑了对有损传输场景的处理,不适合与基于 HTTP 的媒体分发方式相结合,因为 HTTP 已经在网络栈上保证了传输可靠性。
调试和检查 MPEG-TS
http://www.digitalekabeltelevisie.nl/dvb_inspector/(GUI,开源)
http://thumb.co.il/(GUI/Web, 开源)
http://dvbsnoop.sourceforge.net/(CLI, 开源)
https://github.com/tsduck/tsduck(CLI, 开源)
08
Matroska(Webm)容器格式
Matroska 是一种自由和开放标准的容器格式,基于 EBML(可扩展二进制元语言,Extensible Binary Meta Language,基本上是 XML 的二进制形式)。得益于此,标准很容易进行扩展。它几乎可以支持任何编解格式。
WebM
WebM 是基于 Matroska 的容器格式。谷歌主导了其中的开发工作,使它成为替代 MP4 和 MPEG2-TS 的开源方案。同时,WebM 也支持谷歌的开源编解码器:如视频编解码器 VP8 和 VP9,以及音频编解码器 Opus 和 Vorbis。WebM 也可以与 DASH 一起使用 —— 在 Web 上传输 VP9 和 Opus。
调试 Matroska/Webm
mkvinfo 是调试和查看 Matroska 或者 WebM 文件内容的最佳工具:
https://mkvtoolnix.download/
非常感谢大家阅读本篇文章,想要了解有关容器格式和处理的更多信息,请加入我们的每月 Demo 和技术问答:
https://go.bitmovin.com/bitmovin-techtalk
09
容器格式资源
Video Player Datasheet:https://bitmovin.com/video-player-datasheet/
Video Encoding Datasheet:https://bitmovin.com/video-encoding-data-sheet/
Video Analytics Datasheet:https://bitmovin.com/bitmovin-analytics-datasheet/
AV1 Datasheet: https://bitmovin.com/av1-datasheet/
致谢:
本文已获得作者 Armin Trattnig 授权翻译和发布,特此感谢。
原文链接:
https://bitmovin.com/container-formats-fun-1/
版权声明
本文仅代表作者观点,不代表码农殇立场。
本文系作者授权码农殇发表,未经许可,不得转载。