Search code examples
androidkotlinurifilepath

Get path from recorded video


currently i am developing a simple app to record video using kotlin, but i have difficulties when i want to get absolute path from video i recorded before. Here is my code which is written in kotlin

    private fun dispatchTakeVideoIntent() {
        val intent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
        startActivityForResult(intent, 1)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode == RESULT_OK) {
            val videoUri: Uri? = data?.data
            val file = File(videoUri?.path)
        }
    }

I have convert videoUri to path using videoUri?.path but it always return me with something like /external/video/media/55, whereas my video file path is something like /storage/emulated/0/DCIM/Camera/video.mp4

Could i get the file path instead of uri of my recorded video ? any help or hints will be much appreciated.

PS : this might have been asked before in another question : How to get recorded video path in android ? but it didnt have any accepted answer so i think it is fine to asking again.


Solution

  • Could i get the file path instead of uri of my recorded video ?

    There is no requirement for the video to be recorded as a file on the filesystem, let alone in a location that you can access via the filesystem APIs.

    If the scheme of the returned Uri happens to be file, then getPath() will return you a filesystem path to the file. However, there is no guarantee that you can use that file, and the file scheme has largely been banned since Android 7.0.

    It is far more likely that the scheme will be content. That Uri could point to:

    • A local file on external storage that your app could read
    • A local file on external storage, but in a place that your app will lack read access to
    • A local file on internal storage for the other app
    • A local file on removable storage
    • A local file that is encrypted and needs to be decrypted on the fly
    • A stream of bytes held in a BLOB column in a database
    • A piece of content that needs to be downloaded by the other app first
    • ...and so on

    And, just as with an https URL, there is no magic way to convert the path portion of the Uri to some filesystem path.

    i need file system path because i want to process it using FFmpeg later

    I would start by seeing if anyone has an FFmpeg wrapper that can work with a Uri.

    If that is unavailable, then you will need to make a copy of the content in a file that you control:

    • Use ContentResolver and openInputStream() to get an InputStream on the content, passing in your Uri
    • Open a FileOutputStream on some file (e.g., in getCacheDir())
    • Copy the bytes from the InputStream to the FileOutputStream (Kotlin has some great extension functions for this)

    Or, rather than use ACTION_VIDEO_CAPTURE, use a camera library and take the video directly within your app, rather than trying to rely on a third-party app to take the video.