在某些情况下,无法从外部将视频设置为mediaPlayer

时间:2016-11-02 08:59:36

标签: android android-videoview

我需要在videoView方法之外动态改变onPrepared的音量。所以我保存了对videoView我使用setVolume方法的媒体播放器的引用。

private MediaPlayer videoViewMediaPlayer;

videoView onPreparedListener:

videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mediaPlayer) {
        videoViewMediaPlayer = mediaPlayer;
        setVolumeForMediaPlayer(mediaPlayer);
        videoView.setBackgroundColor(Color.TRANSPARENT);
        mediaPlayer.setLooping(false);
    }
});

...
private void setVolumeForMediaPlayer(MediaPlayer mediaPlayer) {
    if (mediaPlayer != null) {
        if (muteAudio)
            mediaPlayer.setVolume(0, 0);
        else
            mediaPlayer.setVolume(1.0f, 1.0f);
    }
}

现在,每当我需要调整mediaPlayer的音量时,我正在使用:

setVolumeForMediaPlayer(videoViewMediaPlayer);

但是,抛出以下异常:

java.lang.IllegalStateException
    at android.media.MediaPlayer._setVolume(Native Method)
    at android.media.MediaPlayer.setVolume(MediaPlayer.java:1604)
    at com.blynq.app.fragments.PlayerPane.setVolumeForMediaPlayer(PlayerPane.java:501)
    at com.blynq.app.fragments.PlayerPane.changeActiveMedia(PlayerPane.java:408)
    at com.blynq.app.asyncs.PanePlayerAsyncTask.onProgressUpdate(PanePlayerAsyncTask.java:130)
    at com.blynq.app.asyncs.PanePlayerAsyncTask.onProgressUpdate(PanePlayerAsyncTask.java:22)
    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:656)
    at android.os.Handler.dispatchMessage(Handler.java:102)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5343)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
  1. 这个例外的原因是什么?
  2. 如果在调用Prepared时看不到videoView,setVolume(0, 0)会将videoView设置为静音吗?
  3. 如何在onPrepared(...)方法之外设置音量?

1 个答案:

答案 0 :(得分:2)

对你的问题做出回应可能会迟到,但回答这个问题以防将来有人偶然发现这个问题。

我在尝试为基于VideoView的MediaPlayer设置音量时遇到了类似的问题,因为我在MediaPlayer重置后立即调用了mediaPlayer.setVolume()方法。在您的代码中检入所有调用setVolumeForMediaPlayer(videoViewMediaPlayer)方法的内容非常重要。

根据MediaPlayer State-Diagram docs

  

在调用reset()之后,新构造的MediaPlayer对象与MediaPlayer对象之间存在微妙但重要的区别。对于两种情况,在空闲状态下调用方法setLooping(boolean),setVolume(float,float)是编程错误。如果在构造MediaPlayer对象后立即调用这些方法中的任何一个,则内部播放器引擎将不会调用用户提供的回调方法OnErrorListener.onError(),并且对象状态保持不变;但是如果在reset()之后立即调用这些方法,则内部播放器引擎将调用用户提供的回调方法OnErrorListener.onError(),该对象将被转换为Error状态。

回答你的问题:

  1. 发生此异常是因为在设置音量时,您的mediaPlayer尚未处于PREPARED状态,并且调用它们会导致它滑动到ERROR状态。可能的解决方案是仅在准备视图或任何后续状态时设置音量。

  2. 是。鉴于状态不是如上所述的ERROR状态。

  3. 我建议您在跟踪状态后仔细调用该方法。例如,您可以在setVolumeForMediaPlayer(videoViewMediaPlayer)方法中检查isPlaying()或isPaused()状态。

  4. PS:另外请注意,我想知道为什么你在onPrepared调用中初始化videoViewMediaPlayer,当你在其他地方使用mediaPlayer参数时。初始化看似安全,但多余。