媒体流式传输基础知识

Derek Herman
Derek Herman
Jaroslav Polakovič
Jaroslav Polakovič

在本文中,您将了解媒体流式传输的更高级概念,最后应该对各种流式传输用例、协议和扩展程序有充分的了解。我们先来解释一下究竟什么是流式传输

媒体流式传输是一种逐个传送和播放媒体内容的方法。播放器不会加载单个文件,如果不针对网络进行优化,速度可能会很慢,而是会读取描述目标媒体如何拆分为单个数据块的清单文件。媒体块稍后会在运行时动态拼接回 - 可能采用不同的比特率,您稍后将对此进行介绍。

请注意,要在您的网站上提供流式传输,服务器必须支持 Range HTTP 请求标头。如需详细了解 Accept-Ranges 标头,请参阅 <video> 和 <source> 标记一文。

流式传输用例

生成媒体块和描述数据流的必要清单并非易事,但流式传输解锁了一些有趣的用例,仅将 <video> 元素指向一组静态源文件是不可能实现的。我们将在后面的部分中详细了解如何向网页添加媒体内容。首先,如果您想要执行更多操作,而不只是将多个文件加载到 <video> 元素中,那么您应该了解流式传输多媒体的一些用例。

  • 自适应流式传输是指媒体块以多种比特率编码,适合客户端当前可用媒体带宽的最高质量媒体块。
  • 在直播中,您可以对媒体块进行编码并实时提供。
  • 注入媒体是指将诸如广告之类的其他媒体注入到流中,而播放器无需更改媒体来源。

流式传输协议

Web 上最常用的两种流式传输协议是基于 HTTP 的动态自适应流式传输 (DASH) 和 HTTP Live Streaming (HLS)。支持这些协议的播放器将提取生成的清单文件,确定要请求的媒体块,然后将它们组合成最终的媒体体验。

使用 <video> 播放直播

许多浏览器都不会以原生方式播放您的视频流。虽然针对 HLS 播放提供一些原生支持,但浏览器通常不支持原生 DASH 流播放。这通常意味着,仅将 <video> 元素中的 <source> 指向清单文件是不够的。

<video controls>
  <source src="manifest.mpd" type="application/dash+xml">
</video>

看似的不足之处实际上是伪装的实力。数据流非常强大,使用数据流的应用具有不同的需求。

清单文件通常描述单个媒体的多个变体。可以考虑采用不同的比特率、多个音轨,甚至是以不同格式编码的同一媒体。

有些应用可能需要在缓冲区中保留大量视频,有些应用可能希望从即将发布的剧集中预提取前几秒的视频,还有一些应用想要实现自己的逻辑以实现自适应流式传输。此时,您希望使用某种内置的浏览器功能来生成要播放的媒体流,恰好有这样一个。

媒体来源扩展程序

幸运的是,W3C 定义了一种称为媒体来源扩展 (MSE) 的方法,可让 JavaScript 生成媒体流。简而言之,MSE 允许开发者将 MediaSource 对象附加到 <video> 元素,并使其播放提取到连接到 MediaSource 实例的缓冲区中的所有媒体数据。

基本示例

const videoEl = document.querySelector('video');
const mediaSource = new MediaSource();

video.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener(
  'sourceopen',
  () => {
    const mimeString = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
    const buffer = mediaSource.addSourceBuffer(mimeString);

    buffer.appendBuffer( /* Video data as `ArrayBuffer` object. */ )
  }
);

上面的简化示例说明了以下几点:

  • <video> 而言,它从网址接收媒体数据。
  • 生成的网址只是一个指向 MediaSource 实例的指针。
  • MediaSource 实例会创建一个或多个 SourceBuffer 实例。
  • 然后,我们只需将二进制媒体数据附加到缓冲区中,例如使用 fetch

虽然这些基本概念很简单,您肯定可以从头开始编写与 DASH 和 HLS 兼容的视频播放器,但大多数人通常会选择现有的成熟开源解决方案之一,例如 Shaka PlayerJW PlayerVideo.js 等。

不过,我们创建了一个名为 Kino 的演示版 Media PWA,该 PWA 演示了如何开发您自己的基本流媒体网站,仅使用简单的 <video> 元素提供离线媒体播放功能。我们的路线图中计划支持各种框架、数字版权管理及其他功能。因此,请不时回来查看更新,或提出功能请求。 如需了解详情,请参阅支持离线流式传输的 PWA 文章。

媒体块格式

长期以来,DASH 和 HLS 都需要以不同的格式对媒体块进行编码。不过,在 2016 年,我们向 HLS 添加了对标准碎片化 MP4 (fMP4) 文件的支持,而 DASH 也支持这种格式。

使用 fMP4 容器和 H.264 编解码器的视频区块受这两种协议的支持,并且可供绝大多数玩家播放。这样,内容制作者只需对视频进行编码一次,从而节省时间和磁盘空间

为了获得更好的质量并减小文件大小,您可能需要选择使用 VP9 等更高效的格式对多组媒体块进行编码。但在继续推进之前,您需要先了解如何准备用于 Web 的媒体文件,接下来就好好了解一下。