Определить, является ли VideoVIew буферизацией - PullRequest
15 голосов
/ 23 октября 2011

Кто-нибудь знает, возможно ли определить, когда VideoView буферизуется?

Я хочу показать ProgressDialog, когда видео буферизируется.

До сих пор я пытался использовать OnPreparedListener, ноэто работает только при первой загрузке видео.Если воспроизводится видео, и пользователь перемещает полосу прокрутки в другую точку, видео все еще «готово», даже если оно буферизируется.

Я также попытался (я знаю, что это ужасно) AsyncThread, который просто занятждет 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...
 }
}

Это не работает, потому что как только вы вызываете start (), кажется, что VideoView проигрывается, даже если он буферизируется.

Решение, о котором я могу подумать, - это создание пользовательского класса типов VideoView, чтобы я мог получить доступ к его экземпляру MediaPlayer.

Есть идеи?Спасибо за чтение.

Ответы [ 6 ]

12 голосов
/ 05 марта 2015

Поскольку API-уровень 17 , теперь вы можете получить доступ к InfoListener из 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.VISIBLE);
                return true;
            }
        }
        return false;
    }

});

mVideoView.setOnInfoListener(onInfoToPlayStateListener);
10 голосов
/ 02 марта 2012

Я пришел со следующим хаком, чтобы не реализовывать пользовательский VideoView.Идея состоит в том, чтобы проверять каждую 1 секунду, является ли текущая позиция такой же, как 1 секунда раньше.Если это так, видео буферизуется.Если нет, видео действительно воспроизводится.

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 - это просто TextView с текстом «Buffering ...», помещенным в центре моего VideoView.

3 голосов
/ 25 июня 2018
VideoView showing Progress while Buffering
Below code worked for me


videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(final MediaPlayer mp) {
                mp.start();
                mp.setOnInfoListener(new MediaPlayer.OnInfoListener() {
                    @Override
                    public boolean onInfo(MediaPlayer mp, int what, int extra) {
                        switch (what) {
                            case MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START: {
                                progressBar.setVisibility(View.GONE);
                                return true;
                            }
                            case MediaPlayer.MEDIA_INFO_BUFFERING_START: {
                                progressBar.setVisibility(View.VISIBLE);
                                return true;
                            }
                            case MediaPlayer.MEDIA_INFO_BUFFERING_END: {
                                progressBar.setVisibility(View.GONE);
                                return true;
                            }
                        }
                        return false;
                    }
                });
            }
        });
3 голосов
/ 31 июля 2015

Следующий код будет отображать диалоговое окно буферизации каждый раз, когда VideoView буферизируется.

    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;
        }
    });
1 голос
/ 25 октября 2011

Я работаю над чем-то похожим, и не смог придумать отличного решения. здесь были опубликованы некоторые интересные решения, которые вы должны проверить, если вы их не видели.

Во всяком случае, я придумал следующий хак, на который намекали в вышеупомянутой теме, и пока работает нормально.

@Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
    float temp = ((float)mp.getCurrentPosition() / (float)mp.getDuration())*100;
    if(Math.abs(percent - temp) < 1) {
        buffer_fail++;
        if(buffer_fail == 15) {
            //buffer failed
        }
    }
}
0 голосов
/ 22 июня 2019

Это сработало для меня

boolean b_start = true;
boolean b_end = true;                                                                  
 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: {
                    dialog1.setVisibility(View.GONE);
                    b_end = false;
                    b_start = false;

                }
                case MediaPlayer.MEDIA_INFO_BUFFERING_START: {
                    if (b_start){
                    dialog1.setVisibility(View.VISIBLE);
                    }
                    b_start = true;

                }
                case MediaPlayer.MEDIA_INFO_BUFFERING_END: {
                    if(b_end){
                    dialog1.setVisibility(View.VISIBLE);
                    }
                    b_end = true;
                }
            }
            return false;
        }

    };


    videoView.setOnInfoListener(onInfoToPlayStateListener);
...