Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"No such file or directory" when using Res.getUri() #4877

Closed
Sanghyun0505 opened this issue May 27, 2024 · 8 comments · Fixed by #4965
Closed

"No such file or directory" when using Res.getUri() #4877

Sanghyun0505 opened this issue May 27, 2024 · 8 comments · Fixed by #4965
Assignees
Labels
question Not a bug, but question or comment resources

Comments

@Sanghyun0505
Copy link

Describe the bug
I was developing multiplatform audio player using MediaPlayer for Android, AVAudioPlayer for iOS. I used new resource api Res.getUri() to get URI of the mp3 file.

actual class AudioPlayer actual constructor(uri: String) {
    private val mediaPlayer = MediaPlayer().apply {
        setDataSource(MainActivity.appContext, uri.toUri())
        prepare()
    }

    actual fun play() = mediaPlayer.start()
}
val audioPlayer = AudioPlayer(Res.getUri("files/Sample.mp3"))

iOS works fine. By the way, there is an issue with Android:

Failed to open file 'jar:file:/data/app/~~iN2KoRgBjEr0KuRV7TmyrT==/com.example.audioplayer-1F2AEdsqRz5PTffEv0pF3t==/base.apk!/files/Sample.mp3'. (No such file or directory)

Affected platforms

  • Android(Compose multiplatform resource issue)

Versions

  • Libraries:
    • Compose Multiplatform version: 1.6.10
  • Kotlin version: 1.9.23
@Sanghyun0505 Sanghyun0505 added bug Something isn't working submitted labels May 27, 2024
@terrakok terrakok self-assigned this May 27, 2024
@terrakok terrakok added question Not a bug, but question or comment and removed bug Something isn't working labels May 27, 2024
@terrakok
Copy link
Collaborator

It is the expected behavior, because the resource on the android side is located inside a jar archive. The Uri has the correct path but your player doesn't support files in jar archives.
You need to implement a data reading from jars.

@terrakok
Copy link
Collaborator

You could try something like: https://stackoverflow.com/questions/15055747/play-media-from-from-zip-file-without-unzipping

(I haven't check it.)

@egorikftp
Copy link

egorikftp commented May 27, 2024

I see in the code logic that for fonts we additionally check if file inside "assets"

image

is it possible to add option to store files on Android in assets folder? it will fix the issue
otherwise it make sharing files logic useless 🙁

@terrakok
Copy link
Collaborator

terrakok commented May 27, 2024

@egorikftp First of all, the font check is dirty hack I'd like to remove but it is impossible to create a font by a byte array on android.

sharing files

Files are not resources. Compose resources are part of UI.

There is no such thing as "assets" on the JVM platform. What you ask is a platform dependent solution. If you want to add file to android assets you may use the android assets folder.

@Woren
Copy link

Woren commented May 28, 2024

For anyone interested I've created issue in Media3/Exoplayer repository. I have almost same use case. More details there.

@terrakok
Copy link
Collaborator

is it possible to add option to store files on Android in assets folder?

BTW, there is a technical limitation for that: to read android assets users have to provide an android context. it will make the library API more complicated

@hichamboushaba
Copy link

BTW, there is a technical limitation for that: to read android assets users have to provide an android context. it will make the library API more complicated

@terrakok I think there is still a valid use case for offering support for assets on the resources library, in addition to the reasons above (which are caused by the fact that usage of Jar resources is not common on Android), there have been some issues with the performance of Jar resources in Android (Per my testing, the performance of Jar resources has improved in recent Android versions, but they are still slower by 15% than assets or raw files).

To solve this issue without impacting the API, I think there are some approaches:

  1. Require passing Context for base functions, but make the common functions Composables, and make use of LocalContext.current in the Android implementations.
  2. Introduce a notion of PlatformContext in the library, and require the client apps to pass it in the APIs

What do you think about these ideas?

@hichamboushaba
Copy link

If someone is looking for some workarounds for the MediaPlayer issue, the issue created by @Woren has some possible solutions, and I shared one additional workaround there too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Not a bug, but question or comment resources
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants