diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamAudioMixer.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamAudioMixer.kt index 25737297..94d50802 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamAudioMixer.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamAudioMixer.kt @@ -1,7 +1,9 @@ package com.utun.chat.data /** Один AudioTrack для всех трансляций. Mixer только копирует и смешивает готовый PCM. - * Input закрывается после исключения из списка; его короткий lock защищает consumer от release. */ + * Input закрывается после исключения из списка; его короткий lock защищает consumer от release. + * Выход принадлежит worker до успешного close; новые inputs ждут cleanup, не открывая второй AudioTrack. + */ internal object StreamAudioMixer { data class OutputState(val played: Long = 0, val leadUs: Long = 0) @Volatile var output = OutputState() @@ -58,11 +60,8 @@ internal object StreamAudioMixer { LogManager.addLog("INFO", "stream", "mixer started: ready PCM only, blockFrames=${mix.frames}") while (true) { val current = synchronized(lock) { - if (inputs.isEmpty()) { - return - } - snapshot - } + if (inputs.isEmpty()) null else snapshot + } ?: break device.step(System.nanoTime(), hold = false, pull = { mix.clear() var active = false @@ -186,8 +185,10 @@ internal class StreamMixedPlayback(val id: Long, pts: Long, private val audioEna true } catch (e: Exception) { outputFailure = e.message ?: "Audio mixing failed" - wake() LogManager.addLog("ERROR", "stream", "mixer input failed id=$id: ${e.message}") + try { wake() } catch (notification: Exception) { + LogManager.addLog("ERROR", "stream", "mixer failure notification failed id=$id: $notification") + } false } } diff --git a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamVideoPlayback.kt b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamVideoPlayback.kt index 622fed52..030b7173 100644 --- a/tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamVideoPlayback.kt +++ b/tools/chatgui-android/app/src/main/java/com/utun/chat/data/StreamVideoPlayback.kt @@ -158,7 +158,8 @@ internal class StreamVideoPlayback( } } } catch (e: Exception) { - if (running) { + val report = running; running = false + if (report) { failure = e LogManager.addLog("ERROR", "video", "viewer video worker failed id=$id generation=$activeGeneration: ${e.message}") wake()