Detect if a VideoVIew is buffering

tonyc picture tonyc · Oct 23, 2011 · Viewed 16.5k times · Source

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.

Answer

cadesalaberry picture cadesalaberry · Mar 5, 2015

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);