You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
When attempting to decode video frames from a file in an Android assets subfolder, the image load fails.
Stack trace:
java.io.FileNotFoundException: video.mp4
at android.content.res.AssetManager.nativeOpenAssetFd(Native Method)
at android.content.res.AssetManager.openFd(AssetManager.java:963)
at coil.decode.VideoFrameDecoder.setDataSource(VideoFrameDecoder.kt:185)
at coil.decode.VideoFrameDecoder.decode(VideoFrameDecoder.kt:39)
at coil.intercept.EngineInterceptor.decode(EngineInterceptor.kt:199)
at coil.intercept.EngineInterceptor.access$decode(EngineInterceptor.kt:41)
at coil.intercept.EngineInterceptor$execute$executeResult$1.invokeSuspend(EngineInterceptor.kt:127)
at coil.intercept.EngineInterceptor$execute$executeResult$1.invoke(Unknown Source:8)
at coil.intercept.EngineInterceptor$execute$executeResult$1.invoke(Unknown Source:4)
at kotlinx.coroutines.intrinsics.UndispatchedKt.startUndispatchedOrReturn(Undispatched.kt:89)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.withContext(Builders.common.kt:169)
at kotlinx.coroutines.BuildersKt.withContext(Unknown Source:1)
at coil.intercept.EngineInterceptor.execute(EngineInterceptor.kt:126)
at coil.intercept.EngineInterceptor.access$execute(EngineInterceptor.kt:41)
at coil.intercept.EngineInterceptor$intercept$2.invokeSuspend(EngineInterceptor.kt:75)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.internal.LimitedDispatcher.run(LimitedDispatcher.kt:42)
at kotlinx.coroutines.scheduling.TaskImpl.run(Tasks.kt:95)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:570)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:677)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:664)
To Reproduce
Put a video file in a subfolder in /assets. E.g. /assets/videos/video.mp4
Attempt to load that file using file:///android_asset/videos/video.mp4
Observe the image load failing with above error logged.
You can also reproduce this in the following fork, where I simply moved the existing video.mp4 into a subfolder and updated the path through which it gets loaded:
As can be seen from the stack trace, the video can no longer be found. It looks like the root cause is in AssetUriFetcher, which only puts the last path segment into AssetMetadata:
That means that an asset url like file:///android_asset/videos/video.mp4 resolves into AssetMetadata("video.mp4"). When the VideoFrameDecoder then attempts to read from this asset, it's effectively trying to locate it in the 'root' of the assets folder, because any information about the subfolder got lost along the way.
Looking at other usages of AssetMetadata, it seems like the same failure will occur when decoding assets from subfolders using ImageDecoderDecoder:
I may be missing some context here, but it seems like the AssetUriFetcher should perhaps feed the path from a few lines above it into the AssetMetaData? (The same path that is used to create a BufferedSource for the ImageSource). Then reads will pick up the correct location.
If that's the way to go, I'm happy to submit a PR. I would also rename AssetMetadata.fileName to something like filePath to reflect its contents.
Logs/Screenshots
See above.
Version
Latest (2.2.1). API level or device does not matter.
The text was updated successfully, but these errors were encountered:
Describe the bug
When attempting to decode video frames from a file in an Android assets subfolder, the image load fails.
Stack trace:
To Reproduce
/assets
. E.g./assets/videos/video.mp4
file:///android_asset/videos/video.mp4
You can also reproduce this in the following fork, where I simply moved the existing
video.mp4
into a subfolder and updated the path through which it gets loaded:https://github.com/mhelder/coil/tree/bug/videoframedecoder-assets-subfolder
As can be seen from the stack trace, the video can no longer be found. It looks like the root cause is in
AssetUriFetcher
, which only puts the last path segment intoAssetMetadata
:coil/coil-base/src/main/java/coil/fetch/AssetUriFetcher.kt
Lines 21 to 28 in b693246
That means that an asset url like
file:///android_asset/videos/video.mp4
resolves intoAssetMetadata("video.mp4")
. When theVideoFrameDecoder
then attempts to read from this asset, it's effectively trying to locate it in the 'root' of the assets folder, because any information about the subfolder got lost along the way.Looking at other usages of
AssetMetadata
, it seems like the same failure will occur when decoding assets from subfolders usingImageDecoderDecoder
:coil/coil-gif/src/main/java/coil/decode/ImageDecoderDecoder.kt
Lines 110 to 112 in 1f1772f
I may be missing some context here, but it seems like the
AssetUriFetcher
should perhaps feed thepath
from a few lines above it into theAssetMetaData
? (The samepath
that is used to create aBufferedSource
for theImageSource
). Then reads will pick up the correct location.If that's the way to go, I'm happy to submit a PR. I would also rename
AssetMetadata.fileName
to something likefilePath
to reflect its contents.Logs/Screenshots
See above.
Version
Latest (2.2.1). API level or device does not matter.
The text was updated successfully, but these errors were encountered: