setPlaybackParams引发IllegalStateException异常

4

我的媒体播放器的使用很典型,只有在尝试设置播放参数时才会出现问题。

  1. 创建媒体播放器:MediaPlayer mMediaPlayer = new MediaPlayer();
  2. 将数据源设置为已知可用的本地媒体文件
  3. mMediaPlayer.prepareAsync();
  4. 在OnPrepared()回调中调用mMediaPlayer.start()

如果我调用:

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

在调用mMediaPlayer.start()之前,播放速度按预期受到影响,并且没有异常出现。如果我在mMediaPlayer.start()调用后放置setSpeed()调用,则应用程序会崩溃并显示非法状态异常。有趣的是,这只发生在手机上(Nexus 5、Priv),但在测试过的平板电脑上(Nexus 7和9)运行良好。我看到一些建议提到暂停音频并等待几百毫秒,但没有帮助。根据文档,在音频正在播放时设置播放速度是完全可以接受的。有人知道这里发生了什么吗?我已经花费太多时间研究这个问题了。谢谢!

1
有人在使用setSpeed()时遇到了问题,似乎通过在创建MediaPlayer时使用getApplicationContext()得以解决 - 请参见AOSP Issue Tracker中的此线程。如果new MediaPlayer()仅在某些设备上将活动用作上下文,则这可能是您的解决方法。由于有太多的“if”,我不会将其发布为答案,但我很想听一听它是否适用于您的情况 :) - Bö macht Blau
1
很不幸,在创建媒体播放器时使用getApplicationContext并没有奏效,谢谢您提供AOSP问题跟踪器的信息。 - Whome
1个回答

6

我解决这个问题的方法是确保通过滑块小部件更改速度时,媒体播放器被重置(通过mMediaPlayer.reset()),然后重新配置,暂停或停止不足以解决问题。

在滑块回调中,我现在存储用户指定的速度,重置媒体播放器并调用播放以恢复媒体播放器在重置前离开的位置。 (以前是更改播放参数和崩溃来源的地方)

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

play() 会重新配置媒体播放器并最终调用 mMediaPlayer.asyncPrepare(),该方法会导致 onPrepared() 回调函数被执行。在此之前,我会配置播放参数。

在 onPrepared() 回调函数中:

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

简而言之,在某些设备上更改播放参数之前,请使用MediaPlayer.reset()。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接