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

我是 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);
}
71794 次浏览

I don't think you post your URI into the mediastore video query

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


Cursor cursor = MediaStore.Video.query(res, data.getData(), new String[]{MediaStore.Video.VideoColumns.DURATION});
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;
}

I think the easiest way is:

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

Use MediaMetadataRetriever to retrieve media specific data:

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()
MediaPlayer mpl = MediaPlayer.create(this,R.raw.videoFile);
int si = mpl.getDuration();

This will give the duration of the video file

Kotlin Extension Solution

Here is the way to fetch media file duration in 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
}

If you want to make it safer (Uri.parse could throw exception), use this combination. The others are generally just useful as well :)

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
}

Not necessary here, but generally helpful additional Uri extensions

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


fun Uri.asFile(): File = File(toString())
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();
object MediaHelper {


const val PICK_IMAGE_FROM_DEVICE = 100
const val PICK_MEDIA_FROM_DEVICE = 101


fun openPhoneGalleryForImage(fragment: Fragment){
Intent(Intent.ACTION_GET_CONTENT).run {
this.type = "image/*"
fragment.startActivityForResult(this, PICK_IMAGE_FROM_DEVICE)
}
}


fun openPhoneGalleryForMedia(fragment: Fragment){
Intent(Intent.ACTION_GET_CONTENT).run {
this.type = "*/*"
fragment.startActivityForResult(this, PICK_MEDIA_FROM_DEVICE)
}
}


fun getMediaType(context: Context, source: Uri): MediaType? {
val mediaTypeRaw = context.contentResolver.getType(source)
if (mediaTypeRaw?.startsWith("image") == true)
return MediaType.Image
if (mediaTypeRaw?.startsWith("video") == true)
return MediaType.Video
return null
}


fun getVideoDuration(context: Context, source: Uri): Long? {
if (getMediaType(context, source) != MediaType.Video)
return null
val retriever = MediaMetadataRetriever()
retriever.setDataSource(context, source)
val duration = retriever.extractMetadata(METADATA_KEY_DURATION)
retriever.release()
return duration?.toLongOrNull()
}
}


enum class MediaType {
Image {
override val mimeType: String = "image/jpeg"
override val fileExtension: String = ".jpg"
},
Video {
override val mimeType: String = "video/mp4"
override val fileExtension: String = ".mp4"
};


abstract val mimeType: String
abstract val fileExtension: String
}
fun File.getVideoDuration(context: Context): Long {
context.contentResolver.query(toUri(), arrayOf(MediaStore.Video.Media.DURATION), null, null, null)?.use {
val durationColumn = it.getColumnIndexOrThrow(MediaStore.Video.Media.DURATION)
it.moveToFirst()
return it.getLong(durationColumn)
}
return 0