Coil: [coil-video] Fails to load preview for video

Created on 22 May 2020  路  7Comments  路  Source: coil-kt/coil

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

bug

All 7 comments

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:

test.zip

@AndroidDeveloperLB Please open a new bug report. Also enabling logs will print out the exception stack trace for the request.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

theScrabi picture theScrabi  路  5Comments

billyjoker picture billyjoker  路  5Comments

RubenGonzalezGonzalez picture RubenGonzalezGonzalez  路  6Comments

gastsail picture gastsail  路  4Comments

GeniusRUS picture GeniusRUS  路  4Comments