Reputation: 4283
I am using Android's MediaPlayer to loop audio files. I set the media player looping with
mMediaPlayer.setLooping(true);
After several repetitions, the loop starts earlier than it should do i.e. if I play the same loop on a computer, with a metronome running independently at the same BPM as the loop, Android's Media player and metronome stay synced for a few bars, but after a couple of loop, the loop played with the app starts too early.
I've read about other peoples complaining about this problem.
I reproduce this problem both on Android 4.4 and Android 6
Here is a minimal Android project for reproducing the problem: https://drive.google.com/open?id=0B9FRLIzBQgR1WWdMU29ZcHdsMXc
Upvotes: 1
Views: 558
Reputation: 5557
In my project, I had the same issue and I found he solution in SO somewhere, I don't remember exactly where. But here what I've done:
You can try using a handler to set seek to beginning x milliseconds before the end of file
loopTimer = new Timer();
loopTask = new TimerTask() {
@Override public void run() {
mMediaPlayer.seekTo(0);
}
};
long waitingTime = mMediaPlayer.getDuration()-mLoopingPreview;
loopTimer.schedule(loopTask, waitingTime, waitingTime);
Now just set mLoopingPreview
to some reasonable time value. I'm using 80ms.
Upvotes: 2
Reputation: 23881
I also faced this problem...in Mediaplayer
There is couple of solution:
1.use ogg format sound file (https://en.wikipedia.org/wiki/.ogg)
2.Can use soundpool it has a looping and caching facility for media play (https://developer.android.com/reference/android/media/SoundPool.html)
3.Also you can use the following class: it initialize a new mediaplayer as soon as the first one finishes..so the delay is less more obvious
public class LoopMediaPlayer {
public static final String TAG = LoopMediaPlayer.class.getSimpleName();
private Context mContext = null;
private int mResId = 0;
private int mCounter = 1;
private MediaPlayer mCurrentPlayer = null;
private MediaPlayer mNextPlayer = null;
public static LoopMediaPlayer create(Context context, int resId) {
return new LoopMediaPlayer(context, resId);
}
private LoopMediaPlayer(Context context, int resId) {
mContext = context;
mResId = resId;
mCurrentPlayer = MediaPlayer.create(mContext, mResId);
mCurrentPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mCurrentPlayer.start();
}
});
createNextMediaPlayer();
}
private void createNextMediaPlayer() {
mNextPlayer = MediaPlayer.create(mContext, mResId);
mCurrentPlayer.setNextMediaPlayer(mNextPlayer);
mCurrentPlayer.setOnCompletionListener(onCompletionListener);
}
private MediaPlayer.OnCompletionListener onCompletionListener = new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.release();
mCurrentPlayer = mNextPlayer;
createNextMediaPlayer();
Log.d(TAG, String.format("Loop #%d", ++mCounter));
}
};
}
to use it just call
LoopMediaPlayer.create(context, R.raw.sound_file_name);
instead of mp.setLooping(true);
Upvotes: 0