I've been using this type of code to get the duration of videos on my Android device:
int dataColumn = cursor
.getColumnIndex(MediaStore.Files.FileColumns.DATA);
String path = cursor.getString(dataColumn);
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
File file = new File(path);
retriever.setDataSource(context, Uri.fromFile(file));
boolean hasVideo = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO).equals("yes");
String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
int duration = 0;
if (time != null && hasVideo) {
duration = (int) Math.ceil(Integer.parseInt(time) / 1000);
}
This was working until I began to target Android 11 (API level 30) in my app. Now the duration is always reported as 0
. I can see that MediaStore.Files.FileColumns.DATA
was deprecated beginning with Android 10 (API level 29), and ContentResolver.openFileDescriptor
is the recommended alternative. However, I don't know how to get a video's duration from a ParcelFileDescriptor
or FileDescriptor
. I also haven't been able to find resources that demonstrate how to do so. So, how can I do that?
I've also tried other possible solutions, none of which have worked:
- Using
retriever.setDataSource(file.getAbsolutePath())
instead ofretriever.setDataSource(context, Uri.fromFile(file))
. I saw that here and here, so I tried it but it didn't work (the duration is still zero) - I tried querying the duration field directly from the
MediaStore
but it still didn't work. This was the code I used:
int vidDurationColumn = cursor.getColumnIndex(MediaStore.Video.Media.DURATION);
int duration = (int)cursor.getInt(vidDurationColumn);
So yeah, I'm open to any ideas that work. Thanks!