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