2013-03-13 91 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(); 
    } 

如何获得此文件的持续时间(秒)?

在此先感谢

---编辑 我得到它的工作,我叫MediaPlayer.getduration()的MediaPlayer.setOnPreparedListener内()方法,因此返回0。

回答

0

你写的文件后,在MediaPlayer中打开它,并调用getDuration。

+0

试过毫秒转换为人类可读的格式,但它总是出于某种原因 – Simon 2013-03-13 19:33:22

+1

返回0没关系我得到它的工作!我在MediaPlayer.setOnPreparedListener方法中调用MediaPlayer.getDuration(),并返回0 – Simon 2013-03-13 19:47:43

10

尝试使用

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 2013-03-13 19:43:35

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 2013-03-13 19:41:02

+0

您不必为第二个播放文件。用户开始录制时设置startTime,并在用户停止录制时计算估计时间。 对于第一个选项,请确保在初始化MediaPlayer之前释放MediaRecorder。如果它仍然返回0,则可能有错误。我会尝试不同的音频格式。 – Erol 2013-03-13 21:42:46

+0

此解决方案适用于某些设备,但不适用于其他设备。任何想法为什么?适用于nexus5,但不适用于hudl。可能支持媒体类型?我正在尝试阅读的文件是h264 mp4。 – speedynomads 2015-09-18 16:25:34

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来说。谢谢! – 2016-06-21 06:15:50

+0

如何获取MediaMetadataCompat.METADATA_KEY_DURATION? – 2017-01-30 18:09:07

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; 
     } 
相关问题