如何将使用MediaRecorder录制的视频长度读入通过context.getFilesDir()构建的私有应用程序存储目录?

BVB*_*BVB 8 android android-video-player android-camera android-mediaplayer android-mediarecorder

我有一个奇怪的问题,通过使用MediaRecorder读取使用设备的相机记录的视频文件的长度/持续时间.该文件记录在应用程序的专用存储目录中,其目的如下:

mMediaRecorder.setOutputFile(context.getFilesDir() + "/recordings/webcam.3gpp");
Run Code Online (Sandbox Code Playgroud)

录制完成后,我尝试使用以下方法读取视频的长度:

方法1:

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

方法2:

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

这些方法都不起作用.mediaMetadataRetriever.extractMetadata返回null并MediaPlayer.create失败并返回IOException.我已经验证该文件存在.

重要说明:如果我将录音保存到"/sdcard/recordings/webcam.3gpp",则不会发生此问题.出于某种原因,我只是无法读取文件位于属于应用程序的专用文件目录中的持续时间.此外,这个问题只发生在运行Android 2.3的Samsung Droid Charge上.它不会发生在运行Android 4.2的三星Galaxy S4和运行Android 4.3的华硕Nexus 7上.

编辑:

如果我拿相同的文件并将其复制到SD卡,然后在那里读取它的长度,一切正常.是什么赋予了?

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

我该怎么做才能解决这个问题?

BVB*_*BVB 6

我能够通过设置一个FileInputStream数据源来解决我的问题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;
Run Code Online (Sandbox Code Playgroud)

我的回答来自/sf/answers/446855881/