检测VideoVIew是否缓冲

有谁知道是否有可能检测VideoView缓冲?

我想在video缓冲时显示ProgressDialog。

到目前为止,我尝试使用OnPreparedListener,但只有在video第一次加载时才起作用。 如果正在播放video,并且用户将滑动条移动到不同的位置,则video仍处于“准备”状态,即使它正在缓冲。

我也试过(我知道这是可怕的)一个AsyncThread只是忙等待isPlaying():

private class BufferTask extends AsyncTask<Void, Void, Void> { protected Void doInBackground(Void...voids) { final VideoView videoView = (VideoView)findViewById(R.id.video); while (!videoView.isPlaying()) { } return null; } protected void onPostExecute(Void v) { // Hide the dialog here... } } 

这是行不通的,因为只要你调用start(),VideoView似乎被认为正在播放,即使它正在缓冲。

我能想到的唯一的解决scheme是构build一个自定义的VideoViewtypes的类,所以我可以访问它的MediaPlayer实例。

有任何想法吗? 谢谢阅读。

Solutions Collecting From Web of "检测VideoVIew是否缓冲"

为了不实现自定义VideoView,我使用了以下黑客技巧。 这个想法是每1秒检查一次,如果当前位置与1秒前相同。 如果是,video缓冲。 如果没有,video真的在玩。

 final Handler handler = new Handler(); Runnable runnable = new Runnable() { public void run() { int duration = videoView.getCurrentPosition(); if (old_duration == duration && videoView.isPlaying()) { videoMessage.setVisibility(View.VISIBLE); } else { videoMessage.setVisibility(View.GONE); } old_duration = duration; handler.postDelayed(runnable, 1000); } }; handler.postDelayed(runnable, 0); 

videoMessage只是一个TextView,文本“Buffering …”放置在我的VideoView的中心。

从API级别17开始 ,您现在可以从MediaPlayer访问InfoListener:

 final MediaPlayer.OnInfoListener onInfoToPlayStateListener = new MediaPlayer.OnInfoListener() { @Override public boolean onInfo(MediaPlayer mp, int what, int extra) { switch (what) { case MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START: { mProgressBar.setVisibility(View.GONE); return true; } case MediaPlayer.MEDIA_INFO_BUFFERING_START: { mProgressBar.setVisibility(View.VISIBLE); return true; } case MediaPlayer.MEDIA_INFO_BUFFERING_END: { mProgressBar.setVisibility(View.VISIBLE); return true; } } return false; } }); mVideoView.setOnInfoListener(onInfoToPlayStateListener); 

每次VideoView缓冲时,以下代码将显示一个缓冲对话框。

  final ProgressDialog bufferingDialog; bufferingDialog = ProgressDialog.show(context, "Buffering", "Please wait", true, true); VideoView videoView; videoView = (VideoView) findViewById(R.id.video_view); videoView.setVideoPath(path); videoView.setMediaController(new MediaController(context)); videoView.requestFocus(); videoView.start(); videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.setOnInfoListener(new MediaPlayer.OnInfoListener() { @Override public boolean onInfo(MediaPlayer mp, int what, int extra) { if (what == MediaPlayer.MEDIA_INFO_BUFFERING_START) bufferingDialog.show(); if (what == MediaPlayer.MEDIA_INFO_BUFFERING_END) bufferingDialog.dismiss(); return false; } }); } }); videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() { @Override public boolean onError(MediaPlayer mp, int what, int extra) { bufferingDialog.dismiss(); return false; } }); 

我正在做类似的事情,不能拿出一个很好的解决scheme。 这里贴出了一些有趣的解决scheme,你应该看看你是否看过。

无论如何,我想到了在上面的线程中暗示的以下黑客行为,现在可以正常工作。

 @Override public void onBufferingUpdate(MediaPlayer mp, int percent) { float temp = ((float)mp.getCurrentPosition() / (float)mp.getDuration())*100; if(Math.abs(percent - temp) < 1) { buffer_fail++; if(buffer_fail == 15) { //buffer failed } } }