前几天作一个需求,社区文章若是是视频类型,须要在文章列表播放视频预览动图。java
这里咱们使用了视频部门的服务,生成视频预览,对方给出的可选格式为 webp、mp四、flv、hls,后面三个都是视频格式,确定不能做为预览图,并且考虑到 webp 有用较小的体积,咱们使用的 fresco 也支持 WebP 的动图,所以果断选择了 WebP 格式。git
fresco 加载动图的方法github
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
复制代码
看起来好像没什么问题,但是等开发完成拿给产品看的时候,产品不乐意了,这个动图怎么只能播放一次呢,我须要循环播放。web
赶忙去补了下课,原来 WebP 动图是能够设置循环次数的,询问了视频部门的同事,原来是他们生成的预览图没有设置循环播放属性,坑爹。。bash
而视频部门也须要排期来支持预览图循环属性,只能这样告诉产品了,产品果真仍是不满意,“我无论,我就要无限循环播放!”ide
只能硬着头皮搞了oop
果真找到了一个相似的问题ui
emm..不过这位仁兄遇到的问题是图片的循环次数是1,但是使用 fresco 却无限循环播放,并且这位仁兄使用的是 gif 动图,这就尴尬了,不过这些都不重要,根本问题是一致的,就是要强行设置动图的播放次数,继续往下看,找到一条点赞数比较多的回答.net
赶忙试一下,纳尼,怎么仍是只放一遍?
仔细看了一下,这位仁兄的版本是 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