Search code examples
androidffmpegstorage-access-framework

FFMPEG Android Storage Access Framework


I'm using FFMPEG on Android to change bitrate etc of videos that weren't recorded within my app.

The problem I'm facing is that I can't get the absolute path for a video the user selects from the SD Card.

I'm using the Android Storage Access Framework and currently get the following Uri: content://com.android.externalstorage.documents/document/9C33-6BBD%3AVideos%2Freaps-driving.mp4

The FFMPEG command I use:

String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
                    String[] cmd = {"-y", "-i", mVideoUri.toString(), "-c:v", "libx264", "-preset", "ultrafast", "-strict", "-2", "-s", optimalVideoSize, "-aspect", "16:9", "-b", bitrate, String.format("/storage/emulated/0/Movies/InstaVid/VID_INSTAVID%s.mp4", timeStamp)};
                    executeFFmpegBinary(cmd, timeStamp);

It doesn't matter if I use mVideoUri.toString() or mVideoUri.getPath().

Is there any way I can get the absolute path?


Solution

  • The problem I'm facing is that I can't get the absolute path for a video the user selects from the SD Card

    First, the Storage Access Framework is not limited to removable storage. If the user chooses something from, say, Google Drive, for all you know, the video is not even on the device at the moment. In another example, Google just released a Samba storage provider, and if the user uses that, the content exists on a file server somewhere on the LAN, not on the device.

    Second, you do not have access to removable storage via the filesystem APIs, except for a couple of select areas (e.g., getExternalFilesDirs()). The user may choose a video outside of there.

    Is there any way I can get the absolute path?

    No. Your choices are:

    • Stop using the Storage Access Framework, and instead use some file picker library, which will limit you to files that you will be able to pass along to ffmpeg.

    • Use a ContentResolver and openInputStream() to get an InputStream on the content identified by the Uri, then use that to make a local copy of the content into a file that you control. Then, pass the path to that local copy to ffmpeg. Delete the local copy when you are done.