多媒体前端技术入门指南

291次阅读  |  发布于3年以前

随着B站、抖音、快手、淘宝直播等直播视频平台的快速崛起,前端衍生出了多媒体技术方向,各公司的传统前端团队里陆续出现了一支新军:Web多媒体团队。光看团队Title,这应该是一个拥有前端×多媒体交叉领域稀有技能的群体。阿里巴巴内部也存在众多Web多媒体团队,在内部我们针对新人整理了一份多媒体前端技术入门指南,今天将这份入门指南也对外分享出来,让大家了解我们近几年在该领域有哪些方向的工作,有哪些实践和落地,本文将从以下几个方面带着大家一窥究竟:

  1. 什么是多媒体前端?
  2. W3C标准的媒体技术
  3. 播放场景和解决方案
  4. 面向消费:直播视频里的业务体系
  5. 面向生产:直播推流、视频剪辑等工具
  6. 阿里巴巴前端委员会多媒体方向的发展和规划

什么是多媒体前端?

利用专业的前端能力,解决多媒体场景下各类技术和业务问题的前端,称之为多媒体前端。目前的多媒体前端主要从两类人群转化而来,一类是学数字媒体专业后从事前端开发的,一类是专业做前端后再学习多媒体的。这是两个成熟的知识体系交叉碰撞后的一个新的工作领域,需要具备高度还原、体验把控、跨端、工程化等前端开发能力,又要具有音视频基础、流媒体协议、播放技术、Web媒体技术等多媒体能力,目前这类人才的缺口还非常大。

W3C 标准的媒体技术

最开始接触多媒体前端开发,一般场景比较简单,比如在网页上播放一个视频/音频,实现基础的播放控制(播放、暂停、进度条、音量大小、静音等)。在HTML5标准之前如果要在浏览器里播放视频内容,需要使用Adobe Flash或微软的Silverlight等插件,但是插件存在需要用户安装的不便捷和不安全等问题,因此W3C的HTML5标准中定义了一系列新的媒体元素来避免使用插件。以下是媒体开发者常用的HTML元素:

HTML元素

浏览器提供的媒体播放功能都是相当简单的,一个 video 或者 audio 标签再加上src就搞定了,但这缺少了诸如视频分段加载、视频码率切换、部分加载、内存管理等现代播放器应该有的功能,需要更定制化的播放需求,或者更丰富的多媒体应用,就要使用媒体API:

媒体API

除了这些媒体API,还有一些技术通常与媒体API共同使用:

与媒体 API 共同使用的技术

播放场景和解决方案

前文提到浏览器里通过<video>就能实现视频播放了,那还需要我们前端做些什么呢?其实<video>也存在很多限制,我们要先从媒体内容的封装格式和编码格式说起。

媒体内容源文件都是比较大的,为了便于传输和存储,需要对原视频文件通过编码来压缩文件大小,再通过容器封装将压缩后的视音频、字幕组合到一个容器内,这就是 编码容器封装 的过程(可以用 压缩饼干封袋包装 来理解,会出现很多不同的压缩工艺和包装规格)。

那么在播放端进行播放时,就要进行相应的 解封装解码 (先拆开包装拿出饼干,享用饼干可以直接吃、也可以碾碎了吃、也可以泡着牛奶吃)。浏览器自带的播放器<video>标签拥有解封装和解码功能,但对媒体内容的格式是有所限制的(浏览器只会拆开特定的包装方式,只能消化特定的饼干吃法)。那浏览器碰到“不会拆、不消化的饼干”,我们要怎么喂给<video>呢?

除了容器格式、编码格式,还有流媒体协议、渲染容器、多实例播放等等问题需要多媒体前端一一解决,下面来分别介绍:

多协议、多容器格式

随着流媒体业务发展,出现了很多新的传输协议,媒体内容进一步包含在一层传输协议中(以HLS协议为例,增加了m3u8索引文件,并将源文件内容分片后封装到了一个个 TS 容器格式中),这样<video>就无法识别了。要支持多协议、多容器格式的播放,开发者可以通过 MSE 来帮助浏览器识别并处理,将媒体内容 转封装 成可识别的容器格式(如MP4),这样<video>就可以识别并播放各种媒体内容了。

上文提到的B站的flv.js以及社区的hls.js都是利用 MSE 来解决多协议、多容器格式的播放器库。

1. flv.js

flv.js是Bilibili网站开源的HTML5 flv播放器,基于HTTP-FLV流媒体协议,通过纯JS实现FLV转封装,使flv格式文件能在Web上进行播放。

但是flv.js也不是所有的flv格式视频都能播放,并且对浏览器环境也有一定的要求,以下是flv.js的使用限制:

2. hls.js

hls.js是基于Http Live Stream协议开发,利用Media Source Extension,用于实现HLS在web上播放的一款js播放库。

由于HLS协议由苹果提出,并且在移动端设备上广泛支持,因此可以被广泛应用于直播场景。而hls.js在pc端只需要支持MSE便可以应用,移动端使用原生video标签设置src便可完成播放。hls.js会先请求m3u8文件,然后读取到文件的分片列表,以及视频的编码格式、时长等。随后会按照顺序去对TS分片进行请求,然后借助MSE将二进制buffer内容进行合流,组成一个可播的媒体资源文件。

阿里内部也有多个团队有类似播放器产品,如阿里云的Aliplayer、淘系的VideoX、优酷的KPlayer,实现思路都基本一致。

3. 阿里云 Aliplayer

Aliplayer 经过几个版本的迭代演进,整个架构更加合理,赋予本身和用户更多的扩展能力,具有独立增加播放类型和功能的能力,比如要h5支持flv的播放能力,只需要新增Flv Extend功能扩展模块,而不用修改其他模块的代码,比如HLS Extend等等,确保不影响其他功能的正常工作,保持每个版本发布的稳定性。

4. 淘系 VideoX

Videox 底层的播放层也经历了几次变化,从最开始简单的 <video>标签,到通过MSE来扩展各种格式的<video>标签,到通过WebAssembly来对编解码格式进行扩展的<canvas> + Web Audio API的方式,未来可能还有底层通信的扩展及上层互动能力的增强。

5. 优酷 KPlayer

KPlayer 目前的方案拆分的较细,包括多个库和组件,主要有KMux 转封装库、KDRM WebDRM插件、KCTRL 播放器控制行为的核心抽象、MediaEngine 解码&渲染&播放的核心抽象、KUI 嵌入式UI框架。KPlayer播放核心设计如下:

多编码格式

上一小节解决了浏览器<video>不支持的协议和格式(不会拆饼干包装)的问题,那遇到不支持的编码格式(不能消化的压缩工艺)该怎么办呢?

新的视频编码标准H.265、AV1等比传统H.264拥有更高压缩率,但浏览器<video>本身并不支持,而业务为了降低成本都全链路切换新的编码格式如H.265,那多媒体前端就要自己实现浏览器端的JS播放器。由于Javascript是一种动态解释型语言,性能比C++等语言差很多,处理多媒体数据时性能短板就体现出来,WebAssembly的出现解决了Javascript的性能短板,极大扩展浏览器端的多媒体处理能力和场景。

对于Web端H.265播放器,阿里内部有多个团队都进行了相应的尝试,包括优酷、阿里云、淘系、ICBU等,思路基本一致,都是通过FFmpeg + Webassembly来实现一个JS播放器,使用JS拉流、解封装,将FFmpeg的265解码能力编译成wasm模块供JS调用,视频经过FFmpeg解码出来YUV帧数据,通过WebGL绘制图像帧数据,而音频方面因为浏览器支持AAC、MP3等主流音频格式,音频数据直接通过Web Audio API进行播放。设计思路如下:

多渲染容器

上面描述的场景主要是PC的Web浏览器,但我们更多的业务场景在移动端,面向消费者的场景对播放的体验和性能要求非常高,于是引入了播放器的跨端支持问题,尤其是跨渲染容器(Webview/Weex/小程序)。端侧的播放器主要使用Native播放器,前端封装成Weex/同层渲染组件,在各渲染容器中运行。

在端侧如果采用原生video方案,存在兼容性及性能问题,播放器本身占用内存高,业务不规范使用会带来稳定性风险,甚至导致APP Crash。以端内H5为例,采用的是和Rax团队、客户端基础团队、客户端播放器团队一起打造的同层渲染方案:

多实例控制

前面提到的都是单个视频播放的场景,实际业务中还有同一个页面中多个播放器的场景,比如列表流、版头等,这时候就引入了播放器多实例控制的问题,需要保证页面内只有一个播放器播放(播放甜区)、内存管理等。

播放器需要具备强大的播控能力,即播放调度能力:

面向消费:直播视频里的业务体系

前面提到的都是单纯的播放功能,但实际的业务场景是直播间或者短视频全屏页,从播放器到直播间/短视频,还有很重要的一个部分就是用户互动层,这就引入了直播视频里的业务体系。 以直播为例,对于观众有两个诉求:观看直播、参与互动。一般直播的设计如下: 通常的直播间架构分为三种:Web直播间、Hybrid直播间、小程序直播间,比如钉钉公开课直播采用的是Web直播间架构,蚂蚁、天猫精灵等采用的是小程序直播间架构,其他绝大多数的业务采用的是Hybrid直播间架构。

Web 直播间架构

纯Web直播间,是指主要运行在Web浏览器上的H5直播间,主要包括H5播放器、事件通道、UI组件等。但移动端浏览器兼容性较差,移动端播放延时较高,所以一般对体验和性能要求高的业务场景,都会选择Hybrid直播间架构。 Hybrid直播间使用原生的播放器能力,兼容性更好,体验更流畅;同时事件通道是Native通道,相对于Web直播间 websocket更安全。

Hybrid 直播间架构

Hybrid直播间的宿主是Native,使用原生播放器,互动玩法是在播放器上面盖了一层互动层(Webview或WEEX容器),并且能够和播放器通信。 Hybrid架构中互动层方案也经历了几个阶段的演变,从最开始的每个玩法组件一个独立层,到所有玩法组件打包到一个层,再到定义出直播容器来动态加载组件: 直播容器具有以下几个特征:- 统一规范的组件消息协议:包括组件包名、组件行为、业务自定义字段等

在Hybrid架构下开发调试组件,需要一个完整的直播间环境和直播容器才能开发调试,没有配套的工程体系,组件开发很低效。所以这种架构下还需要配套的工程体系,主要包含以下几个部分:- def 套件:直播间组件开发脚手架,增强调试能力,包括直播间模拟、调试代理、热更新、编译检测等功能

多媒体前端团队通过打造直播容器和工程体系,才能高效、稳定的构建出直播视频里的业务体系。 当然Hybrid架构因为其联合Native和前端带来了架构上的复杂度,特别是在直播和视频上下滑时直播间的状态管理、播放器实例和webview实例管理等,会导致一些状态问题,比如某直播平台曾出现过“神奇三串”bug:薇娅 直播间里播放的是 李佳琦 的直播流,但展示的是 叶一茜 的商品:

基于Hybrid架构我们可以考虑进一步升级,让播放器和互动层更加融合,形成「超级Video」,或者叫可交互的Video方案,甚至定义新的 <span style="color: rgb(0, 0, 0);font-size: 16px;"><video> 标准。

小程序直播间架构

随着跨端业务的出现,尤其是跨APP的场景,Hybrid直播间架构就像个大胖子,天然没有跨端优势(客户端集成、维护SDK成本极高),在这个背景下小程序直播间架构出现了。小程序直播间设计上分为以下几层:

由蚂蚁和淘宝直播联合打造的小程序直播方案,在多个APP端(包括外部媒体APP)得到了广泛应用。

面向生产:直播推流、视频剪辑等工具

前面提到的更多的是面向消费侧的场景,随着业务的发展,各个多媒体团队开始更加关注生产侧的能力建设,毕竟内容的生产是整个内容生态的血液供给。作为开发者,需要给商家、主播、达人等创作者提供高效、好用的生产工具。在生产侧主要有两个方向,一个是面向直播的直播推流工具,一个是面向视频的视频剪辑工具。

直播推流

直播推流前端主要有两种方案:

视频剪辑

相对于直播的生产,视频的生产覆盖度更广,参与到这个方向建设的团队也更多,包括阿里妈妈、淘系、盒马、1688、阿里小蜜、蚂蚁等。生产文章内容需要用富文本编辑器,那生产视频内容就需要视频剪辑工具,当然这两者的复杂度是完全不一样的。我们打造或智能生产、或高效好用的深度剪辑工具,都是期望降低生产成本,能像编辑文章一样方便地剪辑视频。

传统的桌面剪辑软件是提供一个GUI界面,给用户提供所见既所得的编辑效果反馈,并在编辑完成之后产生编辑描述数据,最后交由图形图像模块、音频处理模块以及视频编码模块去生成最终视频文件。参考大部分开源剪辑软件实现,前半部分GUI通过操作系统图形界面或跨平台如QT、SDL、SWT方式实现,这部分我们称之为 “GUI前端”,而后面涉及图形图像、音频、编码相关部分,大部分都会有一套媒体编辑内核来支撑,例如Linux下著名的MLT、GStreamer等等,这里我们称之为 “编辑内核” 基于以上 GUI前端 + 编辑内核 的思路之下,多媒体前端在剪辑工具上通常有以下几种实现方案:

玩法生产

除了直播推流和视频剪辑,还有结合流媒体识别的玩法生产,比如人脸检测、手势检测、物体识别等叠加滤镜、贴纸、美颜美型、文字等特效,实现直播和视频的媒体智能玩法。外界有Facebook的AR Studio、Snapchat的Lens Studio、抖音的Effect Creator,内部有淘系的MAI(MediaAI Studio),广泛应用于淘宝直播、逛逛等业务。

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8