From 13836905744f6dec599ba7d2e505a8706b23e02d Mon Sep 17 00:00:00 2001 From: eust-w Date: Wed, 18 Jun 2025 11:53:29 +0800 Subject: [PATCH] fix undefined audioSegments and duplicate end-handler --- app/static/js/chat.js | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/app/static/js/chat.js b/app/static/js/chat.js index 795dcb2..f363261 100644 --- a/app/static/js/chat.js +++ b/app/static/js/chat.js @@ -1,4 +1,31 @@ // 页面加载完成后执行 + +// ====== 音频队列处理 ====== +const audioQueue = []; +let audioPlaying = false; + +function enqueueAudio(blob) { + audioQueue.push(blob); + playNextAudio(); +} + +function playNextAudio() { + if (audioPlaying || audioQueue.length === 0) return; + const blob = audioQueue.shift(); + const audio = new Audio(URL.createObjectURL(blob)); + audioPlaying = true; + audio.addEventListener('ended', () => { + audioPlaying = false; + playNextAudio(); + }); + audio.play(); +} + +// 顺序播放一组音频片段(用于重放) +function playAudioSegments(segments) { + segments.forEach(seg => enqueueAudio(seg)); +} + document.addEventListener('DOMContentLoaded', function() { // 加载机器人角色列表 loadRobotCharacters(); @@ -202,6 +229,8 @@ function initChatForm() { const contentDiv = document.createElement('div'); contentDiv.className = 'message-content'; assistantElement.appendChild(contentDiv); + // 存储该消息对应的音频片段集合 + const audioSegments = []; const timeDiv = document.createElement('div'); timeDiv.className = 'message-time'; timeDiv.textContent = getCurrentTime(); @@ -227,7 +256,15 @@ function initChatForm() { if (raw.startsWith('event: end')) { chatMessages.removeChild(typingIndicator); streamEnded = true; - break; + // 为该消息添加重放按钮 + if (audioSegments.length > 0) { + const replayBtn = document.createElement('button'); + replayBtn.className = 'btn btn-sm btn-outline-secondary ms-2 replay-btn'; + replayBtn.innerHTML = ' 重放音频'; + replayBtn.addEventListener('click', () => { playAudioSegments(audioSegments); }); + assistantElement.appendChild(replayBtn); + } + } if (!raw.startsWith('data:')) continue; @@ -241,7 +278,8 @@ function initChatForm() { } else if (obj.type === 'audio') { const audioBytes = Uint8Array.from(atob(obj.content), c => c.charCodeAt(0)); const audioBlob = new Blob([audioBytes], { type: 'audio/wav' }); - new Audio(URL.createObjectURL(audioBlob)).play(); + audioSegments.push(audioBlob); + enqueueAudio(audioBlob); } } catch (e) { console.error('解析事件失败', e, payload);