使用 Fresco 加载 WebP 动图设置循环次数

2,525 阅读2分钟

背景

前几天做一个需求,社区文章如果是视频类型,需要在文章列表播放视频预览动图。

这里我们使用了视频部门的服务,生成视频预览,对方给出的可选格式为 webp、mp4、flv、hls,后面三个都是视频格式,肯定不能作为预览图,而且考虑到 webp 有用较小的体积,我们使用的 fresco 也支持 WebP 的动图,因此果断选择了 WebP 格式。

fresco 加载动图的方法

val uri = Uri.parse("http://voddafz06jj.vod.126.net/voddafz06jj/videoPreview_1821338293_IQAB9DSR.webp")
val controller = Fresco.newDraweeControllerBuilder()
        .setUri(uri)
        .setAutoPlayAnimations(true)
        .build()
drawee_view.controller = controller

看起来好像没什么问题,可是等开发完成拿给产品看的时候,产品不乐意了,这个动图怎么只能播放一次呢,我需要循环播放。

赶紧去补了下课,原来 WebP 动图是可以设置循环次数的,询问了视频部门的同事,原来是他们生成的预览图没有设置循环播放属性,坑爹。。

而视频部门也需要排期来支持预览图循环属性,只能这样告诉产品了,产品果然还是不满意,“我不管,我就要无限循环播放!”

只能硬着头皮搞了

社区寻找帮助

果然找到了一个类似的问题

github.com/facebook/fr…

emm..不过这位仁兄遇到的问题是图片的循环次数是1,可是使用 fresco 却无限循环播放,而且这位仁兄使用的是 gif 动图,这就尴尬了,不过这些都不重要,根本问题是一致的,就是要强行设置动图的播放次数,继续往下看,找到一条点赞数比较多的回答

赶紧试一下,纳尼,怎么还是只放一遍?

仔细看了一下,这位仁兄的版本是 0.10.0,而我们用的版本是 1.2.0,看起来应该是 fresco 改了代码

于是看了下源码,果然不叫 mTotalLoops,改为 mLoopCount

赶快修改代码,再试一次,这次果然可以了

上代码

val uri = Uri.parse("http://voddafz06jj.vod.126.net/voddafz06jj/videoPreview_1821338293_IQAB9DSR.webp")
val controller = Fresco.newDraweeControllerBuilder()
        .setUri(uri)
        .setAutoPlayAnimations(true)
        .setControllerListener(object : BaseControllerListener<ImageInfo>() {
            override fun onFinalImageSet(id: String?, imageInfo: ImageInfo?, animatable: Animatable?) {
                try {
                    if (imageInfo is CloseableAnimatedImage) {
                        val animatedImage = imageInfo.image
                        if (animatedImage is WebPImage) {
                            if (animatable != null) {
                                val field = AbstractAnimatedDrawable::class.java.getDeclaredField("mLoopCount")
                                field.isAccessible = true
                                field.set(animatable, Integer.MAX_VALUE)
                            }
                        }
                    }
                } catch (e: Throwable) {
                    e.printStackTrace()
                }
            }
        })
        .build()
drawee_view.controller = controller

这里只针对 webp 图片设置无限循环,以免影响 gif 图片。

总结

我们遇到了 fresco 加载 webp 动图无法控制播放次数的问题,在社区的帮助下,通过反射修改循环次数,由于版本差异,查看源码改动,并最终解决问题。

不过这仅仅是一个临时方案,而且只针对特定版本有效,说不定 facebook 哪天不爽又改了代码,我们的方案就失效了。还是要按照规范,生成支持循环播放的 webp 动图。

其实今天这篇文章更想表达的是一种解决问题的思路,希望对大家有用。

迁移自我的简书 2018.08.02