媒体流式传输基础知识

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 定义了一种名为 Media Source Extensions (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 准备媒体文件,下一部分将介绍该内容。