libgdx / libgdx

Desktop/Android/HTML5/iOS Java game development framework
http://www.libgdx.com/
Apache License 2.0
23.26k stars 6.43k forks source link

newMusic in androidAudio fail for file in classpath #3333

Closed AlphaDev-Fr closed 8 years ago

AlphaDev-Fr commented 9 years ago

Hello, I put some of my music and sound in my classpath and i need to play them in a android phone.

But i notice the methode com.badlogic.gdx.backends.android.AndroidAudio.newMusic(FileHandle) build the player with : mediaPlayer.setDataSource(aHandle.file().getPath()); which is not working for file in classpath. I have this error :

Prepare failed.: status=0x1

So i try with URL input = FileHandle.class.getResource("/" + aHandle.file().getPath().replace('\\', '/')); mediaPlayer.setDataSource(context, Uri.parse(input.toURI().toString())); but it does not working i have this error :

Illegal character in scheme specific part at index 52: jar:file:/data/app/com.alphadev.android-2.apk!/works sound/musicGame.ogg

Finally i make this crappy code :

        } else if (aHandle.type() == FileType.Classpath) {
            try {
                InputStream input = FileHandle.class.getResourceAsStream("/" + aHandle.file().getPath().replace('\\', '/'));
                File tmpFile = new File(context.getCacheDir(), "cache" + aHandle.file().getName());
                OutputStream output = new FileOutputStream(tmpFile);
                byte[] buffer = new byte[4 * 1024]; // or other buffer size
                int read;

                while ((read = input.read(buffer)) != -1) {
                    output.write(buffer, 0, read);
                }
                output.flush();
                output.close();
                input.close();

                FileInputStream inputStream = new FileInputStream(tmpFile);
                mediaPlayer.setDataSource(inputStream.getFD());
                mediaPlayer.prepare();
                inputStream.close();
                tmpFile.delete();

                AndroidMusic music = new AndroidMusic(this, mediaPlayer);
                synchronized (musics) {
                    musics.add(music);
                }
                return music;
            } catch (Exception ex) {
                throw new GdxRuntimeException("Error loading audio file in Classpath loading: " + file, ex);
            }

I build a cache file with file in classpath and i intialise the datesource of the mediaplayer with a fileDescriptor. I must use the fileDescriptor because the file is not readable by the mediaplayer see this.

I have the same issue for the sound and i fix it same way.

Sorry for my bad english it isn't my native language.

Thank the reading and i hope you solve this issue with a better solution than i found.

MobiDevelop commented 9 years ago

Aside from including your audio files as assets instead of classpath files, I'm not sure there is a better way given the limitations of the MediaPlayer.

badlogic commented 8 years ago

This is unfixable using Android's APIs. Putting your assets into classpath is also bad, as that prevents storage on external storage