2011-01-17 12 views
11

Sto utilizzando uno SoundPool per riprodurre clip audio nella mia app. Tutto va bene, ma ho bisogno di sapere quando la riproduzione della clip è finita.Qual è il modo migliore per ottenere una durata del file audio in Android?

Al momento lo seguo nella mia app ottenendo la durata di ogni clip utilizzando un'istanza MediaPlayer. Funziona bene ma sembra inutile caricare ogni file due volte, solo per ottenere la durata. Potrei calcolare approssimativamente la durata conoscendo la lunghezza del file (disponibile da AssetFileDescriptor) ma dovrei comunque conoscere la frequenza di campionamento e il numero di canali.

Vedo due possibili soluzioni a questo problema:

  1. Capire quando un clip è finito di giocare (non sembra essere possibile con Soundclip).
  2. Avere una classe che può caricare solo l'intestazione di un file audio e darmi la frequenza di campionamento/numero di canali (e, idealmente, il conteggio dei campioni per ottenere la durata esatta).

Qualche suggerimento?

Grazie, Max

Il codice che sto utilizzando in questo momento (funziona bene, ma è piuttosto pesante per lo scopo):

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(); 
    // ... 
} 

Una nota a parte, la questione è già stata asked ma non ha ottenuto risposte.

+0

avete considerato un 'onCompletitionListener'? https://developer.android.com/reference/android/media/MediaPlayer.OnCompletionListener.html#onCompletion%28android.media.MediaPlayer%29 – sschrass

+0

@SatelliteSD semplicemente non funziona (non viene mai chiamato) su nessuno dei dispositivi Io ho. Anche se viene chiamato su alcune versioni del sistema operativo/su alcuni dispositivi, è inaffidabile e quindi inutile. – Gilead

+1

hai doppiato il comando che 'setOnCompletitionListner' viene chiamato dopo' .start() '? – sschrass

risposta

9

Hai provato questo:

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(); 

ma non sono esattamente sicuro che questo è più leggero di exisiting codice.

+3

Non dimenticare di rilasciare 'MediaMetadataRetriever' –

+0

Ho provato questo, ma ho sempre lanciato un IllegalArgumentException da' mmr.setDataSource() '- c'è un modo per scoprire come dovrebbe essere esattamente quel percorso? Perché sospetto che il percorso che uso potrebbe essere errato. Sto usando i file audio in-bundle .m4a e/o .wav. – Jonny

+1

@Meher risposta perfetta +1 –

3

Prova 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(); 
0

questo è un lavoro per me per ottenere beni durata del file audio un totale secondi =====>

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(); 

Updated

metodo per ottenere risorse file audio du razione in secondi

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; 
} 

metodo per ottenere durata del file audio memoria interna in secondi

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; 

} 
+0

Si prega di fornire spiegazione alla risposta. Ciò non solo aiuterà a capire la causa del problema attuale, ma eviterà lo stesso in futuro. –

+0

in realtà scrivo codice per ottenere la durata di qualsiasi file audio in risorse come @William Seemann scrivi ma io uso MediaMetadata per recuperare la durata ... modifico la mia risposta in modo da capire meglio ... puoi chiamare questo metodo per più file audio a ottenere la durata. –

+0

Non ho scritto quel commento perché non ero in grado di capire il tuo codice, ma è una buona pratica su SO per accompagnare la tua soluzione con una spiegazione adeguata. Le risposte solo in codice non sono molto apprezzate. –

Problemi correlati