如何获得视频文件的持续时间?


69

我是Android编程的初学者。

我正在编写一个应用程序,以列出文件夹中的所有视频文件并显示该文件夹中所有视频的信息。但是,当我尝试获取视频时长时,它会返回null,而我找不到方法。

有人可以帮助我吗?

下面是我的代码:

Uri uri = Uri.parse("content://media/external/video/media/9");
Cursor cursor = MediaStore.Video.query(res, data.getData(), new String[]{MediaStore.Video.VideoColumns.DURATION});
if(cursor.moveToFirst()) {
    String duration = cursor.getString(0);
    System.out.println("Duration: " + duration);
}

1
您的代码适用于我的Android 2.3。也许您使用的是2.2或更低版本?
Ngoc Dao 2012年

Answers:


125

使用MediaMetadataRetriever检索媒体的具体数据:

MediaMetadataRetriever retriever = new MediaMetadataRetriever();
//use one of overloaded setDataSource() functions to set your data source
retriever.setDataSource(context, Uri.fromFile(videoFile));
String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
long timeInMillisec = Long.parseLong(time );

retriever.release()

2
这是最好的解决方案(适用于API 10+)
Amir Uval

3
这是一个很好的解决方案,但在某些Android 4.4或更低版本的设备上,extractMetadata方法返回“ null”。我使用MediaPlayer类检索文件的持续时间...
Massimo

提取的持续时间将以“微秒”而非“毫秒”为单位。
Ashkan Sarlak '18

4
^我错了,以毫秒为单位。我之所以这样想是因为该类中的其他方法具有文档和签名:@param timeUs时间位置(以微秒为单位)... getFrameAtTime(long timeUs)
Ashkan Sarlak '18

请注意,extractMetadata在某些设备上将返回null。在这种情况下,您将不得不找到另一种获取持续时间的方法。
ShrimpCrackers

34

我认为最简单的方法是:

MediaPlayer mp = MediaPlayer.create(this, Uri.parse(uriOfFile));
int duration = mp.getDuration();
mp.release();
/*convert millis to appropriate time*/
return String.format("%d min, %d sec", 
        TimeUnit.MILLISECONDS.toMinutes(duration),
        TimeUnit.MILLISECONDS.toSeconds(duration) - 
        TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(duration))
    );

5
无需创建MediaPlayer实例即可获取媒体持续时间。您可以使用MediaMetadataRetriever获取所有必要的元数据。请参阅下面的我的答案以获取更多详细信息。
vir us

这将导致带有多个文件的OOM
Chisko

@ Chisko,OOM是什么?就我而言,我需要确定单个视频文件的持续时间。
Nolesh

@Nolesh OutOfMemory异常。您应该调查一下。
奇斯科(Chisko)'18

最好也将语言环境参数用于String.format()
Sergey Stasishin

7

我不认为您将URI发布到媒体商店视频查询中

Uri uri = Uri.parse("content://media/external/video/media/9");

Cursor cursor = MediaStore.Video.query(res, data.getData(), new String[]{MediaStore.Video.VideoColumns.DURATION});

这比接受的答案和其他答案要
Deepak Kumar

2

Kotlin扩展解决方案

这是在Kotlin中获取媒体文件持续时间的方法

fun File.getMediaDuration(context: Context): Long {
    if (!exists()) return 0
    val retriever = MediaMetadataRetriever()
    retriever.setDataSource(context, Uri.parse(absolutePath))
    val duration = retriever.extractMetadata(METADATA_KEY_DURATION)
    retriever.release()

    return duration.toLongOrNull() ?: 0
}

如果您想使其更安全(Uri.parse可能引发异常),请使用此组合。其他的通常也是有用的:)

fun String?.asUri(): Uri? {
    try {
        return Uri.parse(this)
    } catch (e: Exception) {
    }
    return null
}

val File.uri get() = this.absolutePath.asUri()

fun File.getMediaDuration(context: Context): Long {
    if (!exists()) return 0
    val retriever = MediaMetadataRetriever()
    retriever.setDataSource(context, uri)
    val duration = retriever.extractMetadata(METADATA_KEY_DURATION)
    retriever.release()

    return duration.toLongOrNull() ?: 0
}

这里没有必要,但通常对其他Uri扩展很有帮助

val Uri?.exists get() = if (this == null) false else asFile().exists()

fun Uri.asFile(): File = File(toString())

1
public static long getDurationOfSound(Context context, Object soundFile)
  {
    int millis = 0;
    MediaPlayer mp = new MediaPlayer();
    try
    {
      Class<? extends Object> currentArgClass = soundFile.getClass();
      if(currentArgClass == Integer.class)
      {
        AssetFileDescriptor afd = context.getResources().openRawResourceFd((Integer)soundFile);
            mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
        afd.close();
      }
      else if(currentArgClass == String.class)
      {
        mp.setDataSource((String)soundFile);
      }
      else if(currentArgClass == File.class)
      {
        mp.setDataSource(((File)soundFile).getAbsolutePath());
      }
      mp.prepare();
      millis = mp.getDuration();
    }
    catch(Exception e)
    {
    //  Logger.e(e.toString());
    }
    finally
    {
      mp.release();
      mp = null;
    }
    return millis;
  }

1
MediaPlayer mpl = MediaPlayer.create(this,R.raw.videoFile);   
int si = mpl.getDuration();

这将给出视频文件的持续时间


3
MediaPlayer.create是一种繁重的方法,“ vir us”建议的MediaMetadataRetriever似乎更合适。
Hrk

-1
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(uriOfFile);
long duration = Long.parseLong(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION))
int width = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH));
int height = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT));
retriever.release();

一些上下文解释为什么它可以解决问题将很有用
d219

此代码段不仅提供持续时间,还提供视频分辨率,在某些情况下可能有用。
安库什·蒙德拉
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.