fix undefined audioSegments and duplicate end-handler

This commit is contained in:
eust-w 2025-06-18 11:53:29 +08:00
parent e29eced691
commit 1383690574

View File

@ -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() { document.addEventListener('DOMContentLoaded', function() {
// 加载机器人角色列表 // 加载机器人角色列表
loadRobotCharacters(); loadRobotCharacters();
@ -202,6 +229,8 @@ function initChatForm() {
const contentDiv = document.createElement('div'); const contentDiv = document.createElement('div');
contentDiv.className = 'message-content'; contentDiv.className = 'message-content';
assistantElement.appendChild(contentDiv); assistantElement.appendChild(contentDiv);
// 存储该消息对应的音频片段集合
const audioSegments = [];
const timeDiv = document.createElement('div'); const timeDiv = document.createElement('div');
timeDiv.className = 'message-time'; timeDiv.className = 'message-time';
timeDiv.textContent = getCurrentTime(); timeDiv.textContent = getCurrentTime();
@ -227,7 +256,15 @@ function initChatForm() {
if (raw.startsWith('event: end')) { if (raw.startsWith('event: end')) {
chatMessages.removeChild(typingIndicator); chatMessages.removeChild(typingIndicator);
streamEnded = true; 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 = '<i class="bi bi-play-circle"></i> 重放音频';
replayBtn.addEventListener('click', () => { playAudioSegments(audioSegments); });
assistantElement.appendChild(replayBtn);
}
} }
if (!raw.startsWith('data:')) continue; if (!raw.startsWith('data:')) continue;
@ -241,7 +278,8 @@ function initChatForm() {
} else if (obj.type === 'audio') { } else if (obj.type === 'audio') {
const audioBytes = Uint8Array.from(atob(obj.content), c => c.charCodeAt(0)); const audioBytes = Uint8Array.from(atob(obj.content), c => c.charCodeAt(0));
const audioBlob = new Blob([audioBytes], { type: 'audio/wav' }); const audioBlob = new Blob([audioBytes], { type: 'audio/wav' });
new Audio(URL.createObjectURL(audioBlob)).play(); audioSegments.push(audioBlob);
enqueueAudio(audioBlob);
} }
} catch (e) { } catch (e) {
console.error('解析事件失败', e, payload); console.error('解析事件失败', e, payload);