From 24d678b3e3fd8c8d4e9b6c66002925d2eff179f5 Mon Sep 17 00:00:00 2001 From: Iro <155815508+Iro96@users.noreply.github.com> Date: Fri, 29 Aug 2025 15:42:12 +0700 Subject: [PATCH] fix: TTS lags behind conversation (#494) * Fix bug: By add some logics to Stage.vue * fix bug * Fix bug: Add some logics to Stage.vue * correct lint * fix bug and correct lint * add logic to Stage.vue * correct lint * correct lint (final) * Update packages/stage-ui/src/components/Scenes/Stage.vue Co-authored-by: Makito * Update packages/stage-ui/src/components/Scenes/Stage.vue Co-authored-by: Makito --------- Co-authored-by: Makito --- .../stage-ui/src/components/Scenes/Stage.vue | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/packages/stage-ui/src/components/Scenes/Stage.vue b/packages/stage-ui/src/components/Scenes/Stage.vue index e7911a097..8095494a0 100644 --- a/packages/stage-ui/src/components/Scenes/Stage.vue +++ b/packages/stage-ui/src/components/Scenes/Stage.vue @@ -74,11 +74,21 @@ vrmStore.onShouldUpdateView(async () => { const audioAnalyser = ref() const nowSpeaking = ref(false) const lipSyncStarted = ref(false) +let currentAudioSource: AudioBufferSourceNode | null = null const audioQueue = useQueue<{ audioBuffer: AudioBuffer, text: string }>({ handlers: [ (ctx) => { return new Promise((resolve) => { + // Stop any currently playing audio + if (currentAudioSource) { + try { + currentAudioSource.stop() + currentAudioSource.disconnect() + } + catch {} + currentAudioSource = null + } // Create an AudioBufferSourceNode const source = audioContext.createBufferSource() source.buffer = ctx.data.audioBuffer @@ -90,9 +100,13 @@ const audioQueue = useQueue<{ audioBuffer: AudioBuffer, text: string }>({ // Start playing the audio nowSpeaking.value = true + currentAudioSource = source source.start(0) source.onended = () => { nowSpeaking.value = false + if (currentAudioSource === source) { + currentAudioSource = null + } resolve() } }) @@ -209,6 +223,16 @@ function setupAnalyser() { } onBeforeMessageComposed(async () => { + // Stop any currently playing audio and clear the audio queue + if (currentAudioSource) { + try { + currentAudioSource.stop() + currentAudioSource.disconnect() + } + catch {} + currentAudioSource = null + } + audioQueue.queue.value = [] setupAnalyser() setupLipSync() })