'commit'
This commit is contained in:
@@ -14,7 +14,10 @@ const AudioState = {
|
||||
playback: {
|
||||
audioElement: null,
|
||||
isPlaying: false,
|
||||
audioChunks: [] // 存储接收到的音频块
|
||||
audioChunks: [], // 存储接收到的音频块
|
||||
audioQueue: [], // 音频队列,用于流式播放
|
||||
isStreamPlaying: false, // 是否正在流式播放
|
||||
currentAudioIndex: 0 // 当前播放的音频索引
|
||||
},
|
||||
websocket: {
|
||||
connection: null,
|
||||
@@ -178,12 +181,13 @@ const WebSocketManager = {
|
||||
UIController.toggleElement('thinkingIndicator', false);
|
||||
UIController.setStartRecordButtonEnabled(true);
|
||||
|
||||
// 合并所有音频块并播放
|
||||
if (AudioState.playback.audioChunks.length > 0) {
|
||||
console.log('开始合并和播放音频');
|
||||
this.combineAndPlayAudio();
|
||||
} else {
|
||||
console.warn('没有收到音频数据,无法播放');
|
||||
// 标记流式播放结束
|
||||
AudioState.playback.isStreamPlaying = false;
|
||||
|
||||
// 如果有音频数据但尚未开始播放,则开始播放
|
||||
if (AudioState.playback.audioQueue.length > 0 && !AudioState.playback.isPlaying) {
|
||||
console.log('开始播放队列中的音频');
|
||||
AudioPlayer.processAudioQueue();
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -192,6 +196,9 @@ const WebSocketManager = {
|
||||
console.error('收到错误消息:', data.message);
|
||||
UIController.toggleElement('thinkingIndicator', false);
|
||||
UIController.setStartRecordButtonEnabled(true);
|
||||
// 重置流式播放状态
|
||||
AudioState.playback.isStreamPlaying = false;
|
||||
AudioState.playback.audioQueue = [];
|
||||
alert('处理失败: ' + data.message);
|
||||
break;
|
||||
|
||||
@@ -206,8 +213,20 @@ const WebSocketManager = {
|
||||
// 二进制音频数据
|
||||
console.log('收到音频数据,大小:', event.data.size);
|
||||
console.log('音频数据类型:', event.data.type);
|
||||
|
||||
// 保存到原始音频块数组(保持原有逻辑)
|
||||
AudioState.playback.audioChunks.push(event.data);
|
||||
console.log('当前音频块数量:', AudioState.playback.audioChunks.length);
|
||||
|
||||
// 添加到音频队列(用于流式播放)
|
||||
AudioState.playback.audioQueue.push(event.data);
|
||||
console.log('当前音频队列长度:', AudioState.playback.audioQueue.length);
|
||||
|
||||
// 如果尚未开始流式播放,则开始播放
|
||||
if (!AudioState.playback.isStreamPlaying && !AudioState.playback.isPlaying) {
|
||||
console.log('开始流式播放音频');
|
||||
AudioState.playback.isStreamPlaying = true;
|
||||
AudioPlayer.processAudioQueue();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -355,6 +374,64 @@ const AudioPlayer = {
|
||||
const currentTime = AudioState.playback.audioElement.currentTime;
|
||||
const duration = AudioState.playback.audioElement.duration;
|
||||
UIController.updateTimeDisplay(currentTime, duration);
|
||||
},
|
||||
|
||||
// 初始化流式播放器
|
||||
initStreamPlayer() {
|
||||
// 创建新的音频元素用于流式播放
|
||||
if (!AudioState.playback.streamAudioElement) {
|
||||
AudioState.playback.streamAudioElement = new Audio();
|
||||
|
||||
// 监听音频结束事件
|
||||
AudioState.playback.streamAudioElement.addEventListener('ended', () => {
|
||||
// 当前音频播放完毕,处理队列中的下一个音频
|
||||
this.processAudioQueue();
|
||||
});
|
||||
|
||||
// 监听错误事件
|
||||
AudioState.playback.streamAudioElement.addEventListener('error', (e) => {
|
||||
console.error('流式播放音频错误:', e);
|
||||
// 即使出错,也继续处理队列中的下一个音频
|
||||
this.processAudioQueue();
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
// 处理音频队列
|
||||
processAudioQueue() {
|
||||
// 如果正在播放或队列为空,则返回
|
||||
if (AudioState.playback.isStreamPlaying || AudioState.playback.audioQueue.length === 0) {
|
||||
AudioState.playback.isStreamPlaying = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置播放状态
|
||||
AudioState.playback.isStreamPlaying = true;
|
||||
|
||||
// 从队列中取出第一个音频块
|
||||
const audioBlob = AudioState.playback.audioQueue.shift();
|
||||
|
||||
// 创建音频URL
|
||||
const audioUrl = URL.createObjectURL(audioBlob);
|
||||
|
||||
// 设置音频源并播放
|
||||
AudioState.playback.streamAudioElement.src = audioUrl;
|
||||
AudioState.playback.streamAudioElement.play()
|
||||
.then(() => {
|
||||
console.log('开始播放音频块');
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('播放音频块失败:', error);
|
||||
// 播放失败,继续处理下一个
|
||||
AudioState.playback.isStreamPlaying = false;
|
||||
this.processAudioQueue();
|
||||
})
|
||||
.finally(() => {
|
||||
// 播放完成后释放URL对象
|
||||
setTimeout(() => {
|
||||
URL.revokeObjectURL(audioUrl);
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -589,10 +666,12 @@ const RecordingManager = {
|
||||
};
|
||||
|
||||
// ==================== 初始化 ====================
|
||||
// 页面加载完成后初始化
|
||||
function initializeApp() {
|
||||
console.log('开始初始化学伴录音功能...');
|
||||
|
||||
// 初始化流式播放器
|
||||
AudioPlayer.initStreamPlayer();
|
||||
|
||||
// 检查DOM是否已就绪
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
|
Reference in New Issue
Block a user