Skip to content

Instantly share code, notes, and snippets.

@NikolaDespotoski
Created March 4, 2023 16:34
Show Gist options
  • Save NikolaDespotoski/31f82ee7d081b2e7c69bf4275e69f316 to your computer and use it in GitHub Desktop.
Save NikolaDespotoski/31f82ee7d081b2e7c69bf4275e69f316 to your computer and use it in GitHub Desktop.
Exposing CameraController in Compose.
import androidx.camera.core.CameraSelector
import androidx.camera.view.CameraController
import androidx.camera.view.LifecycleCameraController
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import kotlinx.coroutines.guava.await
val LocalCameraController =
compositionLocalOf<CameraController> { error("CameraController wasn't provided") }
data class CameraControllerScope(
val isPrepared: Boolean = false,
val cameraController: CameraController
)
@Composable
fun CameraController(
lensFacing: Int = CameraSelector.LENS_FACING_FRONT,
cameraSelector: CameraSelector =
if (lensFacing == CameraSelector.LENS_FACING_BACK) CameraSelector.DEFAULT_BACK_CAMERA
else CameraSelector.DEFAULT_FRONT_CAMERA,
content: @Composable CameraControllerScope.() -> Unit
) {
val context = LocalContext.current
val cameraController = remember { LifecycleCameraController(context) }
var scope by remember(cameraController) {
mutableStateOf(CameraControllerScope(cameraController = cameraController))
}
val lifecycleOwner = LocalLifecycleOwner.current
LaunchedEffect(lensFacing, cameraSelector) {
kotlin.runCatching {
cameraController.initializationFuture.await()
scope = scope.copy(isPrepared = false)
}.onSuccess {
cameraController.cameraSelector = cameraSelector
cameraController.bindToLifecycle(lifecycleOwner)
}.onFailure {
it.printStackTrace()
}
}
CompositionLocalProvider(
LocalCameraController provides cameraController,
) {
content(scope)
}
}
@Composable
fun Usage() {
CameraController {
val controller = LocalCameraController.currnet
//or
val cameraController = cameraController //from CameraControllerScope
MyContent()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment