当前位置: 首页 > Web前端 > JavaScript

web端实现RTC视频特效的方案

时间:2023-03-26 23:01:04 JavaScript

随着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应运而生。C、C++、Rust代码可以通过Emscripten编译成WebAssembly,编译后的.wasm文件是一个字节码,可以被JavaScript调用。看到这里,这个解决方案非常令人兴奋,于是我们开始构建自己的WebAssembly。目前比较成熟的支持WebAssembly的框架有Unity、QT等,用Unity和QT编译WebAssembly的过程非常简单,可以轻松搭建测试demo,原生界面也很好的渲染到前端,这让我想起了ActiveX。荣耀!接下来让我们打开相机并进行一些简单的视频处理。满怀期待写出好的代码,尝试跑到前端,却无法完成。我看了一下QTWebAssembly的官网:QtMultimedia框架已经确定不会在WebAssembly中使用,连他们自己都搞不清楚哪些模块可用哪些不可用。在我们看来,前进的道路上有无数的“陷阱”。为了保证安全,WebAssembly运行在沙箱环境中,其权限必须受到限制。我们开玩笑地聊了聊,与ActiveX相比,WebAssembly对开发人员来说似乎是倒退了一步(对用户来说是进步了一步)。本着科学严谨的态度,我们决定另辟蹊径,将这个方案验证到底。前端采集视频,用WebAssembly处理,验证其最终的可行性和网上标榜的接近原生的运行速度。幸运的是,OpenCV提供了一个版本的WebAssembly,只是为了我们做一些简单的验证。搭建原生项目,集成C++版本的OpenCV,WebAssembly版本的OpenCV官方已经提供了测试地址,帮我们省了很多功夫。以双边滤波为例,选择一组合适的参数进行比较验证,diameter选择15,sigma选择30。WebAssembly的表现如下:视频的帧率下降到4FPS(上下浮动),观感明显卡住了。原始表现如下:视频的帧率保持在16FPS(上下波动)。虽然影响体验,但这个值还是满足RTC传输要求的(RTC传输一般以13~30FPS为正常)。继续在原来的基础上加入高斯滤波处理,选择高斯核长宽为3,性能如下:视频的帧率依然保持在14FPS(上下浮动),对性能的影响可以忽略不计,并且仍然满足RTC传输的要求(RTC传输一般视频13~30FPS是正常的)。其他参数的表现与这组测试大致相同,至少在特殊场景的视频处理上,WebAssembly的表现要比native低很多。当然,可能是OpenCV对WebAssembly的支持不够好,但是这组对比和WebAssembly的权限支持还是让我们有些失望。WebSocket本地连接方案该方案没有系统的定义。它的实现思路是将原生项目作为服务端,前端通过localhost端口与其进行交互。HTTP可以用于小数据量(支持更广泛的浏览器),也可以用于大数据量。您可以使用WebSocket(IE10及更高版本)。对于RTC,如果在前端发送,WebSocket可能需要每秒承担数M个数据传输,才能将视频帧从原生进程发送到前端,前端也需要通过WebGL进行渲染。虽然是在本地通信,但是我们担心它的性能会因为捕获帧率溢出,以及在两个进程中捕获音视频可能导致的音视频同步问题,所以没有过多尝试。虚拟相机解决方案多种解决方案都不行,让我们永远不要忘记ActiveX。COM在性能上具有其他解决方案所不具备的巨大优势。其他解决方案不如原生或提倡接近原生的性能,而COM是真正的原生性能。围绕COM做了一些研究,我们发现还有其他的路径可以满足我们的需求,那就是COM组件结合DirectShow将视频发送到模拟摄像头,从而彻底改变采集层面的天空!如果这个方案可行的话,最终的产品不仅会用在我们现在的场景中,所有使用DirectShow进行摄像头调用的应用都可以使用我们封装的视频处理技术。搭建COM工程,封装AI数字人像的实现,调用DirectShow接口完成虚拟摄像头注册和视频流传输,编写批处理脚本将我们的COM注册到系统路径中。完成了大量工作,使用大量相机测试工具进行了测试,并且效果出奇地好。下面是使用AR蒙版处理后的虚拟摄像头接入网易发布会的效果:最终方案经过大量方案验证,我们决定采用虚拟摄像头方案作为我们的最终方案。是无可挑剔的。SchemeStructureKeyImplementation1.首先我们新建一个名为WebCamCOM的动态库工程,使用CoCreateInstance、RegisterFilter等接口将我们的对象注册为DirectShowFilter。2.使用memoryapi.h的接口传递我们定义的数据。这里除了基本的视频数据外,我们还传递了视频的长宽和时间戳信息。3、使用CreateMutex保证内存共享时的访问安全。4.再新建一个动态库工程SharedImageWrapper,只定义一个对外接口。5、根据shouldRotate的输入参数,决定是否垂直翻转(适配Unity)。6.对数据进行简单处理后,视频数据也通过memoryapi.h接口传递给我们定义的DirectShowFilter。7、上层集成SendImage接口,将采集到的RGB数据发送给DirectShow。8.编写批处理脚本,使用regsvr32命令以管理员权限将WebCamCom注册到系统注册表。问题Unity是从下往上收集Texture,直接使用它的数据会造成颠倒,所以需要垂直翻转。Unity可以选择OpenGL渲染和Direct3D渲染,两种渲染方式的Texture句柄的分辨率需要两套接口。OpenGL:D3D:展望虽然DirectShow是目前操作相机的主流框架,但是使用MediaFoundation框架已经成为一种趋势。以后考虑把接口适配到MediaFoundation框架(基于USB摄像头驱动开发也是可行方案)。目前视频处理支持的能力主要集中在数字人像、美化、虚拟背景等方面。在现有框架的基础上,可以结合更多有趣的视频处理技术。插件本身可以结合WebSocket(HTTP)方案,开放一些接口,比如美颜参数,数字人像的形状等,让前端默默的完成插件的配置。该插件可以集成一个实用的设置界面,您可以通过拖放查看预览效果。总结本文介绍了网易在PC端Web端视频处理方案的一些研究,从多个方面比较了一些备选方案的优缺点,最后阐述了在虚拟摄像头方案上的实现思路。也许你不从事音视频领域的开发,也许你不关心PC开发,希望这篇文章能给你一些不同的视角去理解这些技术。限于篇幅,未能详细介绍核心的COM组件机制,略显遗憾。有兴趣的可以逆势把玩一下PC开发的黑科技。