使用 Fresco 載入 WebP 動圖設定迴圈次數
背景
前幾天做一個需求,社群文章如果是視訊型別,需要在文章列表播放視訊預覽動圖。
這裡我們使用了視訊部門的服務,生成視訊預覽,對方給出的可選格式為 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 動圖是可以設定迴圈次數的,詢問了視訊部門的同事,原來是他們生成的預覽圖沒有設定迴圈播放屬性,坑爹。。
而視訊部門也需要排期來支援預覽圖迴圈屬性,只能這樣告訴產品了,產品果然還是不滿意,“我不管,我就要無限迴圈播放!”
只能硬著頭皮搞了
社群尋找幫助
果然找到了一個類似的問題
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