Detect if a VideoVIew is buffering
Following code will show a buffering dialog every time the VideoView is buffering.
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;
}
});
I came with the following hack in order to not implement a custom VideoView. The idea is to check every 1 second if the current position is the same as 1 second before. If it is, the video is buffering. If not, the video is really playing.
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 is just a TextView with the text "Buffering..." placed in the center of my VideoView.
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);