diff --git a/app/src/main/java/app/myzel394/alibi/db/AppSettings.kt b/app/src/main/java/app/myzel394/alibi/db/AppSettings.kt index 49b5481..2a612b9 100644 --- a/app/src/main/java/app/myzel394/alibi/db/AppSettings.kt +++ b/app/src/main/java/app/myzel394/alibi/db/AppSettings.kt @@ -3,20 +3,18 @@ package app.myzel394.alibi.db import android.content.Context import android.media.MediaRecorder import android.os.Build +import androidx.camera.video.Quality +import androidx.camera.video.QualitySelector import app.myzel394.alibi.R -import app.myzel394.alibi.helpers.AudioRecorderExporter import app.myzel394.alibi.helpers.BatchesFolder -import com.arthenica.ffmpegkit.FFmpegKit -import com.arthenica.ffmpegkit.ReturnCode import kotlinx.serialization.Serializable import kotlinx.serialization.json.Json -import java.io.File import java.time.LocalDateTime -import java.time.format.DateTimeFormatter.ISO_DATE_TIME @Serializable data class AppSettings( - val audioRecorderSettings: AudioRecorderSettings = AudioRecorderSettings(), + val audioRecorderSettings: AudioRecorderSettings = AudioRecorderSettings.getDefaultInstance(), + val videoRecorderSettings: VideoRecorderSettings = VideoRecorderSettings.getDefaultInstance(), val notificationSettings: NotificationSettings? = null, val hasSeenOnboarding: Boolean = false, val showAdvancedSettings: Boolean = false, @@ -163,24 +161,6 @@ data class AudioRecorderSettings( else MediaRecorder.AudioEncoder.AMR_NB - fun getSaveFolder(context: Context): File { - val defaultFolder = AudioRecorderExporter.getFolder(context) - - if (saveFolder == null) { - return defaultFolder - } - - runCatching { - return File(saveFolder!!).apply { - if (!exists()) { - mkdirs() - } - } - } - - return defaultFolder - } - fun setIntervalDuration(duration: Long): AudioRecorderSettings { if (duration < 10 * 1000L || duration > 60 * 60 * 1000L) { throw Exception("Interval duration must be between 10 seconds and 1 hour") @@ -368,6 +348,45 @@ data class AudioRecorderSettings( } } +@Serializable +data class VideoRecorderSettings( + val targetedVideoBitRate: Int? = null, + val quality: String? = null, + val targetFrameRate: Int? = null, +) { + fun setTargetedVideoBitRate(bitRate: Int?): VideoRecorderSettings { + return copy(targetedVideoBitRate = bitRate) + } + + fun setQuality(quality: String): VideoRecorderSettings { + return copy(quality = quality) + } + + fun setTargetFrameRate(frameRate: Int?): VideoRecorderSettings { + return copy(targetFrameRate = frameRate) + } + + fun getQualitySelector(): QualitySelector? = + quality?.let { + QualitySelector.from( + QUALITY_NAME_QUALITY_MAP[it]!! + ) + } + + companion object { + fun getDefaultInstance() = VideoRecorderSettings() + + val QUALITY_NAME_QUALITY_MAP: Map = mapOf( + "LOWEST" to Quality.LOWEST, + "HIGHEST" to Quality.HIGHEST, + "SD" to Quality.SD, + "HD" to Quality.HD, + "FHD" to Quality.FHD, + "UHD" to Quality.UHD, + ) + } +} + @Serializable data class NotificationSettings( val title: String, diff --git a/app/src/main/java/app/myzel394/alibi/services/VideoRecorderService.kt b/app/src/main/java/app/myzel394/alibi/services/VideoRecorderService.kt index 3e607bb..aeab575 100644 --- a/app/src/main/java/app/myzel394/alibi/services/VideoRecorderService.kt +++ b/app/src/main/java/app/myzel394/alibi/services/VideoRecorderService.kt @@ -1,6 +1,7 @@ package app.myzel394.alibi.services import android.annotation.SuppressLint +import androidx.camera.core.Camera import androidx.camera.core.CameraSelector import androidx.camera.lifecycle.ProcessCameraProvider import androidx.camera.video.FileOutputOptions @@ -9,7 +10,6 @@ import androidx.camera.video.QualitySelector import androidx.camera.video.Recorder import androidx.camera.video.Recording import androidx.camera.video.VideoCapture -import androidx.camera.video.VideoCapture.withOutput import androidx.core.content.ContextCompat import app.myzel394.alibi.db.RecordingInformation import kotlinx.coroutines.CompletableDeferred @@ -25,6 +25,7 @@ class VideoRecorderService : private val job = SupervisorJob() private val scope = CoroutineScope(Dispatchers.IO + job) + private var camera: Camera? = null private var cameraProvider: ProcessCameraProvider? = null private var videoCapture: VideoCapture? = null private var activeRecording: Recording? = null @@ -48,14 +49,15 @@ class VideoRecorderService : } val recorder = Recorder.Builder() - .setQualitySelector(QualitySelector.from(Quality.HIGHEST)) + .setQualitySelector(settings.quality) + .build() + videoCapture = VideoCapture.Builder(recorder) .build() - videoCapture = withOutput(recorder) runInMain { - cameraProvider!!.bindToLifecycle( + camera = cameraProvider!!.bindToLifecycle( this, - settings.camera, + settings.cameraSelector, videoCapture ) @@ -75,6 +77,7 @@ class VideoRecorderService : cameraProvider = null videoCapture = null + camera = null } override fun start() { @@ -108,7 +111,6 @@ class VideoRecorderService : super.startNewCycle() fun action() { - println("=======================") activeRecording?.stop() val newRecording = prepareVideoRecording() @@ -139,7 +141,9 @@ class VideoRecorderService : override val maxDuration: Long, override val intervalDuration: Long, val folder: String? = null, - val camera: CameraSelector = CameraSelector.DEFAULT_BACK_CAMERA, + val targetVideoBitRate: Int? = null, + val cameraSelector: CameraSelector = CameraSelector.DEFAULT_BACK_CAMERA, + val quality: QualitySelector = QualitySelector.from(Quality.HIGHEST), ) : IntervalRecorderService.Settings( maxDuration = maxDuration, intervalDuration = intervalDuration