【ArchSummit架构师峰会】探讨数据与人工智能相互驱动的关系>>> 了解详情
写点什么

爱奇艺直播 WebAssembly 优化之路

  • 2019-10-31
  • 本文字数:3679 字

    阅读完需:约 12 分钟

爱奇艺直播WebAssembly优化之路

WebAssembly 技术简介

近几年,WebAssembly 技术非常火,可以说是成为了 JavaScript 一个新的转折点。JavaScript 自 1995 年诞生之日起,其性能问题就被大家诟病。直到 2008 年,很多浏览器加入了即时编译器,JavaScript 也开始引入 JITs,再加上 Google 等厂商对其的大力优化,其性能提升了 10 倍不止。由此,JavaScript 也开始跳出了浏览器的范围,在各个领域崭露头脚,比如后台使用的 Node.js 和桌面端使用的 Electron 等。


JIT 技术简而言之是在 JavaScript 解释执行时将常用的二进制代码块暂存下来,在下一次解释执行相同的代码块的时候可以直接运行暂存的二进制代码块,节约了解释的时间。那能不能将所有 JavaScript 代码一次性都编译成二进制,提升运行效率呢?WebAssembly 的出现回答了这个问题。


在 WebAssembly 出现之前,JavaScript 是浏览器里可以运行的唯一的编程语言。而 WebAssembly 技术使浏览器运行别的语言编写的程序变成了可能。目前可以使用 C、C++、Rust、Go、Java、C# 编译器(还有更多)来创建 wasm 模块。浏览器在运行时将 wasm 模块放在专有的虚拟机中运行。由于是二进制的文件,运行效率比解释执行的 JavaScript 脚本要高很多,因此,很多前端开发者也把 WebAssembly 技术视作下一代的前端技术。


目前 WebAssembly 的兼容性如下图所示:



可以看到,在新版本上,主流浏览器不管是在 PC 端还是移动端都支持了 WebAssembly,而且各大浏览器厂商还在持续支持此项技术,相信不久就会得到非常普遍的应用。

WebAssembly 和直播,不一样的火花

一直以来,爱奇艺生产的直播流有 mp4 和 flv 两种格式,但 Html5 的 video 标签原生只支持 mp4 的播放,如何解决 flv 格式在网页端播放的问题就摆在了所有人的面前。一般来说 flv 格式在网页端播放有以下几种解决方案:


1、使用 flash 播放器插件


不过因为性能和安全等各种问题,各大浏览器已经逐渐弱化了这种方式,Chrome 也将在 2020 年左右停止对 flash player 的支持,所以现在基本很少有人用了。


2、网页对 flv 格式的视频解码


使用 canvas 渲染图像,使用 audio 播放声音,相当于网页端做一个播放器,这也是可行的。但各大浏览器厂商对原生 video 控件会针对不同的平台做硬件加速渲染的优化,如果自己渲染的话,硬件加速这块便也需要自己做,这样会耗费极大的人力,并且效果也很难和浏览器原生的硬件加速相比。


3、在网页端将 flv 格式转成 mp4 格式然后使用原生播放器


这也是目前使用得最多的方案。这样既可以播放 flv 的直播流,也可以将渲染丢给原生播放器去做,充分发挥原生播放器的优化能力。


爱奇艺直播使用的就是第三种方式,当 flv 的直播流到达前端时,使用 JavaScript 将 flv 转换成 mp4,再交给原生播放器。但由于 JavaScript 运行效率较低,这部分的性能一直都令人不太满意,所以决定引入 WebAssembly 技术,看看是否能带来不一样的提升。现在打开任意的爱奇艺直播间,在后面输入__enablewasm__=true,就能打开 WebAssembly 转码模式,如下图所示:



体验上,两种模式都能满足流畅观看直播的需求。由此可见,WebAssembly 模块可以很完美地替换原来的 JavaScript 所写的转码模块。下面来看一下如何接入 WebAssembly。

接入 WebAssembly 的步骤

使用 WebAssembly 非常简单,总的来说,分为以下几步:


1、使用 c 编写 flv 转 mp4 的代码


首先定义 WebAssembly 被 js 调用的接口文件:



如果想在被编译成 wasm 文件后可以被 JavaScript 调用,就需要在可以被外部调用的函数前使用 EM_PORT_API 来标识,这样在后面编译的时候 WebAssembly 就会将此函数作为可被 JavaScript 调用的方法抛出。


然后还需定义一些 WebAssembly 调用 JavaScript 的接口,如下面所示:



主要是通知 js 转换 mp4 流的头部信息和已经转好的部分流的缓存区地址等,实际调用的代码需要使用 EM_ASM_()函数包起来,里面填上调用的 JavaScript 方法名和带的参数。


定义好接口后就是转码实现的部分了,这里涉及到 flv 和 mp4 格式的相关知识(对这两种格式不太了解的同学可以自行阅读相关文档)。整体转码采用 flv 和 mp4 双缓存区的模式,流程如下图所示:



a. JavaScript 获取到直播流后将流存入 flv 缓存区;


b. JavaScript 通知 WebAssembly 缓存区首地址和进度;


c. WebAssembly 请求缓存区数据;


d. WebAssembly 进行转码;


e. 将转好的 mp4 片段存入 mp4 缓存区;


f. WebAssembly 通知 JavaScript 转码进度;


最后由 JavaScript 通知原生播放器直接播放 mp4 缓存区的视频流。


2、使用 emcc 编译出 flv2Mp4.js 和 flv2Mp4.wasm


首先需要安装 emscripten 环境,安装和配置的具体步骤可以参考 emscripten 的官网


安装完成后就可以使用 emcc 命令编译 c 文件了,使用命令 emcc main.c -s TOTAL_MEMORY=268435456 -g -o flvToMp4.js,最终可以得到两个文件,flvToMp4.js 和 flvToMp4.wasm。


其中 flvToMp4.wasm 是实际转码的 code,flvToMp4.js 相当于接口文件,播放器可以通过引入 flvToMp4.js 来加载 wasm 文件和调用 wasm 文件中的二进制代码。


通过阅读 flvToMp4.js,我们可以发现自动生成初始化 WebAssembly 的相关代码,获取 WebAssembly 的二进制文件后,调用了 WebAssembly.instantiate(),初始化了 WebAssembly,并且在获取或加载 wasm 文件失败后还能再次重试。



通过查看 getBinaryPromise()方法也可以看到下载的过程。



使用自动生成的代码,就基本可以不用管加载 wasm 文件等问题,非常方便。


3、对接编译好的 wasm 文件


因为转码是高 cpu 的工作,所以将其放入 web_worker 中运行,这样不会阻碍主线程的渲染。



worker 创建后将事件和主线程对应绑定,也即绑定前面定义的 wasm 调用 JavaScript 的几个方法:



上面就是 WebAssembly 通知 JavaScript 的相关消息接口的定义,到此已经完成了整个转码过程的全部接口定义,全部流程就如下面的时序图所展示。



由时序图可以看到播放器在收到流时就会初始化 WebAssembly 模块,初始化完成后进入转码阶段,通知 WebAssembly 进行转码并存入缓存区,再通知播放器播放。

使用 WebAssembly 实际性能对比

体验上能保持一致,那实际性能上有多少提升呢?还是要用数据说话。爱奇艺直播团队先后使用代码打点和浏览器自带的性能监测工具实时监测数据的方式来测试 WebAssembly 的实际使用性能。


1、直播流转码效率情况


首先,测试使用 WebAssembly 实际转码的速度。分别使用原来 JavaScript 所开发的转码模块和使用 WebAssembly 的转码模块进行转换,在实际直播间转换 flv 流数据包的前后进行打点计时,最终得到的数据如下所示:



前后各挑取了 30 包 flv 数据,表中第二列是每一包转码耗时,第三列是包的大小,在表的最后统计了总包的大小和总耗时,由此计算出未开启 WebAssembly 和开启 WebAssembly 的平均传输速率分别为 35305.6 字节/s 和 46608.1 字节/s。可以看出,WebAssembly 开启后转码速度的提升还是非常明显的。


2、运行时浏览器资源消耗情况


WebAssembly 实际应用在直播间中,能给直播间带来什么样的提升呢?最明显的是 cpu 占用率的下降。这一点可以通过使用 Chrome 浏览器自带的 Performance monitor 对使用 WebAssembly 前后的资源消耗做对比来证明。



如上图所示,可以在开发者工具 More tools 中找到 Performance monitor。通过这个工具,可以大概得到平时运行时的 cpu 占用率。下面两张图分别显示稳定播放时未开启 WebAssembly 和开启 WebAssembly 的 cpu 占用率情况:


  • 未开启 WebAssembly



  • 开启 WebAssembly



从图中可以大致看到,未开启 WebAssembly 时,cpu 占用率基本稳定在 7%左右,而开启 WebAssembly 之后,cpu 占用率能稳定在 5%上下,由此可以估算出大约有 10%-20%的提升(注:使用测试机型为 macbookpro 2018 款,cpu i7 2.2 GHz,不同机器测试出的性能可能有差别,波动状况也不完全一致,但在不同平台开启 WebAssembly 基本都能获得不同程度性能的提升)。

WebAssembly 未来的更多可能

使用 WebAssembly 转码还只是 WebAssembly 的一个非常小的用处,爱奇艺直播团队还将使用 WebAssembly 技术实现更多有趣、有价值的功能,比如:


  • c++项目的移植。现在很多图像相关的项目、算法都是由 c++编写的,如果想在浏览器上运行,以前就只能使用 JavaScript 重写一遍;而现在,通过 WebAssembly,只需要极小的改动,就使其能在浏览器上跑起来。

  • 算法的加密。由于 WebAssembly 编译成的 wasm 是二进制文件,反编译的成本很高,部分保密性比较强的算法会使用 WebAssembly 技术。

  • H.265 编码格式的支持。H.265 编码方式凭借其出色的压缩比,被越来越多的产品所应用,但目前各主流浏览器原生还不支持 H.265 的硬解。但是也可以根据同样的思路,使用 WebAssembly 将 H.265 的流转化为 H.264 的流,然后再使用原生播放器播放,最终达到 Web 端播放 H.265 流的效果,这样可以极大地降低带宽成本。


得益于性能上的提升,WebAssembly 开始在各个领域崭露头脚,今后,爱奇艺直播团队也将尝试使用 WebAsssembly 实现更多的功能来优化爱奇艺的直播体验。


本文转载自公众号爱奇艺技术产品团队(ID:iQIYI-TP)


原文链接


https://mp.weixin.qq.com/s/LRGNOuFwHXALs_lhPyN3Zw


2019-10-31 08:003476

评论

发布
暂无评论
发现更多内容

想快速重构智慧园区5A系统,这份方案推荐给你

华为云开发者联盟

系统 智慧园区 HDC.Cloud 2021 端边云协同架构 南向系统

在多人音视频聊天中插入现场直播

anyRTC开发者

android 大前端 音视频 WebRTC RTC

2021 技术展望 | 走向未来的实时生成技术

声网

RTC 2021年展望 RTE 2021技术

2021 技术展望 | 实时互动场景下,音频的技术变迁与机遇

声网

音视频 RTC 2021年展望 RTE 2021技术

2021技术展望|开源十年,WebRTC 的现状与未来

声网

开源 WebRTC 2021年展望 RTE 2021技术

释放千行百业数据价值,华为云DAYU有一套

华为云开发者联盟

大数据 数据湖 华为云 数据价值 dayu

科技“智”造:智慧工厂这样规划,既高效又节能

一只数据鲸鱼

数据可视化 工业物联网 智慧园区 智慧工厂

国人开源的运维监控系统——WGCLOUD

王逅逅

开源 运维 Grafana Prometheus zabbix

如何只用一个小时定制一个行业AI 模型?

华为云开发者联盟

自然语言处理 AI 华为云 hdc ModelArts Pro

“区块链新基建”可否发展可信平台?

电微13828808271

区块链+ 区块链新基建

Linux scp 命令

一个大红包

4月日更

爱好历史的程序员,不容错过!

不脱发的程序猿

程序员 程序人生 4月日更 全历史

文字识别:关键信息提取的3种探索方法

华为云开发者联盟

深度学习 文字识别 图结构 关键信息提取 栅格

构建从目标到研发过程的全生命周期管理体验

PingCode

敏捷开发 研发管理 Jira Atlassian 敏捷开发管理 研发工具

2021 技术展望 | 弱网下的极限实时视频通信

声网

RTC 2021年展望 RTE 2021技术

关于Go语言,你不得不知的并发模式!

博文视点Broadview

云智一体 AI开发模式打造电力行业的智慧化范本

百度大脑

云计算 智能云

“区块链+”司法合约,电子认证不造假

电微13828808271

区块链+

EGG NETWORK公链阿凡提以“完全开放式自治”的唯一标准搭建New-DeFi链上生态EFTalk

币圈那点事

如何实现屏幕共享时的多人实时标注?

拍乐云Pano

windows Electron RTC

2021 技术展望 | AV1 在 RTC 应用实践中的现状与展望

声网

RTC 2021年展望 RTE 2021技术

Javascript执行机制-事件循环

Sakura

4月日更

c 语言思维地基搭建(总概论)

-jf.

4月日更

从金融到物联网 区块链的落地应用将如何改变世界?

CECBC

区块链

「开源免费」基于Vue和Quasar的前端SPA项目crudapi后台管理系统实战之序列号自定义组件(四)

crudapi

Vue crud crudapi 序列号 quasar

事务隔离级别实战学习

U2647

事务隔离级别 事务 4月日更

Python OpenCV 图片模糊操作 blur 与 medianBlur

梦想橡皮擦

Python OpenCV 4月日更

2021 技术展望 | 2021,5G 将会倒逼传输协议、算法做出更多改进

声网

5G RTC 2021年展望 RTE 2021技术

区块链BaaS服务平台开发,助推中小企业快速落地

13828808769

区块链+ #区块链#

SumSwap与金色财经共为 首席创新合作大会在上海拉开帷幕

币圈资讯

集客业务支撑领域标准化产品套件“火麒麟”的配置化能力提升之路

鲸品堂

产品 解决方案 运营商

爱奇艺直播WebAssembly优化之路_文化 & 方法_直播技术团队_InfoQ精选文章