MainActivity: move to FFmpegKit

This commit is contained in:
dece 2023-04-04 18:58:12 +02:00
parent 5b11db8381
commit c5a9dc7288

View file

@ -21,15 +21,15 @@ import android.widget.VideoView
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider import androidx.core.content.FileProvider
import androidx.core.net.toUri import androidx.core.net.toUri
import com.arthenica.mobileffmpeg.Config.RETURN_CODE_CANCEL import com.arthenica.ffmpegkit.FFmpegKit
import com.arthenica.mobileffmpeg.Config.RETURN_CODE_SUCCESS import com.arthenica.ffmpegkit.FFprobeKit
import com.arthenica.mobileffmpeg.FFmpeg import com.arthenica.ffmpegkit.ReturnCode
import com.arthenica.mobileffmpeg.FFprobe
import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.android.material.floatingactionbutton.FloatingActionButton
import java.io.File import java.io.File
import java.io.FileInputStream import java.io.FileInputStream
import java.io.FileOutputStream import java.io.FileOutputStream
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import kotlin.math.roundToLong
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity() {
private val spinner: ProgressBar? get() = findViewById(R.id.progressBar) private val spinner: ProgressBar? get() = findViewById(R.id.progressBar)
@ -171,25 +171,26 @@ class MainActivity : AppCompatActivity() {
currentVideoPath = null currentVideoPath = null
currentVideoUri = null currentVideoUri = null
val mediaInfo = FFprobe.getMediaInformation(inputVideoPath)
// Detect vertical/horizontal resolution, because at the moment we downscale everything to // Detect vertical/horizontal resolution, because at the moment we downscale everything to
// fit Telegram's media preview requirements. If FFprobe fails to returns data, we consider // fit Telegram's media preview requirements. If FFprobe fails to returns data, we consider
// by default the video to be vertical. // by default the video to be vertical.
val isVertical = mediaInfo?.let { val session = FFprobeKit.getMediaInformation(inputVideoPath)
it.streams.getOrNull(0)?.let { streamInformation -> var isVertical = true
var duration: Double = 0.0
if (ReturnCode.isSuccess(session.returnCode)) {
session.mediaInformation.streams.getOrNull(0)?.let { streamInformation ->
if (streamInformation.height != null && streamInformation.width != null) if (streamInformation.height != null && streamInformation.width != null)
streamInformation.height > streamInformation.width isVertical = streamInformation.height > streamInformation.width
else }
true duration = session.mediaInformation.duration.toDouble()
} }
} ?: true
val duration = mediaInfo?.duration?.toLong() ?: 0L
// Save the soundtrack as well cause we can't pass a resource to FFMPEG. // Save the soundtrack as well cause we can't pass a resource to FFMPEG.
// Should be done only once, then it's kept in app internal storage. // Should be done only once, then it's kept in app internal storage.
val themeId = getThemeId() val themeId = getThemeId()
val soundFile = File(filesDir, "$themeId.m4a") val soundFile = File(filesDir, "$themeId.m4a")
if (!soundFile.exists()) { if (!soundFile.exists()) {
Log.i(TAG, "Prepare sound file with a filesystem path.")
resources.openRawResource(getThemeRawResource(themeId)).use { resource -> resources.openRawResource(getThemeRawResource(themeId)).use { resource ->
FileOutputStream(soundFile).use { fos -> FileOutputStream(soundFile).use { fos ->
fos.buffered().write(resource.buffered().readBytes()) fos.buffered().write(resource.buffered().readBytes())
@ -224,7 +225,7 @@ class MainActivity : AppCompatActivity() {
private class MixTask( private class MixTask(
private val activity: WeakReference<MainActivity>, private val activity: WeakReference<MainActivity>,
private val duration: Long, private val duration: Double,
private val videoIsVertical: Boolean private val videoIsVertical: Boolean
): AsyncTask<String, Void, Boolean>() { ): AsyncTask<String, Void, Boolean>() {
private lateinit var videoPath: String private lateinit var videoPath: String
@ -238,8 +239,12 @@ class MainActivity : AppCompatActivity() {
videoPath = params[0]!! videoPath = params[0]!!
val audioPath = params[1]!! val audioPath = params[1]!!
outputPath = params[2]!! outputPath = params[2]!!
val width = if (videoIsVertical) 480 else 640 //val width = if (videoIsVertical) 480 else 640
val durationOpt = if (duration > 0) "-t ${duration}ms" else "" val durationOpt = if (duration > 0) {
"-t ${(duration * 1000).roundToLong()}ms"
} else {
""
}
val command = ( val command = (
"-i $videoPath -i $audioPath" "-i $videoPath -i $audioPath"
+ " -filter_complex amix=duration=longest" + " -filter_complex amix=duration=longest"
@ -248,23 +253,30 @@ class MainActivity : AppCompatActivity() {
+ " $durationOpt -y $outputPath" + " $durationOpt -y $outputPath"
) )
Log.d(TAG, "Calling FFmpeg with command: $command") Log.d(TAG, "Calling FFmpeg with command: $command")
return when (val rc = FFmpeg.execute(command)) { val rc = FFmpegKit.execute(command).returnCode
RETURN_CODE_SUCCESS -> true.also { Log.i(TAG, "Mix succeeded.") } if (ReturnCode.isSuccess(rc)) {
RETURN_CODE_CANCEL -> false.also { Log.i(TAG, "Mix cancelled.") } Log.i(TAG, "Mix succeeded.")
else -> false .also { Log.e(TAG, "Mix failed! rc = $rc") } return true
} }
if (ReturnCode.isCancel(rc))
Log.i(TAG, "Mix cancelled.")
else
Log.e(TAG, "Mix failed! rc = $rc")
return false
} }
override fun onPostExecute(result: Boolean?) { override fun onPostExecute(result: Boolean?) {
File(videoPath).delete() File(videoPath).delete()
activity.get()?.let { activity.get()?.let {
if (result == true) if (result == true) {
it.handleFfmpegOutput(outputPath) it.handleFfmpegOutput(outputPath)
else } else {
it.toast("Crasse de brin !!!")
it.setLoading(false) it.setLoading(false)
} }
} }
} }
}
private fun setLoading(isLoading: Boolean) { private fun setLoading(isLoading: Boolean) {
if (isLoading) { if (isLoading) {