Describe the bug
When I'm trying to load preview for video that I picked from my device I'm getting an exception:
2020-05-22 23:40:14.907 27387-27387/com.example.android I/System.out: load uri: content://com.android.providers.media.documents/document/video%3A158545
2020-05-22 23:40:14.956 27387-27462/com.example.android D/skia: --- Failed to create image decoder with message 'unimplemented'
2020-05-22 23:40:14.956 27387-27462/com.example.android D/skia: --- Failed to create image decoder with message 'unimplemented'
2020-05-22 23:40:14.965 27387-27387/com.example.android I/RealImageLoader: 馃毃 Failed - content://com.android.providers.media.documents/document/video%3A158545 - java.lang.IllegalStateException: BitmapFactory returned a null Bitmap. Often this means BitmapFactory could not decode the image data read from the input source (e.g. network or disk) as it's not encoded as a valid image format.
2020-05-22 23:40:14.967 27387-27387/com.example.android E/RealImageLoader: java.lang.IllegalStateException: BitmapFactory returned a null Bitmap. Often this means BitmapFactory could not decode the image data read from the input source (e.g. network or disk) as it's not encoded as a valid image format.
at coil.decode.BitmapFactoryDecoder.decode(BitmapFactoryDecoder.kt:177)
at coil.RealImageLoader$loadData$2.invokeSuspend(RealImageLoader.kt:349)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:738)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
2020-05-22 23:40:17.922 27387-27523/com.example.android V/FA: Inactivity, disconnecting from the service
Expected behavior
Would like to see thumbnail
To Reproduce
The code is pretty standard
val imageLoader = ImageLoader.Builder(requireContext())
.componentRegistry {
add(VideoFrameFileFetcher(requireContext()))
add(VideoFrameUriFetcher(requireContext()))
}
.build()
val request = LoadRequestBuilder(requireContext())
.data(uri)
.videoFrameMillis(2000)
.target(myImageView)
.build()
imageLoader.execute(request)
Version
coil-version 0.11.0
Android 9
coil-video is added
VideoFrameFetcher relies on the file's extension to automatically handle video files. Since your URI doesn't have an extension, you'll have to set the fetcher explicitly for the request:
val request = LoadRequestBuilder(requireContext())
.data(uri)
.videoFrameMillis(2000)
.target(myImageView)
.fetcher(VideoFrameUriFetcher(requireContext())
.build()
imageLoader.execute(request)
VideoFrameFetcher relies on the file's extension to automatically handle video files. Since your URI doesn't have an extension, you'll have to set the fetcher explicitly for the request:
val request = LoadRequestBuilder(requireContext()) .data(uri) .videoFrameMillis(2000) .target(myImageView) .fetcher(VideoFrameUriFetcher(requireContext()) .build() imageLoader.execute(request)
@colinrtwhite Thanks, it works. I think it should be specified in docs somehow. It wasn't clear from the exception. Do you have any plans to support thumbnails from remote sources, like video url's?
Good point - I'll add a section to the docs about it.
As for video frames from a url, I'd like to, but I don't think it's possible. MediaMetadataRetriever requires the ability to read backwards and forwards in a source. We can handle short backwards reads by buffering them into memory, however even small video files (10MB) would consume a lot of memory to decode. Large video files would throw an out of memory error easily. By restricting it to file/uris only we avoid having to buffer into memory.
Can anyone please share a POC of this?
I can't find LoadRequestBuilder, and all I want is to go over frames of a video (short duration between frames, so that if I wished, I could even play them one after another).
@AndroidDeveloperLB LoadRequestBuilder was replaced with ImageRequest.Builder.
@colinrtwhite Seems not to work as I expect. I chose to show the image of the first second of some video file, and when I play the video file, it has content, but when I debug here, I get a black bitmap.
See attached project and screenshot:
@AndroidDeveloperLB Please open a new bug report. Also enabling logs will print out the exception stack trace for the request.