From a19f2a57c3ffa38374c36dce998690f768e81013 Mon Sep 17 00:00:00 2001 From: xuncha <1658671838@qq.com> Date: Fri, 6 Feb 2026 17:42:42 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=AF=AD=E9=9F=B3=E6=92=AD?= =?UTF-8?q?=E6=94=BE=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/ChatPage.tsx | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/pages/ChatPage.tsx b/src/pages/ChatPage.tsx index 8d2ed72..482b6b7 100644 --- a/src/pages/ChatPage.tsx +++ b/src/pages/ChatPage.tsx @@ -1546,6 +1546,28 @@ function ChatPage(_props: ChatPageProps) { ) } +// 全局语音播放管理器:同一时间只能播放一条语音 +const globalVoiceManager = { + currentAudio: null as HTMLAudioElement | null, + currentStopCallback: null as (() => void) | null, + play(audio: HTMLAudioElement, onStop: () => void) { + // 停止当前正在播放的语音 + if (this.currentAudio && this.currentAudio !== audio) { + this.currentAudio.pause() + this.currentAudio.currentTime = 0 + this.currentStopCallback?.() + } + this.currentAudio = audio + this.currentStopCallback = onStop + }, + stop(audio: HTMLAudioElement) { + if (this.currentAudio === audio) { + this.currentAudio = null + this.currentStopCallback = null + } + }, +} + // 前端表情包缓存 const emojiDataUrlCache = new Map() const imageDataUrlCache = new Map() @@ -1985,6 +2007,7 @@ function MessageBubble({ message, session, showTime, myAvatarUrl, isGroupChat, o const handleEnded = () => { setIsVoicePlaying(false) setVoiceCurrentTime(0) + globalVoiceManager.stop(audio) } const handleTimeUpdate = () => { setVoiceCurrentTime(audio.currentTime) @@ -1999,6 +2022,7 @@ function MessageBubble({ message, session, showTime, myAvatarUrl, isGroupChat, o audio.addEventListener('loadedmetadata', handleLoadedMetadata) return () => { audio.pause() + globalVoiceManager.stop(audio) audio.removeEventListener('play', handlePlay) audio.removeEventListener('pause', handlePause) audio.removeEventListener('ended', handleEnded) @@ -2433,6 +2457,7 @@ function MessageBubble({ message, session, showTime, myAvatarUrl, isGroupChat, o if (isVoicePlaying) { audio.pause() audio.currentTime = 0 + globalVoiceManager.stop(audio) return } if (!voiceDataUrl) { @@ -2467,6 +2492,11 @@ function MessageBubble({ message, session, showTime, myAvatarUrl, isGroupChat, o } audio.src = source try { + // 停止其他正在播放的语音,确保同一时间只播放一条 + globalVoiceManager.play(audio, () => { + audio.pause() + audio.currentTime = 0 + }) await audio.play() } catch { setVoiceError(true)