I'm using a SeekBar to display the progress of an audio file and for seeking to a certain time. For updating I use a Runnable which calls getCurrentPosition() on a MediaPlayer every second or so. Every time that happens there is a small amount of lag in the audio. Since I call it often, I get very noticeable stuttering while playing something. If it's relevant, I'm using setAudioStreamType(AudioManager.STREAM_MUSIC) and the file format is mp4 whith AAC audio (no video) and I'm using Android 2.3.4. Is there a way to get good audio with getCurrentPosition(), or do I have to implement my own progress calculations?
The Runnable:
private Runnable mUpdateTask = new Runnable(){
@Override
public void run() {
mSeekBar.setProgress((int) (mPlayer.getCurrentPosition() * 100 / mArrayAdapter.getRecording(mPlayingId).mDuration));
mHandler.postDelayed(mUpdateTask, 999);
}
};
I had the same problem or something similar.
When I've used mMediapPlayer.getCurrentPosition()
in a TimerTask to update the SeekBar, I heard sound problems like echo but actually the problem wasn't there..
The issue is that I've also used SeekBar OnSeekBarChangeListener
for manual seek but what happened is that update the seekBar from the TimerTask also triggered the listener, which did mp.seekTo(progress)
and this, caused the mp to return back to that position again..
I've fixed it by using the fromUser
argument as suggested here to do seek only if the seekBar changed manually.
Here is my sample code:
The TimerTask:
public void initializeTimerTask() {
mTimerTask = new TimerTask() {
public void run() {
int progress = mp.getCurrentPosition()/1000;
runOnUiThread(new Runnable() {
@Override
public void run() {
mSeekBar.setProgress(progress);
tvDuration.setText(DateUtils.formatElapsedTime(progress));
}
});
}
};
}
Listener:
mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if(mp != null && fromUser){
mp.seekTo(progress * 1000);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
you can do something like this:
private Runnable mUpdateTask = new Runnable(){
@Override
public void run()
{
mSeekBar.setProgress(mMediapPlayer.getCurrentPosition());
mHandler.postDelayed(mUpdateTask, 999);
}
};
you can also apply seek bar progress change listener as follow:
mSeekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener()
{
@Override
public void onStopTrackingTouch(SeekBar seekBar)
{
}
@Override
public void onStartTrackingTouch(SeekBar seekBar)
{
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser)
{
if (fromUser)
{
int secProgress = seekBar.getSecondaryProgress();
if (secProgress> progress)
{
mMediapPlayer.seekTo(progress);
}
else
{
seekBar.setProgress(mSeekBar.getProgress());
}
}
}
});
mMediapPlayer.setOnBufferingUpdateListener(new OnBufferingUpdateListener()
{
@Override
public void onBufferingUpdate(MediaPlayer mp, int percent)
{
mSeekBar.setSecondaryProgress((mSeekBar.getMax()/100)*percent);
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With