视频直播之webp礼物解决方案

注意
本文最后更新于 2016-10-17,文中内容可能已过时。

最近在Tiki项目中要使用到礼物和边框效果,然后我们开发团队研究了几种实现的思路。

  • 视频:成本最低,不需要额外的设计以及开发成本,直接在收到消息的时候显示就好了。但是性能消耗比较大,Tiki内部已经有两个视频流了,本身编解码的消耗不小了,如果还同时显示边框和显示的话,相当于又多了两个视频流,性能压力大。Android端机型比较多,低端机型不少,所以这个方案放弃。

  • 图片:图片方案中动图方案又分好几种,先上性能图 图片来自http://blog.ibireme.com/2015/11/02/mobile_image_benchmark/

感谢该文作者的辛苦测试

首先引用下维基百科的解释:

APNG(Animated Portable Network Graphics)格式是PNG的位图动画扩展,但未获PNG组织官方认可。它的扩展方法类似GIF89a,仍对原版PNG保持向下兼容。APNG第1帧为标准PNG图像,剩余的动画和帧速等数据放在PNG扩展数据块里,因此只支持原版PNG的软件会正确显示第1帧。APNG与Mozilla社区关系密切,格式标准文档设置在Mozilla网站。

APNG 目前并没有被 PNG 官方所接受,所以 libpng 并不能直接解码 APNG。不过网上有不少APng的第三方库,还是可以解决播放的问题。但之后的一个测试显示,APNG的压缩效率不高,同样的动图用FFMpeg生成的APNG的图片比Webp的图片大了将近1倍,最后我们决定放弃APNG。

BGP是属于一个移动端比较冷门的格式,我们在备选方案中也曾经考虑过。虽然BGP有着H.265的压缩编码,拥有很高的压缩比,但是效率是硬伤。在所有的格式比较中,解码速度基本只有别的格式的1/2到1/10,基本不能用到礼物这种需要及时显示的需求上,况且我们App的CPU和GPU负载很高。

Gif在使用范围上很广泛,第三方库也很多,但是有一个致命的缺点,它通常只支持256色索引颜色,这导致它只能通过抖动、差值等方式模拟较多丰富的颜色;它的 Alpha 通道只有1bit,这意味着一个像素只能是完全透明或者完全不透明。

对于我们Tiki礼物来说,颜色很丰富,没有办法很好的显示。

WebP这个格式就是为了减少图片流量而生的,起初WebP并不支持动图这一种形式,直到后来在0.2.0的版本上加上了动图,又称AnimatedWebP。一开始我们也并没有考虑使用WebP,首先没有很好的制作AnimatedWebP工具,实现WebP这个编码的也只有Google自家实现,如果用命令行来实现的话,对设计师太不友好了。其次Android和iOS平台的第三方库来支持播放AnimatedWebP的不多,对于平台的支持也是一个问题(之后iOS用YYWebImage,Android用Fresco)。

之后我们综合各方考虑,还是使用AnimatedWebP。因为首先平台支持上,Android和iOS都有相应的解决方案。其次效率和压缩比上,AnimatedWebP有一个比较好的权衡。再者AnimatedWebP支持24bit的RGB色,能有很好的色彩空间。

接下来我们就要考虑,如何用简单的方法,将设计师的输出的媒体格式转换成AnimatedWebP。一开始我们用FFMpeg封装,将视频转换成AnimatedWebP。一开始还是蛮成功的,但是后续测试发现Fresco对于这种补帧形式的AnimatedWebP支持不是很好,会出现丢失色块的问题。在不能改动Fresco的前提下,继续研究WebP发现,WebP有提供webpmux和gif2webp两个库,gif2webp肯定是不考虑的。webpmux是将多个webp直接压缩到一个web文件中,所以不存在补帧的问题。那么问题迎刃而解了,我们直接将webmux和cwebp包进程序中,把设计师输出的PNG序列用cwebp先转成WebP静态序列,之后再利用webmux将WebP静态序列封装成一个AnimatedWebP文件。这样在不很影响文件大小的情况下,就完成了AnimatedWebP的产出。

地址是https://github.com/TinoGuo/iToolsBox。大家如果有兴趣可以去fork,star下那是最好的啦,有什么不足和问题请私信我。

引用:

https://zh.wikipedia.org/wiki/APNG

http://blog.ibireme.com/2015/11/02/mobile_image_benchmark/