efpies
efpies

Reputation: 3725

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;
}

Upvotes: 5

Views: 4548

Answers (1)

efpies
efpies

Reputation: 3725

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.

Upvotes: 7

Related Questions