Skip to content

Commit

Permalink
fix: change camera preview to full screen size
Browse files Browse the repository at this point in the history
  • Loading branch information
materoy committed Feb 27, 2024
1 parent 6f8b68c commit 3866148
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 136 deletions.
Original file line number Diff line number Diff line change
@@ -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
}
)
}
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
},
)
}
}
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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

Expand All @@ -61,124 +52,86 @@ 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)
}
}
}
}
}

}

@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
Expand Down

0 comments on commit 3866148

Please sign in to comment.