In my Android application I want to play sequentially some sound that was divided to parts before. Each part is a .wave file with 2-3 seconds length.
I do perform that successfully, but I have a noticeable delay between those parts.
My code looks now like that -
localMediaPlayer = new MediaPlayer[3];
localMediaPlayer[0] = MediaPlayer.create(this, R.raw.sound_1);
localMediaPlayer[1] = MediaPlayer.create(this, R.raw.sound_2);
localMediaPlayer[2] = MediaPlayer.create(this, R.raw.sound_3);
public void onClick_localBtn(View v){
Toast.makeText(this, "Play Local Sound", Toast.LENGTH_LONG).show();
localMediaPlayer[0].start();
localMediaPlayer[0].setOnCompletionListener(new MediaPlayer.OnCompletionListener(){
public void onCompletion(MediaPlayer mp) {
localMediaPlayer[1].start();
}
});
localMediaPlayer[1].setOnCompletionListener(new MediaPlayer.OnCompletionListener(){
public void onCompletion(MediaPlayer mp) {
localMediaPlayer[2].start();
}
});
}
How can I improve my code that those parts will play smooth and with no delay, like if it were a 1 file sound?
Thanks.
When you start playing your (N)th media player, call prepareAsync()
on your (N+1)th media player:
localMediaPlayer[0].start();
localMediaPlayer[1].prepareAsync();
localMediaPlayer[0].setOnCompletionListener(new MediaPlayer.OnCompletionListener(){
public void onCompletion(MediaPlayer mp) {
localMediaPlayer[1].start();
localMediaPlayer[2].prepareAsync();
}
});
localMediaPlayer[1].setOnCompletionListener(new MediaPlayer.OnCompletionListener(){
public void onCompletion(MediaPlayer mp) {
localMediaPlayer[2].start();
}
});
Edit
Based on your update and your comment, perhaps a better way would to be time the playing of the next media player according to the duration of the previous player minus some delta:
private static final int DURATION_DELTA = 1000;
private Handler mHandler = new Handler();
public void playMediaPlayer(final int index) {
if (index >= localMediaPlayer.length || localMediaPlayer[index] == null)
return;
localMediaPlayer[index].start();
final int duration = localMediaPlayer[index].getDuration();
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
playMediaPlayer(index + 1);
}
}, duration - DURATION_DELTA);
}
This code will basically play a media player, then schedule playing the next media player approx 1 second before the next media player ends. It's a bit "hacky", but you can play around with it (the value for DURATION_DELTA) until you get the best results.