AbedElazizShe / LightCompressor

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

VideoBitrate does not effect result #135

Open james04gr opened 2 years ago

james04gr commented 2 years ago

I am recording a video with my camera (Samsung S22 with Android 12) and after the recording i use the configuration

context = applicationContext,
            uris = uris,
            isStreamable = false,
            storageConfiguration = StorageConfiguration(
                saveAt = Environment.DIRECTORY_MOVIES, // => the directory to save the compressed video(s). Will be ignored if isExternal = false.
                isExternal = true // => false means save at app-specific file directory. Default is true.
            ),
            configureWith = Configuration(
                  quality = VideoQuality.LOW,
                isMinBitrateCheckEnabled = false,
                videoBitrate = 480000,
                disableAudio = false,
                keepOriginalResolution = true
            ),

However, the result video that is produced has a video bitrate ~= 4200kbps. Why is this happening? Doesn' t the result video supposed to have a videoBitrate ~= 480kpbs?

sbattaglino commented 1 year ago

Similar results here.

Expected 500kbps, I got 900kbps

videoResizedFile?.let { _ ->
    try {
        val contentUri = FileProvider.getUriForFile(
            this, "${BuildConfig.APPLICATION_ID}.fileprovider", File(videoPath)
        )
        VideoCompressor.start(context = applicationContext, // => This is required
            uris = listOf(contentUri), // => Source can be provided as content uris
            isStreamable = true, storageConfiguration = StorageConfiguration(
                //saveAt = videoResizedPath, // => the directory to save the compressed video(s). Will be ignored if isExternal = false.
                isExternal = false, // => false means save at app-specific file directory. Default is true.
                fileName = videoResizedFile?.name // => an optional value for a custom video name.
            ), configureWith = Configuration(
                //quality = Constants.UPLOAD_VIDEO_QUALITY,
                isMinBitrateCheckEnabled = false,
                videoBitrate = 500000,
                disableAudio = false,
                keepOriginalResolution = false,
                videoWidth = Constants.VIDEO_WIDTH.toDouble(),
                videoHeight = Constants.VIDEO_HEIGHT.toDouble()
            ), listener = object : CompressionListener {
                override fun onProgress(index: Int, percent: Float) {
                    Log.d(tag, "onProgress: $percent")
                    //runOnUiThread {}
                }

                override fun onStart(index: Int) {
                    Log.d(tag, "onStart")
                }

                override fun onSuccess(index: Int, size: Long, path: String?) {
                    Log.d(tag, "onSuccess $path")
                    path?.apply {
                        viewModel.saveFile(
                            MessageType.MEDIA_VIDEO.value,
                            File(this)
                        )
                    }
                }

                override fun onFailure(index: Int, failureMessage: String) {
                    Log.d(tag, "onFailure $failureMessage")
                }

                override fun onCancelled(index: Int) {
                    Log.d(tag, "onCancelled")
                }
            })
    } catch (e: Exception) {
        e.printStackTrace()
    }
}
AbedElazizShe commented 1 year ago

Hi @james04gr and @sbattaglino thank you for openning this issue. It is an interesting one,

I made a change where videoBitrate is not videoBitrateInMbps just to make it clearer, and handled the conversion accordingly. The results will be close enough, for example, 5mbps could result with 5.3mbps.

I came accross this page: https://developer.android.com/reference/android/media/MediaCodec#qualityFloor, it seems low bitrates won't be accpted.