本文档提供了一些准则,可指导您使用 HTTP 动态自适应流式传输 (DASH) 传送格式从编码器流式传输 YouTube 上的实时数据。旨在帮助编码器供应商为其产品添加 DASH 传送支持。
了解 DASH
下表列出了一些关键的 DASH 功能和属性:
- 基于开放标准。
- 基于 HTTP。因此,DASH 适合互联网基础架构,并且可以遍历防火墙。
- 支持高传输比特率。DASH 支持多个同时进行的 HTTP 会话和非顺序分段传递,与依赖单个 TCP 连接的协议相比,可提供更大的弹性。
- 通过 HTTPS 安全传送。
- 通过 HTTP 和 HTTPS 进行无损传送。
- 与编解码器无关。
- 支持包含 H264 和 AAC 的 MP4 以及包含 VP8/VP9 和 Vorbis/Opus 的 WebM。
规格
- ISO/IEC 23009-1:2014 信息技术 -- 基于 HTTP 的动态自适应流式传输 (DASH) 对 DASH 进行了介绍。
- WebM DASH 规范中介绍了基于 DASH 的 WebM。
要求
以下各小节介绍了使用 DASH 向 YouTube 传送直播内容的要求。
计时
YouTube DASH 端点充当被动 HTTP 服务器,用于记录编码器发送的 PUT 方法调用。
- DASH 端点支持同时建立多个 TCP 连接。您可以根据 HTTP/1.1 重复使用连接。
- MPD 和初始化片段应在第一个媒体片段后的 3 秒内执行 PUT。(我们建议您在 MPD 中添加初始化片段。)
- 每个片段或 MPD 都必须使用单独的 PUT 请求;不支持对多个片段进行多部分上传。
- 为提高上传带宽,媒体段的 PUT 操作可能会在时间上重叠。
- 片段可在大约 3 秒的时间范围内按非连续顺序提供。
- MPD 和初始化片段应至少每 60 秒更新一次,并使用更新后的
availabilityStartTime
和startNumber
。(如上所述,初始化片段可包含在 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
属性标识将分配给第一个媒体片段的编号。)
初始化段长度
初始化片段的长度不得超过 100kb。(通常,初始化细分比该细分小得多。)如果 MPD 中包含初始化片段,则包含该片段的 data:
网址不得超过 100kb。
编码器输出
初始化片段和媒体片段必须构成具有封闭 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 请求失败(无论是由于超时还是其他错误),则对应于视频串流中的一个间断。因此,您应使用随机二进制指数退避算法重试任何此类请求:
- 失败后,等待
[0 ... 100]
毫秒之间的随机时间段,然后重试请求。 - 如果请求再次失败,请等待
[0 ... 200]
毫秒之间的随机时间段,然后重试请求。 - 如果请求再次失败,请等待
[0 ... 400]
毫秒之间的随机时间段,然后重试请求。 - 等等
请注意,如果反复出现故障,应向编码器操作员发出信号,因为这些故障对应的是直播失败。
HTTP 响应代码
以下部分介绍了 YouTube 在响应通过 DASH 传送的片段时返回的响应代码。
200 (OK)
HTTP 200 (OK) 响应表示 YouTube 服务器收到了预期的操作,并成功处理了该操作。
202(已接受)
对于任何 PUT 或 POST 操作,HTTP 202 (Accepted) 响应都表示该操作是意外操作,并被接受以便延迟处理。但是,延迟的操作可能会成功或失败,因此该响应并不能保证 YouTube 实际上能够成功处理该操作。
此响应最常见于非依序投放细分受众群的情况。通常,YouTube 在收到上述片段后可以正确处理已接受的片段,您无需重新发送片段。
例如,在以下任一情况下,YouTube 都可以返回 202 响应:
- 在 MPD 之前收到初始化段。
- 先接收媒体段,然后再收到 MPD 和初始化段。
- 媒体段先于较早的片段接收,例如在片段 2 之前接收的片段 3。
但是,如果 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(不允许的方法)响应表示发送的请求不是 POST
或 PUT
。
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©=0&file=
该序列显示了单独发送的 MPD 和初始化片段。不过,初始化部分可以直接在 MPD 中表示,因此建议采用这种做法。此外,MPD 和初始化片段应至少每 60 秒更新一次。因此,这些细分的网址最终会按此顺序再次出现,它们随后会是更多媒体片段的网址。
PUT upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx©=0&file=dash.mpd PUT upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx©=0&file=init.mp4 PUT upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx©=0&file=media001.mp4 PUT upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx©=0&file=media002.mp4 PUT upload.youtube.com/dash_upload?cid=xxxx-xxxx-xxxx-xxxx©=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©=0&file=media-$Number%09d$.webm"/> <Representation id="1" width="1920" height="1080"> <SubRepresentation contentComponent="1"/> </Representation> </AdaptationSet> </Period> </MPD>
MPD
以下示例 MPD 没有嵌入式初始化片段,但也符合向 YouTube 进行 WebM(VP8 或 VP9、Opus)提取的要求:
<?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©=0&file=init.webm" media="/dash_upload?cid=xxxx-xxxx-xxxx-xxxx©=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 数据网址中嵌入了初始化段。我们建议您按此方式嵌入初始化部分,而不是单独发送初始化部分。
此示例符合向 YouTube 进行 ISO BMFF(H.264、AAC)提取的要求。为了方便阅读,系统已省略数据网址的大部分内容:
<?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©=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 没有嵌入式初始化片段,但也符合向 YouTube 进行 ISO BMFF(H.264、AAC)提取的要求:
<?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©=0&file=init.mp4" media="/dash_upload?cid=xxxx-xxxx-xxxx-xxxx©=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。这适用于在广播期间在两者之间进行切换,以及将其中一个用作主要提取方法,将另一个用作备用提取方法。