Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pause and seek in Android MediaPlayer

I have a SeekBar and a MediaPlayer. I want to seek while it's paused, but is seems that docs lies to me:

Please note that seekTo(int) can also be called in the other states, such as Prepared, Paused and PlaybackCompleted state.

As usual, on Android I have to write workarounds instead of code (and in which state is MediaPlayer at this time I can't know, so this table and state machine is completely useless). Because instead of onSeekComplete onCompletion (over 9000 times, I'm not joking) method is called! onSeekComplete is called only after calling seekTo from onPrepared (WHY, GOD, WHY???). I don't even know what to do. I spent about 5 hours on it and nothing is fixed. What can I do?

UPD

Here is my code.

private void setupMediaPlayer() {
    savedMediaPlayerState = null;

    mediaPlayer = application.getMediaPlayer();

    String mp3Path = "/path/to/mp3";

    mediaPlayer.setOnCompletionListener(this);
    mediaPlayer.setOnSeekCompleteListener(this);
    mediaPlayer.setOnErrorListener(this);

    mediaPlayer.setDataSource(mp3Path);
    mediaPlayer.prepare();
}

@Override
public void onProgressChanged(android.widget.SeekBar sb, int i, boolean b) {
    Log.i(TAG, String.format("Progress changed! %d", i));
    if (b) {
        mediaPlayer.seekTo(i);
        updateProgressBarAndDurationLabels(i, mediaPlayer.getDuration(), false);
    }
}

@Override
public void onStartTrackingTouch(android.widget.SeekBar sb) {
    handler.removeCallbacks(updateTimeTask);
    mediaPlayer.pause();
}

@Override
public void onStopTrackingTouch(android.widget.SeekBar sb) {
    int totalDuration = mediaPlayer.getDuration();
    int currentPosition = sb.getProgress();// * totalDuration / 100;

    mediaPlayer.seekTo(currentPosition);
    mediaPlayer.start();

    updateProgressBar();

    isSeeking = false;
}

@Override
public void onCompletion(MediaPlayer mediaPlayer) {
    if (!isSeeking) {
        Log.i(TAG, "completed"); // Called over 9000 times
        audioStopped();
    }
}

@Override
public boolean onError(MediaPlayer mediaPlayer, int i, int i2) {
    return false;    // Error -38 lol
}

@Override
public void onSeekComplete(MediaPlayer mp) {
    Log.i(TAG, String.format("seek to: %d", mp.getCurrentPosition()));
    isSeeking = false;
}
like image 755
efpies Avatar asked Feb 20 '13 20:02

efpies


People also ask

How do I pause and resume MediaPlayer on Android?

Calling start() to resume playback for a paused MediaPlayer object, and the resumed playback position is the same as where it was paused. When the call to start() returns, the paused MediaPlayer object goes back to the Started state.

How do I pause MediaPlayer in android programmatically?

To pause MediaPlayer , call pause() . Stopped State: MediaPlayer is in this state when media stops playing. If MediaPlayer is in this state and you want to play the media again, you have to prepare it again by calling prepare() or prepareAsync() .

How can I stop MediaPlayer in another activity?

You can't destroy one activity from another activity. But you can pause the media player by creating a new instance of MediaPlayer in the second activity and callind the 'stop' method !


1 Answers

After adding the onErrorListener, I discovered that the error with what=-38 is happening here. However, returning true from onError solved my problem. Nobody knows what does it mean.

like image 165
efpies Avatar answered Oct 01 '22 15:10

efpies