关于前端:Web端实现RTC视频特效的解决方案

3次阅读

共计 4135 个字符,预计需要花费 11 分钟才能阅读完成。

需要

随着 RTC 技术的倒退,音视频通信的门槛降到了一个极低的规范。挪动端、PC 端、Web 端、小程序,顺手拿起一个设施就能够实现高质量的音视频通话。而且随同着挪动互联网的倒退(4G,5G),AI 技术的演进,人们对于音视频通信的需要不再停留在听得见看失去,而是开始谋求更多交互新鲜的通信形式,如美颜、道具、互动涂鸦等等。音视频通信方向的拓展层出不穷,尤其在 ToC 的场景。

从技术的角度来讲,原生的视频解决技术曾经并不稀奇。很多相似于 OpenCV 这样的库早已将本人的人脸捕获,图像处理等能力开源,新建一个工程调用不多的接口就能够实现一些简略的视频解决。然而 Web 端在这一块却始终落后原生,再厉害的前端技术在宣扬性能的时候都只敢说靠近原生,其瓶颈在此可见一斑(JavaScript 的设计初衷并不是运行速度)。

技术选型

 ActiveX 计划 

2000 年左右,微软为了战胜过后崛起的新兴浏览器 Netscape,心愿研发一个计划能够让本人的龙头产品 office 在 IE 上运行,这便是 ActiveX 技术。听起来很梦幻的一项技术原生与浏览器的无缝交互。ActiveX 与 Office 的联合最终也的确遏制了 Netscape 的倒退,让 IE 浏览器在很长一段时间霸占着支流的位置。

ActiveX 理论就是一个基于 COM 规范开发的 COM 组件,其通过在装置的时候将本人的 GUID 配合装置门路写入到注册表中,JavaScript 能够轻松通过 GUID 来加载到这个原生对象并通过简略的点语法实现调用。因为是 COM 组件,接口调用竟然是间接在内存间进行,与原生工程调用动静库(DLL)无异。更离谱的是,ActiveX 反对原生的 UserControl 间接渲染在浏览器。MFC、QT、winform、WPF,支流的 Windows 界面开发框架都能够实现 ActiveX 的开发。(不得不抵赖,随着挪动互联网的蓬勃发展,PC 上的开发技术开始式微了,这些名词远没有 flutter、vue 等名词来得耳熟能详)。在应用 WPF 实现了一个 ActiveX 插件的开发调用后咱们大受震撼。就是这样一个听起来无所不能的计划,为什么就变得如此冷门?答案是:安全性。

因为 ActiveX 的高权限,高灵活性,使得它能够在用户的 PC 上“随心所欲”。肆意操作新增或批改本地文件内容、拜访登录信息、在浏览器中间接运行内部可执行文件等,光听这些就让人感觉不寒而栗。在 21 世纪初,互联网刚刚衰亡的年代,大家广泛没搞明确计算机、互联网是什么的年代,不晓得有多少游戏账号就因为用户点击了容许加载 ActiveX 插件而被盗。

所以 Chrome、Firefox 等浏览器开始逐步摈弃对 ActiveX 的反对,就连微软本人也在 Edge 中不再反对 ActiveX,只有年轻失修的 IE 还在倔强反对。然而惋惜的是,IE 浏览器也曾经进行保护,而且行将退出 Windows 零碎预装的名单。大势所趋,ActiveX 的计划也注定被吞没在技术倒退的潮流中。

ActiveX 很好,尤其是银行、政府等应用公有网络的单位,ActiveX 的安全性问题对他们来说仿佛不那么致命。然而咱们不可能针对一个将死的技术来进行咱们的新方案设计,或者说 ActiveX 会是咱们特定场景下的备选计划,但永远不可能成为咱们的首选。

 WebAssembly 计划 

随着 ActiveX 的败落,急需有一个新的计划来补充原生与前端交互的需要,此时 WebAssembly 应运而生。

通过 Emscripten 即可将 C、C++、Rust 代码编译为 WebAssembly,编译取得的 .wasm 文件为一种可被 JavaScript 调用的字节码。

看到这些,这个计划是令人期待的,于是咱们入手来搭建本人的 WebAssembly。目前比拟成熟的反对 WebAssembly 框架有 Unity、QT 等,Unity 与 QT 编译 WebAssembly 的过程都很简略,能够轻易搭建出测试 Demo,且原生的界面也很好地渲染到了前端,不禁让我想起 ActiveX 已经的荣光!

接下来让咱们来调起摄像头并做些简略的视频解决吧。满怀期待写好代码,尝试在前端运行,无奈实现。看了一眼 QT WebAssembly 的官网:

QtMultimedia 框架曾经被确定无奈在 WebAssembly 应用,连他们本身都还没搞清楚哪些 Module 可用哪些不可用,在咱们看来前路有数不清的“坑”。

为了保障安全性,WebAssembly 运行在沙盒环境,其权限必然受限。咱们开玩笑地聊到,对于开发者而言 WebAssembly 绝对于 ActiveX 都像是一种退化(对用户无疑是提高)。

本着迷信谨严的态度,咱们决定另辟蹊径将这个计划验证到底,由前端采集视频,WebAssembly 做解决,以此来验证其最终的可行性,以及网上所吹牛的靠近原生的运行速度。

侥幸的是 OpenCV 提供了 WebAssembly 的版本,正好能够供咱们做一些简略验证。搭建原生工程,集成 OpenCV 的 C++ 版本,而 WebAssembly 版本的 OpenCV 其官网曾经提供了测试地址,帮咱们节俭了不少工作。

以双边滤波为例,选取一组适合参数进行比照验证,diameter 选取 15,sigma 选取 30。

WebAssembly 的体现如下:

视频的帧率曾经降落到了 4FPS(高低浮动),观感已有显著卡顿。

原生上的体现如下:

视频的帧率仍然放弃 16FPS(高低浮动),尽管体验有所影响,然而该值仍然满足 RTC 传输要求(RTC 传输个别视 13~30FPS 为失常)。

持续在原生上增加高斯滤波解决,选取高斯核长宽各为 3,体现如下:

视频的帧率仍然放弃在 14FPS(高低浮动),对性能影响可疏忽,仍然满足 RTC 传输要求(RTC 传输个别视 13~30FPS 为失常)。

其余参数的体现大抵与这组测试雷同,起码在非凡场景的视频解决中 WebAssembly 的性能是远低于原生。当然可能是 OpenCV 对 WebAssembly 的反对还不够好,然而这组比照以及 WebAssembly 的权限反对曾经让咱们对其有些悲观。

 WebSocket 本地连接计划 

这个计划并无零碎的定义,其实现思路为以原生工程为 Server,前端通过 localhost 的端口与其交互,数据量小的能够用 HTTP(反对的浏览器更广),数据量大的能够用 WebSocket(IE10 以上)。对于 RTC,如果发送在前端,则 WebSocket 可能须要承当每秒数 M 的数据传输来将视频帧从原生过程发送到前端,前端还须要通过 WebGL 进行渲染。

尽管是在本地通信,但溢出的采集帧率以及音视频在两个过程采集所可能导致的音画同步问题都让咱们对其的体现示意担心,所以并未有过多尝试。

 虚构摄像头计划 

多个计划都行不通,让咱们对 ActiveX 朝思暮想。COM 在性能上有着其余计划所不具备的微小劣势,其余计划或是性能不如原生或是宣扬性能靠近原生,而 COM 则是实实在在的原生性能。

围绕 COM 进行一番调研,咱们发现还有其余门路能够满足咱们的需要,即 COM 组件联合 DirectShow 来将视频发送到模仿摄像头,从而在采集层面实现偷天换日!如果这个计划可行,那么最终的产品将不仅能够用于咱们眼下的场景,所有应用 DirectShow 进行摄像头调用的利用都将能够应用咱们封装的视频解决技术。

搭建 COM 工程,封装 AI 数字人形象的实现,调用 DirectShow 接口实现虚构摄像头注册与视频流传递,编写批处理脚本将咱们的 COM 注册到零碎门路。实现一系列工作,应用诸多摄像头测试工具进行测试,成果出奇的好。

以下为应用 AR 面具解决后的虚构摄像头接入网易会议的成果:

最终计划

通过大量的计划验证,咱们决定以虚构摄像头的计划作为咱们最终的计划,无论从性能还是耦合性来说,这个计划都是无可挑剔。

计划构造 

要害实现 

1. 首先咱们新建一个动静库工程命名 WebCamCOM,并应用 CoCreateInstance 与 RegisterFilter 等接口将咱们的对象注册为 DirectShow Filter。

2. 借助 memoryapi.h 的接口来传递咱们定义的数据,此处咱们除了传递根本的视频数据之外还额定传递了视频长宽与工夫戳的信息。

3. 通过应用 CreateMutex 来保障内存共享时的拜访平安。

4. 新建另一个动静库工程命名 SharedImageWrapper,对外只定义一个接口。

5. 依据 shouldRotate 入参来决定是否须要做垂直方向的翻转(用于适配 Unity)。

6. 简略解决 data 之后同样通过 memoryapi.h 接口往咱们定义好的 DirectShow Filter 传递视频数据。

7. 下层集成 SendImage 接口即能够将采集的 RGB 数据发送至 DirectShow。

8. 编写批处理脚本,应用 regsvr32 命令以管理员权限将 WebCamCom 注册至零碎注册表。

问题 

  1. Unity 对 Texture 的采集自下而上,间接应用其 data 会有上下颠倒的景象,故须要做一次垂直翻转。
  2. Unity 可选 OpenGL 渲染与 Direct3D 渲染,两种渲染形式的 Texture 句柄解析须要用两套接口。

OpenGL:

D3D:

瞻望

DirectShow 尽管是目前支流的操作摄像头的框架,然而 Media Foundation 框架的应用曾经成为趋势,思考将来将接口适配到 Media Foundation 框架(基于 USB 摄像头驱动开发也是一个可行的计划)。

目前视频解决所反对的能力次要还是围绕数字人形象、美颜、虚构背景,基于现有的框架其实能够联合更多好玩的视频解决技术进来。

插件自身能够联合 WebSocket(HTTP)的计划来凋谢一些接口,诸如美颜参数、数字人形象的形状,这样前端能够默默实现对插件的配置。

插件能够整合出实用的设置界面,可通过拖拖拽拽查看预览成果。

总结

本文介绍了网易在 PC Web 端视频解决计划上的一些探索,从多个方面比照了一些可选计划的优劣,最终在虚构摄像头计划上大抵论述了实现思路。兴许您不从事音视频畛域的开发,兴许您对 PC 开发不以为意,心愿本文能够给您一些不一样的角度去意识这些技术。受限于篇幅,未对外围的 COM 组件机制做具体介绍略有遗憾,大家如有趣味也可逆潮流来玩转一下 PC 开发中的黑科技。

正文完
 0