由白玉兰开源开放研究院指导,联合掌门教育、声网、vue北京,举办的第二期前端技术分享活动,已于6.19号落幕,如下为大咖讲师们,现场演讲的整理稿,感谢你们的支持:前端
分享嘉宾——李顺博,Web引擎开发高级工程师,如下为李顺博同窗精彩演讲的部份内容:vue
目前,针对WebRTC来讲,最大的问题就是使用体验不理想,常常卡顿,主要问题咱们能够简单从下面三点分析:node
Web平台碎片化严重。WebRTC官方正式标准一直到最近两年才被肯定下来,并且标准的迭代很是迅速,好比国外的chrome、Firefox,国内的360浏览器、QQ浏览器等等,都有基于本身想法上的可选性实现。web
WebRTC实现细节不可控。对于不少Web的开发者而言,咱们每每比较关注的是Media、Vedio这些HTML5标签自己,但好比我要想控制里面的一些网络传输FEC、弱网对抗、带宽估计、优先级保障等算法、使用特殊的编码解码,依赖纯Web是作不到的,这不是浏览器的使命,若是想要作这种更底层的控制,就只能要想其余办法参与到里面去。算法
计算密集型算法可选项少。咱们不少时候须要对视频进行一些预处理的动做,好比美颜功能,如今通用的作法是首先须要获取到用户本地的一些原始的视频采集数据,而后绘制到canvas上,经过canvas接口获取到imagedata,将imagedata传递到Web Assembly,而后再对它进行进一步的算法运算,好比磨皮、提亮等等这些操做,而后从新绘制到canvas里面,这个过程链路自己比较长。还有一点就是Web Assembly技术自己,也是一直在不停发展,他自己有本身的限制,好比Web Assembly的实现是基于chrome自己的一个render主线程驱动。虽而后续出现了Web worker的工做线程实现以及并行计算等,可是执行性能也不是特别好,若是咱们但愿可以充分利用的计算资源,在这种状况下就很难实现。chrome
另外,对于GPU部分,WebGl实现的细节上是有侧重点的,由于浏览器WEB自己是要面向整个标签页的渲染,而不只是视频窗口这一小块,因此相比专业的视频渲染性能方面的表现并不太好。canvas
在最开始咱们作技术评估的时候,可选框架有几大类,Electron、CEF、Qt等等,但不少的开发框架,像CEF和Qt基础技术栈比较偏向C、C++、Java等等,开发习惯和生态上和咱们前端开发体验不一致,尤为是它的开发工具链是须要独立构建,因此最终咱们选择了Electorn,它是基于Nodejs的一个技术方案,前端在开发的时候,咱们可使用熟悉的开发环境,好比说Npm、yarn,还有包括后续的测试打包等整个构建过程。小程序
对于原生扩展能力的注入,咱们将一些关键的业务逻辑的实现,经过用C++代码放到V8引擎里与原生能力结合起来的,后续经过bridge,将能力暴露给上层。这里最大的问题在于每个V8引擎版本,底层C++的接口并不一致,而且,随着nodejs版本的升级,每一个版本里面的接口实现也略微不一样的,这也是长期以来让社区比较诟病问题。这里咱们的解决方案是,采用nodejs提供的node api实现,它是向后兼容的,以此来保持底层接口一致性,解决开发插件接口和node版本依赖的问题。api
当咱们的js层调用经过bridge注入到native后,驱动咱们另一个团队开发的native SDK,包含了声网主要的功能和算法,好比咱们的RTN网络接入、AI降噪算法、背景分割、超分算法等等。另外从前端开发体验上,用户只须要改动少许的代码,就能够完成基于agora sdk ng开发的自有APP的适配,这也是咱们框架的初衷之一,保持外部开发用户的体验的基础上,可以提高它里面的应用能力。浏览器
音视频应用的特色就是它的数据体积比较大,每一帧数据根据用户视频分辨率的不一样,从几K到几十M都有可能,同时,咱们还必须对这些数据进行解码、编码等等操做,这就要求咱们可以去充分使用用户本地的计算能力,这里就涉及到子线程相关的调度操做,经过异步事件驱动,咱们能够设计异步事件的队列管理,原平生台生产、主线程消费的模式。另外由于单个数据体积比较大,若是渲染线程和异步线程数据交互经过copy进行交互,内存开销可想而知,这里就必须使用到一些node api提供的external-ArrayBuffer技术,相似智能指针引用的解决方案,咱们只须要保证Buffer的生命周期便可,即在js层调用期间可用,指针销毁时同时销毁buffer,避免内存泄漏。
受限于网络风暴等等问题,咱们用户不少时候分辨率很难保持1080P不变,这个时候咱们就须要一些平衡算法,在帧率和分辨率之间作平衡,这种状况下,视频宽窄就有可能发生变化,那咱们就须要针对这种状况作一些特殊处理,canvas是能够经过更新texture的方式,适配视频数据帧的宽高、步长等,而后经过CSS样式控制总体页面渲染比例及布局便可,不须要再作重采样来保证宽高比,这个作法也是和传统原生视频应用渲染方面有明显差别的地方。
本地音频采集完通常不须要本地回放,但在一些业务场景下,咱们的用户但愿可以根据本身的声音反馈作一些特殊处理,好比用户会但愿能够经过直观的听到本身的音量来调整麦克风的相对位置等等。并且这也算是咱们为了可以保证与agora sdk ng这一致性功能。因为浏览器音频播放是异步执行的,即主线程将音频数据转发给音频线程,音频线程播放结束后通知主线程,主线程再处理下一个音频数据段,这个过程自己是会有始终消耗的,因此在实时音频播放场景中的直观体验就是,随着时间增加,时延累加明显,而且数据播放间隔出现有明显噪音。
咱们的解决方案比较简单直接,采用audio workletprocessor接口,由咱们来控制音频传递给音频播放线程的频率,流式传递音频数据到异步线程,这样就避免线程间反馈形成的时延累加,听起来会很顺滑,加上每次数据段比较短,约10ms左右,用户听起来就感受本身的声音变大了,没有明显的回音感。
将来咱们但愿可以把更多声网nativeSDK能力暴露到上层应用中,好比咱们的桌面共享、AI降噪、美声、vp9编码解码、背景分割、美颜、超分等等,咱们声网内部已经进入到测试环节,后续也但愿可以赋能给咱们的用户更加方便、强大的Web应用开发能力。