2011-10-23 63 views
14

有誰知道是否有可能檢測VideoView何時緩衝?檢測VideoVIew是否緩衝

我想在視頻緩衝時顯示ProgressDialog。

到目前爲止,我嘗試使用OnPreparedListener,但只有當視頻第一次加載時才起作用。如果正在播放視頻,並且用戶將滑動條移動到不同的點,則視頻仍處於「準備」狀態,即使它正在緩衝。

我也嘗試過(我知道這是可怕的),關於IsPlaying模塊()只是忙等待的AsyncThread:

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... 
} 
} 

這並不是因爲只要你調用開始工作()一個VideoView似乎被認爲是在玩,即使它在緩衝。

我能想到的唯一解決方案是構建自定義VideoView類型類,以便可以訪問其MediaPlayer實例。

任何想法?謝謝閱讀。

+1

問題解決了嗎? –

回答

1

我正在做類似的事情,不能想出一個很好的解決方案。一些有趣的解決方案發布here,你應該檢查,如果你沒有看到他們。

無論如何,我想出了以上在上述線程中暗示的黑客行爲,現在可以正常工作。

@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

這不能在VideoView中使用。 – Rui

+2

因此,將其與從VideoView.setOnPreparedListener獲得的MediaPlayer一起使用 –

9

爲了不實現自定義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

這看起來像遞歸式指數存儲器消費者代碼片段。不是嗎? – Behnam

7

由於API level 17,你現在可以從MediaPlayer的訪問InfoListener:

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

我們不應該在緩衝結束時隱藏進度嗎? –

4

下面的代碼會在每次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; 
     } 
    });