Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read length of video recorded with MediaRecorder into private app storage directory constructed via context.getFilesDir()?

I am having a weird issue reading the length/duration of a video file recorded with a device's camera by using MediaRecorder. The file is recorded into the application's private storage directory, which is set like so:

mMediaRecorder.setOutputFile(context.getFilesDir() + "/recordings/webcam.3gpp");

After recording is complete, I attempt to read the length of the video with these methods:

Method 1:

MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(context.getFilesDir() + "/recordings/webcam.3gpp");
String time = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
return Long.parseLong(time);

Method 2:

MediaPlayer mp = MediaPlayer.create(context, Uri.parse(context.getFilesDir() + "/recordings/webcam.3gpp"));
long duration = mp.getDuration();
mp.release();
return duration;

None of the methods work. mediaMetadataRetriever.extractMetadata returns null and MediaPlayer.create fails with an IOException. I have verified that the file exists.

Important note: This issue DOES NOT happen if I save the recording to "/sdcard/recordings/webcam.3gpp". For some reason, I just cannot read the duration when the file is in the private files directory that belongs to the application. Also, this issue ONLY happens on my Samsung Droid Charge, which runs Android 2.3. It DOES NOT happen on a Samsung Galaxy S4, which runs Android 4.2, and Asus Nexus 7, which runs Android 4.3.

Edit:

If I take the same file and copy it to the sdcard, then read the length of it there, everything works. What gives?

copy(new File(context.getFilesDir() + "/recordings/webcam.3gpp"), new File("/sdcard/wtfisthiscrap.3gpp"));
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource("/sdcard/wtfisthiscrap.3gpp");
String time = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
return Long.parseLong(time); // works!

What can I do to solve this issue?

like image 232
BVB Avatar asked Oct 30 '13 17:10

BVB


1 Answers

I was able to solve my issue by setting a FileInputStream as the data source of MediaPlayer.

MediaPlayer mp = new MediaPlayer();
FileInputStream stream = new FileInputStream(context.getFilesDir() + "/recordings/webcam.3gpp");
mp.setDataSource(stream.getFD());
stream.close();
mp.prepare();
long duration = mp.getDuration();
mp.release();
return duration;

The source of my answer comes from https://stackoverflow.com/a/6383655/379245

like image 108
BVB Avatar answered Oct 20 '22 03:10

BVB