2013-03-13 2 views
11

Я сделал приложение для диктофона, и я хочу показать продолжительность записей в списке. Я сохраняю записи следующим образом:получить продолжительность аудиофайла

MediaRecorder recorder = new MediaRecorder(); 
recorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT); 
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); 
folder = new File(Environment.getExternalStorageDirectory() 
      + File.separator + "Audio recordings"); 
String[] files = folder.list(); 
    int number = files.length + 1; 
    String filename = "AudioSample" + number + ".mp3"; 
    File output = new File(Environment.getExternalStorageDirectory() 
      + File.separator + "Audio recordings" + File.separator 
      + filename); 
    FileOutputStream writer = new FileOutputStream(output); 
    FileDescriptor fd = writer.getFD(); 
    recorder.setOutputFile(fd); 
    try { 
     recorder.prepare(); 
     recorder.start(); 
    } catch (IllegalStateException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     Log.e(LOG_TAG, "prepare() failed"); 
     e.printStackTrace(); 
    } 

Как я могу получить продолжительность в секундах этого файла?

Заранее спасибо

--- EDIT я получил это работает, я назвал MediaPlayer.getduration() внутри MediaPlayer.setOnPreparedListener() метод, так что возвращается 0.

ответ

0

После записи файла , откройте его в MediaPlayer и вызовите getDuration на нем.

+0

Пытался что, но она всегда возвращает 0 для какой-то причины – Simon

+1

Не важно, что я получил работу! Я вызвал MediaPlayer.getDuration() в методе MediaPlayer.setOnPreparedListener и чем он возвращает 0 – Simon

10

Использование Try

long totalDuration = mediaPlayer.getDuration(); // to get total duration in milliseconds 

long currentDuration = mediaPlayer.getCurrentPosition(); // to Gets the current playback position in milliseconds 

Отдел по 1000 для преобразования в секундах.

Надеюсь, это вам помогло.

+1

MediaPlayer.getduration() возвращает 0 по какой-то странной причине, вы знаете, почему? – Simon

19

Либо попробовать это, чтобы получить длительность в миллисекундах:

MediaPlayer mp = MediaPlayer.create(yourActivity, Uri.parse(pathofyourrecording)); 
int duration = mp.getDuration(); 

Или измерить время, прошедшее с recorder.start() до recorder.stop() в наносекунд:

long startTime = System.nanoTime();  
// ... do recording ...  
long estimatedTime = System.nanoTime() - startTime; 
+0

первый возвращает 0, и если я хочу использовать второе решение, мне нужно воспроизвести файл, и я не хочу этого – Simon

+0

Вам не нужно играть в файл для второго. Вы устанавливаете startTime, когда пользователь начинает запись и вычисляет расчетное время, когда пользователь останавливает запись. Для первого варианта убедитесь, что вы отпустите MediaRecorder перед инициализацией MediaPlayer. Если он все еще возвращает 0, вероятно, будет ошибка. Я бы попробовал разные аудиоформаты. – Erol

+0

Это решение работает на некоторых устройствах, но не на других. Любая идея почему? Работает на nexus5, но не на hudl. Могут ли поддерживаемые типы носителей? Файл, который я пытаюсь прочитать, - h264 mp4. – speedynomads

1

Вы смотрели на Ringdroid?. Это довольно легкий вес, и интеграция прямолинейна. Он хорошо работает с медиафайлами VBR.

Для вашей проблемы с получением продолжительности вы можете сделать что-то вроде ниже, используя Ringdroid.

public class AudioUtils 
{ 
    public static long getDuration(CheapSoundFile cheapSoundFile) 
    { 
     if(cheapSoundFile == null) 
      return -1; 
     int sampleRate = cheapSoundFile.getSampleRate(); 
     int samplesPerFrame = cheapSoundFile.getSamplesPerFrame(); 
     int frames = cheapSoundFile.getNumFrames(); 
     cheapSoundFile = null; 
     return 1000 * (frames * samplesPerFrame)/sampleRate; 
    } 

    public static long getDuration(String mediaPath) 
    { 
     if(mediaPath != null && mediaPath.length() > 0) 
      try 
      { 
       return getDuration(CheapSoundFile.create(mediaPath, null)); 
      }catch (FileNotFoundException e){} 
      catch (IOException e){} 
     return -1; 
    } 
} 

Надежда, что помогает

39

MediaMetadataRetriever представляет собой легкий и эффективный способ сделать это. MediaPlayer слишком тяжелы и могут возникнуть проблемы с производительностью в условиях высокой производительности, как скроллинг, пейджинг, листинг и т.д.

Кроме того, Error (100,0) может произойти на MediaPlayer, так как это тяжелый и иногда перезапускать нужно сделать снова и снова.

Uri uri = Uri.parse(pathStr); 
MediaMetadataRetriever mmr = new MediaMetadataRetriever(); 
mmr.setDataSource(AppContext.getAppContext(),uri); 
String durationStr = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); 
int millSecond = Integer.parseInt(durationStr); 
+0

Это было приятно найти, поскольку, похоже, в MediaPlayer.getDuration() есть ошибка - по крайней мере, для mp4. Благодаря! –

+0

Как мне получить MediaMetadataCompat.METADATA_KEY_DURATION? –

3

Самый быстрый способ сделать это через MediaMetadataRetriever. Тем не менее, есть улов

, если вы используете URI и контекст для установки источника данных вы можете столкнуться с ошибкой https://code.google.com/p/android/issues/detail?id=35794

Раствор использовать абсолютный путь к файлу для извлечения метаданных медиа-файлов.

Ниже приведен фрагмент код, чтобы сделать так

private static String getDuration(File file) { 
       MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever(); 
       mediaMetadataRetriever.setDataSource(file.getAbsolutePath()); 
       String durationStr = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION); 
       return Utils.formateMilliSeccond(Long.parseLong(durationStr)); 
      } 

Теперь вы можете конвертировать миллисекунды в удобочитаемый формат, используя один из ниже форматов

 /** 
     * Function to convert milliseconds time to 
     * Timer Format 
     * Hours:Minutes:Seconds 
     */ 
     public static String formateMilliSeccond(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 String.format("%02d Min, %02d Sec", 
    //    TimeUnit.MILLISECONDS.toMinutes(milliseconds), 
    //    TimeUnit.MILLISECONDS.toSeconds(milliseconds) - 
    //      TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(milliseconds))); 

      // return timer string 
      return finalTimerString; 
     } 
Смежные вопросы