Has anyone achieved getting files from `commonMain...
# multiplatform
p
Has anyone achieved getting files from
commonMain/composeResouces/files
using
Res.getUri()
? I'm trying to use
Res.getUri
to play a wav file, and I got
filenotfoundexception
when passing it to AudioSystem.getAudioInputStream:
Copy code
val uri = Res.getUri("files/frog.wav")
val audioInputStream = AudioSystem.getAudioInputStream(File(uri))
According to documentation: If you want to process multiplatform resources using other libraries included in your project, you can pass platform-specific file paths to these other APIs. To get a platform-specific path, call the
Res.getUri()
function with the project path to the resource *this post has been moved to compose desktop subforum, as it is more appropiated, I'm not deleting it because it haves a thread started and can help someone
w
CMP resources is URI based via the platform specific URI resolver. Files in jars for desktop JVM, assets for Android, static paths for Wasm, etc. If you need a raw file you gotta copy it out first.
p
sorry I don't understand what you mean, can you elaborate your answer? maybe with a link or sample code?
how can I have all my wavs outside the .jar and how can I access them?
c
and as I know your next question will be “do you have an example” - heres one for you https://www.baeldung.com/java-play-sound
p
Hi christian, that sounds good, but how can I use old java resources in compose desktop?
where should be placed in the project structure?
I'm using exactly that java way to play sound:
Copy code
val uri = "????"
val audioInputStream = AudioSystem.getAudioInputStream(File(uri))
val clip: Clip = AudioSystem.getClip()
clip.open(audioInputStream)
clip.start()
The problem is how to get that uri value and where to put the files
w
It might help to read up on what URIs are. They're not guaranteed to be backed by files.
If you need a File, you need to use
Res.readBytes
to copy the data to a file on disk, which you can then pass to whatever audio API.
c
@Pablo , I believe in your skills as a developer to find that out yourself. Java resources are there for over 10 years so you might find enough documentation about where to put those files. Also don’t try to get the URI. Use the stream you get from getResourceAsStream.
p
christian, java resources can be over 10 years out there, but compose desktop is not plain java, it has its own project structure, and I can't figure out where should that file be placed into compose desktop project structure, and how to reach it with a string path.
can't find a single link with someone using this approach in compose desktop
if it is possible (I don't have it clear), for achieving it you need to know where to place the files and how to access them (path route)
also, when you compile the project for release, the project folders change, are not the same than when you develop in Android Studio, and some things are placed inside a .jar file, for example
Solved, It was necessary to cut all the uri route until the end of the .jar, so I made a substring until
!/
Also it was necessary to add buffer for mark/reset support. Finally the working code is as follows:
Copy code
val uri = Res.getUri(sound.path)
val resourcePath = uri.substringAfter("!/") // getting the route inside the jar
val resourceStream: InputStream? = javaClass.getResourceAsStream("/$resourcePath")
    
resourceStream?.let {
    val bufferedIn: InputStream = BufferedInputStream(resourceStream) // adding buffer for mark/reset support
    val audioInputStream = AudioSystem.getAudioInputStream(bufferedIn)
    val clip: Clip = AudioSystem.getClip()
    clip.open(audioInputStream)
    clip.start()
}
w
That would only work for desktop though. If you're only targeting desktop, then it doesn't really make sense to use CMP resources. You could just use regular Java resources like Christian described.
p
I tried, and didn't achieved it
don't know what can I do to solve it without using files folder and Res.getUri
also probably better to do it using something that is portable to other targets
c
the thing is you are not making it “portable to other targets”. a jar file is JVM only and also
AudioSystem
is an JVM only class. Your code will neither work on Android nor on any other target other than JVM. JVM Resources are, no matter if its KMP, CMP, etc., for JVM put in a directory
resources
next to your
java
or
kotlin
folders.
and to access the jpg one would use
MyClass.javaClass.getResourceAsStream("/page_background.jpg")
compose desktop provides helper functions as well https://github.com/JetBrains/compose-multiplatform/blob/aeddeba1659370ab1b553c9e3f[…]14f45/tutorials/Image_And_Icons_Manipulations/README.md?plain=1
p
thank you very much christian, I'll learn how to correctly store the JVM only logic on desktopMain using actual/expect and will try your proposal. For now, I'm not porting to other platforms, but the idea is to do it soon, so I'm trying to make my projects the most prepared to be ported as possible, so learning how to only use JVM code on desktopMain is a must. Now, as you noted, I'm using JVM only code on commonMain, and I'm going to solve that issue.
👍🏼 1