礼物特效动画

礼物特效动画

背景

在直播房间里面的虚拟礼物是主播和观众互动的重要道具,也能带来比较多的收入。先前的实现方案是使用动态图片格式,用GIF和webp,虽然使用起来还算方便,但是有许多不足:没法播放音频、帧速过低、制造复杂特效不方便、体积过大。新的多媒体格式的动画特效恰恰可以解决这些缺陷,能够实现流畅高帧率酷炫特效动画,提高用户付费率,增加营收。

相关知识

  • 视频解码;动画用的是h264编码的,为了提高解码效率,在移动平台都是使用各自系统提供的硬解码VideoToolBox(iOS)和MediaCodec(Android)

  • 音频解码;音频使用的aac编码,解码不复杂,硬解和软解都可以。

  • 动画的渲染;视频在移动平台使用OpenGL ES比较方便,解码后渲染到view。

  • 音视频同步; 根据pts,使视频同步到音频。

设计实现和测试

1.iOS实现

为了方便快捷,iOS上面的实现直接使用的是ijkplayer这个第三方库,ijkplayer使用的是FFmpeg对动画视频进行解码,使用SDL播放音频,在渲染的时候有个问题:MP4格式h264编码的多媒体格式,不支持alpha通道,而我们的动画要求有些部分是透明的,所以我们在制作动画视频的时候,把一个视频一分为二,左边部分通过黑白度来表示透明度,右边为动画效果,在shader中编写合成算法实现最终效果,首先通过shader把解码后的yuv图片转换成rgb, 渲染到texture上面,然后再进入根据黑白度合成的shader,最后渲染到对应的view上面。音视频同步的问题,ijkplayer使用的ffplay的源码,已经很好的解决了,默认视频跟音频同步。

2.Android实现

安卓上使用NDK里面的MediaCodec接口,实现音视频的解码,通过Java传入的surface接收解码的数据,然后送入和iOS一样的shader进行绘制。音频播放使用OpenSL ES进行播放,使用事件驱动的方式实现播放。安卓的硬解使用Java层的MediaCodec比较多,使用NDK同时进行音视频很少,网上基本找不到资料,这里面有个坑就是音视频必须要有两个不同的AMediaExtractor和FileDes分别作用于音视频的track,否则就会在一些手机上出现一些播放异常。

3.实现效果

左边的是原视频,右边是手机上渲染效果。

4.测试

通过上千次的循环播放动画流畅,没有内存泄漏,音视频基本同步的,完成的预期目标。

总结和改进

在使用安卓的NDK中MediaCodec同时进行音视频解码坑还是挺多的,看了安卓官网的文档,都只有单独针对视频,网上的也基本上用Java层的接口,通过多次试验终于兼容5.0系统所有设备。在音视频解码和播放的多线程处理犯过几个错误,及时改过来了。对安卓NDK开发还是需要再加深了解。安卓的OpenGL ES的渲染放在Java层,效率比NDK会差一些,后续可以用NDK的接口实现。iOS上面也可以不用ijkplayer直接使用原生接口实现,可以解决这个很重的依赖,减少包的体积。

原文地址:https://www.cnblogs.com/song-jw/p/13561201.html