From 7c060fc35c26932f1ebbd6236949a7ec697f1b05 Mon Sep 17 00:00:00 2001 From: CrabSAMA <40541269+CrabSAMA@users.noreply.github.com> Date: Thu, 20 Nov 2025 12:48:11 +0800 Subject: [PATCH] fix: lazy init audioplayer to fix no tts message also switch audio source bug (#28433) --- web/app/components/base/chat/chat/hooks.ts | 22 +++++++++++++++---- .../workflow-app/hooks/use-workflow-run.ts | 22 +++++++++++++++---- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/web/app/components/base/chat/chat/hooks.ts b/web/app/components/base/chat/chat/hooks.ts index 665e7e8bc3..a10b359724 100644 --- a/web/app/components/base/chat/chat/hooks.ts +++ b/web/app/components/base/chat/chat/hooks.ts @@ -29,6 +29,7 @@ import type { Annotation } from '@/models/log' import { WorkflowRunningStatus } from '@/app/components/workflow/types' import useTimestamp from '@/hooks/use-timestamp' import { AudioPlayerManager } from '@/app/components/base/audio-btn/audio.player.manager' +import type AudioPlayer from '@/app/components/base/audio-btn/audio' import type { FileEntity } from '@/app/components/base/file-uploader/types' import { getProcessedFiles, @@ -308,7 +309,15 @@ export const useChat = ( else ttsUrl = `/apps/${params.appId}/text-to-audio` } - const player = AudioPlayerManager.getInstance().getAudioPlayer(ttsUrl, ttsIsPublic, uuidV4(), 'none', 'none', noop) + // Lazy initialization: Only create AudioPlayer when TTS is actually needed + // This prevents opening audio channel unnecessarily + let player: AudioPlayer | null = null + const getOrCreatePlayer = () => { + if (!player) + player = AudioPlayerManager.getInstance().getAudioPlayer(ttsUrl, ttsIsPublic, uuidV4(), 'none', 'none', noop) + + return player + } ssePost( url, { @@ -582,11 +591,16 @@ export const useChat = ( onTTSChunk: (messageId: string, audio: string) => { if (!audio || audio === '') return - player.playAudioWithAudio(audio, true) - AudioPlayerManager.getInstance().resetMsgId(messageId) + const audioPlayer = getOrCreatePlayer() + if (audioPlayer) { + audioPlayer.playAudioWithAudio(audio, true) + AudioPlayerManager.getInstance().resetMsgId(messageId) + } }, onTTSEnd: (messageId: string, audio: string) => { - player.playAudioWithAudio(audio, false) + const audioPlayer = getOrCreatePlayer() + if (audioPlayer) + audioPlayer.playAudioWithAudio(audio, false) }, onLoopStart: ({ data: loopStartedData }) => { responseItem.workflowProcess!.tracing!.push({ diff --git a/web/app/components/workflow-app/hooks/use-workflow-run.ts b/web/app/components/workflow-app/hooks/use-workflow-run.ts index 3ab1c522e7..c8949651e5 100644 --- a/web/app/components/workflow-app/hooks/use-workflow-run.ts +++ b/web/app/components/workflow-app/hooks/use-workflow-run.ts @@ -17,6 +17,7 @@ import { handleStream, ssePost } from '@/service/base' import { stopWorkflowRun } from '@/service/workflow' import { useFeaturesStore } from '@/app/components/base/features/hooks' import { AudioPlayerManager } from '@/app/components/base/audio-btn/audio.player.manager' +import type AudioPlayer from '@/app/components/base/audio-btn/audio' import type { VersionHistory } from '@/types/workflow' import { noop } from 'lodash-es' import { useNodesSyncDraft } from './use-nodes-sync-draft' @@ -323,7 +324,15 @@ export const useWorkflowRun = () => { else ttsUrl = `/apps/${resolvedParams.appId}/text-to-audio` } - const player = AudioPlayerManager.getInstance().getAudioPlayer(ttsUrl, ttsIsPublic, uuidV4(), 'none', 'none', noop) + // Lazy initialization: Only create AudioPlayer when TTS is actually needed + // This prevents opening audio channel unnecessarily + let player: AudioPlayer | null = null + const getOrCreatePlayer = () => { + if (!player) + player = AudioPlayerManager.getInstance().getAudioPlayer(ttsUrl, ttsIsPublic, uuidV4(), 'none', 'none', noop) + + return player + } const clearAbortController = () => { abortControllerRef.current = null @@ -470,11 +479,16 @@ export const useWorkflowRun = () => { onTTSChunk: (messageId: string, audio: string) => { if (!audio || audio === '') return - player.playAudioWithAudio(audio, true) - AudioPlayerManager.getInstance().resetMsgId(messageId) + const audioPlayer = getOrCreatePlayer() + if (audioPlayer) { + audioPlayer.playAudioWithAudio(audio, true) + AudioPlayerManager.getInstance().resetMsgId(messageId) + } }, onTTSEnd: (messageId: string, audio: string) => { - player.playAudioWithAudio(audio, false) + const audioPlayer = getOrCreatePlayer() + if (audioPlayer) + audioPlayer.playAudioWithAudio(audio, false) }, onError: wrappedOnError, onCompleted: wrappedOnCompleted,