¿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.
- Soundpool no está en bucle en Android 4.3
- Y otra vez sobre problemas de memoria con SoundPool
- Android SoundPool cortar archivo de sonido corto
- Problemas de Android Soundpool
- Reproducir sonido utilizando el ejemplo de grupo de sonidos
Veo dos posibles soluciones a ese problema:
- Averiguar cuándo ha terminado de reproducir un clip (no parece posible con SoundClip).
- 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.
- ¿Por qué varias llamadas de Android SoundPool.unload devuelven true / false dependiendo del pedido?
- Error SoundPool: no hay más nombres de pista disponibles
- Volumen de secuencia en SoundPool vs volumen en AudioManager
- Android 2.2 - La muestra 0 de SoundPool no está LISTA
- Sincronización de sonidos Android
- Excepción no captada lanzada por el finalizador java.lang.IllegalStateException: Binder se ha finalizado
- El sonido no se reproduce en la versión de Android superior a 4,0
- AudioFlinger no pudo crear pista. Estado: -12
¿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; }
- Construir una RatingBar utilizando imágenes cargadas desde la web
- ¿Cómo puedo restar estas listas más rápido?