diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/ui/screens/StreamScreen.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/ui/screens/StreamScreen.kt index 2ca3dd10..a00666dc 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/ui/screens/StreamScreen.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/ui/screens/StreamScreen.kt @@ -19,10 +19,13 @@ import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.Alignment import androidx.compose.ui.platform.LocalContext +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 androidx.core.content.ContextCompat +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.LifecycleEventObserver import com.utun.chat.R import com.utun.chat.data.LogManager import com.utun.chat.data.NativeLib @@ -131,6 +134,21 @@ fun StreamScreen(channelId: String, channelName: String, onBack: () -> Unit) { @Composable private fun LiveStreamView(group: Long, source: Long, localPreview: Boolean) { + val owner = LocalLifecycleOwner.current + var visible by remember(owner) { mutableStateOf(owner.lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) } + DisposableEffect(owner) { + val observer = LifecycleEventObserver { _, event -> + if (event == Lifecycle.Event.ON_START) visible = true + if (event == Lifecycle.Event.ON_STOP) visible = false + } + owner.lifecycle.addObserver(observer) + onDispose { owner.lifecycle.removeObserver(observer) } + } + if (visible) LiveStreamSurface(group, source, localPreview) +} + +@Composable +private fun LiveStreamSurface(group: Long, source: Long, localPreview: Boolean) { val engine = remember(group, source, localPreview) { StreamPlayerEngine(group, source, localPreview) } val aspect by engine.aspect.collectAsState() val status by engine.status.collectAsState() @@ -140,21 +158,22 @@ private fun LiveStreamView(group: Long, source: Long, localPreview: Boolean) { Text(stringResource(status)) Box(Modifier.weight(1f).fillMaxWidth(), contentAlignment = Alignment.Center) { AndroidView(factory = { context -> - TextureView(context).apply { - surfaceTextureListener = object : TextureView.SurfaceTextureListener { - override fun onSurfaceTextureAvailable(texture: SurfaceTexture, width: Int, height: Int) { - surface = Surface(texture); engine.start(surface!!) - } - override fun onSurfaceTextureSizeChanged(texture: SurfaceTexture, width: Int, height: Int) {} - override fun onSurfaceTextureDestroyed(texture: SurfaceTexture): Boolean { - engine.stop(); surface?.release(); surface = null; return true + TextureView(context).apply { + keepScreenOn = true + surfaceTextureListener = object : TextureView.SurfaceTextureListener { + override fun onSurfaceTextureAvailable(texture: SurfaceTexture, width: Int, height: Int) { + surface = Surface(texture); engine.start(surface!!) + } + override fun onSurfaceTextureSizeChanged(texture: SurfaceTexture, width: Int, height: Int) {} + override fun onSurfaceTextureDestroyed(texture: SurfaceTexture): Boolean { + engine.stop(); surface?.release(); surface = null; return true + } + override fun onSurfaceTextureUpdated(texture: SurfaceTexture) {} + } } - override fun onSurfaceTextureUpdated(texture: SurfaceTexture) {} - } - } - }, modifier = Modifier.aspectRatio(aspect, matchHeightConstraintsFirst = true), onRelease = { view -> - engine.stop(); view.surfaceTextureListener = null; surface?.release(); surface = null - }) + }, modifier = Modifier.aspectRatio(aspect, matchHeightConstraintsFirst = true), onRelease = { view -> + engine.stop(); view.surfaceTextureListener = null; surface?.release(); surface = null + }) } } }