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

Tue*_*yen 60 android

我是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);
}
Run Code Online (Sandbox Code Playgroud)

vir*_* us 107

使用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()
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的解决方案,但方法extractMetadata在Android 4.4或更低版本的某些设备上返回"null".我使用MediaPlayer类来检索文件持续时间...... (3认同)
  • ^我错了,以毫秒为单位。我之所以这样想是因为该类中的其他方法具有文档和签名:@param timeUs时间位置(以微秒为单位)... getFrameAtTime(long timeUs) (3认同)
  • 这是最佳解决方案(适用于API 10+) (2认同)

Nol*_*esh 31

我认为最简单的方法是:

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))
    );
Run Code Online (Sandbox Code Playgroud)

  • 无需创建MediaPlayer实例即可获取媒体持续时间.您可以使用MediaMetadataRetriever获取所有必需的元数据.有关详细信息,请参阅下面的答案. (5认同)

Gib*_*olt 12

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
}
Run Code Online (Sandbox Code Playgroud)

如果您想让它更安全(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
}
Run Code Online (Sandbox Code Playgroud)

此处不必要,但通常有用的附加 Uri 扩展

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

fun Uri.asFile(): File = File(toString())
Run Code Online (Sandbox Code Playgroud)


blo*_*ggg 5

我不认为您将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});
Run Code Online (Sandbox Code Playgroud)