So I'm trying to play a certain mix of songs that user chooses. I'm making an array of strings that are filenames that should be played in MediaPlayer. The problem is that all of the songs play at the same time. I've tried everything but still don't know how to make sure player waits for a song to end before it starts another one.
Here's what I've tried:
public void play(View v){
if(player==null)
{
while(true) {
if(i==brojac) break; //checking if the arraylist has ended
if(player.isPlaying()==false) {
i++;
String s = lista.get(i).toString();
player = MediaPlayer.create(this, (this.getResources().getIdentifier(s, "raw", this.getPackageName())));
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
stopPlayer();
}
});
player.start();
}
}
}
}
private void stopPlayer()
{
if(player!=null)
{
player.release();
player=null;
}
}
EDIT
With the answer below everything works,but the player is having noticable gap. I've solved it with setNextPlayer() function, but the app crashes due to recreating the player while it is playing.
void playSong(int currentSong) {
player = MediaPlayer.create(this, currentSong);
player1 = MediaPlayer.create(this,this.getResources().getIdentifier(lista.get(i+1).toString(),"raw",getPackageName()));
player.setNextMediaPlayer(player1);
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
player.release();
i++;
if(i==brojac) return;
player1.start();
playSong(MainActivity.this.getResources().getIdentifier(lista.get(i).toString(),"raw",getPackageName()));
}
});
if(i==0) {
player.start();
}
}
I believe you want this :
ArrayList<Integer> songs = new ArrayList<>();
private MediaPlayer mediaPlayer;
private int currentIndex = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Field[] fields = R.raw.class.getFields();
for (Field field : fields)
songs.add(getResources().getIdentifier(field.getName(), "raw", getPackageName()));
playSong(songs.get(currentIndex));
}
void playSong(int currentSong) {
mediaPlayer = MediaPlayer.create(this, currentSong);
mediaPlayer.setOnCompletionListener(completeListener);
mediaPlayer.start();
}
MediaPlayer.OnCompletionListener completeListener = mp -> {
mp.release();
currentIndex++;
playSong(songs.get(currentIndex));
};
Explication :
The below code, will get all the audio files from raw
folder and store them in the ArrayList
called songs :
Field[] fields = R.raw.class.getFields();
for (Field field : fields)
songs.add(getResources().getIdentifier(field.getName(), "raw", getPackageName()));
To play song :
void playSong(int currentSong) {
mediaPlayer = MediaPlayer.create(this, currentSong);
mediaPlayer.setOnCompletionListener(completeListener);
mediaPlayer.start();
}
the OnCompletionListener
listener, when the song ends, you need to increment the currentIndex
so the songs.get(currentIndex)
will give you the next song
MediaPlayer.OnCompletionListener completeListener = mp -> {
mp.release();
currentIndex++;
playSong(songs.get(currentIndex));
};