Hello Guys,
Assets manager in my Android games is able to find 3d models & textures but for some reason fails to find audio files. Here is the exception I’m getting:
java.lang.UnsupportedOperationException: Cannot load audio files from classpath.Place your audio files in Android's assets directory
at com.jme3.audio.plugins.NativeVorbisLoader.load(NativeVorbisLoader.java:122)
at com.jme3.asset.DesktopAssetManager.loadLocatedAsset(DesktopAssetManager.java:260)
at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:374)
at com.jme3.audio.AudioNode.<init>(AudioNode.java:164)
at com.jme3.audio.AudioNode.<init>(AudioNode.java:144)
at com.scenemaxeng.projector.SceneMaxApp.loadAudioResource(SceneMaxApp.java:880)
at com.scenemaxeng.projector.SceneMaxApp.loadResource(SceneMaxApp.java:864)
at com.scenemaxeng.projector.SceneMaxApp.run(SceneMaxApp.java:719)
at com.abware.scenemax3dgamehub.JmeProjectorFragment.runScript(JmeProjectorFragment.java:63)
at com.abware.scenemax3dgamehub.ui.FullscreenGameActivity$7.run(FullscreenGameActivity.java:255)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
I’m using FileLocator with my assets manager to all the needed assets
assetManager.registerLocator
and as I said it works with 3d models & textures but not with audio files…
It’s not an option for me to put my audio files in the assets folder since my games & assets are dynamic (generated).
What can be done?
Thank you.
EDIT: I see that the assets manager’s file locator DID find the audio file but inside the NativeVorbisLoader class in the “load” method it would not accept AssetInfoFile but only AndroidAssetInfo so I wonder if the “load” method was the correct one to call… Looks like the “load” method will only work with assets put inside the assets folder. File assets should be loaded with other load method. I think.
So, you are using DesktopAssetManager to load Android Audio ?
I think you can just make sceneMax3d copy the assets (using File io & streams or even cmd commands) generated by the project in general into the asset folder so you can package apk & send to users in future, i mean by making the assets a part of android apk…but dynamically.
As you can see here, this is the android asset folder, i have my jme assetFolder there, i can make a java program to copy/paste any assets into this folder so android.content.res.AssetManager can locate my resources :
If you look at the code, all that method does is call loadAsset(key). Which is the same thing already being called by AudioNode… which OP can’t change anyway.
I’m not generating APKs. so copy to assets folder will not help here.
What I don’t understand is why all other assets can be loaded from the internal storage but audio file are not…
When jme initializes assetManager through the LegacyApplication, it does getResources for the current class to locate the asset folder using SystemDelegate & it then passes that to the DesktopAssetManager to locate assets, but if the platform is android then that will use Android.cfg file instead of getResources which will direct it to com.jme3.asset.plugins.AndroidLocator instead of using DesktopAssetManager,
So, i am not sure if calling registerLocator would override initAssetManager() call that LegacyApplication does…
yes! and its working perfectly except audio files for some reason. Models, textures anything is loaded perfectly from the storage but not audio files (OGG types). WAV files has another loader which I think doesn’t have this restriction but I got a crash there which I need to check…
I didn’t succeed to load OGG files from android assets, but i cannot remember the problem, if wav file works then ogg should too…this restriction to the audioData not to the extension of audio.
I can think of a solution, but it may be complex & it may not work…
So, create a custom Class of AssetLocater, then inside locate() use activityContext.getExternalFilesDir() it returns File pointing at /shared/0/emulated/ your internal storage dir, to create streams that will point to the asset folder you have inside the internal storage
Then registerLocator(clazzName)
So generally you will substitute the use of AndroidLocator class…
But there is no problem with locating the OGG file. it is located OK but the asset manager’s FileLocator. the problem is with the NativeVorbisLoader which for some reason doesn’t allow loading files which are not from the assets folder
The only workaround I can think about is not letting JME playing sounds but to delegate the play sound command to Android itself but I really don’t want to go to that path…