喜欢用优酷看视频发弹幕的同学应该已经发现,最新版本上很多剧都上线了全新的基于 AI 人脸识别的跟随弹幕,以往的普通弹幕或高级弹幕都是在播放器顶端自右向左以跑马灯式的效果展示,而这种跟随弹幕是以气泡样式挂在人物头像旁边,随着人物移动而移动。这种跟随弹幕可玩性更高,有才网友可发挥余地更大,下面就列举几个例子。
结合人物动作的玩法:
结合人物所处场景的玩法:
自编自导人物对话:
从几个视频 demo 中可以看出,相比普通弹幕,这种跟随弹幕是以一种类似剧中人物的内心 OS 的方式展示出来的,与视频无割离感,更有趣更新颖更精彩,有更多玩法。
本文主要讲诉一下跟随弹幕是如何展示的,从构架图开始讲解实现流程;再由开发过程中遇到的棘手问题,分享技术策略;最后分享未来规划。
一、跟随弹幕架构图
整个流程自下而上,分成算法侧、服务端、客户端三层:
首先,算法侧按每秒 25 帧的频率进行视频抽帧,对每一帧进行人脸识别,配合人脸跟踪和平滑处理,生成每一帧的人脸元数据;
其次,服务端将多个帧的人脸元数据通过降噪、防抖、合并后组合成一组组的人脸组数据,将该数据与跟随弹幕数据一起下发给客户端;
最后,客户端在互动 SDK 中将每组人脸数据生成一个脚本,脚本中完成弹幕跟随该人脸轨迹的移动而移动。
下面着重介绍下每个模块或子模块完成的任务:
1.算法侧
1)视频抽帧模块:将视频流按每秒 25 帧(可配置)的频率抽帧。抽帧频率越高,人脸移动轨迹越平滑,但后面人脸识别算法耗时也随之增加;
2)模型训练模块:提供多张多角度剧中出现的人物图像,给模型训练模块来训练,生成对应人脸库,再配合已训练完成的明星库,这两个库可以大大提高人脸检测的准确度;
3)人脸检测:识别每一帧图像中的人脸,并给出坐标;
4)人脸跟踪:为方便服务端生成人脸的运动轨迹,需要把连续几帧中的相同人脸标记出来;
5)平滑处理:由于每帧中识别出的人脸坐标有一定的偏移量,所以整段人脸轨迹中会出现抖动现象,平滑处理就是通过微调每帧人脸坐标让整个人脸移动轨迹更平滑。
2.服务端
1)降噪:算法侧不关心每一帧上到底哪张人脸重要或不重要,所以会有大量的路人脸是出现一秒不到就消失的,这种无意义的噪点需要直接过滤掉,即降噪处理;
2)防抖:如果算法侧平滑处理未达到要求,人脸在运动过程中还是有抖动,服务端可以对元数据进行二次加工,让人脸移动更平滑;
3)合并:算法侧吐出的都是每一帧的元数据,但客户端关心的是一张人脸由出现到消失的整个轨迹过程,服务端会把元数据合并成一组组人脸的轨迹数据,即人脸组数据;
4)气泡弹幕数据:跟随弹幕的数据,每条弹幕都对应着一张人脸,也指定了弹幕开始展示的时该。
3.客户端
1)互动 SDK 模块:加载各种互动脚本,每个脚本都是一个小的互动,比如电影评分、百科 tips、双流酷看等。利用了互动 SDK 的基础能力,这里把每张人脸由出现到消失的整个过程当做一个小的互动脚本;
2)人脸脚本:人脸脚本中包含着该张人脸的轨迹坐标和对应该张人脸的弹幕气泡数据,脚本中有个定时器在轮询,查找着当前时刻对应人脸的坐标,如果该时刻有跟随弹幕数据则把该数据展示在人脸旁边,继续轮询即达到了弹幕气泡跟随人脸移动的效果。
二、为什么不通过客户端直接识别人脸?
1.实时观看对于时间要求太高
对于客户端来说,最终需要知道的是一张张人脸由出现到消失整个轨迹过程,如果客户端做识别,目前只能识别到某一帧中人脸数据,追踪、平滑处理、防抖、过滤、合并,这整个过程下来耗时太大,根本无法满足用户实时观看的需求;
2.端侧识别准确度达不到要求
先前做弹幕穿人时,iOS 端接入过 AliNN 提供的 SDK,人脸检测还是偶而出现未检测到的情况,如果人脸检测准确度上不能达到要求,必须自己做补帧处理,这个补帧处理很难做到实时;
3.端侧识别影响用户体验
端侧识别时手机 cup 消耗增大,即耗电量会增大,同时可能也影响到播放器卡顿率。
三、棘手的问题
1.在即将切镜头时发跟随弹幕,如何停留的问题
用户发弹幕的时刻恰好在人脸马上消失的时刻(比如马上要切镜头),这时由于人脸会马上消失,而其它人脸会马上出来,问题来了,如果为了保证用户能看到自己发的弹幕,那这条跟随弹幕就需要强制在屏幕上停留几秒,但就因为这几秒钟导致切镜头后这条跟随弹幕很尴尬。测试同学反馈说弹幕在切镜头后很奇怪,给人一种“天空飘来一句话”的感觉。
对这个问题,最终我们的解决办法是切镜头前一刻发的跟随弹幕,在切镜头后直接跑渐隐效果,这样即保证了用户能看清自己的弹幕又保证不会尴尬地挂在下一个镜头的人脸上。视频效果如下:
2.大剧热综频繁剪辑导致人脸数据时间轴错乱的问题
一个视频特别是综艺上线后,会时不时地多次剪辑。一旦剪辑后,人脸数据和进度条时间会错位,运营同学可能会给出一个大概时间比如在一分二十秒位置剪掉十秒这样的数据,但人脸数据必须与进度条时间在毫秒级单位上对应,否则会出现明显延迟或超前。如果重跑数据,可能需要几个小时下线掉该功能,如果要复用数据就必须知道精确的毫秒值,然后剪切部分之后的人脸及弹幕数据全部做偏移处理,所以问题就是如何获取精确的剪切时长。
按照如下方式,只需要跑新视频剪切点前后一小段人脸数据,即可计算出剪切的毫秒级时间,然后将原视频中在剪切点后的人脸数据及弹幕数据全部偏移对应时间即解决了数据错位问题。
四、未来展望
剧中的人脸数据如果只应用在跟随弹幕中就大材小用了,下一步我们准备把带有人脸数据和人体数据的脚本做为基本脚本,后面除了跟随弹幕脚本,还会有弹幕穿人脚本等等。后续客户端这部分架构可能会调整,见下图。方便大家通过外部注入等方式,构建自己想要的脚本。
所以当你有了创新点子,也需要使用到人脸人体数据时,可以继承自基本脚本拿到数据后直接定制自己想要的功能,借助成熟的优化过的人脸人体数据,快速地完成 demo。
比如 YY 一个场景,由于某些原因,需要给明星 A 所出现的镜头打上马赛克,或下掉明星A参演的电影。下掉电影肯定不能接受,毕竟花了大价钱买版权;靠人工对大量镜头重新剪辑又不现实,这就到了考验各视频 APP 技术能力的时候了。我们借助互动 SDK 提供的能力,通过已经下发的人脸 ID 判断出是明星A时给下发的人脸框打上马赛克,问题就解决了。