androidandroid-mediacodecmediametadataretriever

MediaExtractor, MediaMetadataRetriever with Raw/Asset File


I try to read a video file inside either raw/assets folder, I have tried the following approaches but none of them works. I am testing on API 16. Each approach, I try with and without mp4 extension. I really appreciate that somebody can help me with it

All approaches will not crash, MediaMetadataRetriever can set data source, but cannot get width, height and screenshot. VideoExtractor always return

06-04 16:44:10.519: E/FileSource(8695): Failed to open file FILE_PATH. (No such file or directory)
06-04 16:44:10.519: E/DecodeActivity(8695): Can't find video info!

Approach 1:android.resource

String filePath = "android.resource://" + this.activity.getPackageName() + "/raw/green_backhand_slice";
videoExtractor.setDataSource(activity.getApplicationContext(), Uri.parse(filePath), null);
metaRetriever.setDataSource(act.getApplication(), Uri.parse(filePath));

Approach 2: android_asset

this.filePath = "file:///android_asset/green_backhand_slice";
videoExtractor.setDataSource(activity.getApplicationContext(), Uri.parse(this.filePath), null);
metaRetriever.setDataSource(act.getApplication(), Uri.parse(filePath));

Approach 3: asset file descriptor

AssetFileDescriptor assetFD = null;
try {
    assetFD = getAssets().openFd("green_backhand_slice.mp4");
} catch (IOException e) {
    e.printStackTrace();
}

metaRetriever.setDataSource(assetFD.getFileDescriptor());

Solution

  • Here are some ways to do it:

    1.raw:

    final AssetFileDescriptor afd=getResources().openRawResourceFd(R.raw.t);
    mediaMetadataRetriever.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
    

    2.raw as uri:

    final String uriPath="android.resource://"+getPackageName()+"/raw/t";
    final Uri uri=Uri.parse(uriPath);
    mediaMetadataRetriever.setDataSource(getApplication(),uri);
    

    3.assets:

    final AssetFileDescriptor afd=getAssets().openFd("t.mp4");
    mediaMetadataRetriever.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
    

    EDIT: another, in case you want to use the raw as a uri but got it without the name:

    val uri= Uri.parse("android.resource://" + getPackageName() + "/raw/" + resources.getResourceEntryName(R.raw.t))