设置自适应流媒体源

假设您想在服务器上设置一个自适应流媒体源,以便在 HTML 媒体元素中使用。您将如何操作?本文解释了如何操作,并介绍了两种最常见的格式:MPEG-DASH 和 HLS(HTTP 实时流)。

选择格式

在自适应流格式方面,有很多选择;我们决定选择以下两种,因为它们之间可以支持大多数现代浏览器。

  • MPEG-DASH
  • HLS(HTTP 实时流)

为了自适应地流式传输媒体,我们需要将媒体分成块。我们需要提供多个不同质量的文件,这些文件分布在多个时间点上。质量和时间点越多,流的“自适应性”就越强,但我们通常希望在大小、编码时间和自适应性之间找到一个务实的平衡。

好消息是,一旦我们以适当的格式对媒体进行编码,我们就几乎可以开始了。对于通过 HTTP 进行的自适应流,不需要特殊的服务器端组件。

MPEG-DASH 和 HLS 都使用播放列表格式来构建构成可能流的媒体组件。各种比特率流被分成片段并放置在相应的服务器文件夹中——我们必须向媒体播放器提供一个链接来查找文件或播放列表,这些文件或播放列表指定了这些流文件夹的名称和位置。

MPEG-DASH 编码

MPEG-DASH 是一种自适应比特率流技术,它支持通过互联网从传统的 HTTP Web 服务器交付媒体内容。

媒体演示描述 (MPD) 文件用于保存有关各种流及其关联带宽的信息。在您的视频源 (src) 属性中,您指向 MPD 而不是像非自适应媒体那样指向媒体文件。

MPD 文件告诉浏览器各种媒体片段位于何处,它还包括诸如 mimeType 和编解码器之类的元数据,以及其他详细信息,例如字节范围——它是一个 XML 文档,在许多情况下将为您生成。

我们可以使用一些配置文件。我们将看看用于点播 (VOD) 的按需配置文件和实时配置文件。

对于实时服务流,实时配置文件是必需的。配置文件之间的流切换功能相同。

使用实时配置文件而不是按需配置文件进行 VOD 内容的其他原因可能是

  1. 您的客户端或服务器不支持范围请求
  2. 您的服务器无法有效地缓存范围请求
  3. 您的服务器无法有效地预取范围请求
  4. SIDX* 很大,并且必须首先加载它会稍微减慢启动速度
  5. 您希望将原始文件用于 DASH 和其他形式的交付(例如 Microsoft Smooth Streaming)作为过渡策略
  6. 您可以将相同的媒体文件用于实时传输和稍后的 VOD

*SIDX 或 SegmentIndexBox 是一个结构,通过给出其最早的呈现时间和其他元数据来描述一个片段,并且通常会构成 MPD 文件的大部分。

按需配置文件

此配置文件允许在“按需”之间切换流——也就是说,您只需要提供一组连续的文件并为每个文件指定带宽,然后将自动选择相应的文件。

这是一个简单的示例,它提供了一个音频轨道表示和四个单独的视频表示。

xml
<?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="static"
  mediaPresentationDuration="PT654S"
  minBufferTime="PT2S"
  profiles="urn:mpeg:dash:profile:isoff-on-demand:2011">

  <BaseURL>http://example.com/ondemand/</BaseURL>
  <Period>
    <!-- English Audio -->
    <AdaptationSet mimeType="audio/mp4" codecs="mp4a.40.5" lang="en" subsegmentAlignment="true" subsegmentStartsWithSAP="1">
      <Representation id="1" bandwidth="64000">
        <BaseURL>ElephantsDream_AAC48K_064.mp4.dash</BaseURL>
      </Representation>
    </AdaptationSet>
    <!-- Video -->
    <AdaptationSet mimeType="video/mp4" codecs="avc1.42401E" subsegmentAlignment="true" subsegmentStartsWithSAP="1">
      <Representation id="2" bandwidth="100000" width="480" height="360">
        <BaseURL>ElephantsDream_H264BPL30_0100.264.dash</BaseURL>
      </Representation>
      <Representation id="3" bandwidth="175000" width="480" height="360">
        <BaseURL>ElephantsDream_H264BPL30_0175.264.dash</BaseURL>
      </Representation>
      <Representation id="4" bandwidth="250000" width="480" height="360">
        <BaseURL>ElephantsDream_H264BPL30_0250.264.dash</BaseURL>
      </Representation>
      <Representation id="5" bandwidth="500000" width="480" height="360">
        <BaseURL>ElephantsDream_H264BPL30_0500.264.dash</BaseURL>
      </Representation>
    </AdaptationSet>
  </Period>
</MPD>

生成 MPD 文件后,您可以从视频标签内引用它。

html
<video src="my.mpd" type="application/dash+xml"></video>

最好为尚不支持 MPEG-DASH 的浏览器提供备用方案

html
<video>
  <source src="my.mpd" type="application/dash+xml" />
  <!-- fallback -->
  <source src="my.mp4" type="video/mp4" />
  <source src="my.webm" type="video/webm" />
</video>

实时配置文件

处理 MPEG-DASH 时一个有用的软件是Dash Encoder。它使用MP4Box将媒体编码为 MPEG-DASH 格式。

注意:您需要熟悉 make 文件和安装依赖项才能使此软件正常运行。

注意:由于 MPEG-DASH 解码部分使用 JavaScript 完成,并且 MSE 文件通常使用 XHR 获取,请记住同源策略。

注意:如果您使用 WebM,则可以使用本教程中所示的方法HTML 5 视频的 DASH 自适应流

编码后,您的文件结构可能如下所示

play list ->                /segments/news.mp4.mpd

main segment folder ->      /segments/main/

100 Kbps segment folder ->  /segments/main/news100 contains (1.m4s, 2.m4s, 3.m4s … )

200 Kbps segment folder ->  /segments/main/news200 contains (1.m4s, 2.m4s, 3.m4s … )

300 Kbps segment folder ->  /segments/main/news300 contains (1.m4s, 2.m4s, 3.m4s … )

400 Kbps segment folder ->  /segments/main/news400 contains (1.m4s, 2.m4s, 3.m4s … )

播放列表或.mpd文件包含明确列出所有各种比特率文件所在位置的 XML。

xml
<?xml version="1.0"?>
  <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" profiles="urn:mpeg:dash:profile:isoff-main:2011" type="static" mediaPresentationDuration="PT0H9M56.46S">
    <BaseURL>
      http://example.com/segments
    </BaseURL>
    <Period start="PT0S">
      <AdaptationSet bitstreamSwitching="true">

        <Representation id="0" codecs="avc1" mimeType="video/mp4" width="320" height="240" startWithSAP="1" bandwidth="46986">
          <SegmentBase>
            <Initialization sourceURL="main/news100/1.m4s" range="0-862"/>
          </SegmentBase>
          <SegmentList duration="1">
            <SegmentURL media="main/news100/2.m4s" mediaRange="863-7113"/>
            <SegmentURL media="main/news100/3.m4s" mediaRange="7114-14104"/>
            <SegmentURL media="main/news100/4.m4s" mediaRange="14105-17990"/>
          </SegmentList>
        </Representation>

        <Representation id="1" codecs="avc1" mimeType="video/mp4" width="320" height="240" startWithSAP="1" bandwidth="91932">
          <SegmentBase>
            <Initialization sourceURL="main/news200/1.m4s" range="0-864"/>
          </SegmentBase>
          <SegmentList duration="1">
            <SegmentURL media="main/news200/2.m4s" mediaRange="865-11523"/>
            <SegmentURL media="main/news200/3.m4s" mediaRange="11524-25621"/>
            <SegmentURL media="main/news200/4.m4s" mediaRange="25622-33693"/>
          </SegmentList>
        </Representation>

        <Representation id="1" codecs="avc1" mimeType="video/mp4" width="320" height="240" startWithSAP="1" bandwidth="270370">
          <SegmentBase>
            <Initialization sourceURL="main/news300/1.m4s" range="0-865"/>
          </SegmentBase>
          <SegmentList duration="1">
            <SegmentURL media="main/news300/2.m4s" mediaRange="866-26970"/>
            <SegmentURL media="main/news300/3.m4s" mediaRange="26971-72543"/>
            <SegmentURL media="main/news300/4.m4s" mediaRange="72544-95972"/>
          </SegmentList>
        </Representation></AdaptationSet>
    </Period>
  </MPD>

MPD 文件告诉浏览器各种媒体片段位于何处,它还包括诸如 mimeType 和编解码器之类的元数据,以及其他详细信息,例如字节范围。通常,这些文件将为您生成。

注意:您还可以将音频和视频流分成单独的文件,然后可以根据带宽分别对它们进行优先级排序和提供服务。

生成 MPD 文件后,您可以从<video>元素中按预期引用它

html
<video src="my.mpd" type="application/dash+xml"></video>

最好提供一个备用方案

html
<video>
  <source src="my.mpd" type="application/dash+xml" />
  <!-- fallback -->
  <source src="my.mp4" type="video/mp4" />
  <source src="my.webm" type="video/webm" />
</video>

注意:MPEG-DASH 播放依赖于dash.js和浏览器对媒体源扩展的支持,请参阅最新的dash.js 参考播放器

HLS 编码

HTTP 实时流 (HLS) 是 Apple 实现的一种基于 HTTP 的媒体流协议。它已集成到 iOS 和 OSX 平台中,并且在移动和桌面 Safari 以及大多数 Android 设备上都能很好地工作,但有一些注意事项

媒体通常编码为 MPEG-4(H.264 视频和 AAC 音频),并打包到 MPEG-2 传输流中,然后将其分解成片段并保存为一个或多个.ts媒体文件。Apple 提供工具将媒体文件转换为适当的格式。

HLS 编码工具

有许多有用的工具可用于 HLS 编码

  • 流片段器——Apple 为 Mac 平台提供的工具——从本地网络获取媒体流,并将媒体分成大小相等的媒体文件以及索引文件。
  • Apple 还为 Mac 提供了文件片段器——它接收适当编码的文件,将其分解并生成索引文件,方式类似于流片段器。

注意:您可以在使用 HTTP 实时流中找到有关这些工具的更多详细信息。

索引文件(播放列表)

HLS 索引文件(类似于 MPEG-DASH 的.mpd文件)包含有关所有媒体片段所在位置的信息,以及其他元数据,例如带宽应用程序。Apple 使用.m3u8格式(其.m3u播放列表格式的扩展)作为索引文件——请参见下面的示例

#EXT-X-VERSION:3
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXT-X-MEDIA-SEQUENCE:1

# Old-style integer duration; avoid for newer clients.
#EXTINF:10,
http://media.example.com/segment0.ts

# New-style floating-point duration; use for modern clients.
#EXTINF:10.0,
http://media.example.com/segment1.ts
#EXTINF:9.5,
http://media.example.com/segment2.ts
#EXT-X-ENDLIST

注意:有关如何为 Apple 的 HLS 格式编码媒体的全面信息,请参阅Apple 的开发者页面

另请参阅

有关自适应流的更多资源。

一般信息

HLS 概述和参考

MPEG-DASH 概述和参考

MPEG-DASH 工具