diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/atoms/CameraPreview.kt b/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/atoms/CameraPreview.kt index d0530ac9..3046973a 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/atoms/CameraPreview.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/atoms/CameraPreview.kt @@ -1,56 +1,56 @@ package app.myzel394.alibi.ui.components.RecorderScreen.atoms +import android.util.Log import android.view.ViewGroup import androidx.camera.core.CameraSelector import androidx.camera.core.Preview -import androidx.camera.lifecycle.ProcessCameraProvider import androidx.camera.view.PreviewView +import androidx.compose.foundation.layout.Box import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.viewinterop.AndroidView +import app.myzel394.alibi.ui.utils.getCameraProvider import kotlinx.coroutines.launch @Composable fun CameraPreview( - modifier: Modifier = Modifier, - scaleType: PreviewView.ScaleType = PreviewView.ScaleType.FILL_CENTER, + modifier: Modifier, cameraSelector: CameraSelector = CameraSelector.DEFAULT_BACK_CAMERA ) { val coroutineScope = rememberCoroutineScope() val lifecycleOwner = LocalLifecycleOwner.current - AndroidView( - modifier = modifier, - factory = { context -> - val previewView = PreviewView(context).apply { - this.scaleType = scaleType - layoutParams = ViewGroup.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT - ) - } - // CameraX Preview UseCase - val previewUseCase = Preview.Builder() - .build() - .also { - it.setSurfaceProvider(previewView.surfaceProvider) - } - - coroutineScope.launch { - val cameraProvider = ProcessCameraProvider.getInstance(context).get() - try { - // Must unbind the use-cases before rebinding them. - cameraProvider.unbindAll() - cameraProvider.bindToLifecycle( - lifecycleOwner, cameraSelector, previewUseCase + Box(modifier = modifier) { + // Video preview + AndroidView( + factory = { context -> + val previewView = PreviewView(context).apply { + layoutParams = ViewGroup.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT, ) - } catch (ex: Exception) { } - } + val previewUseCase = Preview.Builder() + .build() + .also { it.setSurfaceProvider(previewView.surfaceProvider) } - previewView - } - ) -} \ No newline at end of file + coroutineScope.launch { + val cameraProvider = context.getCameraProvider() + try { + cameraProvider.unbindAll() + cameraProvider.bindToLifecycle( + lifecycleOwner, + cameraSelector, + previewUseCase + ) + } catch (ex: Exception) { + Log.e("CameraPreview", "Use case binding failed", ex) + } + } + previewView + }, + ) + } +} diff --git a/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/organisms/VideoRecordingStatus.kt b/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/organisms/VideoRecordingStatus.kt index a269bb6b..74f068f1 100644 --- a/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/organisms/VideoRecordingStatus.kt +++ b/app/src/main/java/app/myzel394/alibi/ui/components/RecorderScreen/organisms/VideoRecordingStatus.kt @@ -1,23 +1,17 @@ package app.myzel394.alibi.ui.components.RecorderScreen.organisms import android.content.res.Configuration -import android.util.Log -import android.view.ViewGroup -import androidx.camera.core.Preview -import androidx.camera.view.PreviewView import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.aspectRatio import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.CameraAlt import androidx.compose.material3.HorizontalDivider @@ -32,22 +26,19 @@ import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp -import androidx.compose.ui.viewinterop.AndroidView import app.myzel394.alibi.R +import app.myzel394.alibi.ui.components.RecorderScreen.atoms.CameraPreview import app.myzel394.alibi.ui.components.RecorderScreen.atoms.TorchStatus import app.myzel394.alibi.ui.components.RecorderScreen.molecules.RecordingControl import app.myzel394.alibi.ui.components.RecorderScreen.molecules.RecordingStatus import app.myzel394.alibi.ui.models.VideoRecorderModel import app.myzel394.alibi.ui.utils.CameraInfo import app.myzel394.alibi.ui.utils.KeepScreenOn -import app.myzel394.alibi.ui.utils.getCameraProvider import com.valentinilk.shimmer.shimmer import kotlinx.coroutines.launch @@ -61,78 +52,79 @@ fun VideoRecordingStatus( when (orientation) { Configuration.ORIENTATION_LANDSCAPE -> { - Row( - modifier = Modifier.fillMaxSize(), - horizontalArrangement = Arrangement.SpaceEvenly, - verticalAlignment = Alignment.CenterVertically, - ) { - Column( - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement - .spacedBy(32.dp), - modifier = Modifier - .weight(1f) - .fillMaxWidth(0.9f) - .align(Alignment.CenterVertically), - ) { - _VideoGeneralInfo(videoRecorder) - _VideoRecordingStatus(videoRecorder) - } - Box( - modifier = Modifier - .weight(1f) - .fillMaxWidth(0.9f) + Box { + CameraPreview( + modifier = Modifier, + cameraSelector = videoRecorder.cameraSelector + ) + Row( + modifier = Modifier.fillMaxSize(), + horizontalArrangement = Arrangement.SpaceEvenly, + verticalAlignment = Alignment.CenterVertically, ) { Column( + horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement .spacedBy(32.dp), - horizontalAlignment = Alignment.CenterHorizontally, + modifier = Modifier + .weight(1f) + .fillMaxWidth(0.9f) + .align(Alignment.CenterVertically), ) { - _VideoControls(videoRecorder) - CameraPreview( - videoRecorder, - modifier = Modifier - .aspectRatio(5 / 2F) - .padding(horizontal = 12.dp) - ) - HorizontalDivider() - _PrimitiveControls(videoRecorder) + _VideoGeneralInfo(videoRecorder) + _VideoRecordingStatus(videoRecorder) + } + Box( + modifier = Modifier + .weight(1f) + .fillMaxWidth(0.9f) + ) { + Column( + verticalArrangement = Arrangement + .spacedBy(32.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + _VideoControls(videoRecorder) + HorizontalDivider() + _PrimitiveControls(videoRecorder) + } } } } } else -> { - Column( - modifier = Modifier - .fillMaxSize() - .padding(bottom = 32.dp), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.SpaceBetween, - ) { + Box { CameraPreview( - videoRecorder, modifier = Modifier - .padding(24.dp) - .aspectRatio(3 / 2F) + modifier = Modifier, + cameraSelector = videoRecorder.cameraSelector ) Column( + modifier = Modifier + .fillMaxSize() + .padding(bottom = 32.dp), horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement - .spacedBy(16.dp), + verticalArrangement = Arrangement.SpaceBetween, ) { - _VideoGeneralInfo(videoRecorder) - _VideoRecordingStatus(videoRecorder) - } + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement + .spacedBy(16.dp), + ) { + _VideoGeneralInfo(videoRecorder) + _VideoRecordingStatus(videoRecorder) + } - Column( - verticalArrangement = Arrangement - .spacedBy(16.dp), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - _VideoControls(videoRecorder) - HorizontalDivider() - _PrimitiveControls(videoRecorder) + Column( + verticalArrangement = Arrangement + .spacedBy(16.dp), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + _VideoControls(videoRecorder) + HorizontalDivider() + _PrimitiveControls(videoRecorder) + } } } } @@ -140,45 +132,6 @@ fun VideoRecordingStatus( } -@Composable -fun CameraPreview(videoRecorder: VideoRecorderModel, modifier: Modifier) { - val coroutineScope = rememberCoroutineScope() - val lifecycleOwner = LocalLifecycleOwner.current - - Box(modifier = modifier.clip(RoundedCornerShape(12.dp))) { - - // Video preview - AndroidView( - factory = { context -> - val previewView = PreviewView(context).apply { - layoutParams = ViewGroup.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT, - ) - } - val previewUseCase = Preview.Builder() - .build() - .also { it.setSurfaceProvider(previewView.surfaceProvider) } - - coroutineScope.launch { - val cameraProvider = context.getCameraProvider() - try { - cameraProvider.unbindAll() - cameraProvider.bindToLifecycle( - lifecycleOwner, - videoRecorder.cameraSelector, - previewUseCase - ) - } catch (ex: Exception) { - Log.e("CameraPreview", "Use case binding failed", ex) - } - } - previewView - }, - ) - } -} - @Composable fun _VideoGeneralInfo(videoRecorder: VideoRecorderModel) { val context = LocalContext.current