前言
随着桌面应用开发技术的发展,程序的跨平台性和代码的维护成本显得尤为重要,目前优酷Windows平台采用QT作为UI的主要开发方案,DuiLib辅助一些扩展插件开发,Mac平台采用原生的Native UI开发,由于历史原因并没有将Windows端的QT框架迁移到Mac端,两端分别维护耗费不同人力。
优酷新的客户端开发采用当前主流的Electron框架,Electron框架内部采用Chromium内核实现渲染,因此我们可以整合优酷的Web平台的业务从而实现一套代码三端(Mac、Windows、Web)通用,极大的降低开发和维护成本。
这里有一个疑问是浏览器本身已经具备高清晰度(4K、8K)的播放能力,为什么还要做一个基于浏览器内核的客户端?原因如下:
浏览器局限性以及成本、体验
1. 优酷生产的视频从用户体验以及带宽成本等因素考虑,视频格式采用的为H.264或H.265编码格式,拿Chrome浏览器举例,持VP9和AV1但不支持HEVC(H.265)编码格式,所以浏览器想播放高清晰度(4K、8K)视频只能采用VP9或者AV1编码的视频,直接采用浏览器内核无法播放H.265编码的视频,那优酷大部分的4K视频都无法播放。
2. 优酷生产的视频源若进行编码格式改造成本也很高,另外Web的播放体验相比桌面应用会差一些,加上历史优酷一直都在发布桌面应用如果直接使用Web播放而去掉客户端用户也难以接受。
播放技术方案
窗口融合
在视频播放上我们需要考虑跨平台性以及开发成本,所以尽量使用Electron框架自身能力来实现播控、弹幕等基础UI部分,Native播放器仅做最基础的视频解码和渲染工作,所以要解决的关键问题是Native播放器的渲染窗口如何结合Electron创建的窗口,下文将详细介绍桌面原生窗口和Electron框架下窗口的融合过程。
Electron框架下创建的桌面窗口都是由BrowserWindow类来完成的,该类具备操控原生窗口的能力,通过getNativeWindowHandle方法能够拿到对应平台的窗口对象指针(Buffer),将Buffer转换为Long类型传递到C++ SDK设置父子窗口即可完成渲染窗口嵌入到BrowserWindow,API介绍如下图
JS和C++ SDK交互原理
Electron框架结合了NodeJS和Chromium,NodeJS是可以加载C++动态库的从而实现JS直接调用C++接口的能力,我们采用了Node-Addon-Api的接入体系,该体系可以按照NodeJS加载库的协议模式来编译生成C++接口层。
Node-Addon-Api体系采用Google的GYP编译模式,支持跨平台编译并支持编译依赖,支持生成XCode以及Vistual Studio工程等等,也可以直接使用命令行编译。
由于NodeJS是基于Libuv事件队列来实现异步化的,所以C++异步回调JS必须经过事件队列回调到主线程,对于频繁通信效率上可能会有一定损耗,Node-Addon-Api提供了ThreadSafeFunction来辅助实现异步接口回调,优酷客户端接口为了用户体验接口全部采用异步回调通知。
整体播放框架流程图
播放窗口实现效果图如下:
可以看到视频渲染窗口是完全嵌入到Electron提供的背景窗口上,Electron播控窗口附着于背景窗口之上。
Native客户端Electron客户端播放性能对比
测试机器型号及环境
CPU:Intel Core i5-6200U 2.3GHz
内存:8G
显卡:Inter HD Graphics 520
操作系统:Windows 10 64位
Electron版本:13.1.9
播放数据对比
测试数据上看Electron在资源占用上会比原始客户端高,但尚在可接受的范围内,测试过程中发现视频起播速度较慢,这个也是我们目前优化的重心,Electron起播慢的原因主要是窗口创建以及浏览器引擎的加载,包括Web页面的加载都比较耗时,所以导致起播速度比较慢。
从技术角度看我们对于起播速度优化是能够做到和Native体感保持一致的,主要是从窗口处理页面加载预处理等手段来降低首次播放的耗时,总体上Electron客户端相对原生客户端在性能上略有差距,但尚可接受。
总结
框架优缺点
优点:
Electron框架本身依赖于NodeJS的环境,在开发过程中可以很方便的依赖一些开源的npm包,利用npm包管理工具可以很好的控制依赖插件包,Electron也提供了完善的打包和自动升级体系,这方面不用耗费太大的开发经历即可实现自动升级和打包。
Electron利用NodeJS的Addon体系可以友好的和C++模块结合,在一些需要高性能的场景可以通过C++库来实现供JS来调用,窗口管理和托盘图标等系统相关功能Electron自身也提供一套比较完善的API,除了优秀的Web开发体系外能够很好的和桌面系统特性结合,完成开发桌面级APP的开发工作。
缺点:
Electron框架依赖于Chromium内核,所以采用的是多进程模式导致CPU和内存占用比较高,另外在开发过程中发现窗口创建到网页显示还是有一定延迟,针对于一些特殊场景下窗口显示等还是有一些bug,应用对机器性能要求会偏高,在低端机器上表现会稍微差一些,包括程序启动和页面加载体感不是很好。
思考
从开发过程中感受Electron框架体系还是非常优秀的,在众多桌面跨平台框架能够脱颖而出也提高了桌面应用拥抱Web开发体系的信心,未来机器性能不断提升的情况下,Web和Native的体验差距会变得很微弱,Electron能够提高桌面应用开发效率提供优质的应用体验,所以未来Electron可能会越来越流行。
在优酷新老版本升级开发中,为了提升用户体验我们一直在寻找优质的播放方案,包括对Electron自身内部实现原理的研究,最终选择了本文中的窗口融合形式,业务上能够尽量复用之前的逻辑,减少开发成本,播放上能够为用户提供Native级别的体验,后续我们将不断打磨基于Electron框架下的新版应用,为用户提供高质量的播放能力和客户端体验。