音视频的学习,本身就是一个难题。
要学习WebRTC,并运用到实际项目中,是难上加难。
要在WebRTC投入运用后,并改善音视频的质量,那简直是......要人命!
碰到难题,是放弃?还是保持孜孜不倦,左右上下前后而求索的精神?
结果给了我一个明确而完美的答案。
经过一段时间对WebRTC源码,openGLES,glsl的学习,终于还是找到了一种能够改善视频质量的方法,成功实现了美颜功能。
最最关键的是,哎呦!效果还不错哟。
记得在最开始的时候,很多次想要放弃,而且遇到了诸多的问题,内心挣扎了很多次,但最后还是像攻下城堡一样,将困难一个一个的攻了下来。
笔者在这里将完整地总结一下实现美颜的艰辛过程。
我将分几个方面,来向大家讲述,我是如何在android端实现WebRTC视频美颜的。
首先,向大家总结性陈述一下,我会说的几个方面。
1.音视频开发前期的调研及实现原理
2.需要学习什么
3.如何开发,代码如何写(我将贴出大部分源码,供各位批评指正)
4.遇到了哪些瓶颈问题
5.如何去测试检验
1.音视频开发前期的调研及实现原理
这阶段的内心OS:什么是高斯滤波,什么又是高斯模糊?他们是两兄弟吗?怎么又来了个双边滤波,他和高斯滤波才是失散多年的亲兄弟吧?怎么网上搜索到的与美颜有关的sdk都是收费的,而且价格比我家乡最高的山脉还要高?
确实是这样的,最开始从总监处接到这个光荣而又艰巨的任务后,我的心情是忐忑中带着一丝小小的兴奋的。
当天在网络上搜索了相关的资料以后,只剩下了忐忑,没有了兴奋。
要实现美颜功能,确实对我来说太困难了,看到那些算法的名字,我感觉我交了无数个新朋友,得一个一个的去接触,并深入了解认识。
说实话,在最开始的时候,我就有打退堂鼓的想法,可工作毕竟是工作,上级交代的任务,也不好直接拒绝,尤其是对于有着轻度社恐的程序员本人来说,拒绝别人的话,总是像我爱你三个字一样,难以说出口(总监给我这个任务,我好想对你说我爱你......雪亮的头顶)。
只好硬着头皮开始冲。
我辈遇到疑问,那自然是离不开去拜访一下度娘,可整整在美颜及WebRTC相关的内容中冲浪了许久,得出了一些基本判断。
对于这方面的资料,非常匮乏,毕竟WebRTC的兴起和风靡,也才几年的时间,可我更看到了,如果想在网络上找到一些实实在在关于美颜如何实现的硬核干货,还是有着相当的困难。
很多的文章,只是挨了一下边,在我看到最后发现,讲了个寂寞,我在想,大哥,咱不缺这点流量吧!而且我还在很多有一点点靠谱的文章下面留言,最后基本没得到回复,好像有一个哥们,无私的回复了我,但从他的回复中,我好像猜到了他也是最终没有实现,倒在了半路上。
然后我想着,既然网上找不到一例WebRTC+美颜实现的具体且详细的方案,那看有没有第三方开源的,这一找发现,结果是没有,而且sdk价格贵的离谱。
这时我也想到了一个问题,即使我真的向公司建议花钱去买别人的SDK进行集成,那也不见得就会有用,因为和自己的业务集成起来,也不会是一件轻松的事情,到时因为这个美颜功能而导致业务需要大范围调整,那不是芭比Q了吗?
最后,经历了心如死灰,内心无比折磨的阶段后,我一咬牙一狠心,决定挥刀...,自研。
前期的调研工作和资料搜集,也没有白干,起码对美颜的实现方式及大致脉络和原理,有了些些的了解。
主要有这么几个方面的认识吧。
第一:确定在WebRTC中实现美颜,应该在视频采集之后,编码之前进行。之所以在这个阶段实现美颜,有着莫大的好处,起码和业务实现了充分的解耦,基本不用考虑业务对美颜实现的影响,也不用担心美颜带来的其他问题。
第二:如果真的要实现美颜,靠我自己目前掌握的知识,是根本达不到目的的,唯一的方法,就是去学习,而要学习新的东西,尤其是感觉自己以前从来没有接触过的知识面,很容易让人产生畏难的情绪,而你唯一的选择,就是去克服他。说实在的,在认识到这点以后,我总结出一个对自己非常有用的道理:尽量选择去做难的事情,如果你把某个难度的事情做好了,那么低于这个难度的几乎所有问题,你都可以轻易的解决。
第三:网上大部分关于美颜如何实现的文章,都是无图无真相,也就是大概说说而已,真正的干货,寥寥无几。不必在这方面寄托太大的希望,不然会很失望。起码以我最后实现的结果来看,很多文章都没有摸到皮毛。
2.需要学习什么?
WebRTC中实现视频的美颜,首先需要学习的东西,自然是WebRTC本身相关的知识。我是基于android平台实现的,所以需要了解WebRTC在android平台的相关API。
这里包含有视频的采集捕捉,视频的具体数据格式,视频的处理方法,视频的传输和编解码等,难度越大的问题,你需要储备的知识,无论是在广度和深度上,都有很大程度的增加。
除了对WebRTC本身API的深入了解及运用外,还需要掌握实现算法的方法和编程语言。
这里主要是GLSL的学习,算法的具体实现,需要非常漫长的学习过程,以及其他方面的深度知识,我这里仅仅只是美颜相关算法的实现,可以说在算法领域,已经是很简单的一些算法了,而且网络上,也能找到相关算法的源码实现。
这些算法主要包括磨皮、美白、饱和度、明亮度、滤镜。
我实现美颜的方案中,主要包含了这几种算法的组合,将他们抽象成封装类,并形成过滤链,将android设备采集到的OES纹理数据,通过过滤后,形成2D纹理进行渲染。
这些算法的实现,是基于离屏渲染的,于是乎,便有了基于GPU的编程,这里就不得不提图形图像编程接口OpenGL了,OpenGL在java语言这里,被抽象成了伪代码。
学习起来,其实这部分还不是非常困难,因为网络上,能够找到与此有关的资料,已经足够你全面而深入的了解关于OpenGL的绝大多数知识了。
3.如何开发,代码如何写
下面直接上干货,给大家看一下,我是如何用代码实现美颜的。
第一步,更新WebRTCAPI
因为项目历史原因,经过查找资料后发现,目前公司采用的WebRTC版本,和我制定的美颜实现方案中,关于视频处理需要的API,在已使用的版本中,根本不存在。
当然如果相应的API已经在您的项目中存在,那么这一步可以不用考虑了。
而要判断需不需要更新,其实很简单,那就是确定你的项目中,是否包含VideoProcess类。
这个类,对于处理WebRTC视频数据,从而添加美颜算法,有着至关重要的作用。
下面是这个类的使用方法:
privateVideoTrackcreateVideoTrack(PeerConnectionFactorypcFactory,VideoCapturercapture,SurfaceViewRenderercallbacks){mVideoSource=pcFactory.createVideoSource(capture.isScreencast());YuvConverteryuvConverter=newYuvConverter();SurfaceTextureHelpersurfaceTextureHelper=SurfaceTextureHelper.create("surface_texture_thread",mEglContext,true,yuvConverter);capture.initialize(surfaceTextureHelper,callbacks.getContext(),mVideoSource.getCapturerObserver());capture.startCapture(pcConfig.videoWidth,pcConfig.videoHeight,pcConfig.videoFps);//屏幕共享时,不进行美颜处理,直接走webrtc的采集流程if(!isScreenShare){BeautyVideoProcessorbeautyVideoProcessor=newBeautyVideoProcessor(surfaceTextureHelper,callbacks.getContext(),yuvConverter);mVideoSource.setVideoProcessor(beautyVideoProcessor);}VideoTracklocalVideoTrack=pcFactory.createVideoTrack(VIDEO_TRACK_TAG,mVideoSource);localVideoTrack.addSink(callbacks);if(MeetRoomActivity2.OPT_LISTnull!=justForOptList){localVideoTrack.addSink(justForOptList);}returnlocalVideoTrack;}
从代码可以看到,这里从视频源获得了视频轨。
而在捕捉到视频数据的过程中,有一个类的使用,非常显眼,便是BeautyVideoProcessor类,没错,如果使用了这个类,那么VideoCapture捕捉到的视频数据,便会走到这里,然后再传输到底层,我就是在这个地方,进行视频数据美颜处理的,而这里,正是视频数据捕捉之后,编码之前的位置所在。
下面,给大家看看BeautyVideoProcessor的具体实现
package