Mediaplayer actualización de progreso a seekbar no suave?

Estoy trabajando en una aplicación con grabadora y reproductor. Estoy usando mediaplayer para reproducir el archivo .wav grabado y mientras tanto quiero actualizar a un buscador. Todo está funcionando bien Pero mi problema es la actualización de progreso de mediaplayer a seekbar no está sucediendo suavemente, si somos playig un pequeño archivo, el pulgar de la barra de búsqueda salta en segundos o entre.

¿Puede alguien ayudarme con una solución para hacer que busque el progreso en seekbar. Mi código se muestra a continuación. Estoy totlay pegado aquí.

mediaPlayerIntiate(); mediaPlayerSetSource(); mMediaPlayer.start(); task = new TimerTask() { @Override public void run() { Graphbar.post(new Runnable() { @Override public void run() { if (mMediaPlayer != null) { if (playButtonState == MediaMode.PLAY) { if (mMediaPlayer.isPlaying()) { Graphbar.setProgress(mMediaPlayer .getCurrentPosition()); mediaPlayerUpdateTimer(mMediaPlayer .getCurrentPosition()); enableRewindandForward(); } } } } }); } }; timer = new Timer(); timer.schedule(task, 0, 8); 

MMediaPlayer.getCurrentPosition () Devuelve el tiempo actual en milisegundos y lo estás actualizando a Seekbar cuya capacidad máxima es 100. Haz una fórmula con longitud de archivo y 100. prueba esta función

  MediaPlayer mMediaPlayer = new MediaPlayer(); final SeekBar mSeelBar = new SeekBar(this); final int duration = mMediaPlayer.getDuration(); final int amoungToupdate = duration / 100; Timer mTimer = new Timer(); mTimer.schedule(new TimerTask() { @Override public void run() { runOnUiThread(new Runnable() { @Override public void run() { if (!(amoungToupdate * mSeelBar.getProgress() >= duration)) { int p = mSeelBar.getProgress(); p += 1; mSeelBar.setProgress(p); } } }); }; }, amoungToupdate); 

Y este proceso se debe llamar cuando el jugador de medios comienza a jugar. dentro

 mediaPlayer.setOnPreparedListener(new OnPreparedListener(){ @Override public void onPrepared(MediaPlayer mp) { **// call here** }); 

Actualizar

Actualizar 125 veces en segundos no es algo que debas hacer. Aumente su intervalo para actualizar SeekBar. Añadiendo esto después de leer los comentarios de NullPointer

Aquí es cómo manejar el buscador;

  mediaPlayer.setOnPreparedListener(new OnPreparedListener(){ @Override public void onPrepared(MediaPlayer mp) { mediaPlayer.start(); new SeekBarHandler().execute(); }); 

Ahora tengo una tarea Async llamada SeekBarHandler que maneja el buscador como este:

  public class SeekBarHandler extends AsyncTask<Void, Void, Void> { @Override protected void onPostExecute(Void result) { Log.d("##########Seek Bar Handler ################","###################Destroyed##################"); super.onPostExecute(result); } @Override protected void onProgressUpdate(Void... values) { seekBar.setProgress(mediaPlayer.getCurrentPosition()); super.onProgressUpdate(values); } @Override protected Void doInBackground(Void... arg0) { while(mediaPlayer.isPlaying()&&isViewOn==true) { try { Thread.sleep(200); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } onProgressUpdate(); } return null; } } 

Ahora en mi onPause, termino el AsyncTask ya que no tiene sentido mantener el hilo en marcha cuando el usuario no puede ver la barra de búsqueda

  protected void onPause() { isViewOn=false; super.onPause(); } 

Y en onResume inicie el AsyncTaskAgain como este

  protected void onResume() { isViewOn=true; new SeekBarHandler().execute(); super.onResume(); } 

Como puedes ver, utilizo una bandera booleana isViewOn para comprobar si la vista está activada o no para manejar la barra de búsqueda.

 player.prepare(); // or start() ScheduledExecutorService service = Executors.newScheduledThreadPool(1); service.scheduleWithFixedDelay(new Runnable() { @Override public void run() { progressBar.setProgress(player.getCurrentPosition()); } }, 1, 1, TimeUnit.MICROSECONDS); 

Seekbar.setProgress () sólo acepta int. Por lo tanto, la mayoría de nosotros tiende a pasar el porcentaje transcurrido a este método. Sin embargo, si necesita una progresión mucho más suave, puede utilizar la duración en milisegundos como MAX. Entonces conseguimos actualizar la progresión del seekbar cada milisegundo. A continuación se muestra un ejemplo y he actualizado cada 15 milisegundos como casi todos los teléfonos Android viene con una tasa de actualización de 60 fps (frames por segundo).

  try{ mediaPlayer.start(); seekbar.setProgress(0); seekbar.setMax(mediaPlayer.getDuration()); // Updating progress bar seekHandler.postDelayed(updateSeekBar, 15); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } /** * Background Runnable thread * */ private Runnable updateSeekBar = new Runnable() { public void run() { long totalDuration = mediaPlayer.getDuration(); long currentDuration = mediaPlayer.getCurrentPosition(); // Displaying Total Duration time remaining.setText(""+ milliSecondsToTimer(totalDuration-currentDuration)); // Displaying time completed playing elapsed.setText(""+ milliSecondsToTimer(currentDuration)); // Updating progress bar seekbar.setProgress((int)currentDuration); // Call this thread again after 15 milliseconds => ~ 1000/60fps seekHandler.postDelayed(this, 15); } }; /** * Function to convert milliseconds time to * Timer Format * Hours:Minutes:Seconds * */ public String milliSecondsToTimer(long milliseconds){ String finalTimerString = ""; String secondsString = ""; // Convert total duration into time int hours = (int)( milliseconds / (1000*60*60)); int minutes = (int)(milliseconds % (1000*60*60)) / (1000*60); int seconds = (int) ((milliseconds % (1000*60*60)) % (1000*60) / 1000); // Add hours if there if(hours > 0){ finalTimerString = hours + ":"; } // Prepending 0 to seconds if it is one digit if(seconds < 10) { secondsString = "0" + seconds; }else { secondsString = "" + seconds; } finalTimerString = finalTimerString + minutes + ":" + secondsString; // return timer string return finalTimerString; } 

El problema que está experimentando tiene que ver con la forma en que se diseña / implementa SeekBar de Android. Si bien funciona muy bien, estás limitado por una combinación de segmentos utilizados (es decir, seekbar.setMax(int) ) y el tiempo de retardo de tu Handler.

Dicho esto, he subclasificado SeekBar para hacer mi propio SmoothSeekBar que utiliza ViewPropertyAnimators en lugar de un Handler.

Compruébelo aquí: https://github.com/Indatus/Android-SmoothSeekBar

  • Barra de progreso personalizada en Android?
  • Cancelar ProgressDialog y detener el hilo
  • Android ProgressDialog no funciona con la red móvil
  • No se puede crear el controlador dentro de hilo que no ha llamado Looper.prepare () dentro de AsyncTask para ProgressDialog
  • El indicador de progreso indeterminado ActionBarSherlock no desaparecerá en el simulador
  • Android: actualización de la barra de progreso de la notificación, correctamente
  • Diálogo de progreso con asynctask
  • Android: muestra el círculo de progreso como Google hace en sus aplicaciones
  • Pasar argumentos a AsyncTask y devolver resultados
  • ¿Cómo puedo mostrar un diálogo Progress entre dos actividades?
  • Utilizar la barra de progreso circular como alarmdialog o progressdialog
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.