2

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();
dherediat
  • 146
  • 13
  • 1
    It's probably not about the code, it's the way to go in LibGDX. Check extension of your file, sample rate and few other attributes. There some threads about the android not playing some files in LibGDX. It occured to me too, but it's been awhile i used LibGDX so can remember exactly. – Thracian May 13 '17 at 17:04
  • @fatih-ozcan meaning check if that sample rate and format are supported on that android? And need to keep the files only in certain folder I think. Maybe test with a music file from apropular libGdx github project so you know it works – tgkprog May 13 '17 at 17:50
  • Yes, you should check the file attributes. There are some threads about here and in LibGDX forums too. It has nothing to do with AssetManager, or the folder you put them. They can be directly inside assets folder. But to keep thing tidy, i keep them inside audio folder benath the assets folder. – Thracian May 13 '17 at 17:53
  • AssetManager is for loading assets asycronously to keep your app running while loading instead of waiting all files to load. – Thracian May 13 '17 at 17:54

1 Answers1

4

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();
        }
    }

    ...
}
Abhishek Aryan
  • 19,936
  • 8
  • 46
  • 65
  • Can you point to a good github project that illustrates this? So can see where how to do the Assetmanager once only. (2) And for me one more here in comments that shows how to implement google pay? thank you @abhishek-aryan – tgkprog May 13 '17 at 17:49
  • google pay implementation is different topic from this question so you need to create another topic for the same. – Abhishek Aryan May 13 '17 at 17:56
  • I don't know any GitHub project that demonstrate particularly how to use `Music` with `AssetManager`, You can easily use that, most of code is in answer and also take a look of [AssetManager](https://github.com/libgdx/libgdx/wiki/Managing-your-assets) . If further you've some problem you can ask here. – Abhishek Aryan May 13 '17 at 18:04
  • I don't understand your 1st question. According to me you can't play youtube player sound in background in your native Android. Youtube is third party App having own Activity and Services that works in his own context you can't get his services and use. – Abhishek Aryan May 13 '17 at 19:20
  • 1
    I am explaining very bad i write in the phone and can't show a code example. I try your code and thank you :D – dherediat May 13 '17 at 19:33
  • abhishek i have this error now: Caused by: com.badlogic.gdx.utils.GdxRuntimeException: Couldn't load dependencies of asset: /storage/emulated/0/Download/prueba.mp3 – dherediat May 15 '17 at 15:56
  • Path should be of internal storage that is in your Android Assets folder. – Abhishek Aryan May 15 '17 at 15:58
  • If you're using `AssetManager` than show me the code how you load your `.mp3` file – Abhishek Aryan May 15 '17 at 16:00
  • and how you create object of `SongFile` class what you pass in parameter ? – Abhishek Aryan May 15 '17 at 16:08
  • You are loading `.json` as `Music` into `AssetManager`. And what is it `/storage/emulated/0/download/` I think this is some your device storage address – Abhishek Aryan May 15 '17 at 16:15
  • yes i have saved the json and the mp3 of the song in my phone – dherediat May 15 '17 at 16:15
  • default constructor of `AssetManager` uses `InternalFileHandleResolver` so when you pass file in first argument it supposed file is from `Assets` of Android module, but it's not true in your case – Abhishek Aryan May 15 '17 at 16:19
  • And one more thing there is no default `.json` loader so you need to create own if you want to load `.json` file inside `AssetManager` – Abhishek Aryan May 15 '17 at 16:23
  • Use `ExternalFileHandleResolver` in constructor of `AssetManager`, After that you able to load `.mp3` into `AssetManager` but still not `.json` file. – Abhishek Aryan May 15 '17 at 16:27
  • still you're loading `patronnotas.json` with class type `Music.class` – Abhishek Aryan May 15 '17 at 16:55
  • Make sure you've permission of storage access on Android Device. – Abhishek Aryan May 15 '17 at 17:03
  • you have an example with libgdx in android? – dherediat May 15 '17 at 17:20
  • @dherediat I updated my answer, written in kotlin but you can understand what I mean. – Abhishek Aryan May 15 '17 at 20:12
  • @AbhishekAryan update the code and null pointer in the line 30 – dherediat May 16 '17 at 15:07
  • given code working fine for me, music start playing. I updated in `.java`, check my answer – Abhishek Aryan May 16 '17 at 19:21
  • yes with this code the app dont break... Many Thanks you for your support :D i owe many money :) – dherediat May 17 '17 at 07:31