Use this library which supports targetSdkVersion 29.
implementation 'com.arthenica:mobile-ffmpeg-video:4.4'
Command used for video compression:
val complexCommand = arrayOf(
"-y",
"-i",
inputPath!!,
"-s",
"640x480",
"-r",
"25",
"-vcodec",
"mpeg4",
"-b:v",
"1000k",
"-b:a",
"48000",
"-ac",
"2",
"-ar",
"22050",
outputFilePath
)
Compression method:
private fun execFFmpegBinary(command: Array<String>, inputPath: String?, listener: CompressionListener?, outputFilePath: String) {
Config.enableLogCallback { message -> Log.e(Config.TAG, message.text) }
Config.enableStatisticsCallback { newStatistics ->
Log.e(
Config.TAG,
String.format(
"frame: %d, time: %d",
newStatistics.videoFrameNumber,
newStatistics.time
)
)
Log.d(
TAG,
"Started command : ffmpeg " + Arrays.toString(command)
)
val videoLength = inputPath?.let { VideoUtils.getVideoDuration(it) }
Log.d(TAG, "execFFmpegBinary: Video Length : $videoLength")
val progress: Float =
java.lang.String.valueOf(newStatistics.time).toFloat() / videoLength!!
val progressFinal = progress * 100
Log.d(TAG, "Video Length: $progressFinal")
Log.d(
Config.TAG,
java.lang.String.format(
"frame: %d, time: %d",
newStatistics.videoFrameNumber,
newStatistics.time
)
)
Log.d(
Config.TAG,
java.lang.String.format(
"Quality: %f, time: %f",
newStatistics.videoQuality,
newStatistics.videoFps
)
)
//progressDialog.setProgress(progressFinal.toInt())
//val adjustProgress = progressFinal/1.5f
Log.d(TAG, "execFFmpegBinary: Progress: ${progressFinal.toInt()}")
listener?.onProgress(progressFinal.toInt())
Log.d(TAG, "progress : $newStatistics")
}
Log.d(
TAG,
"Started command : ffmpeg " + Arrays.toString(command)
)
/* progressDialog.setMessage("Processing...")
progressDialog.show()*/
val executionId = com.arthenica.mobileffmpeg.FFmpeg.executeAsync(
command
) { executionId1: Long, returnCode: Int ->
if (returnCode == RETURN_CODE_SUCCESS) {
Log.d(
TAG,
"Finished command : ffmpeg " + Arrays.toString(command)
)
listener?.compressionFinished(SUCCESS, true, fileOutputPath = outputFilePath)
} else if (returnCode == Config.RETURN_CODE_CANCEL) {
Log.e(
TAG,
"Async command execution cancelled by user."
)
listener?.onFailure(String.format(
"Async command execution cancelled by user."
))
//if (progressDialog != null) progressDialog.dismiss()
} else {
Log.e(
TAG,
String.format(
"Async command execution failed with returnCode=%d.",
returnCode
)
)
listener?.onFailure(String.format(
"Async command execution failed with returnCode=%d.",
returnCode
))
// if (progressDialog != null) progressDialog.dismiss()
}
}
Log.e(TAG, "execFFmpegMergeVideo executionId-$executionId")
}
Compression Listener:
interface CompressionListener {
fun compressionFinished(
status: Int,
isVideo: Boolean,
fileOutputPath: String?
)
fun onFailure(message: String?)
fun onProgress(progress: Int)
}
Call using:
execFFmpegBinary(complexCommand, inputPath, listener, outputFilePath)