Detach direct camera preview immediately when UI goes to background
This commit is contained in:
1 parent
78054b2c1d
commit
b8a2d7a555
2 files changed
+16
-6
No files matched your search
@@ -46,6 +46,7 @@ class StreamPreview {
|
||||
private var target: StreamPreviewTarget? = null
|
||||
private var owner: ((StreamPreviewTarget?) -> Unit)? = null
|
||||
private var closed = false
|
||||
private var visible = true
|
||||
private val mutable = MutableStateFlow(StreamPreviewState())
|
||||
val state: StateFlow<StreamPreviewState> = mutable
|
||||
|
||||
@@ -53,7 +54,7 @@ class StreamPreview {
|
||||
val next = StreamPreviewTarget(texture)
|
||||
if (closed) { LogManager.addLog("WARN", "video", "direct preview attach after capture stopped"); return next }
|
||||
val previous = target
|
||||
target = next.retain(); owner?.invoke(next.retain()); previous?.release()
|
||||
target = next.retain(); owner?.invoke(if (visible) next.retain() else null); previous?.release()
|
||||
LogManager.addLog("INFO", "video", "direct preview attached target=${System.identityHashCode(next)} bound=${owner != null}")
|
||||
return next // Первую ссылку освобождает UI в onSurfaceTextureDestroyed, возвращая false.
|
||||
}
|
||||
@@ -67,7 +68,15 @@ class StreamPreview {
|
||||
|
||||
@Synchronized internal fun bind(listener: (StreamPreviewTarget?) -> Unit) {
|
||||
check(!closed && owner == null)
|
||||
owner = listener; listener(target?.retain())
|
||||
owner = listener; listener(if (visible) target?.retain() else null)
|
||||
}
|
||||
|
||||
/** Lifecycle отключает output сразу, даже когда Compose уже приостановил recomposition. */
|
||||
@Synchronized fun setVisible(value: Boolean) {
|
||||
if (visible == value || closed) return
|
||||
visible = value; owner?.invoke(if (visible) target?.retain() else null)
|
||||
if (!visible) mutable.value = mutable.value.copy(active = false)
|
||||
LogManager.addLog("INFO", "video", "direct preview visibility=$visible target=${target?.let(System::identityHashCode)}")
|
||||
}
|
||||
|
||||
internal fun update(format: StreamPreviewFormat?, active: Boolean = false, failed: Boolean = false) {
|
||||
|
||||
@@ -298,13 +298,14 @@ private fun StreamRotationMark(top: Int) {
|
||||
private fun LiveStreamView(group: Long, source: Long, epoch: Long, localPreview: StreamPreview?) {
|
||||
val owner = LocalLifecycleOwner.current
|
||||
var visible by remember(owner) { mutableStateOf(owner.lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) }
|
||||
DisposableEffect(owner) {
|
||||
DisposableEffect(owner, localPreview) {
|
||||
localPreview?.setVisible(visible)
|
||||
val observer = LifecycleEventObserver { _, event ->
|
||||
if (event == Lifecycle.Event.ON_START) visible = true
|
||||
if (event == Lifecycle.Event.ON_STOP) visible = false
|
||||
if (event == Lifecycle.Event.ON_START) { localPreview?.setVisible(true); visible = true }
|
||||
if (event == Lifecycle.Event.ON_STOP) { localPreview?.setVisible(false); visible = false }
|
||||
}
|
||||
owner.lifecycle.addObserver(observer)
|
||||
onDispose { owner.lifecycle.removeObserver(observer) }
|
||||
onDispose { owner.lifecycle.removeObserver(observer); localPreview?.setVisible(false) }
|
||||
}
|
||||
val context = LocalContext.current
|
||||
val configuration = LocalConfiguration.current
|
||||
|
||||
Reference in new issue
Block a user