安卓VideoView MediaPlayer OnInfoListener - 事件未触发

9

以下是给出的源代码片段:

videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(MediaPlayer mediaPlayer) {

            mediaPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
                @Override
                public boolean onInfo(MediaPlayer mp, int what, int extra) {
                    if (what == MediaPlayer.MEDIA_INFO_BUFFERING_END){
                        activity.dismissDialog(DialogID.DIALOG_LOADING);
                        return true;
                    } 
                    return false;
                }
            });
        }
    });

我正在使用安卓3.x+设备流式传输HLS流,并尝试在缓冲完成后隐藏加载对话框。视频流传输可以正常工作,但信息事件从未被触发。有什么想法吗?

有人能提供一个好的解决方案吗? - sleeping.ninja
我只是在想,是否在onPrepared(...)中设置OnInfoListener已经太晚了。prepareAsync()的文档如下所示:“(...)对于流,您应该调用prepareAsync(),它会立即返回,而不是阻塞直到足够的数据被缓冲。”这听起来好像onPrepared(...)将不会被触发,直到缓冲区已经填满。你有没有尝试过反射?这样可以让你随时设置OnInfoListener - MH.
7个回答

3

我知道现在已经很晚了,但是为了那些仍在寻找解决方案的用户,我还是要发布这篇文章(这种方法对我有效):

        progressDialog.show();
        videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(MediaPlayer mediaPlayer) {
                mediaPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
                    @Override
                    public boolean onInfo(MediaPlayer mp, int what, int extra) {
                        if (what == MediaPlayer.MEDIA_INFO_BUFFERING_END){
                            progressDialog.dismiss();
                            return true;
                        } else if(what == MediaPlayer.MEDIA_INFO_BUFFERING_START){
                            progressDialog.show();
                        }
                        return false;
                    }
                });
                progressDialog.dismiss();
                videoView.start();
            }
        });

一旦视频开始播放,setOnInfoListener会被触发。随后,我们就可以使用它来在视频中间缓冲时显示或隐藏进度条。 - Myth
1
在我的情况下仍然没有被解雇。 - DIRTY DAVE

2

我不完全确定OP在问什么,但这里有一些非常及时的信息。

我不会依赖onPrepared。我发现它不可靠。

我发现对于通过MediaPlayer进行HLS流媒体传输,最有用的两个信息是视频的持续时间和视频的进度位置。您可以通过监听进度更新来获取这两个信息。

当持续时间大于零时,您就知道视频已经真正准备好,并且可以操作(快进或倒退)。当进度位置发生变化时,您就知道视频已经完成缓冲并开始播放。当然,只有在视频正在播放时才有效。 MediaPlayer往往会传递不准确的信息。

这些信息大多数情况下是准确的,并且通常可以依赖它们是“相当”及时的。这种及时性因设备而异。


2

1

onPreparedMediaPlayer 准备开始缓冲时调用,而不是在视频完全缓冲时调用。然而,在 onPrepared 方法中解除加载对话框是完全自然的。

此外,MEDIA_INFO_BUFFERING_END 用于在填充缓冲区后恢复播放,因此我认为它不应该用于解除对话框。所以这应该可以工作:

videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mediaPlayer) {
        activity.dismissDialog(DialogID.DIALOG_LOADING);
    }
});

这是我已经尝试过的事情。我正在尝试解决由于初始缓冲区、网络状况不佳或寻求而可能导致的缓冲区欠载问题。您的方法对于任何这些情况都不起作用。 - sleeping.ninja

0

你不需要通过setOnInfoListener方法来实现。

只需重写setOnPreparedListener方法即可,如API所示:

public void setOnPreparedListener (MediaPlayer.OnPreparedListener l)

注册一个回调函数,在媒体文件加载并准备好时调用。

因此,你可以在setOnPreparedListener方法中解除对话框的显示。

像这样:

    vv.setOnPreparedListener(new OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {

            handler.post(new Runnable() {
            @Override
        public void run() {
                Toast.makeText(MainActivity.this, "finish11", Toast.LENGTH_LONG).show();
        }
        });
        }
    });

我的结果和他的结果有什么不同?而且,当缓冲区完成加载时,它会变得很慢。我从Android API中复制了它。 在这里查看http://developer.android.com/reference/android/widget/VideoView.html#setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener) - Sruit A.Suk
让我重申一下我给@Cristian的答案。 这是我已经尝试过的事情。我正在尝试解决由于初始缓冲区、网络状况不佳或搜索引起的缓冲区欠读问题。你的方法对于这些情况都不适用。 - sleeping.ninja

0
你可以在videoView上设置OnPreparedListener,因为它是你的对象,但是如果你检查VideoView的源代码,你会发现mMediaPlayer是它的私有成员,所以任何外部修改都不会应用于它。
根据你的要求,你需要缓冲状态,所以你可以有一个线程或处理程序或一些东西来更新你的UI以获取缓冲状态,这里有一个方法。
int percent = videoView.getBufferPercentage();

if(percent == 100){
// buffering done 
} 

2
在赏金说明中仔细阅读,这不是他想要的: “我不想要一个解决方案轮询播放头以检查进度使用onBufferUpdate进行估计(根据SO上较旧的帖子,这不准确)。" - yorkw
请检查我在第一段所说的内容Translated text: - Vishal Pawar
@yorkw 是正确的。如果您查看videoview的AOSP源代码,getBufferPercentage返回的值与onBufferUpdate(percent)相同。onBufferUpdate告诉您有多少内容已缓冲相对于整个视频。例如,80%表示已缓冲了视频的80%。 - sleeping.ninja

0
如果您想在每次缓冲(初始时间或后续缓冲不足)时显示加载,请确保再次显示它:
// at the beginning
show

boolean onInfo(int what, int extra) {
  switch (what) {
    case MEDIA_INFO_BUFFERING_END:
      "hide";
      break;
    case MEDIA_INFO_BUFFERING_START
      "show":
  }
}

因此,这个事件序列将按预期执行:

- whenever you start (setVideoURI or start): show
- onPrepared: just plug the info listener
- onInfo BUFFERING_END   hide (it's playing)
- onInfo BUFFERING_START show (it's buffering again)
- onInfo BUFFERING_END   hide (it's playing)

更新:

这是基于信息事件正常工作的假设。当然。


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