2011-10-23 13 views
14

¿Alguien sabe si es posible detectar cuando un VideoView está almacenado en el búfer?Detecta si un VideoVIew está almacenando en el buffer

Quiero mostrar un ProgressDialog cuando el video está almacenado.

Hasta ahora he intentado usar un OnPreparedListener, pero eso solo funciona cuando el video se carga por primera vez. Si se está reproduciendo un video y el usuario mueve la barra de fregado a un punto diferente, el video todavía está "preparado" aunque esté almacenado en el búfer.

También probé (sé que esto es horrible) un AsyncThread que sólo ocupado espera en 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... 
} 
} 

Esto no funciona porque tan pronto como se llama a start() un VideoView parece se considerará jugar aunque sea buffering

La única solución que se me ocurre es crear una clase de tipo de VideoView personalizada para que pueda acceder a su instancia de MediaPlayer.

¿Alguna idea? Gracias por leer.

+1

¿Ha solucionado su problema? –

Respuesta

1

Estoy trabajando en algo similar, y no pude encontrar una gran solución. Se publicaron algunas soluciones interesantes here que debería verificar si no las ha visto.

De todos modos, se me ocurrió el siguiente truco que se insinuó en el hilo anterior y funciona bien por ahora.

@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

Esto no se puede usar dentro de VideoView. – Rui

+2

Así que úselo con el MediaPlayer que obtiene de VideoView.setOnPreparedListener –

9

Vine con el siguiente truco para no implementar un VideoView personalizado. La idea es verificar cada 1 segundo si la posición actual es la misma que 1 segundo antes. Si es así, el video está en buffering. Si no, el video realmente se está reproduciendo.

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 es sólo un TextView con el texto "Buffering ..." colocado en el centro de mi VideoView.

+3

Esto se ve como una pieza recursiva de código de memoria exponencial. ¿No es así? – Behnam

7

Desde API level 17, ahora se puede acceder al InfoListener del 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

¿No deberíamos ocultar el progreso en el buffering end? –

4

siguiente código mostrará un cuadro de diálogo cada vez que el búfer VideoView se almacena en búfer.

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