「视频直播技术详解」系列之六:现代播放器原理

​关于直播的技术文章很多,成体系的很少。咱们将用七篇文章,更系统化地介绍当下大热的视频直播各环节的关键技术,帮助视频直播创业者们更全面、深刻地了解视频直播技术,更好地技术选型。html

本系列文章大纲以下:前端

(一)采集git

(二)处理github

(三)编码和封装算法

(四)推流和传输浏览器

(五)延迟优化缓存

(六)现代播放器原理安全

(七)SDK 性能测试模型服务器

在上一篇延迟优化中,咱们分享了很多简单实用的调优技巧。本篇是《视频直播技术详解》系列之六:现代播放器原理。网络


 

近年来,多平台适配需求的增加致使了流媒体自适应码率播放的兴起,这迫使 Web 和移动开发者们必须从新思考视频技术的相关逻辑。首先,巨头们分分发布了 HLS、HDS 和 Smooth Streaming 等协议,把全部相关细节都隐藏在它们专供的 SDK 中。开发者们无法自由的修改播放器中的多媒体引擎等逻辑:你无法修改自适应码率的规则和缓存大小,甚至是你切片的长度。这些播放器可能用起来简单,可是你没有太多去定制它的选择,即使是糟糕的功能也只能忍受。

可是随着不一样应用场景的增长,可定制化功能的需求愈来愈强。仅仅是直播和点播之间,就存在不一样的 buffer 管理、ABR 策略和缓存策略等方面的差异。这些需求催生了一系列更为底层关于多媒体操做 API 的诞生:Flash 上面的 Netstream,HTML5 上的 Media Source Extensions,以及 Android 上的 Media Codec,同时业界又出现了一个基于 HTTP 的标准流格式 MPEG-DASH。这些更高级的能力为开发者提供了更好的灵活性,让他们能够构建适合本身业务需求的播放器和多媒体引擎。

今天咱们来分享一下如何构建一个现代播放器,以及构建这样一个播放器须要哪些关键组件。一般来讲,一个典型的播放器能够分解成三部分:UI、 多媒体引擎和解码器,如图 1 所示:

图 1. 现代播放器架构

用户界面(UI):这是播放器最上层的部分。它经过三部分不一样的功能特性定义了终端用户的观看体验:皮肤(播放器的外观设计)、UI(全部可自定义的特性如播放列表和社交分享等)以及业务逻辑部分(特定的业务逻辑特性如广告、设备兼容性逻辑以及认证管理等)。

多媒体引擎:这里处理全部播放控制相关的逻辑,如描述文件的解析,视频片断的拉取,以及自适应码率规则的设定和切换等等,咱们将在下文中详细讲解这部份内容。因为这些引擎通常和平台绑定的比较紧,所以可能须要使用多种不一样的引擎才能覆盖全部平台。

解码器和 DRM 管理器:播放器最底层的部分是解码器和 DRM 管理器,这层的功能直接调用操做系统暴露出来的 API。解码器的主要功能在于解码并渲染视频内容,而 DRM 管理器则经过解密过程来控制是否有权播放。

接下来咱们将使用例子来介绍各层所扮演的不一样角色。

1、用户界面(UI)

UI 层是播放器的最上层,它控制了你用户所能看到和交互的东西,同时也可使用你本身的品牌来将其定制,为你的用户提供独特的用户体验。这一层最接近于咱们说的前端开发部分。在 UI 内部,咱们也包含了业务逻辑组件,这些组件构成了你播放体验的独特性,虽然终端用户无法直接和这部分功能进行交互。

UI 部分主要包含三大组件:

1. 皮肤

皮肤是对播放器视觉相关部分的统称:进度控制条、按钮和动画图标等等,如图 2 所示。和大部分设计类的组件同样,这部分组件也是使用 CSS 来实现的,设计师或者开发者能够很方便的拿来集成(即使你使用的是 JW Player 和 Bitdash 这种整套解决方案)。

图 2. 播放器皮肤

2. UI 逻辑

UI 逻辑部分定义了播放过程当中和用户交互方面全部可见的交互:播放列表、缩略图、播放频道的选择以及社交媒体分享等。基于你预期达到的播放体验,还能够往这部分中加入不少其它的功能特性,其中有不少以插件的形式存在了,或许能够从中找到一些灵感:Plugins · videojs/video.js Wiki · GitHub 逻辑部分包含的功能较多,咱们不一一详细介绍,直接以 Eurosport 播放器的 UI 来做为例子直观感觉一下这些功能。

图 3. Eurosport 播放器的用户界面


从图 3 能够看出,除了传统的 UI 元素以外,还有一个很是有趣的特性,在用户观看 DVR 流媒体的时候,直播以小视窗的形式展现,观众能够经过这个小窗口随时回到直播中。因为布局或者 UI 和多媒体引擎彻底独立,这些特性在 HTML5 中使用 dash.js 只须要几行代码就能实现。对于 UI 部分来讲,最好的实现方式是让各类特性都以插件/模块的形式添加到 UI 核心模块中。

3. 业务逻辑

除了上面两部分「可见」的功能特性以外,还有一个不可见的部分,这部分构成了你业务的独特性:认证和支付、频道和播放列表的获取,以及广告等。这里也包含一些技术相关的东西,好比用于 A/B 测试模块,以及和设备相关的配置,这些配置用于在多种不一样类型的设备之间选择多个不一样的媒体引擎。

为了揭开底层隐藏的复杂性,咱们在这里更详细的讲解一下这些模块:

设备检测与配置逻辑:这是最重要的特性之一,由于它将播放和渲染剥离开来了。例如,基于你浏览器的不一样版本,播放器可能会自动为你选择一个基于 HTML5 MSE 的多媒体引擎 hls.js,或者为你选择一个基于 flash 的播放引擎 FlasHls 来播放 HLS 视频流。这部分的最大特色在于,不管你使用什么样的底层引擎,在上层均可以使用相同的 JavaScript 或者 CSS 来定制你的 UI 或者业务逻辑。

可以检测用户设备的能力容许你按需配置终端用户的体验:若是是在移动设备而非 4K 屏幕设备上播放,你可能须要从一个较低的码率开始。

A/B 测试逻辑:A/B 测试是为了可以在生产环节中灰度部分用户。例如,你可能会给部分 Chrome 用户提供一个新的按钮或者新的多媒体引擎,而且还能保证它全部的工做都正常如期进行。

广告(可选):在客户端处理广告是最复杂的业务逻辑之一。如 videojs-contrib-ads 这个插件模块的流程图给出同样,插入广告的流程中包含多个步骤。对于 HTTP 视频流来讲,你或多或少会用到一些已有的格式如 VAST、VPAID 或者 Google IMA,它们可以帮你从广告服务器中拉取视频广告(一般是过期的非自适应格式),放在视频的前期、中期和后期进行播放,且不可跳过。

总结:

针对你的定制化需求,你可能选择使用包含全部经典功能的 JW Player 来播放(它也容许你定制部分功能),或者基于 Videojs 这样的开源播放器来定制你本身的功能特性。甚至为了在浏览器和原生播放器之间统一用户体验,你也能够考虑使用 React Native 来进行 UI 或者皮肤的开发,使用 Haxe 来进行业务逻辑的开发,这些优秀的库均可以在多种不一样类型的设备之间共用同一套代码库。

图 4. 业务逻辑流程图

2、多媒体引擎

近年来,多媒体引擎更是以一种全新独立的组件出如今播放器架构中。在 MP4 时代,平台处理了全部播放相关的逻辑,而只将一部分多媒体处理相关的特性(仅仅是播放、暂停、拖拽和全屏模式等功能)开放给开发者。

然而,新的基于 HTTP 的流媒体格式须要一种全新的组件来处理和控制新的复杂性:解析声明文件、下载视频片断、自适应码率监控以及决策指定等等甚至更多。起初,ABR 的复杂性被平台或者设备提供商处理了。然而,随着主播控制和定制播放器需求的递增,一些新的播放器中慢慢也开放了一些更为底层的 API(如 Web 上的 Media Source Extensons,Flash 上的 Netstream 以及 Android 平台的 Media Codec),并迅速吸引来了不少基于这些底层 API 的强大而健壮的多媒体引擎。

图 5. Google 提供的多媒体处理引擎 Shakaplayer 的数据流程图


接下来咱们将详细讲解现代多媒体处理引擎中各组件的细节:

1. 声明文件解释和解析器

在基于 HTTP 的视频流中,一切都是以一个描述文件开始。该声明文件包含了媒体服务器所需理解的元信息:有多少种不一样类型的视频质量、语言以及字母等,它们分别是什么。解析器从 XML 文件(对于 HLS 来讲则是一种特殊的 m3u8 文件)中取得描述信息,而后从这些信息中取得正确的视频信息。固然,媒体服务器的类型不少,并非全部都正确的实现了规范,所以解析器可能须要处理一些额外的实现错误。

一旦提取了视频信息,解析器则会从中解析出数据,用于构建流式的视觉图像,同时知道如何获取不一样的视频片断。在某些多媒体引擎中,这些视觉图像先以一副抽象多媒体图的形式出现,而后在屏幕上绘制出不一样 HTTP 视频流格式的差别特征。

在直播流场景中,解析器也必须周期性的从新获取声明文件,以便得到最新的视频片断信息。

2. 下载器(下载声明文件、多媒体片断以及密钥)

下载器是一个包装了处理 HTTP 请求原生 API 的模块。它不只用于下载多媒体文件,在必要的时候也能够用于下载声明文件和 DRM 密钥。下载器在处理网络错误和重试方面扮演着很是重要的角色,同时可以收集当前可用带宽的数据。

注意:下载多媒体文件可能使用 HTTP 协议,也可能使用别的协议,如点对点实时通讯场景中的 WebRTC 协议。

3. 流播放引擎

流播放引擎是和解码器 API 交互的中央模块,它将不一样的多媒体片断导入编码器,同时处理多码率切换和播放时的差别性(如声明文件和视频切片的差别,以及卡顿时的自动跳帧)。

4. 资源质量参数预估器(带宽、CPU 和帧率等)

预估器从各类不一样的维度获取数据(块大小,每片断下载时间,以及跳帧数),并将其汇聚起来用于估算用户可用的带宽和 CPU 计算能力。这是输出用于 ABR (Adaptive Bitrate, 自适应码率)切换控制器作判断。

5. ABR 切换控制器

ABR 切换器多是多媒体引擎中最为关键的部分——一般也是你们最为忽视的部分。该控制器读取预估器输出的数据(带宽和跳帧数),使用自定义算法根据这些数据作出判断,告诉流播放引擎是否须要切换视频或者音频质量。该领域有不少研究性的工做,其中最大的难点在于在再缓冲风险和切换频率(太频繁的切换可能致使糟糕的用户体验)之间找到平衡。

6. DRM 管理器(可选组件)

今天全部的付费视频服务都基于 DRM 管理,而 DRM 则很大程度上依赖于平台或者设备,咱们将在后续讲解播放器的时候看到。多媒体引擎中的 DRM 管理器是更底层解码器中内容解密 API 的包装。只要有可能,它会尽可能经过抽象的方式来屏蔽浏览器或者操做系统实现细节的差别性。该组件一般和流处理引擎紧密链接在一块儿,由于它常常和解码器层交互。

7. 格式转换复用器(可选组件)

后文中咱们将看到,每一个平台在封包和编码方面都有它的局限性(Flash 读的是 FLV 容器封装的 H.264/AAC 文件,MSE 读的是 ISOBMFF 容器封装的 H.264/AAC 文件)。这就致使了有些视频片断在解码以前须要进行格式转换。例如,有了 MPEG2-TS 到 ISOBMFF 的格式转换复用器以后,hls.js 就能使用 MSE 格式的内容来播放 HLS 视频流。多媒体引擎层面的格式转换复用器曾经遭受质疑;然而,随着现代 JavaScript 或者 Flash 解释权性能的提高,它带来的性能损耗几乎能够忽略不计,对用户体验也不会形成多大的影响。

总结

多媒体引擎中也有很是多的不一样组件和特性,从字幕到截图到广告插入等等。接下来咱们也会单独写一篇文章来对比多种不一样引擎的差别,经过一些测试和市场数据来为引擎的选择给出一些实质性的指导。值得注意的是,要构建一个兼容各平台的播放器,提供多个可自由替换的多媒体引擎是很是重要的,由于底层解码器是和用户平台相关的,接下来咱们将重点讲解这方面的内容。

3、解码器和 DRM 管理器

出于解码性能(解码器)和安全考虑(DRM),解码器和 DRM 管理器与操做系统平台密切绑定。

图 6. 解码器、渲染器和 DRM 工做流程图

1. 解码器

解码器处理最底层播放相关的逻辑。它将不一样封装格式的视频进行解包,并将其内容解码,而后将解码后的视频帧交给操做系统进行渲染,最终让终端用户看到。

因为视频压缩算法变得愈来愈复杂,解码过程是一个须要密集计算的过程,而且为了保证解码性能和流畅的播放体验,解码过程须要强依赖于操做系统和硬件。如今的大部分解码都依赖于 GPU 加速解码的帮助(这也是为何免费而更强大的 VP9 解码器没有赢得 H.264 市场地位的缘由之一)。若是没有 GPU 的加速,解码一个 1080P 的视频就会占去 70% 左右的 CPU 计算量,而且丢帧率还可能很严重。

在解码和渲染视频帧的基础之上,管理器也提供了一个原生的 buffer,多媒体引擎能够直接与该 buffer 进行交互,实时了解它的大小并在必要的时候刷新它。

咱们前面提到,每一个平台都有它本身的渲染引擎和相应的 API:Flash 平台有 Netstream,Android 平台有 Media Codec API,而 Web 上则有标准的 Media Sources Extensions。MSE 愈来愈吸引眼球,未来可能会成为继浏览器以后其它平台上的事实标准。

2. DRM 管理器

图 7. DRM 管理器

今天,在传输工做室生产的付费内容的时候,DRM 是必要的。这些内容必须防止被盗,所以 DRM 的代码和工做过程都向终端用户和开发者屏蔽了。解密过的内容不会离开解码层,所以也不会被拦截。

为了标准化 DRM 以及为各平台的实现提供必定的互通性,几个 Web 巨头一块儿建立了通用加密标准Common Encryption (CENC) 和通用的多媒体加密扩展Encrypted Media Extensions,以便为多个 DRM 提供商(例如,EME 可用于 Edge 平台上的 Playready 和 Chrome 平台上的 Widewine)构建一套通用的 API,这些 API 可以从 DRM 受权模块读取视频内容加密密钥用于解密。

CENC 声明了一套标准的加密和密钥映射方法,它可用于在多个 DRM 系统上解密相同的内容,只须要提供相同的密钥便可。

在浏览器内部,基于视频内容的元信息,EME 能够经过识别它使用了哪一个 DRM 系统加密,并调用相应的解密模块(Content Decryption Module, CDM)解密 CENC 加密过的内容。解密模块 CDM 则会去处理内容受权相关的工做,得到密钥并解密视频内容。

CENC 没有规定受权的发放、受权的格式、受权的存储、以及使用规则和权限的映射关系等细节,这些细节的处理都由 DRM 提供商负责。

4、总结

今天咱们深刻了解了一下视频播放器三个层面的不一样内容,这个现代播放器结构最优秀之处在于其交互部分彻底和多媒体引擎逻辑部分分离,让主播能够无缝而自由灵活的定制终端用户体验,同时在多种不一样终端设备上使用不一样的多媒体引擎还能保证顺利播放多种不一样格式的视频内容。

在 Web 平台,得益于多媒体引擎如 dash.js、Shaka Player 和 hls.js 这些趋于成熟库的帮助, MSE 和 EME 正在成为播放的新标准,同时也愈来愈多有影响力的厂家使用这些播放引擎。近年来,注意力也开始伸向机顶盒和互联网电视,咱们也看到愈来愈多这样的新设备使用 MSE 来做为其底层多媒体处理引擎。咱们也将持续投入更多的力量去支持这些标准。

 

本文由七牛云布道师何李石翻译自How Modern Video Players Work,原文可去七牛云官方博客查看。

相关文章
相关标签/搜索