通过 DASH 提供 YouTube 直播内容

本文档提供了相关指南,介绍了如何使用基于 HTTP 的动态自适应流式传输 (DASH) 交付格式从编码器在 YouTube 上直播数据。旨在帮助编码器供应商为其产品添加 DASH 交付支持。

了解 DASH

下表列出了一些关键的 DASH 功能和属性:

  • 基于开放式标准。
  • 基于 HTTP。因此,DASH 适合互联网基础架构,并且可以穿透防火墙。
  • 支持高传输比特率。DASH 支持多个并发 HTTP 会话和非顺序分段传送,与依赖单个 TCP 连接的协议相比,可提供更高的恢复能力。
  • 通过 HTTPS 安全地传送。
  • 通过 HTTP 和 HTTPS 实现无损交付。
  • 编解码器无关。
  • 支持包含 H264 和 AAC 的 MP4,以及包含 VP8/VP9 和 Vorbis/Opus 的 WebM。

规格

要求

以下各子部分介绍了使用 DASH 向 YouTube 传送直播活动的要求。

计时

YouTube DASH 端点充当被动 HTTP 服务器,用于记录编码器发送的 PUT 方法调用。

  • DASH 端点支持并发 TCP 连接。您可以按照 HTTP/1.1 的规定重用连接。
  • MPD 和初始化段应在第一个媒体段的 3 秒内放置。(建议您在 MPD 中添加初始化段。)
  • 每个段或 MPD 必须使用单独的 PUT 请求;不支持对多个段进行多部分上传。
  • 媒体片段的 PUT 操作可能会在时间上重叠,以提高上传带宽。
  • 细分可以在大约 3 秒的时间窗口内以非顺序方式提供。
  • MPD 和初始化片段应至少每 60 秒更新一次,并包含更新后的 availabilityStartTimestartNumber。(如上所述,初始化段可以包含在 MPD 中。在这种情况下,一个 PUT 请求可以同时更新这两个细分。)

网址结构

您的编码器必须通过将字符串附加到 YouTube 端点基本网址来形成 PUT 网址。您需要使用 YouTube Live Streaming API 创建 DASH 提取端点。

随后,编码器可以通过 YouTube Live Streaming API 以编程方式获取端点的基本网址。如果您想手动向编码器提供网址,还可以在 YouTube 直播活动界面中查看基本网址。

附加到基本网址的字符串可以包含以下 ASCII 字符集:

  • 小写字母:a-z
  • 大写字母:A-Z
  • 数字:0-9
  • 特殊字符:_(下划线)、-(连字符)、.(英文句点)

MPD 网址

除了上述要求之外,MPD 网址还必须以 .mpd 结尾,以便 YouTube 服务器轻松识别 MPD。其他细分网址不得以 .mpd 结尾。

初始化和媒体段网址

如果数据位于 ISO BMFF 容器中,初始化片段网址和所有媒体片段网址都必须以 .mp4 结尾;如果数据位于 WebM 容器中,则必须以 .webm 结尾。

MPD 内容

MPD 必须完整且符合 DASH 标准。它必须包含以下每个元素各一个。此列表列出了 YouTube 特别要求的元素,DASH 标准可能会列出其他必需元素。这些元素使用 XPath 语法表示,并且与 DASH 标准保持一致。

  • /mpd:MPD/attribute::type
  • /mpd:MPD/mpd:Period
  • /mpd:MPD/mpd:Period/mpd:AdaptationSet
  • /mpd:MPD/mpd:Period/mpd:AdaptationSet/attribute::mimeType (video/mp4 or video/webm)
  • /mpd:MPD/mpd:Period/mpd:AdaptationSet/mpd:SegmentTemplate
  • /mpd:MPD/mpd:Period/mpd:AdaptationSet/mpd:SegmentTemplate/attribute::media
  • /mpd:MPD/mpd:Period/mpd:AdaptationSet/mpd:SegmentTemplate/attribute::initialization
  • /mpd:MPD/mpd:Period/mpd:AdaptationSet/mpd:SegmentTemplate/attribute::startNumber

请注意,元素值必须满足以下要求:

  • <MPD> 元素的 minimumUpdatePeriod 属性必须设置为小于或等于 60 秒 (PT60S) 的值。
  • <SegmentTemplate> 元素的 media 属性必须指定媒体片段网址是使用 $Number$ 生成的。(startNumber 属性用于标识将分配给第一个媒体段的编号。)

初始化片段长度

初始化段不得超过 100 KB。(通常,初始化段比这小得多。)如果 MPD 中包含初始化分段,则包含该分段的 data: 网址不得超过 100 KB。

编码器输出

初始化段和媒体段必须构成具有封闭 GOP(画面组)的多路复用 ISO BMFF 或 WebM 文件流。

  • GOP 大小应约为 2 秒,且不得超过 8 秒。
  • 多路复用流必须同时包含音轨和视频轨道。

其他最佳实践

加密

YouTube 支持通过 HTTPS 进行流加密。我们强烈建议您使用此功能。

MPD 中的初始化片段

您可以根据 RFC 2397,使用 data: 网址直接在 MPD 中表示初始化段。这样可以简化视频流设置,并降低初始化段与视频流其余部分不对应的可能性。

相应元素的 XPath 为:

/mpd:MPD/mpd:Period/mpd:AdaptationSet/mpd:SegmentTemplate/attribute:data

目标片段时长

为了获得良好的提取性能,并在吞吐量和延迟之间取得良好的平衡,媒体片段的长度应介于 1 到 5 秒之间。我们强烈建议您使用以下两个元素在 MPD 中传达这些细分的预期时长:

  • /mpd:MPD/mpd:Period/mpd:AdaptationSet/mpd:SegmentTemplate/attribute::duration
  • /mpd:MPD/mpd:Period/mpd:AdaptationSet/mpd:SegmentTemplate/attribute::timescale

根据这些属性计算出的时长应在所有实际片段时长的 2 倍范围内,否则可能会影响流式传输性能。

请注意,提取的目标时长并不等于 YouTube 生成的直播块时长。YouTube 会对输入进行转码和重新分块,输出目标时长取决于相应直播是针对串流质量还是延迟时间进行了优化。

重试和指数退避

所有 HTTP PUT 请求都应该使用超时来执行,我们建议将超时值设置为比片段时长大 500 毫秒的值。

无论是因为超时还是其他错误,失败的媒体片段 PUT 请求都对应于视频流中的间隙。因此,您应使用随机化的二进制指数退避算法重试任何此类请求:

  1. 失败后,等待 [0 ... 100] 毫秒之间的随机一段时间,然后重试请求。
  2. 如果请求再次失败,请等待 [0 ... 200] 毫秒之间的随机时间段,然后重试请求。
  3. 如果请求再次失败,请等待 [0 ... 400] 毫秒之间的随机时间段,然后重试请求。
  4. 等等

请注意,如果出现重复故障,应向编码器操作员发出信号,因为这表示广播失败。

HTTP 响应代码

以下部分介绍了 YouTube 针对通过 DASH 传送的片段返回的响应代码。

200 (OK)

HTTP 200 (OK) 响应表示 YouTube 服务器收到了预期操作并成功处理了该操作。

202(已接受)

如果对任何 PUT 或 POST 操作的 HTTP 响应为 202(已接受),则表示该操作是意外的,但已接受该操作以供延迟处理。不过,延迟执行的操作可能会成功,也可能会失败,因此相应响应并不能保证 YouTube 实际上能够成功处理该操作。

当分段以非顺序方式传送时,最常出现此响应。通常,YouTube 可以在收到前面的片段后正确处理接受的片段,因此您无需重新发送该片段。

例如,在以下任一情况下,YouTube 都可以返回 202 响应:

  • 在 MPD 之前收到初始化段。
  • 媒体段在 MPD 和初始化段之前接收。
  • 媒体片段的接收顺序与片段的播放顺序不一致,例如片段 3 在片段 2 之前收到。

不过,如果 YouTube 在收到 POST 或 PUT 请求后无法完全验证商品标识码,202 响应也可能表示商品标识码不正确。例如,YouTube 在收到 MPD 之前收到并接受了初始化段,但该初始化段被证明无效,就会发生这种情况。在这种情况下,YouTube 会接受初始化分段并返回 202,然后在收到 MPD 后确定该分段是否有效。您可以通过在 MPD 中添加初始化段来避免这种特定情况。

400 (Bad Request)

HTTP 400(错误请求)响应表示发生了以下问题之一:

  • 网址格式不正确。
  • 帖子过大(超过 10MB)。
  • 无法解析 MPD。
  • MPD 中的初始化分段已损坏。

401 (Unauthorized)

HTTP 401(未经授权)响应表示 YouTube DASH 端点的基本网址已损坏或过期。

405(不允许使用的方法)

HTTP 405(不允许使用的方法)响应表示发送了 POSTPUT 以外的请求。

409(冲突)

如果对任何 PUT 或 POST 操作的 HTTP 响应为 409(冲突),则表示 YouTube 无法处理相应请求。例如,如果请求者已发送大量媒体片段,但 YouTube 仍未收到 MPD、初始化片段或两者,则可能会出现此响应。在该示例中,编码器需要重新传输 MPD 和初始化段,然后才能重试失败的请求。

500(内部服务器错误)

HTTP 500(内部服务器错误)响应表示服务器无法处理请求。对于此错误,我们建议您使用指数退避算法重试请求。

示例

网址序列

以下网址序列显示了为通过 DASH 传送内容而发出的一系列 PUT 请求。此序列假设 YouTube DASH 端点的基本网址为:

http://upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=

此序列显示了单独发送的 MPD 和初始化段。不过,初始化段可以直接在 MPD 中表示,建议采用这种做法。此外,MPD 和初始化片段应至少每 60 秒更新一次。因此,最终,这些片段的网址会再次出现在此序列中,然后后面会跟上更多媒体片段的网址。

PUT upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=dash.mpd
PUT upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=init.mp4
PUT upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=media001.mp4
PUT upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=media002.mp4
PUT upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=media003.mp4
...

WebM 片段

包含嵌入式初始化段的 MPD

以下示例 MPD 在 RFC 2397 数据网址中嵌入了初始化段。我们建议您以这种方式嵌入初始化细分,而不是单独发送。

此示例符合将 WebM(VP8 或 VP9、Opus)内容上传到 YouTube 的要求。为了便于阅读,大多数数据网址已被省略:

<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns="urn:mpeg:dash:schema:mpd:2011"
     xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd"
     type="dynamic" 
     profiles="urn:mpeg:dash:profile:isoff-live:2011" 
     minimumUpdatePeriod="PT60S"
     minBufferTime="PT12S"
     availabilityStartTime="2016-04-13T20:52:58" >
  <Period start="PT0S" id="1">
    <AdaptationSet mimeType="video/webm">
      <ContentComponent contentType="video" id="1"/>
      <SegmentTemplate timescale="1000"
           duration="2000"
           startNumber="1"
           initialization="data:video/mp4;base64,AAAAGGZ0eXBpc...AAA"
           media="/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=media-$Number%09d$.webm"/>
      <Representation id="1" width="1920" height="1080">
        <SubRepresentation contentComponent="1"/>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

MPD

以下示例 MPD 没有嵌入初始化段,但同样符合 WebM(VP8 或 VP9、Opus)向 YouTube 提取的要求:

<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns="urn:mpeg:dash:schema:mpd:2011"
     xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd"
     type="dynamic" 
     profiles="urn:mpeg:dash:profile:isoff-live:2011" 
     minimumUpdatePeriod="PT60S"
     minBufferTime="PT12S"
     availabilityStartTime="2016-04-13T20:52:58" >
  <Period start="PT0S" id="1">
    <AdaptationSet mimeType="video/webm">
      <ContentComponent contentType="video" id="1"/>
      <SegmentTemplate timescale="1000"
           duration="2000"
           startNumber="1"
           initialization="/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=init.webm"
           media="/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=media-$Number%09d$.webm"/>
      <Representation id="1" width="1920" height="1080">
        <SubRepresentation contentComponent="1"/>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

初始化

以下内容显示了 WebM 初始化段的示例布局。它包含 WebM 流中第一个集群之前的部分(但不包括第一个集群)。

媒体

以下内容显示了 WebM 媒体片段的示例布局。它由单个 WebM 集群组成。与 ISO BMFF 流一样,附加到一系列集群的初始化片段应生成有效的 WebM 流。

ISO BMFF 片段

包含嵌入式初始化段的 MPD

以下示例 MPD 在 RFC 2397 数据网址中嵌入了初始化段。我们建议您以这种方式嵌入初始化细分,而不是单独发送。

此示例符合将 ISO BMFF(H.264、AAC)内容提取到 YouTube 的要求。为了便于阅读,大多数数据网址已被省略:

<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="urn:mpeg:dash:schema:mpd:2011"   
    xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" 
    type="dynamic"
    minimumUpdatePeriod="PT30S" 
    availabilityStartTime="2016-05-04T20:47:25" 
    minBufferTime="PT12S" 
    profiles="urn:mpeg:dash:profile:isoff-live:2011">
  <Period start="PT0S" id="1">
    <AdaptationSet mimeType="video/mp4" codecs="avc1.4d401e,mp4a.40.2">
      <ContentComponent contentType="video" id="1"/>
      <ContentComponent contentType="audio" id="2"/>
      <SegmentTemplate timescale="600"
             media="/dash_upload?cid=ug50-xg26-cbc1-2p0h&staging=1&copy=0&file=media$Number%09d$.mp4"
             initialization="data:video/mp4;base64,AAAAGGZ0eXBpc281AA...AA"
             duration="306"
             startNumber="1"/>
      <Representation id="1" width="640" height="360" bandwidth="526952">
        <SubRepresentation contentComponent="1" bandwidth="526952" 
codecs="avc1.4d401e"/>
        <SubRepresentation contentComponent="2" bandwidth="125584" codecs="mp4a.40.2"/>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

MPD

以下示例 MPD 没有嵌入初始化段,但同样符合 ISO BMFF (H.264、AAC) 提取到 YouTube 的要求:

<?xml version="1.0" encoding="UTF-8"?>
<MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns="urn:mpeg:dash:schema:mpd:2011"
     xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd"
     type="dynamic"
     profiles="urn:mpeg:dash:profile:isoff-live:2011"
     minimumUpdatePeriod="PT60S" 
     minBufferTime="PT12S"
     availabilityStartTime="2016-04-13T20:51:31" >
  <Period start="PT0S" id="1">
    <AdaptationSet mimeType="video/mp4" codecs="avc1.4d401e,mp4a.40.2">
      <ContentComponent contentType="video" id="1"/>
      <ContentComponent contentType="audio" id="2"/>
      <SegmentTemplate timescale="600"
           duration="1200"
           startNumber="1"
           initialization="/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=init.mp4"
           media="/dash_upload?cid=xxxx-xxxx-xxxx-xxxx&copy=0&file=media$Number%09d$.mp4"/>
      <Representation id="1" width="640" height="360" bandwidth="526952">
        <SubRepresentation contentComponent="1" bandwidth="526952" codecs="avc1.4d401e"/>
        <SubRepresentation contentComponent="2" bandwidth="125584" codecs="mp4a.40.2"/>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

初始化

下图显示了多路复用 ISO BMFF 初始化段的布局示例。YouTube 不一定使用原子,但这是一个符合标准的示例。尤其是,音频轨道和视频轨道都会显示。

媒体

下图显示了多路复用 ISO BMFF 媒体片段的布局示例。YouTube 不一定会使用所有原子,但这是一个符合标准的示例。特别是,音频轨道和视频轨道都会显示。可以将一系列此类片段附加到初始化片段,以生成有效且完整的多路复用 ISO BMFF 流。

已知的限制

RTMP 和 DASH 提取

无法将 RTMP 和 DASH 推送到 YouTube。这不仅适用于在直播期间在这两种方法之间切换,还适用于将一种方法用作主要推流方法,将另一种方法用作备用推流方法。