2011-10-23 51 views
14

Có ai biết nếu có thể phát hiện khi VideoView đang lưu vào bộ đệm không?Phát hiện nếu VideoVIew đang lưu vào bộ đệm

Tôi muốn hiển thị ProgressDialog khi video đang lưu vào bộ đệm.

Cho đến nay, tôi đã thử sử dụng OnPreparedListener nhưng chỉ hoạt động khi video được tải lần đầu tiên. Nếu video đang phát và người dùng di chuyển thanh chà đến một điểm khác thì video vẫn được "chuẩn bị" ngay cả khi video đang được lưu vào bộ đệm.

Tôi cũng đã cố gắng (Tôi biết điều này là khủng khiếp) một AsyncThread mà chỉ chờ đợi bận rộn trên 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... 
} 
} 

này không hoạt động bởi vì ngay sau khi bạn gọi start() một VideoView dường như được coi là chơi ngay cả khi đang lưu vào bộ đệm.

Giải pháp duy nhất tôi có thể nghĩ đến là xây dựng lớp loại VideoView tùy chỉnh để tôi có thể truy cập phiên bản MediaPlayer của nó.

Bất kỳ ý tưởng nào? Cảm ơn vì đã đọc.

+1

Sự cố của bạn có được giải quyết không? –

Trả lời

1

Tôi đang làm việc tương tự và không thể đưa ra giải pháp tuyệt vời. Một số giải pháp thú vị đã được đăng here mà bạn nên kiểm tra xem bạn đã không nhìn thấy chúng chưa.

Dù sao, tôi đã đưa ra bản hack sau đã được gợi ý trong chuỗi ở trên và hoạt động ok ngay bây giờ.

@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

Điều này không thể được sử dụng bên trong một VideoView. – Rui

+2

Vì vậy, hãy sử dụng nó với MediaPlayer mà bạn nhận được từ VideoView.setOnPreparedListener –

9

Tôi đi kèm với lỗi sau để không triển khai VideoView tùy chỉnh. Ý tưởng là để kiểm tra mỗi 1 giây nếu vị trí hiện tại là giống như 1 giây trước. Nếu có, video sẽ được lưu vào bộ đệm. Nếu không, video thực sự đang phát.

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 chỉ là một TextView có văn bản "Buffering ..." được đặt ở giữa VideoView của tôi.

+3

Điều này trông giống như một đoạn mã đệ quy của người tiêu dùng bộ nhớ đệ quy. Phải không? – Behnam

7

Kể từ API level 17, bây giờ bạn có thể truy cập vào InfoListener từ 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); 
+1

Chúng ta không nên ẩn tiến trình khi kết thúc bộ đệm? –

4

mã sau sẽ hiển thị một hộp thoại đệm mỗi khi VideoView là đệm.

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; 
     } 
    }); 
Các vấn đề liên quan