Search code examples
javaandroidlibgdx

How to load music in Android with libGDX?


I want load mp3 song in an android app with libgdx library but i don't find the way to works. I don't know how programm this "issue".

Assets Manager could be the class for works with mp3 song?

I found also this way:

Gdx.files.newMusic(file); 

but in Android don´t work and desktop the same code work.

Update: Parse Method

public void parse() {
        JsonReader reader = new JsonReader();
        JsonValue rootElem = reader.parse(file);
        JsonValue songDataElem = rootElem.get("songData");
        JsonValue notesDataElem = songDataElem.get("notes");
        JsonValue barsDataElem = songDataElem.get("bars");
        JsonValue keysDataElem = songDataElem.get("keys");
        JsonValue audioDataElem = rootElem.get("audioData");

        NoteData[] notes = new NoteData[notesDataElem.size];
        for (int i = 0; i < notesDataElem.size; i++) {
            notes[i] = new NoteData(notesDataElem.get(i).getInt("pitch"), notesDataElem.get(i).getFloat("time"));
        }
        BarData[] bars = new BarData[barsDataElem.size];
        for (int i = 0; i < barsDataElem.size; i++) {
            BarData bar = new BarData(barsDataElem.get(i).getFloat("time"));
            bars[i] = bar;
        }
        char[] keys = new char[keysDataElem.size];
        for (int i = 0; i < keysDataElem.size; i++) {
            keys[i] = keysDataElem.getChar(i);
        }
        float tempo = songDataElem.getFloat("tempo");
        String file = audioDataElem.getString("file");
        songData = new SongData(notes, bars, keys, tempo);
        parsed = true;
    }

and the constructor:

 public SongFile(FileHandle file) {
    manager = new AssetManager(new ExternalFileHandleResolver());
    file = Gdx.files.external(file.path());//30
    if (file.exists()) {
        manager.load(file.path(), Music.class);
        manager.finishLoading();
        music = manager.get(file.path(), Music.class);
        music.setLooping(true);
        music.play();
    }

}

In the main class:

String file = "/storage/emulated/0/download/prueba.mp3";
SongFile songFile = new SongFile(new FileHandle(file));
songFile.parse();
song = songFile.makeSong();

Solution

  • To load a Music instance we can do the following:

    Music music = Gdx.audio.newMusic(Gdx.files.internal("data/mymusic.mp3"));
    

    You can also use AssetManager to load your Music so that you can manage your assets in proper way.

    AssetManager manager = new AssetManager();
    manager.load("data/mymusic.mp3", Music.class);
    manager.finishLoading();
    

    You can get your Music after assets have been successfully loaded.

    Music music = manager.get("data/mymusic.mp3", Music.class);
    

    Various Playback attributes that can use to play music

    music.play();
    

    Check this thread if you've some particular problem on Android. Some times Sound may not play on Android devices but on desktop, it does play.

    EDIT

    Add this permission to AndroidMainfest.xml file.

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    

    Make it clear for Android your targetSdkVersion is less than 23 if not take permission at run time by user before proceeding any work related to your File IO. For current targetSdkVersion check your defaultConfig of android build.gradle file, if not present their check AndroidManifest.xml file.

    External Destination is address where we keep our own data like video, music and all.

    Gdx.files.getExternalStoragePath() give path /storage/emulated/0/ in Android and User Directory on Desktop like this C:\Users\Abhishek Aryan\

    /storage/emulated/0/ represent inbuilt Storage and Download is inside inbuilt storage.

    if(Gdx.app.type==Application.ApplicationType.Android) {
    
         var assetManager = AssetManager(ExternalFileHandleResolver())
         var fileHandle = Gdx.files.external("/Download/WorldmapTheme.mp3")
    
         if (fileHandle.exists()) {
    
            assetManager.load(fileHandle.path(), Music::class.java)
            assetManager.finishLoading();
    
            var music = assetManager.get<Music>(fileHandle.path())
            music.setLooping(true)
            music.play()
         }
    }
    

    EDIT 2

    This code working fine for me, Hopefully this will work for you

    // code inside create() method of ApplicationListener

    if(Gdx.app.getType()== Application.ApplicationType.Android) {
        String file = "/download/prueba.mp3";
        FileHandle fileHandle = Gdx.files.external(file);
        SongFile songFile = new SongFile(fileHandle);
        songFile.parse();
        song = songFile.makeSong();
    }
    

    Constructor of SongFile class

    public class SongFile {
    
        AssetManager manager;
        Music music;
    
        public SongFile(FileHandle file){
            manager = new AssetManager(new ExternalFileHandleResolver());
            if (file.exists()) {
                manager.load(file.path(), Music.class);
                manager.finishLoading();
                music = manager.get(file.path(), Music.class);
                music.setLooping(true);
                music.play();
            }
        }
    
        ...
    }