Browse Source

Pause viewers in the background and keep visible playback awake

master
evgeny 1 week ago
parent
commit
039c0f71f5
  1. 47
      tools/chatgui-android/app/src/main/java/com/utun/chat/ui/screens/StreamScreen.kt

47
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
})
}
}
}

Loading…
Cancel
Save