大厂Data+Agent 秘籍:腾讯/阿里/字节解析如何提升数据分析智能。 了解详情
写点什么

爱奇艺直播 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:003866

评论

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

软件测试/测试开发丨Docker 镜像构建可以分享的快乐

测试人

Docker 软件测试 测试开发

TCP 三次握手,给我长脸了噢

程序员小富

TCP

openGemini正式加入openEuler DB SIG,携手开展全方面技术创新

华为云开源

时序数据库

如何让人形机器人“行稳致远”?这篇顶级期刊的论文提出了新方法

优必选科技

机器人

屡试不爽!一份阿里Java程序性能实战笔记,啃完让你程序快上200%

Java你猿哥

Java ssm 面经

【Docker】MacOs安装

Aldeo

Docker 云原生

专业HTML文本编辑器:BBEdit 激活版

真大的脸盆

Mac Mac 软件 文本编辑器 文本编辑

全球运营商的新共识:2025走向自智网络L4

脑极体

自智网络

为什么 APISIX Ingress 是比 Emissary-ingress 更好的选择?

API7.ai 技术团队

干货 | BitSail Connector开发详解系列一:Source

字节跳动数据平台

开源 数据集成 数据引擎 企业号 3 月 PK 榜

LeetCode题解:137. 只出现一次的数字 II,排序后搜索,JavaScript,详细注释

Lee Chen

JavaScript LeetCode

《2022年IT行业项目管理调查报告》重磅发布!

禅道项目管理

最佳实践|焱融全闪存储实现与美的集团破千万 IOPS 性能

焱融科技

文件存储 分布式文件存储 高性能存储 全闪存储 美的

2 万字长文:声明式配置技术概述

Peefy

DevOps 编程语言 开发者工具 #Kubernetes# #开源

Apache Flink X Apache Doris 构建极速易用的实时数仓架构

Apache Flink

大数据 flink 实时计算

易观:正视GPT-4功能缺陷与能力局限可更好探索大模型应用

易观分析

科技

阿里P8架构师都在卷的《23种设计模式加强版》宝典

程序知音

Java 架构 编程语言 设计模式 后端技术

你关切的Code Review三大问题,我以业务实践作答

极狐GitLab

DevOps Code Review 代码质量 代码规范 代码评审

字节跳动DataLeap数据血缘实践

Openlab_cosmoplat

数据 开源社区 数据血缘

复旦邱锡鹏:深度剖析 ChatGPT 类大语言模型的关键技术

NLP资深玩家

人工智能 ChatGPT

最强阿里及大厂350道面试大全:框架+数据库+并发+开源+微服务

Java你猿哥

Java 数据库 架构 微服务 面经

软件测试/测试开发丨学习Docker就应该掌握的dockerfile语法与指令

测试人

Docker 软件测试 测试开发

graphpad prism基础使用教程

互联网搬砖工作者

阿里云Elasticsearch让搜索上云像使用“水电”一样简单

阿里云大数据AI技术

阿里云 搜索 Elasticearch

带你全方面了解字节A/B实验的文化与工具

字节跳动数据平台

大数据 AB testing实战 实验 A/B测试 企业号 3 月 PK 榜

微帧自研|客观评价模型与主观DMOS分数拟合的分享与实用性探讨

微帧Visionular

计算机视觉 视频编解码

无需二次开发,SOAP-to-REST 简化企业用户的业务迁移和整合

API7.ai 技术团队

关于文件传输协议,你不知道的事

镭速

两会代表热议采用ChatGPT指导论文写作:防范抄袭的探索与思考

GPU算力

人工智能 深度学习 ChatGPT

远程桌面工具:Microsoft Remote Desktop激活版

真大的脸盆

Mac 远程办公 Mac 软件 远程工具

让 API 管理效率更进一步的 API7 DevPortal

API7.ai 技术团队

api 网关 API7

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