android - 在某些情况下无法从外部设置 videoview 的 mediaPlayer 的音量

标签 android android-videoview

我需要在 onPrepared 方法之外动态改变 videoView 的音量。因此,我保存了对 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. 如果调用 onPrepared 时 videoView 不可见,是否会将 setVolume(0, 0) 将 videoView 设置为静音?
  3. 如何在 onPrepared(...) 方法之外设置音量?

最佳答案

现在回答您的问题可能已经太晚了,但还是回答这个问题以防其他人将来偶然发现此线程。

我在尝试为基于 VideoView 的 MediaPlayer 设置音量时遇到了类似的问题,因为我在 MediaPlayer 重置后立即调用 mediaPlayer.setVolume() 方法。请务必检查代码中调用 setVolumeForMediaPlayer(videoViewMediaPlayer) 方法的位置。

根据MediaPlayer State-Diagram docs ,

There is a subtle but important difference between a newly constructed MediaPlayer object and the MediaPlayer object after reset() is called. It is a programming error to invoke methods setLooping(boolean), setVolume(float, float) in the Idle state for both the cases. If any of these methods is called right after a MediaPlayer object is constructed, the user supplied callback method OnErrorListener.onError() won't be called by the internal player engine and the object state remains unchanged; but if these methods are called right after reset(), the user supplied callback method OnErrorListener.onError() will be invoked by the internal player engine and the object will be transfered to the Error state.

回答您的问题:

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

  2. 是的。鉴于该状态不处于上述 ERROR 状态。

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

PS:另一方面,我想知道当您在其他地方使用 mediaPlayer 参数时,为什么要在 onPrepared 调用中初始化 videoViewMediaPlayer 。这种初始化看起来很安全,但其实是多余的。

关于android - 在某些情况下无法从外部设置 videoview 的 mediaPlayer 的音量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40375880/

相关文章:

Android VideoView : Video view is much darker in a dialog view

java - 无法在 Recyclerview 上播放视频

java - 使用 appcompat v7 时项目中出现 Android 错误

android - 如何在调用任何api时在android中将参数作为json发布

Java 计时器 - 调用的函数未完成!

android - Viewpager上的VideoView,切换页面时停止视频

android - Android VideoView-管理错误的网址错误?

android - 使用 ActionBarCompat 和 requestWindowFeature

java - SQLite 删除级联不工作 : FOREIGN KEY constraint failed

android - Android MediaPlayer(使用VideoView)没有视频,只有音频播放