feat: Add cameraID and enableAudio pass from UI to VideoRecorderService

This commit is contained in:
Myzel394 2023-12-04 18:56:29 +01:00
parent 60f53f3649
commit add9c8cde5
No known key found for this signature in database
GPG Key ID: 79CC92F37B3E1A2B
7 changed files with 78 additions and 40 deletions

View File

@ -1,8 +1,10 @@
package app.myzel394.alibi.services
import android.annotation.SuppressLint
import android.content.Intent
import android.util.Range
import androidx.camera.core.Camera
import androidx.camera.core.CameraControl
import androidx.camera.core.CameraSelector
import androidx.camera.core.TorchState
import androidx.camera.lifecycle.ProcessCameraProvider
@ -27,6 +29,7 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.coroutines.withTimeoutOrNull
import kotlin.properties.Delegates
const val CAMERA_CLOSE_TIMEOUT = 20000L
@ -49,11 +52,23 @@ class VideoRecorderService :
// Absolute last completer that can be awaited to ensure that the camera is closed
private var _cameraCloserListener = CompletableDeferred<Unit>()
private var selectedCamera: CameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
private lateinit var selectedCamera: CameraSelector
private var enableAudio by Delegates.notNull<Boolean>()
var cameraControl: CameraControl? = null
private set
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (intent?.action == "init") {
selectedCamera = CameraSelector.Builder().requireLensFacing(
intent.getIntExtra("cameraID", CameraSelector.LENS_FACING_BACK)
).build()
enableAudio = intent.getBooleanExtra("enableAudio", true)
}
return super.onStartCommand(intent, flags, startId)
}
override fun start() {
super.start()
@ -189,7 +204,13 @@ class VideoRecorderService :
private fun prepareVideoRecording() =
videoCapture!!.output
.prepareRecording(this, settings.getOutputOptions(this))
.withAudioEnabled()
.run {
if (enableAudio) {
return@run withAudioEnabled()
}
this
}
override fun getRecordingInformation(): RecordingInformation = RecordingInformation(
folderPath = batchesFolder.exportFolderForSettings(),

View File

@ -8,13 +8,13 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import app.myzel394.alibi.R
import app.myzel394.alibi.ui.models.VideoRecorderSettingsModel
import app.myzel394.alibi.ui.models.VideoRecorderModel
import app.myzel394.alibi.ui.utils.CameraInfo
@Composable
fun CamerasSelection(
cameras: Iterable<CameraInfo>,
videoSettings: VideoRecorderSettingsModel
videoSettings: VideoRecorderModel,
) {
val CAMERA_LENS_TEXT_MAP = mapOf(
CameraInfo.Lens.BACK to stringResource(R.string.ui_videoRecorder_action_start_settings_cameraLens_back_label),

View File

@ -38,7 +38,9 @@ import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.input.pointer.PointerEventPass
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.input.pointer.positionChange
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
@ -53,19 +55,20 @@ import app.myzel394.alibi.ui.components.RecorderScreen.atoms.CameraPreview
import app.myzel394.alibi.ui.components.atoms.GlobalSwitch
import app.myzel394.alibi.ui.components.atoms.PermissionRequester
import app.myzel394.alibi.ui.effects.rememberPrevious
import app.myzel394.alibi.ui.models.VideoRecorderSettingsModel
import app.myzel394.alibi.ui.models.VideoRecorderModel
import app.myzel394.alibi.ui.utils.CameraInfo
import kotlin.math.abs
@OptIn(
ExperimentalMaterial3Api::class,
)
@Composable
fun VideoRecorderPreparationSheet(
showPreview: Boolean,
videoSettings: VideoRecorderModel,
onDismiss: () -> Unit,
videoSettings: VideoRecorderSettingsModel = viewModel(),
onPreviewVisible: () -> Unit,
onPreviewHidden: () -> Unit,
showPreview: Boolean,
onStartRecording: () -> Unit,
) {
val sheetState = rememberModalBottomSheetState(true) { sheetValue ->
@ -87,7 +90,7 @@ fun VideoRecorderPreparationSheet(
Unit
else
BottomSheetDefaults.DragHandle()
}
},
) {
Box(
modifier = Modifier
@ -184,6 +187,9 @@ fun VideoRecorderPreparationSheet(
onLongPress = {
onPreviewVisible()
},
onTap = {
onStartRecording()
}
)
},
horizontalArrangement = Arrangement.Center,

View File

@ -8,7 +8,6 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.CameraAlt
import androidx.compose.material.icons.filled.Mic
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
@ -27,6 +26,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import app.myzel394.alibi.R
import app.myzel394.alibi.db.AppSettings
import app.myzel394.alibi.ui.components.atoms.PermissionRequester
@ -48,12 +48,13 @@ fun VideoRecordingStart(
if (showSheet) {
VideoRecorderPreparationSheet(
showPreview = showPreview,
videoSettings = videoRecorder,
onDismiss = {
showSheet = false
},
onPreviewVisible = onHideAudioRecording,
onPreviewHidden = onShowAudioRecording,
showPreview = showPreview,
onStartRecording = {
videoRecorder.startRecording(context, appSettings)
},

View File

@ -90,8 +90,13 @@ abstract class BaseRecorderModel<S : IntervalRecorderService.Settings, I, T : In
recordingTime = null
}
protected open fun handleIntent(intent: Intent) = intent
// If override, call `super` AFTER setting the settings
open fun startRecording(context: Context, settings: AppSettings) {
open fun startRecording(
context: Context,
settings: AppSettings,
) {
this.settings = settings
runCatching {
@ -121,7 +126,7 @@ abstract class BaseRecorderModel<S : IntervalRecorderService.Settings, I, T : In
),
)
}
}
}.let(::handleIntent)
ContextCompat.startForegroundService(context, intent)
context.bindService(intent, connection, Context.BIND_AUTO_CREATE)
}

View File

@ -1,14 +1,36 @@
package app.myzel394.alibi.ui.models
import android.Manifest
import android.content.Context
import android.content.Intent
import androidx.camera.core.CameraSelector
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import app.myzel394.alibi.db.AppSettings
import app.myzel394.alibi.db.RecordingInformation
import app.myzel394.alibi.helpers.VideoBatchesFolder
import app.myzel394.alibi.services.VideoRecorderService
import app.myzel394.alibi.ui.utils.CameraInfo
import app.myzel394.alibi.ui.utils.PermissionHelper
class VideoRecorderModel :
BaseRecorderModel<VideoRecorderService.Settings, RecordingInformation, VideoRecorderService, VideoBatchesFolder?>() {
override var batchesFolder: VideoBatchesFolder? = null
override val intentClass = VideoRecorderService::class.java
var enableAudio by mutableStateOf(true)
var cameraID by mutableIntStateOf(CameraInfo.Lens.BACK.androidValue)
val cameraSelector: CameraSelector
get() = CameraSelector.Builder().requireLensFacing(cameraID).build()
fun init(context: Context) {
enableAudio = PermissionHelper.hasGranted(context, Manifest.permission.RECORD_AUDIO)
cameraID = CameraInfo.Lens.BACK.androidValue
}
override fun onServiceConnected(service: VideoRecorderService) {
service.settings = VideoRecorderService.Settings.from(settings)
@ -18,4 +40,15 @@ class VideoRecorderModel :
recorderState = service.state
recordingTime = service.recordingTime
}
override fun handleIntent(intent: Intent) =
intent.apply {
putExtra("cameraID", cameraID)
putExtra("enableAudio", enableAudio)
}
override fun startRecording(context: Context, settings: AppSettings) {
super.startRecording(context, settings)
}
}

View File

@ -1,28 +0,0 @@
package app.myzel394.alibi.ui.models
import android.Manifest
import android.Manifest.permission.RECORD_AUDIO
import android.content.Context
import android.graphics.Camera
import android.hardware.camera2.CameraManager
import androidx.camera.core.CameraSelector
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import app.myzel394.alibi.ui.utils.CameraInfo
import app.myzel394.alibi.ui.utils.PermissionHelper
class VideoRecorderSettingsModel : ViewModel() {
var enableAudio by mutableStateOf(true)
var cameraID by mutableIntStateOf(CameraInfo.Lens.BACK.androidValue)
val cameraSelector: CameraSelector
get() = CameraSelector.Builder().requireLensFacing(cameraID).build()
fun init(context: Context) {
enableAudio = PermissionHelper.hasGranted(context, Manifest.permission.RECORD_AUDIO)
cameraID = CameraInfo.Lens.BACK.androidValue
}
}