9

this following source code snippet is given:

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

I am streaming HLS streams with Android 3.x+ devices and trying to hide a loading dialog once the buffering is completed. The video streaming works, but the info events are never fired.

Any ideas?

Nabil
  • 91
  • 1
  • 1
  • 3
  • Can anyone provide a good solution for this? – sleeping.ninja Nov 01 '12 at 04:31
  • I'm just wondering whether setting the `OnInfoListener` in `onPrepared(...)` is simply too late in the chain of calls. The documentation on `prepareAsync()` says the following: *"(...) For streams, you should call prepareAsync(), which returns immediately, **rather than blocking until enough data has been buffered**."* That sounds to me as if `onPrepared(...)` will not get hit until the buffers have already been filled. Any change you've already given reflection a try? That should allow you to set the `OnInfoListener` any time you like. – MH. Nov 06 '12 at 23:52

7 Answers7

3

I know its too late, But posting it for the users still seeking for the solution (This worked for me):

        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();
            }
        });
Myth
  • 1,218
  • 12
  • 15
  • setOnInfoListener gets fired once a video is started. Then we can use this for showing and hiding progress-bar during the intermediate buffering of the video. – Myth Dec 27 '16 at 13:28
  • 1
    Still not being fired in my case – DIRTY DAVE Dec 22 '19 at 00:49
2

You're right, the events are never fired. This is a known HLS bug that I don't think Google will fix.

This applies to the onInfo and the buffering events.

See https://code.google.com/p/android/issues/detail?id=42767 and https://code.google.com/p/googletv-issues/issues/detail?id=2

Sorry!

cade
  • 563
  • 4
  • 15
2

Not fully sure as to what the OP is asking, but here are some very untimely bits of information.

I wouldn't rely on onPrepared. I find it to be unreliable.

I have found the two most useful pieces of information for HLS streaming through the MediaPlayer are the duration of the video and the progress position of the video. You get both of these by listening to progress updates.

When the duration is greater than zero, you know the video is truly prepared and can be manipulate (scrub). When progress position changes, you know the video is done buffering and has commenced playback. This last item only works when the video is playing of course. The MediaPlayer tends to relay inaccurate information.

These pieces of information are mostly accurate and can usually be relied upon to be "fairly" timely. This timeliness varies from device to device.

javahead76
  • 1,050
  • 10
  • 11
1

onPrepared is called when the MediaPlayer is prepared to start buffering, not when the video is completely buffered. However, it is completely natural to dismiss the loading dialog from within the onPrepared method.

Also MEDIA_INFO_BUFFERING_END is used when MediaPlayer is resuming playback after filling buffers, so I do not think it should be something to use to dismiss the dialog. So this should work:

videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mediaPlayer) {
        activity.dismissDialog(DialogID.DIALOG_LOADING);
    }
});
Cristian
  • 198,401
  • 62
  • 356
  • 264
  • This is something I've already tried. I'm trying to account for buffer underruns that maybe caused due to initial buffer, rebuffers due to poor network conditions or rebuffers due to seek. Your method wouldn't work for any of those scenarios. – sleeping.ninja Nov 10 '12 at 00:19
0

You can able to set OnPreparedListener on videoView because its your object but if you checkout source of VideoView you will find that mMediaPlayer is its private member so any change that you do from external will not be applied to it.

As per your requirement you need buffering status so you can have thread or handler or some thing so you can update your UI to get buffer status there is one method

int percent = videoView.getBufferPercentage();

if(percent == 100){
// buffering done 
} 
Vishal Pawar
  • 4,324
  • 4
  • 28
  • 54
  • 2
    Have a read in the bounty notes, this is not what he want: _"I don't want a solution * that polls to look at the play head to check for progress * that uses onBufferUpdate to estimate (based on older post on SO this isn't accurate."_ – yorkw Nov 01 '12 at 22:33
  • please check what I said in first para – Vishal Pawar Nov 02 '12 at 07:00
  • @yorkw is right. If you look at AOSP source for videoview, getBufferPercentage return the same value as onBufferUpdate(percent) does. onBufferUpdate tells you how much content has buffered with respect to the whole video. For example 80% means, 80% of the video has been buffered – sleeping.ninja Nov 10 '12 at 00:06
0

You no need to go through setOnInfoListener

by overriding setOnPreparedListener method is enough. as in the api show

public void setOnPreparedListener (MediaPlayer.OnPreparedListener l)

Register a callback to be invoked when the media file is loaded and ready to go.

so, you can dismiss your dialog inside setOnPreparedListener method is enough

like this

    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();
        }
        });
        }
    });
Sruit A.Suk
  • 7,073
  • 7
  • 61
  • 71
  • Whats the different between my result and his result ? also, it's load when the buffer is complete. I copied it from the Android API. See it here http://developer.android.com/reference/android/widget/VideoView.html#setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener) – Sruit A.Suk Nov 10 '12 at 17:41
  • Let it me reiterate the answer I gave @Cristian. This is something I've already tried. I'm trying to account for buffer underruns that maybe caused due to initial buffer, rebuffers due to poor network conditions or rebuffers due to seek. Your method wouldn't work for any of those scenarios. – sleeping.ninja Nov 10 '12 at 20:37
0

If you want to show loading each time it's buffering (initial time or subsequent buffer underruns) just ensure to show it again:

// 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":
  }
}

So this event sequence will do as desired:

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

Update:

This is assuming the info events work. Of course.

helios
  • 13,574
  • 2
  • 45
  • 55