Android VideoView MediaPlayer OnInfoListener - eve

2019-04-24 06:38发布

问题:

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?

回答1:

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!



回答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.



回答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();
            }
        });


回答4:

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


回答5:

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 
} 


回答6:

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


回答7:

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.