feat: Added VideoRecorderSettings

This commit is contained in:
Myzel394 2023-11-26 23:01:48 +01:00
parent f75a1a8a33
commit 92d1d6582a
No known key found for this signature in database
GPG Key ID: 79CC92F37B3E1A2B
2 changed files with 54 additions and 31 deletions

View File

@ -3,20 +3,18 @@ package app.myzel394.alibi.db
import android.content.Context import android.content.Context
import android.media.MediaRecorder import android.media.MediaRecorder
import android.os.Build import android.os.Build
import androidx.camera.video.Quality
import androidx.camera.video.QualitySelector
import app.myzel394.alibi.R import app.myzel394.alibi.R
import app.myzel394.alibi.helpers.AudioRecorderExporter
import app.myzel394.alibi.helpers.BatchesFolder import app.myzel394.alibi.helpers.BatchesFolder
import com.arthenica.ffmpegkit.FFmpegKit
import com.arthenica.ffmpegkit.ReturnCode
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import java.io.File
import java.time.LocalDateTime import java.time.LocalDateTime
import java.time.format.DateTimeFormatter.ISO_DATE_TIME
@Serializable @Serializable
data class AppSettings( data class AppSettings(
val audioRecorderSettings: AudioRecorderSettings = AudioRecorderSettings(), val audioRecorderSettings: AudioRecorderSettings = AudioRecorderSettings.getDefaultInstance(),
val videoRecorderSettings: VideoRecorderSettings = VideoRecorderSettings.getDefaultInstance(),
val notificationSettings: NotificationSettings? = null, val notificationSettings: NotificationSettings? = null,
val hasSeenOnboarding: Boolean = false, val hasSeenOnboarding: Boolean = false,
val showAdvancedSettings: Boolean = false, val showAdvancedSettings: Boolean = false,
@ -163,24 +161,6 @@ data class AudioRecorderSettings(
else else
MediaRecorder.AudioEncoder.AMR_NB 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 { fun setIntervalDuration(duration: Long): AudioRecorderSettings {
if (duration < 10 * 1000L || duration > 60 * 60 * 1000L) { if (duration < 10 * 1000L || duration > 60 * 60 * 1000L) {
throw Exception("Interval duration must be between 10 seconds and 1 hour") 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<String, Quality> = 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 @Serializable
data class NotificationSettings( data class NotificationSettings(
val title: String, val title: String,

View File

@ -1,6 +1,7 @@
package app.myzel394.alibi.services package app.myzel394.alibi.services
import android.annotation.SuppressLint import android.annotation.SuppressLint
import androidx.camera.core.Camera
import androidx.camera.core.CameraSelector import androidx.camera.core.CameraSelector
import androidx.camera.lifecycle.ProcessCameraProvider import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.camera.video.FileOutputOptions import androidx.camera.video.FileOutputOptions
@ -9,7 +10,6 @@ import androidx.camera.video.QualitySelector
import androidx.camera.video.Recorder import androidx.camera.video.Recorder
import androidx.camera.video.Recording import androidx.camera.video.Recording
import androidx.camera.video.VideoCapture import androidx.camera.video.VideoCapture
import androidx.camera.video.VideoCapture.withOutput
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import app.myzel394.alibi.db.RecordingInformation import app.myzel394.alibi.db.RecordingInformation
import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.CompletableDeferred
@ -25,6 +25,7 @@ class VideoRecorderService :
private val job = SupervisorJob() private val job = SupervisorJob()
private val scope = CoroutineScope(Dispatchers.IO + job) private val scope = CoroutineScope(Dispatchers.IO + job)
private var camera: Camera? = null
private var cameraProvider: ProcessCameraProvider? = null private var cameraProvider: ProcessCameraProvider? = null
private var videoCapture: VideoCapture<Recorder>? = null private var videoCapture: VideoCapture<Recorder>? = null
private var activeRecording: Recording? = null private var activeRecording: Recording? = null
@ -48,14 +49,15 @@ class VideoRecorderService :
} }
val recorder = Recorder.Builder() val recorder = Recorder.Builder()
.setQualitySelector(QualitySelector.from(Quality.HIGHEST)) .setQualitySelector(settings.quality)
.build()
videoCapture = VideoCapture.Builder(recorder)
.build() .build()
videoCapture = withOutput(recorder)
runInMain { runInMain {
cameraProvider!!.bindToLifecycle( camera = cameraProvider!!.bindToLifecycle(
this, this,
settings.camera, settings.cameraSelector,
videoCapture videoCapture
) )
@ -75,6 +77,7 @@ class VideoRecorderService :
cameraProvider = null cameraProvider = null
videoCapture = null videoCapture = null
camera = null
} }
override fun start() { override fun start() {
@ -108,7 +111,6 @@ class VideoRecorderService :
super.startNewCycle() super.startNewCycle()
fun action() { fun action() {
println("=======================")
activeRecording?.stop() activeRecording?.stop()
val newRecording = prepareVideoRecording() val newRecording = prepareVideoRecording()
@ -139,7 +141,9 @@ class VideoRecorderService :
override val maxDuration: Long, override val maxDuration: Long,
override val intervalDuration: Long, override val intervalDuration: Long,
val folder: String? = null, 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( ) : IntervalRecorderService.Settings(
maxDuration = maxDuration, maxDuration = maxDuration,
intervalDuration = intervalDuration intervalDuration = intervalDuration