媒体流式传输基础知识

德里克·赫尔曼
Derek Herman
雅罗斯拉夫·波拉科维奇
Jaroslav Polakovič

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

媒体流式传输是一种逐段传送和播放媒体内容的方式。播放器会读取描述目标媒体如何拆分为各个数据块的清单文件,而不是加载单个文件(如果未针对网络进行优化,加载速度可能很慢)。系统稍后会将媒体块动态拼接在一起 - 可能以不同的比特率,稍后您会了解这一点。

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

流式传输用例

生成媒体块和描述数据流的必要清单并不简单,但流式传输可解锁一些有趣的用例,仅通过将 <video> 元素指向一组静态源文件是无法实现的。下一部分将详细了解如何向网页添加媒体。首先,除了将多个文件加载到 <video> 元素中之外,如果您想更进一步,则应了解流式多媒体的几种用例。

  • 自适应流式传输是指以多种比特率对媒体块进行编码,然后将适合客户端当前可用带宽的最高质量媒体块返回给媒体播放器。
  • 直播是指对媒体块进行编码并实时提供。
  • 注入媒体是指将其他媒体(如广告)注入流的操作,播放器无需更改媒体来源。

流式传输协议

网络上两种最常用的流式传输协议是 Dynamic Adaptive Streaming over 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,来演示如何开发自己的基本流媒体网站,该网站只需使用简单的 <video> 元素即可提供离线媒体播放功能。我们的路线图中有一些计划可以支持框架、数字版权管理以及其他功能。因此,请经常回来查看更新,或者请求新功能。 如需了解详情,请参阅支持离线流式传输的 PWA 一文。

媒体块格式

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

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

为了提高质量并减小文件大小,您可能需要选择使用更高效的格式(如 VP9)对多组媒体块进行编码,但在深入介绍之前,您需要先学习如何准备用于 Web 的媒体文件,接下来就是课程内容。