diff --git a/app/src/main/java/app/myzel394/alibi/helpers/BatchesFolder.kt b/app/src/main/java/app/myzel394/alibi/helpers/BatchesFolder.kt index b1dd014..d40d575 100644 --- a/app/src/main/java/app/myzel394/alibi/helpers/BatchesFolder.kt +++ b/app/src/main/java/app/myzel394/alibi/helpers/BatchesFolder.kt @@ -122,6 +122,28 @@ data class BatchesFolder( } } + suspend fun exportToOneFile( + recordingStart: LocalDateTime, + extension: String, + disableCache: Boolean = false, + ) { + if (!disableCache && checkIfOutputAlreadyExists(recordingStart, extension)) { + return + } + + val filePaths = getBatchesForFFmpeg() + val outputFile = getOutputFileForFFmpeg( + date = recordingStart, + extension = extension, + ) + + MediaConverter.concatenate( + inputFiles = filePaths, + outputFile = outputFile, + extraCommand = " -acodec copy" + ).await() + } + fun exportFolderForSettings(): String { return when (type) { BatchType.INTERNAL -> "_'internal" diff --git a/app/src/main/java/app/myzel394/alibi/helpers/MediaConverter.kt b/app/src/main/java/app/myzel394/alibi/helpers/MediaConverter.kt new file mode 100644 index 0000000..865ccc0 --- /dev/null +++ b/app/src/main/java/app/myzel394/alibi/helpers/MediaConverter.kt @@ -0,0 +1,47 @@ +package app.myzel394.alibi.helpers + +import android.util.Log +import com.arthenica.ffmpegkit.FFmpegKit +import com.arthenica.ffmpegkit.ReturnCode +import kotlinx.coroutines.CompletableDeferred + +class MediaConverter { + companion object { + fun concatenate( + inputFiles: Iterable, + outputFile: String, + extraCommand: String = "", + ): CompletableDeferred { + val completer = CompletableDeferred() + + val filePathsConcatenated = inputFiles.joinToString("|") + val command = + "-protocol_whitelist saf,concat,content,file,subfile" + + " -i 'concat:$filePathsConcatenated' -y" + + extraCommand + + " $outputFile" + + FFmpegKit.executeAsync( + command + ) { session -> + if (!ReturnCode.isSuccess(session!!.returnCode)) { + Log.d( + "Audio Concatenation", + String.format( + "Command failed with state %s and rc %s.%s", + session.state, + session.returnCode, + session.failStackTrace, + ) + ) + + completer.completeExceptionally(Exception("Failed to concatenate audios")) + } else { + completer.complete(Unit) + } + } + + return completer + } + } +} \ No newline at end of file diff --git a/app/src/main/java/app/myzel394/alibi/ui/screens/AudioRecorderScreen.kt b/app/src/main/java/app/myzel394/alibi/ui/screens/AudioRecorderScreen.kt index abc7d67..b95e361 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/screens/AudioRecorderScreen.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/screens/AudioRecorderScreen.kt @@ -33,7 +33,6 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.FocusManager import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp @@ -45,7 +44,6 @@ import app.myzel394.alibi.ui.utils.rememberFileSaverDialog import app.myzel394.alibi.R import app.myzel394.alibi.dataStore import app.myzel394.alibi.db.AppSettings -import app.myzel394.alibi.helpers.AudioRecorderExporter import app.myzel394.alibi.helpers.BatchesFolder import app.myzel394.alibi.ui.effects.rememberSettings import app.myzel394.alibi.ui.models.AudioRecorderModel @@ -131,16 +129,13 @@ fun AudioRecorderScreen( ?: settings.lastRecording ?: throw Exception("No recording information available") val batchesFolder = BatchesFolder.importFromFolder(recording.folderPath, context) - val outputFile = batchesFolder.getOutputFileForFFmpeg( + + batchesFolder.exportToOneFile( recording.recordingStart, - recording.fileExtension - ) - - AudioRecorderExporter(recording).concatenateFiles( - batchesFolder, - outputFile, + recording.fileExtension, ) + // Save file val name = batchesFolder.getName( recording.recordingStart, recording.fileExtension,