优化语音播放逻辑

This commit is contained in:
xuncha
2026-02-06 17:42:42 +08:00
committed by xuncha
parent 1eab835458
commit 4d1632a9b9

View File

@@ -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<string, string>() const emojiDataUrlCache = new Map<string, string>()
const imageDataUrlCache = new Map<string, string>() const imageDataUrlCache = new Map<string, string>()
@@ -1985,6 +2007,7 @@ function MessageBubble({ message, session, showTime, myAvatarUrl, isGroupChat, o
const handleEnded = () => { const handleEnded = () => {
setIsVoicePlaying(false) setIsVoicePlaying(false)
setVoiceCurrentTime(0) setVoiceCurrentTime(0)
globalVoiceManager.stop(audio)
} }
const handleTimeUpdate = () => { const handleTimeUpdate = () => {
setVoiceCurrentTime(audio.currentTime) setVoiceCurrentTime(audio.currentTime)
@@ -1999,6 +2022,7 @@ function MessageBubble({ message, session, showTime, myAvatarUrl, isGroupChat, o
audio.addEventListener('loadedmetadata', handleLoadedMetadata) audio.addEventListener('loadedmetadata', handleLoadedMetadata)
return () => { return () => {
audio.pause() audio.pause()
globalVoiceManager.stop(audio)
audio.removeEventListener('play', handlePlay) audio.removeEventListener('play', handlePlay)
audio.removeEventListener('pause', handlePause) audio.removeEventListener('pause', handlePause)
audio.removeEventListener('ended', handleEnded) audio.removeEventListener('ended', handleEnded)
@@ -2433,6 +2457,7 @@ function MessageBubble({ message, session, showTime, myAvatarUrl, isGroupChat, o
if (isVoicePlaying) { if (isVoicePlaying) {
audio.pause() audio.pause()
audio.currentTime = 0 audio.currentTime = 0
globalVoiceManager.stop(audio)
return return
} }
if (!voiceDataUrl) { if (!voiceDataUrl) {
@@ -2467,6 +2492,11 @@ function MessageBubble({ message, session, showTime, myAvatarUrl, isGroupChat, o
} }
audio.src = source audio.src = source
try { try {
// 停止其他正在播放的语音,确保同一时间只播放一条
globalVoiceManager.play(audio, () => {
audio.pause()
audio.currentTime = 0
})
await audio.play() await audio.play()
} catch { } catch {
setVoiceError(true) setVoiceError(true)