mirror of
https://github.com/Myzel394/Alibi.git
synced 2025-06-18 23:05:26 +02:00
commit
24928661c5
@ -1,56 +1,56 @@
|
|||||||
package app.myzel394.alibi.ui.components.RecorderScreen.atoms
|
package app.myzel394.alibi.ui.components.RecorderScreen.atoms
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.camera.core.CameraSelector
|
import androidx.camera.core.CameraSelector
|
||||||
import androidx.camera.core.Preview
|
import androidx.camera.core.Preview
|
||||||
import androidx.camera.lifecycle.ProcessCameraProvider
|
|
||||||
import androidx.camera.view.PreviewView
|
import androidx.camera.view.PreviewView
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||||
import androidx.compose.ui.viewinterop.AndroidView
|
import androidx.compose.ui.viewinterop.AndroidView
|
||||||
|
import app.myzel394.alibi.ui.utils.getCameraProvider
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CameraPreview(
|
fun CameraPreview(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier,
|
||||||
scaleType: PreviewView.ScaleType = PreviewView.ScaleType.FILL_CENTER,
|
|
||||||
cameraSelector: CameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
|
cameraSelector: CameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
|
||||||
) {
|
) {
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
val lifecycleOwner = LocalLifecycleOwner.current
|
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
|
Box(modifier = modifier) {
|
||||||
val previewUseCase = Preview.Builder()
|
// Video preview
|
||||||
.build()
|
AndroidView(
|
||||||
.also {
|
factory = { context ->
|
||||||
it.setSurfaceProvider(previewView.surfaceProvider)
|
val previewView = PreviewView(context).apply {
|
||||||
}
|
layoutParams = ViewGroup.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
coroutineScope.launch {
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
val cameraProvider = ProcessCameraProvider.getInstance(context).get()
|
|
||||||
try {
|
|
||||||
// Must unbind the use-cases before rebinding them.
|
|
||||||
cameraProvider.unbindAll()
|
|
||||||
cameraProvider.bindToLifecycle(
|
|
||||||
lifecycleOwner, cameraSelector, previewUseCase
|
|
||||||
)
|
)
|
||||||
} 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
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -33,6 +33,7 @@ import androidx.compose.ui.platform.LocalDensity
|
|||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import app.myzel394.alibi.R
|
import app.myzel394.alibi.R
|
||||||
|
import app.myzel394.alibi.ui.components.RecorderScreen.atoms.CameraPreview
|
||||||
import app.myzel394.alibi.dataStore
|
import app.myzel394.alibi.dataStore
|
||||||
import app.myzel394.alibi.ui.components.RecorderScreen.atoms.SaveCurrentNowModal
|
import app.myzel394.alibi.ui.components.RecorderScreen.atoms.SaveCurrentNowModal
|
||||||
import app.myzel394.alibi.ui.components.RecorderScreen.atoms.TorchStatus
|
import app.myzel394.alibi.ui.components.RecorderScreen.atoms.TorchStatus
|
||||||
@ -54,68 +55,79 @@ fun VideoRecordingStatus(
|
|||||||
|
|
||||||
when (orientation) {
|
when (orientation) {
|
||||||
Configuration.ORIENTATION_LANDSCAPE -> {
|
Configuration.ORIENTATION_LANDSCAPE -> {
|
||||||
Row(
|
Box {
|
||||||
modifier = Modifier.fillMaxSize(),
|
CameraPreview(
|
||||||
horizontalArrangement = Arrangement.SpaceEvenly,
|
modifier = Modifier,
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
cameraSelector = videoRecorder.cameraSelector
|
||||||
) {
|
)
|
||||||
Column(
|
Row(
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
modifier = Modifier.fillMaxSize(),
|
||||||
verticalArrangement = Arrangement
|
horizontalArrangement = Arrangement.SpaceEvenly,
|
||||||
.spacedBy(32.dp),
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
modifier = Modifier
|
|
||||||
.weight(1f)
|
|
||||||
.fillMaxWidth(0.9f)
|
|
||||||
.align(Alignment.CenterVertically),
|
|
||||||
) {
|
|
||||||
_VideoGeneralInfo(videoRecorder)
|
|
||||||
_VideoRecordingStatus(videoRecorder)
|
|
||||||
}
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.weight(1f)
|
|
||||||
.fillMaxWidth(0.9f)
|
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
verticalArrangement = Arrangement
|
verticalArrangement = Arrangement
|
||||||
.spacedBy(32.dp),
|
.spacedBy(32.dp),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
modifier = Modifier
|
||||||
|
.weight(1f)
|
||||||
|
.fillMaxWidth(0.9f)
|
||||||
|
.align(Alignment.CenterVertically),
|
||||||
) {
|
) {
|
||||||
_VideoControls(videoRecorder)
|
_VideoGeneralInfo(videoRecorder)
|
||||||
HorizontalDivider()
|
_VideoRecordingStatus(videoRecorder)
|
||||||
_PrimitiveControls(videoRecorder)
|
}
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.weight(1f)
|
||||||
|
.fillMaxWidth(0.9f)
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
verticalArrangement = Arrangement
|
||||||
|
.spacedBy(32.dp),
|
||||||
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
|
) {
|
||||||
|
_VideoControls(videoRecorder)
|
||||||
|
HorizontalDivider()
|
||||||
|
_PrimitiveControls(videoRecorder)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
Column(
|
Box {
|
||||||
modifier = Modifier
|
CameraPreview(
|
||||||
.fillMaxSize()
|
modifier = Modifier,
|
||||||
.padding(bottom = 32.dp),
|
cameraSelector = videoRecorder.cameraSelector
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
)
|
||||||
verticalArrangement = Arrangement.SpaceBetween,
|
|
||||||
) {
|
|
||||||
Box {}
|
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxSize()
|
||||||
|
.padding(bottom = 32.dp),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
verticalArrangement = Arrangement
|
verticalArrangement = Arrangement.SpaceBetween,
|
||||||
.spacedBy(16.dp),
|
|
||||||
) {
|
) {
|
||||||
_VideoGeneralInfo(videoRecorder)
|
Column(
|
||||||
_VideoRecordingStatus(videoRecorder)
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
}
|
verticalArrangement = Arrangement
|
||||||
|
.spacedBy(16.dp),
|
||||||
|
) {
|
||||||
|
_VideoGeneralInfo(videoRecorder)
|
||||||
|
_VideoRecordingStatus(videoRecorder)
|
||||||
|
}
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
verticalArrangement = Arrangement
|
verticalArrangement = Arrangement
|
||||||
.spacedBy(16.dp),
|
.spacedBy(16.dp),
|
||||||
horizontalAlignment = Alignment.CenterHorizontally,
|
horizontalAlignment = Alignment.CenterHorizontally,
|
||||||
) {
|
) {
|
||||||
_VideoControls(videoRecorder)
|
_VideoControls(videoRecorder)
|
||||||
HorizontalDivider()
|
HorizontalDivider()
|
||||||
_PrimitiveControls(videoRecorder)
|
_PrimitiveControls(videoRecorder)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
16
app/src/main/java/app/myzel394/alibi/ui/utils/Context.kt
Normal file
16
app/src/main/java/app/myzel394/alibi/ui/utils/Context.kt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
package app.myzel394.alibi.ui.utils
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import androidx.camera.lifecycle.ProcessCameraProvider
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import kotlin.coroutines.resume
|
||||||
|
import kotlin.coroutines.suspendCoroutine
|
||||||
|
|
||||||
|
suspend fun Context.getCameraProvider(): ProcessCameraProvider = suspendCoroutine { continuation ->
|
||||||
|
ProcessCameraProvider.getInstance(this).also { future ->
|
||||||
|
future.addListener({
|
||||||
|
continuation.resume(future.get())
|
||||||
|
}, ContextCompat.getMainExecutor(this))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user