Search code examples
androidmedia-playerandroid-videoview

Detect if a VideoVIew is buffering


Does anyone know if it's possible to detect when a VideoView is buffering?

I want to show a ProgressDialog when the video is buffering.

So far I tried using a OnPreparedListener, but that only works when the video is first loaded. If a video is playing and the user moves the scrub bar to a different point the video is still "prepared" even though it is buffering.

I also tried (I know this is awful) an AsyncThread that just busy waits on 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...
 }
}

This doesn't work because as soon as you call start() a VideoView seems to be considered playing even though it is buffering.

The only solution I can think of is building a custom VideoView type class so I can access its MediaPlayer instance.

Any ideas? Thanks for reading.


Solution

  • Since API level 17, you can now access the InfoListener from the MediaPlayer:

    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.GONE);
                    return true;
                }
            }
            return false;
        }
    
    });
    
    mVideoView.setOnInfoListener(onInfoToPlayStateListener);