AbedElazizShe / LightCompressor

A powerful and easy-to-use video compression library for android uses MediaCodec API.
Apache License 2.0
509 stars 117 forks source link

Setting isExternal to false does not use saveAt as subfolder #143

Closed VincentJoshuaET closed 11 months ago

VincentJoshuaET commented 1 year ago

This is how I compress my video URIs

    VideoCompressor.start(
        context,
        listOf(uri),
        true,
        StorageConfiguration(saveAt = Environment.DIRECTORY_PICTURES, isExternal = false),
        Configuration(VideoQuality.LOW),
        listener
    )

where Environment.DIRECTORY_PICTURES = "Pictures"

With above, the file gets saved at /data/data/PACKAGE_NAME/files/FILE_NAME.mp4 instead of /data/data/PACKAGE_NAME/files/Pictures/FILE_NAME.mp4

The corresponding source code:

private fun saveVideoInInternal(
    context: Context,
    videoFileName: String,
    videoFile: File
): File {
    context.openFileOutput(videoFileName, Context.MODE_PRIVATE)
        .use { outputStream ->
            FileInputStream(videoFile).use { inputStream ->
                val buf = ByteArray(4096)
                while (true) {
                    val sz = inputStream.read(buf)
                    if (sz <= 0) break
                    outputStream.write(buf, 0, sz)
                }

            }
        }
    return File(context.filesDir, videoFileName)
}

I think context.filesDir should be changed to context.getExternalFilesDir(Environment.DIRECTORY_PICTURES) where Environment.DIRECTORY_PICTURES is the specified saveAt property

AbedElazizShe commented 1 year ago

Hi @VincentJoshuaET . Thank you for opening this issue. In the documentation: "- saveAt: the directory where the video should be saved in. The value will be ignored if isExternal is false."

So if isExternal is false, the library saves in internal storage. Do you want to create a nested folder?

charlesgles9 commented 1 year ago

@AbedElazizShe

In your saveVideoFile function in your library you used the context.getExternalFilesDir function to fetch the storage path but you have to split the string first so the saveAt argument won't work even when the isExternal boolean flag is set to true. Took me a while to realize it was actually saving to the application cache folder rather than the internal public directories.

getExternalFilesDir(null) returns a path to the cache folder /android/emulated/0/Android/data/my.application.app/

so we need to split the string and get the substring from index 0 till the last indexOf("Android")

charlesgles9 commented 1 year ago

This is a function I've come up with that returns the correct path of the sd card

Screenshot from 2022-12-12 18-34-28

AbedElazizShe commented 1 year ago

Version 1.3.0 is handling this in a clearer way.