分类: Android平台
2020-02-26 14:22:56
相信大家都对直播不会陌生,直播的技术也越来越成熟了,目前有这样的一个技术,当弹幕飘到主播的脸上的时候,弹幕会自动消失,出了人脸范围内,就继续显示出来。这个原理非常的简单,其实就是人脸识别,将人脸识别范围内的弹幕全都隐藏。说起来容易做起来难,本文将分以下几点讲述如何实现RTMP视频流的人脸识别。
笔者一开始想直接使用别人封装好的播放器,输入地址就能播放。接入后发现,确实接入和使用都很简单,也能够显示,但是有一个很致命的问题,就是没有提供获取裸数据的接口,因而没办法进行人脸识别,后面我就转用了ffmpeg。当然如果只是想在设备上播放RTMP流,bilibili的ijkplayer的框架是完全没有问题的,接入和使用都很简单下面是他们的地址。
解析方案已经选择完毕,接下来就是绘制和人脸识别,绘制我采用OpenGL。原因是之前有自己封装过一个自定义surfaceView,直接拿来用就可以了。人脸识别引擎我选择虹软的引擎,原因有二,一是使用起来比较简单,虹软的demo写的不错,很多东西可以直接抄过来;二是免费,其他公司的引擎我也用过,都是有试用期限,我不喜欢有期限的东西,而且虹软的引擎效果也不错,当然是我的首选。
在src/main目录下新建cpp以及jniLibs目录,并将ffmpeg库放入,如下图所示。
首先我们在src/main/cpp目录下新建两个文件,CMakeLists.txt,rtmpplayer-lib。CMake用于库间文件的管理与构建,rtmpplayer-lib是放我们解析数据流的jni代码用的。
CMakeLists.txt
点击(此处)折叠或打开
我们需要在指定上面我们的CMake文件的位置,以及指定构建的架构。
点击(此处)折叠或打开
在上述的步骤都完成后,我们就可以构建了,点击build下的refresh linked C++ prject,再点击右侧Gradle/other/externalNativeBuildDebug,等待构建完成后就可以在build/intermediates/cmake下就可以看到自己构建成功的so库了,如果能看到libnative-lib.so那么恭喜你,ffmpeg接入就算完成了。
上面提到了native-lib.cpp,我们要在这个文件内编写解析RTMP数据流的Jni代码。
点击(此处)折叠或打开
在上面的jni操作完成后,我们已经获得了解析完成的裸数据,接下来只要将裸数据传到java层,我们也就算是大功告成了,这里我们用回调来实现。
点击(此处)折叠或打开
点击(此处)折叠或打开
onFrameAvailable得到的data就是我们需要的NV21格式的数据了,下图是我播放湖南卫视得到的数据回调,从hashCode上来看,每次的数据回调都不一样,可以认为数据是实时刷新的。
新建了RtmpPlayer单例类做为Jni与java层交互的通道。
点击(此处)折叠或打开
至此为止我们已经获得NV21的裸数据,由于时间有限,文章需要写的内容比较多,因此需要分为上下两篇进行讲述。在下篇内我会讲述如何通过OpenGL将我们获得的NV21数据绘制上去,以及如何通过NV21裸数据进行人脸识别,并绘制人脸框。这也是为何我们费尽心机想要得到NV21裸数据的原因。上篇的ffmpeg接入如有问题,可以在下篇最后的附录查看我上传的demo,参考demo可能上手的更容易些。