androidmedia-playerandroid-mediaplayer

setPlaybackParams Causes IllegalStateException


My use of the media player is quite typical and only exhibits issues when attempting to set Playback parameters.

  1. Create the media player MediaPlayer mMediaPlayer = new MediaPlayer();
  2. setDataSource to a local mediate file that is know to work
  3. mMediaPlayer.prepareAsync();
  4. The OnPrepared() callback calls mMediaPlayer.start()

If I call:

if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M) {
     mMediaPlayer.setPlaybackParams(new PlaybackParams().setSpeed(2.0f));
}

Before I call mMediaPlayer.start() the playback speed is affected as expected and no exceptions occur. If I place the setSpeed() call after the mMediaPlayer.start() call the application crashes with an illegateStateException.

What's interesting is that this only happens on the phones (nexus 5, priv) but works fine on the tablets tested (nexus 7 and 9).

Some of the suggestions I've seen mention pausing the audio and waiting a few hundred milliseconds, it didn't help.

Based on the docs setting the playback speed while the audio is playing is perfectly acceptable. Does anyone have an idea what's going on here? I've spent way too much time investigating this.

Thanks!


Solution

  • My solution to this problem ended up being making sure that when the speed was changed via the slider widget the media player was reset (via mMediaPlayer.reset()) and then reconfigured, pausing or stopping wasn't sufficient.

    In the slider callback I now store the speed specified by the user, reset the media player and call play to resume where the media player left off before the reset. (Previously this was where the playback parameters were changed and the crash originated from)

    public void onStopTrackingTouch(DiscreteSeekBar discreteSeekBar) {
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M) {
             mSpeed = speed;
             mMediaPlayer.reset();
             play(mCurrentMediaId);
        }
    }
    

    play() reconfigures the media player and eventually calls mMediaPlayer.asyncPrepare(); which leads to the onPrepared() callback to be executed, it basically calls mMediaPlayer.start(), before this call I configure the playback parameter:

    Inside the onPrepared() callback:

    if (mMediaPlayer != null && !mMediaPlayer.isPlaying()) {
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.M) {
            mMediaPlayer.setPlaybackParams(new PlaybackParams().setSpeed(mSpeed));
        }
        mMediaPlayer.start();
        mState = PlaybackState.STATE_PLAYING;
                ...
    

    tl;dr; MediaPlayer.reset() before changing playback parameters on some devices.