Azure 媒体服务分片 MP4 实时引入规范

本规范适用于 Azure 媒体服务,描述基于分片 MP4 的实时传送视频流引入的协议和格式。 媒体服务提供实时传送视频流服务,让客户使用 Azure 作为云平台来实时流式传输实时事件和广播内容。 此外,本文档还介绍了有关构建高度冗余和稳健的实时引入机制的最佳做法。

1.一致表示法

本文档中的关键字“必须”、“不得”、“需要”、“应”、“不应”、“应该”、“不应该”、“建议”、“可以”和“可选”均根据 RFC 2119 中所述予以解释。

2.服务关系图

下图显示媒体服务中实时传送视频流服务的高级体系结构:

  1. 实时编码器将实时源推送到通过 Azure 媒体服务 SDK 创建并设置的通道。
  2. 媒体服务中的通道、节目与流式处理终结点处理所有的实时传送视频流功能,包括引入、格式化、云 DVR、安全性、可伸缩性和冗余。
  3. 另外,客户也可以选择在流式处理终结点与客户端终结点之间部署 Azure 内容交付网络层。
  4. 客户端终结点使用 HTTP 自适应流式处理协议从流式处理终结点开始流式传输。 示例包括 Microsoft 平滑流式处理、通过 HTTP 的动态自适应流式处理(DASH 或 MPEG-DASH)和 Apple HTTP Live Streaming (HLS)。

引入流

3.位流格式 – ISO 14496-12 分片 MP4

本文档所述的实时传送视频流引入的有线格式基于 [ISO-14496-12]。 若要深入了解分片 MP4 格式以及点播视频文件和实时传送视频流引入的扩展,请参阅 [MS-SSTR]

实时引入格式定义

下表列出了适用于 Azure 媒体服务的实时引入的特殊格式定义:

  1. “ftyp”、“LiveServerManifestBox”及“moov”框必须连同每个请求 (HTTP POST) 一起发送。 这些框必须在流的开头发送,每当需要恢复流引入时,编码器都必须重新连接。 有关详细信息,请参阅 [1] 中的第 6 节。
  2. [1] 中的第 3.3.2 节定义了实时引入名为“StreamManifestBox”的可选框。 由于 Azure 负载均衡器的路由逻辑,此框已被弃用。 引入到媒体服务时不应出现此框。 如果存在此框,媒体服务会以无提示方式将其忽略。
  3. 每个片段必须有在 [1] 的 3.2.3.2 中定义的“TrackFragmentExtendedHeaderBox”框。
  4. 应使用第 2 版的“TrackFragmentExtendedHeaderBox”框,才能在多个数据中心生成具有相同 URL 的媒体片段。 对于跨数据中心故障转移基于索引的流格式(例如 Apple HLS 和基于索引的 MPEG DASH),片段索引字段是必需的。 若要启用跨数据中心故障转移,片段索引必须在多个编码器之间同步,并且后续的每个媒体片段都必须增加 1,即使跨编码器重启或失败。
  5. [1] 中的第 3.3.6 节定义了名为“MovieFragmentRandomAccessBox”(“mfra”)的框,此框可能会在实时引入结束时发送,表示通道流式传输结束 (EOS)。 媒体服务的引入逻辑使得 EOS 的使用方式已过时,不应发送实时引入的“mfra”框。 如果已发送,媒体服务会以无提示方式将其忽略。 若要重置引入点的状态,建议使用通道重置。 此外,建议使用程序停止来结束演播与流。
  6. MP4 片段持续时间应为常量,以减小客户端清单的大小。 常量 MP4 片段持续时间也可以通过使用重复标记来改进客户端下载启发。 持续时间可能会波动,以补偿非整数帧速率。
  7. MP4 片段持续时间应该大约为 2 到 6 秒之间。
  8. MP4 片段时间戳和索引(“TrackFragmentExtendedHeaderBox”、fragment_ absolute_ timefragment_index)应以递增顺序送达。 尽管媒体服务在复制片段方面很有弹性,但是其根据媒体时间线重新排序片段的功能非常有限。

4.协议格式 – HTTP

媒体服务基于 ISO 分片 MP4 的实时引入使用长时间运行的标准 HTTP POST 请求,以将分片 MP4 格式打包的编码媒体数据传输到服务。 每个 HTTP POST 发送一个完整的分片 MP4 位流(“流”),其开头为标头框(“ftyp”、“实时服务器清单框”及“moov”框),后接一系列片段(“moof”与“mdat”框)。 有关 HTTP POST 请求的 URL 语法,请参阅 [1] 中的第 9.2 节。 以下是 POST URL 的示例:

http://customer.channel.mediaservices.chinacloudapi.cn/ingest.isml/streams(720p)

要求

详细要求如下:

  1. 编码器应使用相同的引入 URL 来发送包含空白“正文”(内容长度为零)的 HTTP POST 请求,以此开始广播。 这可有助于编码器快速检测实时引入终结点是否有效,以及是否需要任何身份验证或其他条件。 服务器在收到整个请求(包括 POST 正文)之前,无法对每个 HTTP 协议传回 HTTP 响应。 由于实时事件具有长时间运行的性质,如果不执行此步骤,编码器在完成发送所有数据之前,可能无法检测任何错误。
  2. 编码器必须处理任何因为 (1) 而造成的错误或身份验证质询。 如果 (1) 成功并返回 200 响应,则继续进行。
  3. 编码器必须以分片 MP4 流开始新的 HTTP POST 请求。 有效负载必须以标头框开头后接片段。 请注意,由于上一个请求在流结束前终止,因此,即使编码器必须重新连接,“ftyp”、“实时服务器清单框”及“moov”框(依此顺序)仍必须连同每个请求一起发送。
  4. 因为无法预测实时事件的整个内容长度,编码器必须使用区块传输编码进行上传。
  5. 当事件结束时,在发送最后一个片段之后,编码器必须正常结束区块传输编码消息序列(大多数 HTTP 客户端堆栈会自动处理)。 编码器必须等候服务返回最终响应代码,然后终止连接。
  6. 如 [1] 中第 9.2 节所述,编码器不得使用 Events() 名词来实时引入媒体服务。
  7. 如果 HTTP POST 请求在流结束前终止或超时并出现一个 TCP 错误,则编码器必须使用新的连接来发出新的 POST 请求,并按照上述要求操作。 此外,编码器必须在流中为每个轨迹重新发送之前的两个 MP4 片段,并恢复流式传输,而不在媒体时间线上造成中断。 为每个轨迹重新发送最后两个 MP4 片段可确保不会丢失数据。 换句话说,如果流包含音频和视频轨迹,并且当前 POST 请求失败,则编码器必须重新连接,并为音频轨迹重新发送最后两个片段(先前已成功发送),为视频轨迹重新发送最后两个片段(先前已成功发送),以确保不会丢失任何数据。 编码器必须维护媒体片段的“转发”缓冲区,当重新连接时会重新发送此缓冲区。

5.时间刻度

[MS-SSTR] 描述了 SmoothStreamingMedia(第 2.2.2.1 节)、StreamElement(第 2.2.2.3 节)、StreamFragmentElement(第 2.2.2.6 节)和 LiveSMIL(第 2.2.7.3.1 节)的时间刻度使用情况。 如果没有时间刻度值,则使用默认值 10,000,000 (10 MHz)。 尽管平滑流式处理格式规范不会阻止使用其他时间刻度值,但大多数编码器实现会使用此默认值 (10 MHz) 来生成平滑流式处理引入数据。 由于 Azure 媒体动态打包功能的原因,建议为视频流使用 90-KHz 时间刻度,为音频流使用 44.1 KHZ 或 48.1 KHZ 时间刻度。 如果不同的流采用不同的时间刻度值,则必须发送流级时间刻度。 有关详细信息,请参阅 [MS-SSTR]

6.“流”的定义

流是指在撰写实时演播内容、处理流故障转移和冗余方案的实时引入中操作的基本单位。 流定义为一个唯一的分片 MP4 位流,其中可包含单个轨迹或多个轨迹。 完整实时演播可能包含一个或多个流,具体取决于实时编码器的配置。 以下示例演示了使用流撰写完整实时演播内容的各种选项。

示例:

客户想要创建实时传送视频流演播,其中包含以下音频/视频比特率:

视频 – 3000kbps、1500kbps、750kbps

音频 – 128 kbps

选项 1:在一个流中包含所有轨迹

在此选项中,单个编码器生成所有音频/视频轨迹,然后将它们捆绑成一个分片 MP4 位流。 分片的 MP4 位流然后会通过单个 HTTP POST 连接发送。 在此示例中,此实时演播只有一个流。

流-单个轨道

选项 2:将每个轨道包含在单独的流中

在此选项中,编码器在每个分片 MP4 位流中放置一个轨道,然后通过独立的 HTTP 连接发布所有流。 这可通过一个或多个编码器来实现。 从实时引入的角度来看,此实时演播由四个流组成。

流-单独轨道

选项 3:将音频轨道与比特率最低的视频轨道捆绑成一个流

在此选项中,客户选择将音频轨道与比特率最低的视频轨道捆绑成一个分片 MP4 位流,并让另外两个视频轨道保留在单独的流。

流-音频和视频轨道

摘要

此列表并不完整,只列出了此示例中部分可用的引入选项。 事实上,实时引入支持将轨道以任何组合方式分组到流中。 客户和编码器供应商可以根据工程复杂性、编码器容量以及冗余与故障转移注意事项,来选择自己的实现。 但是,在大多数情况下,整个实时演播只有一个音频轨道。 因此,请务必确保包含音频轨道的引入流正常运行。在考虑到这个要点的情况下,用户通常会将音频轨道放入其自己的流中(如选项 2),或者将它与比特率最低的视频轨道捆绑在一起(如选项 3)。 此外,若要获得更好的冗余与容错效果,强烈建议针对嵌入到媒体服务的实时引入,将同一个音频轨道通过两个不同的流(选项 2 中采用冗余音频轨道)发送,或者将音频轨道与至少两个比特率最低的视频轨道捆绑在一起(选项 3 将音频与至少两个视频流捆绑在一起)。

7.服务故障转移

根据实时传送视频流的性质,良好的故障转移支持是确保服务可用性的关键。 媒体服务可以处理各种类型的故障,包括网络错误、服务器错误和存储问题。 当与实时编码器端适当的故障转移逻辑结合使用时,客户可以从云实现高度可靠的实时传送视频流服务。

本部分讨论服务故障转移方案。 在此案例中,服务的某个位置发生故障,且故障将自身记录为网络错误。 以下是如何实施编码器以处理服务故障转移的一些建议:

  1. 建立超时值为 10 秒的 TCP 连接。 如果尝试建立连接超过 10 秒,便会中止操作并重试。
  2. 发送 HTTP 请求消息区块的超时值较短。 如果目标 MP4 片段持续时间为 N 秒,请使用介于 N 和 2 N 秒之间的发送超时;例如,如果 MP4 片段持续时间是 6 秒,则使用 6 到 12 秒的超时。 如果发生超时,请重置连接,打开新连接,并以新连接恢复流引入。
  3. 为每个轨迹维护一个循环缓冲区,其中包含最后两个已成功完全发送到服务的片段。 如果流的 HTTP POST 请求在流结束前终止或超时,则打开新的连接,并开始另一个 HTTP POST 请求、重新发送流标头、为每个轨迹重新发送最后两个片段,但不在媒体时间轴上造成不连续情况。 这会减少数据丢失的可能性。
  4. 建议编码器不要限制在发生 TCP 错误后,重新尝试创建连接或恢复流式传输的次数。
  5. 发生 TCP 错误后:

    a. 必须关闭当前连接,并且必须为新的 HTTP POST 请求创建新的连接。

    b. 新的 HTTP POST URL 必须与初始 POST URL 相同。

    c. 新的 HTTP POST 必须包括与初始 POST 相同的流标头(“ftyp”、“实时服务器清单框”及“moov”框)。

    d.单击“下一步”。 必须重新发送为每个轨迹发送的最后两个片段,且必须恢复流式传输,而不在媒体时间线上造成中断。 MP4 片段时间戳必须连续递增,甚至可跨越 HTTP POST 请求。

  6. 如果未以匹配 MP4 片段持续时间的速率发送数据,则编码器应该终止 HTTP POST 请求。 不发送数据的 HTTP POST 请求可以防止媒体服务在服务更新事件中很快与编码器断开连接。 出于此原因,稀疏(广告信号)轨道的 HTTP POST 应该短暂留存,并在发送疏松片段之后立即终止。

8.编码器故障转移

编码器故障转移是第二种故障转移方案,必须妥善配置此方案才能进行端到端实时流式传送。 在此方案中,错误状况会发生在编码器端。

编码器故障转移

发生编码器故障转移时,实时引入终结点上预期会:

  1. 应创建新的编码器实例以恢复流式传输,如图表中所示(以虚线表示的 3000k 视频流)。
  2. 新编码器必须使用与故障实例相同的 HTTP POST 请求 URL。
  3. 新编码器的 POST 请求必须包含与故障实例相同的分片 MP4 标头框。
  4. 新编码器必须与所有其他运行中的编码器正确同步,相同的实时演播才能生成与相符片段边界同步的音频/视频样本。
  5. 新流必须在语义上等同于上一个流,并可在标头与片段级别互换。
  6. 新的编码器应该尝试最大程度地减少数据丢失。 媒体片段的 fragment_absolute_timefragment_index 应从编码器上次停止的时间点开始增加。 fragment_absolute_timefragment_index 应连续增加,但允许视需要造成中断。 媒体服务会忽略已收到并处理的片段,因此,在片段重新发送端造成错误,要好过在媒体时间线上造成中断。

9.编码器冗余

对于某些需要更高可用性与优质体验的重要实时事件,建议使用主动-主动冗余编码器,以实现无缝故障转移,且不会丢失数据。

编码器冗余

如图表中所示,两组编码器同时将每个流的两个副本推送到实时服务。 此设置之所以受支持,是因为媒体服务能够根据流 ID 与片段时间戳筛选出重复片段。 生成的实时流与存档是所有流的单个副本,此副本很有可能是从两个源聚合而成。 例如,在假设的极端条件下,只要有一个编码器(不一定是同一个)在任意给定时间点对每个流运行,则从服务生成的实时流就会是连续的,且不会丢失数据。

此方案的要求与“编码器故障转移”的要求几乎相同,不同之处在于,第二组编码器将与主编码器同时运行。

10.服务冗余

对于高度冗余的全局分发,有时必须跨区域备份以处理区域灾难。 通过扩展“编码器冗余”拓扑,客户可以选择在不同的区域部署冗余服务,并与第二组编码器连接。 此外,客户还可与内容交付网络提供商合作,在两个服务部署之前部署全局流量管理器,以此无缝路由客户端流量。 编码器的要求与“编码器冗余”的要求相同。 唯一的例外是第二组编码器需要指向另一个实时引入终结点。 下图显示了此设置:

服务冗余

11.特殊类型的引入格式

本部分介绍用于处理特定方案的特殊类型的实时引入格式。

稀疏轨道

当以丰富的客户端体验传递实时传送视频流演播时,通常需要传输与主要媒体数据时间同步的事件或带内信号。 动态实时广告插播就是一个例子。 这种类型的事件信号不同于一般音频/视频流,因为它具有稀疏的性质。 换句话说,信号数据通常不会连续发生,其间隔难以预测。 稀疏轨道的概念专门用于引入和广播带内信号数据。

以下步骤是引入稀疏轨道的建议实现方式:

  1. 创建独立的分片 MP4 位流,其中只包含稀疏轨道,而不包含音频/视频轨道。
  2. 在如 [1] 的第 6 节定义的“实时服务器清单框”中,使用“parentTrackName”参数指定父轨道的名称。有关详细信息,请参阅 [1] 中的 4.2.1.2.1.2 节。
  3. 在“实时服务器清单框”中,“manifestOutput”必须设置为“true”。
  4. 根据信号事件的稀疏性质,建议如下:

    a. 实时事件开始时,编码器会将初始标头框发送给服务,使服务可以在客户端清单中注册稀疏轨道。

    b. 未发送数据时,编码器应该终止 HTTP POST 请求。 不发送数据的长时间运行 HTTP POST 可以防止媒体服务在服务更新或服务器重启事件中很快与编码器断开连接。 在这些情况下,在套接字上的接收操作中,会暂时阻止媒体服务器。

    c. 在此期间如果没有可用的信号数据,编码器应该关闭 HTTP POST 请求。 POST 请求处于活动状态时,编码器应发送数据。

    d.单击“下一步”。 发送稀疏片段时,编码器可以设置显式 content-Length 标头(如果可用)。

    e.在“新建 MySQL 数据库”边栏选项卡中,接受法律条款,并单击“确定”。 通过新连接发送稀疏片段时,编码器应从标头框开始发送,接着发送新片段。 这适用于在中途发生故障转移的情况,并会与先前从未看到稀疏轨道的新服务器建立新的稀疏连接。

    f.单击“保存”以保存设置。 当时间戳值相等或更大的对应父轨道片段可供客户端使用时,稀疏轨道片段便可供客户端使用。 例如,如果稀疏片段的时间戳 t=1000,则预期在客户端看到“视频”(假设父轨道名称为“video”)片段时间戳为 1000 或以上后,便可下载 t=1000 的稀疏片段。 请注意,实际信号能够在演播时间线上的不同位置上用于其指定用途。 在此示例中,t=1000 的稀疏片段具有 XML 有效负载,可在数秒后将广告插入到某个位置。

    g. 稀疏轨道片段的有效负载可以为不同格式(例如 XML、文本或二进制),具体取决于方案。

冗余音频轨道

在典型的 HTTP 自适应流式处理方案中(例如平滑流式处理或 DASH),通常在整个演播中只有一个音频轨道。 具有多个质量级别的视频轨道可让客户端在错误条件中选择,而音频轨道不同于这类轨道,当引入的流中有损坏的音频轨道时,音频轨道会是唯一的故障点。

为解决此问题,媒体服务支持实时引入冗余音频轨道。 其思路是同一音频轨迹可在不同的流中多次发送。 尽管服务只会在客户端清单中注册音频轨道一次,但它能够使用冗余的音频轨道作为备份,以在主音频轨道发生问题时检索音频片段。 为了引入冗余音频轨道,编码器需要:

  1. 在多个分片 MP4 位流中创建相同的音频轨道。 冗余的音频轨道必须在语义上与片段时间戳相同,并可在标头与片段级别互换。
  2. 确保实时服务器清单中的“audio”条目([1] 中的第 6 节)对于所有冗余音频轨道都是相同的。

以下是冗余音频轨道的建议实现方式:

  1. 让流独自发送每个唯一的音频轨迹。 此外,为每个音频轨道流发送冗余流,其中第二个流与第一个流的唯一不同之处在于 HTTP POST URL 中的标识符:{protocol}://{server address}/{publishing point path}/Streams({identifier})。
  2. 使用独立的流发送两个最低视频比特率。 其中每个流还应该包含每个唯一音频轨迹的副本。例如,当支持多种语言时,这些流应包含每种语言的音频轨迹。
  3. 使用独立的服务器(编码器)实例来编码和发送 (1) 与 (2) 中所提到的冗余流。