@@ -4,65 +4,62 @@ import android.content.Context
44import android.graphics.Bitmap
55import android.graphics.drawable.BitmapDrawable
66import android.graphics.drawable.Drawable
7- import android.media.MediaMetadataRetriever
8- import android.net.Uri
97import android.util.DisplayMetrics
108import com.bumptech.glide.Glide
11- import com.bumptech.glide.Priority
12- import com.bumptech.glide.load.data.DataFetcher
13- import com.bumptech.glide.load.model.GenericLoaderFactory
14- import com.bumptech.glide.load.model.ModelLoaderFactory
15- import com.bumptech.glide.load.model.stream.StreamModelLoader
169import com.bumptech.glide.request.Request
17- import com.bumptech.glide.request.animation.GlideAnimation
1810import com.bumptech.glide.request.target.SizeReadyCallback
1911import com.bumptech.glide.request.target.Target
12+ import com.bumptech.glide.request.transition.Transition
2013import org.wordpress.aztec.Html
2114import org.wordpress.aztec.glideloader.extensions.upscaleTo
22- import java.io.ByteArrayInputStream
23- import java.io.ByteArrayOutputStream
24- import java.io.IOException
25- import java.io.InputStream
2615
2716class GlideVideoThumbnailLoader (private val context : Context ) : Html.VideoThumbnailGetter {
2817
2918 override fun loadVideoThumbnail (source : String , callbacks : Html .VideoThumbnailGetter .Callbacks , maxWidth : Int ) {
3019 loadVideoThumbnail(source, callbacks, maxWidth, 0 )
3120 }
3221
33- override fun loadVideoThumbnail (source : String , callbacks : Html .VideoThumbnailGetter .Callbacks , maxWidth : Int , minWidth : Int ) {
34-
22+ override fun loadVideoThumbnail (
23+ source : String ,
24+ callbacks : Html .VideoThumbnailGetter .Callbacks ,
25+ maxWidth : Int ,
26+ minWidth : Int
27+ ) {
3528 Glide .with (context)
36- .using(ThumbnailLoader (context))
37- .load(source)
3829 .asBitmap()
30+ .load(source)
3931 .fitCenter()
4032 .into(object : Target <Bitmap > {
4133 override fun onLoadStarted (placeholder : Drawable ? ) {
4234 callbacks.onThumbnailLoading(placeholder)
4335 }
4436
45- override fun onLoadFailed (e : Exception ? , errorDrawable : Drawable ? ) {
37+ override fun onLoadFailed (errorDrawable : Drawable ? ) {
4638 callbacks.onThumbnailFailed()
4739 }
4840
49- override fun onResourceReady (resource : Bitmap ? , glideAnimation : GlideAnimation <in Bitmap >? ) {
41+ override fun onResourceReady (resource : Bitmap , glideAnimation : Transition <in Bitmap >? ) {
5042 // Upscaling bitmap only for demonstration purposes.
5143 // This should probably be done somewhere more appropriate for Glide (?).
52- if (resource != null && resource.width < minWidth) {
53- return callbacks.onThumbnailLoaded(BitmapDrawable (context.resources, resource.upscaleTo(minWidth)))
44+ if (resource.width < minWidth) {
45+ return callbacks.onThumbnailLoaded(
46+ BitmapDrawable (context.resources, resource.upscaleTo(minWidth))
47+ )
5448 }
5549
56- // By default, BitmapFactory.decodeFile sets the bitmap's density to the device default so, we need
57- // to correctly set the input density to 160 ourselves.
58- resource? .density = DisplayMetrics .DENSITY_DEFAULT
50+ // By default, BitmapFactory.decodeFile sets the bitmap's density to the device default so,
51+ // we need to correctly set the input density to 160 ourselves.
52+ resource.density = DisplayMetrics .DENSITY_DEFAULT
5953 callbacks.onThumbnailLoaded(BitmapDrawable (context.resources, resource))
6054 }
6155
6256 override fun onLoadCleared (placeholder : Drawable ? ) {}
6357
64- override fun getSize (cb : SizeReadyCallback ? ) {
65- cb?.onSizeReady(maxWidth, maxWidth)
58+ override fun getSize (cb : SizeReadyCallback ) {
59+ cb.onSizeReady(maxWidth, maxWidth)
60+ }
61+
62+ override fun removeCallback (cb : SizeReadyCallback ) {
6663 }
6764
6865 override fun setRequest (request : Request ? ) {
@@ -82,64 +79,4 @@ class GlideVideoThumbnailLoader(private val context: Context) : Html.VideoThumbn
8279 }
8380 })
8481 }
85-
86- // Based on a Gist from Stepan Goncharov (https://gist.github.com/stepango/5edcbdb408b0ba87f8383f868961c257)
87- internal class ThumbnailLoader (val context : Context ) : StreamModelLoader<String> {
88-
89- override fun getResourceFetcher (src : String , width : Int , height : Int ) = VideoThumbnailFetcher (src, context)
90-
91- internal class Factory : ModelLoaderFactory <String , InputStream > {
92- override fun build (context : Context , factories : GenericLoaderFactory ) = ThumbnailLoader (context)
93-
94- override fun teardown () = Unit
95- }
96-
97- class VideoThumbnailFetcher (val source : String , val context : Context ) : DataFetcher<InputStream> {
98- var stream: InputStream ? = null
99- @Volatile
100- var cancelled = false
101-
102- override fun getId (): String = source
103-
104- override fun loadData (priority : Priority ): InputStream ? {
105- val retriever = MediaMetadataRetriever ()
106- try {
107-
108- val uri = Uri .parse(source)
109- val isRemote = uri?.scheme?.startsWith(" http" , true ) ? : false
110- if (isRemote) {
111- retriever.setDataSource(source, emptyMap())
112- } else {
113- retriever.setDataSource(context, uri)
114- }
115-
116- if (cancelled) return null
117- val picture = retriever.frameAtTime
118- if (cancelled) return null
119- if (picture != null ) {
120- val bitmapData = ByteArrayOutputStream ().use { bos ->
121- picture.compress(Bitmap .CompressFormat .JPEG , 90 , bos)
122- bos.toByteArray()
123- }
124- if (cancelled) return null
125- stream = ByteArrayInputStream (bitmapData)
126- return stream
127- }
128- } finally {
129- retriever.release()
130- }
131- return null
132- }
133-
134- override fun cleanup () = try {
135- stream?.close()
136- } catch (e: IOException ) {
137- // Just Ignore it
138- } ? : Unit
139-
140- override fun cancel () {
141- cancelled = true
142- }
143- }
144- }
14582}
0 commit comments