¿Cuál es la mejor manera de obtener una duración de archivo de audio en Android?

Estoy usando un SoundPool para reproducir clips de audio en mi aplicación. Todo está bien, pero necesito saber cuándo ha terminado la reproducción del clip.

Por el momento lo rastreo en mi aplicación mediante la obtención de la duración de cada clip utilizando una instancia de MediaPlayer . Eso funciona bien, pero parece un derroche para cargar cada archivo dos veces, sólo para obtener la duración. Podría calcular aproximadamente la duración de mí mismo sabiendo la longitud del archivo (disponible de AssetFileDescriptor ) pero todavía necesitaría saber la tarifa de la muestra y el número de canales.

Veo dos posibles soluciones a ese problema:

  1. Averiguar cuándo ha terminado de reproducir un clip (no parece posible con SoundClip).
  2. Tener una clase que podría cargar sólo el encabezado de un archivo de audio y me dan la frecuencia de muestreo / número de canales (e idealmente, el recuento de muestras para obtener la duración exacta).

¿Alguna sugerencia?

Gracias, Max

El código que estoy usando en este momento (funciona bien, pero es bastante pesado para el propósito):

String[] fileNames = ... MediaPlayer mp = new MediaPlayer(); for (String fileName : fileNames) { AssetFileDescriptor d = context.getAssets().openFd(fileName); mp.reset(); mp.setDataSource(d.getFileDescriptor(), d.getStartOffset(), d.getLength()); mp.prepare(); int duration = mp.getDuration(); // ... } 

En una nota lateral, esta pregunta ya se ha hecho, pero no obtuvo respuestas.

¿Has probado esto:

 String mediaPath = Uri.parse("android.resource://<your-package-name>/raw/filename").getPath(); MediaMetadataRetriever mmr = new MediaMetadataRetriever(); mmr.setDataSource(mediaPath); String duration = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); mmr.release(); 

Pero no estoy exactamente seguro de que esto es más ligero que el código existente.

Intente FFmpegMediaMetadataRetriever :

 String[] fileNames = ... FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever(); for (String fileName : fileNames) { AssetFileDescriptor d = context.getAssets().openFd(fileName); mmr.setDataSource(d.getFileDescriptor(), d.getStartOffset(), d.getLength()); String duration = mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_DURATION); } mmr.release(); 

Esto es trabajo para mí para obtener activos audio duración del archivo en segundos totales =====>

 MediaMetadataRetriever mmr = new MediaMetadataRetriever(); AssetFileDescriptor d = context.getAssets().openFd(fileName); mmr.setDataSource(d.getFileDescriptor(), d.getStartOffset(), d.getLength()); String duration = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); mmr.release(); 

Actualizado

Método para obtener la duración del archivo de audio activos en segundos

  public String gettotaltimeassets() { MediaMetadataRetriever mmr = new MediaMetadataRetriever(); AssetFileDescriptor d = null; try { d = getApplicationContext().getAssets().openFd("ASSETS FILE NAME"); } catch (IOException e) { e.printStackTrace(); } mmr.setDataSource(d.getFileDescriptor(), d.getStartOffset(), d.getLength()); String duration = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); long dur = Long.parseLong(duration); String seconds = String.valueOf((dur % 60000) / 1000); Log.d("seconds===========>", seconds); mmr.release(); return seconds; } 

Método para obtener la duración del archivo de audio de almacenamiento interno en segundos

 public String gettotaltimestorage(String filePath) { // load data file Log.d("time=================>","time=================>"); MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever(); metaRetriever.setDataSource(YourACTIVITY.this, Uri.parse(filePath)); Log.d("time=================>","time=================>"); String out = ""; // get mp3 info // convert duration to minute:seconds String duration = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); Log.d("time=================>", duration); long dur = Long.parseLong(duration); String seconds = String.valueOf((dur % 60000) / 1000); Log.d("seconds===========>", seconds); // close object metaRetriever.release(); return seconds; } 
  • MediaPlayer de Android setNextMediaPlayer () alternativa
  • SoundPool "AudioFlinger no pudo crear pista, estado: -12"
  • Android L SoundPool.load () regresión
  • Grabar / capturar la reproducción interna de sonido de la aplicación de Android y exportar mp3?
  • ¿Cómo sé si se ha terminado de reproducir un sonido en android?
  • Soundpool reproduce sólo los primeros 5 segundos del archivo. ¿Por qué?
  • Seamless Looping con SoundPool en Android?
  • ¿Por qué mis sonidos SoundPool no se reproducen simultáneamente en onClick ()?
  • La piscina de sonido no termina jugando el archivo completo
  • Android es la forma más rápida de cargar y reproducir sonido en la aplicación
  • Cómo sincronizar sonidos con SoundPool
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.