diff --git a/src/views/AIchat.vue b/src/views/AIchat.vue
index 9b122bd..9c5fa74 100644
--- a/src/views/AIchat.vue
+++ b/src/views/AIchat.vue
@@ -156,6 +156,9 @@ const playAudioSequence = (audioUrls) => {
audioStore.isPlaying = false;
audioStore.isPaused = false;
audioStore.playbackPosition = 0;
+ // 清除音频实例,确保下次点击从头开始
+ audioStore.soundInstance = null;
+ audioStore.nowSound = null;
if (audioSequence.length > 0) {
audioStore.setCurrentAudioUrl(audioSequence[0]);
}
@@ -230,22 +233,33 @@ const playAudioSequence = (audioUrls) => {
// 重写togglePlayPause方法以支持音频序列控制
const originalTogglePlayPause = audioStore.togglePlayPause;
audioStore.togglePlayPause = () => {
+ console.log('音频控制按钮被点击');
+ console.log('当前播放状态:', audioStore.isPlaying);
+ console.log('当前暂停状态:', audioStore.isPaused);
+ console.log('当前音频实例:', audioStore.soundInstance);
+ console.log('当前索引:', currentIndex, '音频序列长度:', audioSequence.length);
+
if (audioStore.soundInstance) {
if (audioStore.isPlaying) {
// 暂停当前音频
+ console.log('暂停当前音频');
audioStore.pause();
} else if (audioStore.isPaused) {
// 从暂停位置继续播放
+ console.log('从暂停位置继续播放');
audioStore.play();
} else {
// 重新开始播放当前音频或从头开始播放序列
+ console.log('重新开始播放,当前索引:', currentIndex);
if (currentIndex >= audioSequence.length) {
+ console.log('所有音频已播放完成,从头开始');
currentIndex = 0; // 重置到第一个音频
}
playNext();
}
} else {
// 没有音频实例时,从头开始播放
+ console.log('没有音频实例,从头开始播放');
currentIndex = 0;
playNext();
}
@@ -467,7 +481,7 @@ const processTypingQueue = async () => {
};
// 添加打字机任务到队列
-const addTypingTask = (message, content, speed = 50) => {
+const addTypingTask = (message, content, speed) => {
typingQueue.value.push({ message, content, speed });
processTypingQueue();
};
@@ -620,28 +634,194 @@ watch(
four: { completed: false, result: null, error: null },
};
+ // 音频预加载状态跟踪
+ const audioPreloadStatus = {
+ one: { loaded: false, url: null },
+ two: { loaded: false, url: null },
+ three: { loaded: false, url: null },
+ four: { loaded: false, url: null }
+ };
+
+ // 音频播放队列管理
+ const audioQueue = ref([]);
+ const isPlayingAudio = ref(false);
+
+ // 播放音频队列
+ const playNextAudio = () => {
+ if (audioQueue.value.length === 0 || isPlayingAudio.value) {
+ return;
+ }
+
+ isPlayingAudio.value = true;
+ const audioInfo = audioQueue.value.shift();
+
+ console.log(`开始播放${audioInfo.name}音频`);
+
+ if (audioStore.nowSound) {
+ audioStore.nowSound.stop();
+ }
+
+ const audio = new Howl({
+ src: [audioInfo.url],
+ html5: true,
+ format: ["mp3", "acc"],
+ rate: 1.2,
+ onplay: () => {
+ audioStore.isPlaying = true;
+ audioStore.isPaused = false;
+ console.log(`${audioInfo.name}音频开始播放`);
+ },
+ onpause: () => {
+ audioStore.isPlaying = false;
+ audioStore.isPaused = true;
+ audioStore.playbackPosition = audio.seek() || 0;
+ console.log(`${audioInfo.name}音频已暂停,位置:`, audioStore.playbackPosition);
+ },
+ onresume: () => {
+ audioStore.isPlaying = true;
+ audioStore.isPaused = false;
+ console.log(`${audioInfo.name}音频继续播放`);
+ },
+ onend: () => {
+ audioStore.isPlaying = false;
+ audioStore.isPaused = false;
+ audioStore.playbackPosition = 0;
+ isPlayingAudio.value = false;
+ console.log(`${audioInfo.name}音频播放完成`);
+ // 播放下一个音频
+ setTimeout(() => {
+ playNextAudio();
+ }, 100);
+ },
+ onstop: () => {
+ audioStore.isPlaying = false;
+ audioStore.isPaused = false;
+ audioStore.playbackPosition = 0;
+ isPlayingAudio.value = false;
+ console.log(`${audioInfo.name}音频已停止`);
+ },
+ onloaderror: (id, err) => {
+ console.error(`${audioInfo.name}音频播放失败:`, err);
+ isPlayingAudio.value = false;
+ // 播放下一个音频
+ setTimeout(() => {
+ playNextAudio();
+ }, 100);
+ }
+ });
+
+ // 设置当前音频URL到store
+ audioStore.setCurrentAudioUrl(audioInfo.url);
+ audioStore.nowSound = audio;
+ audioStore.setAudioInstance(audio);
+ audio.play();
+ };
+
+ // 添加音频到播放队列
+ const addToAudioQueue = (url, name) => {
+ if (url && audioStore.isVoiceEnabled) {
+ audioQueue.value.push({ url, name });
+ console.log(`音频${name}已添加到播放队列`);
+ // 如果当前没有播放音频,立即开始播放
+ if (!isPlayingAudio.value) {
+ playNextAudio();
+ }
+ }
+ };
+
+ // 重写audioStore的togglePlayPause方法以支持队列播放控制
+ const originalTogglePlayPause = audioStore.togglePlayPause;
+ audioStore.togglePlayPause = () => {
+ console.log('主页音频控制按钮被点击');
+ console.log('当前音频状态 - isPlaying:', audioStore.isPlaying, 'isPaused:', audioStore.isPaused);
+ console.log('当前音频实例:', audioStore.soundInstance);
+
+ if (audioStore.soundInstance) {
+ if (audioStore.isPlaying) {
+ // 暂停当前音频
+ console.log('暂停当前音频');
+ audioStore.soundInstance.pause();
+ } else if (audioStore.isPaused && audioStore.playbackPosition > 0) {
+ // 从暂停位置继续播放
+ console.log('从暂停位置继续播放音频,位置:', audioStore.playbackPosition);
+ audioStore.soundInstance.seek(audioStore.playbackPosition);
+ audioStore.soundInstance.play();
+ } else {
+ // 重新开始播放
+ console.log('重新开始播放音频');
+ audioStore.soundInstance.play();
+ }
+ } else {
+ console.log('没有音频实例,尝试播放队列中的音频');
+ // 没有音频实例时,尝试播放队列中的音频
+ if (!isPlayingAudio.value && audioQueue.value.length > 0) {
+ playNextAudio();
+ }
+ }
+ };
+
+ // 预加载音频函数
+ const preloadAudio = (url, apiKey) => {
+ if (!url || !audioStore.isVoiceEnabled) {
+ audioPreloadStatus[apiKey].loaded = true;
+ return Promise.resolve();
+ }
+
+ return new Promise((resolve) => {
+ const audio = new Howl({
+ src: [url],
+ html5: true,
+ format: ["mp3", "acc"],
+ rate: 1.2,
+ preload: true,
+ onload: () => {
+ console.log(`音频${apiKey}预加载完成:`, url);
+ audioPreloadStatus[apiKey].loaded = true;
+ audioPreloadStatus[apiKey].url = url;
+ resolve();
+ },
+ onloaderror: (id, err) => {
+ console.error(`音频${apiKey}预加载失败:`, err);
+ audioPreloadStatus[apiKey].loaded = true; // 标记为已处理,避免阻塞
+ resolve();
+ }
+ });
+ });
+ };
+
+ // 检查第一个接口是否可以开始输出(文本和音频都准备好)
+ const canStartFirstOutput = () => {
+ return apiStatus.one.completed && audioPreloadStatus.one.loaded;
+ };
+
// 检查并按顺序执行代码的函数
const checkAndExecuteInOrder = () => {
- // 检查OneAPI
- if (apiStatus.one.completed && !apiStatus.one.executed) {
- apiStatus.one.executed = true;
- if (apiStatus.one.result) {
- console.log("执行OneAPI代码:", apiStatus.one.result);
- // 在这里添加OneAPI成功后需要执行的代码
- // 删除正在为您生成信息
- chatStore.messages.pop();
- // 添加报告头和时间
- addTypingTask(
- {
- sender: "ai",
- class: "title1",
- type: "title1",
- content: codeData.value.name + "全景作战报告",
- date: moment().format("DD/MM/YYYY"),
- },
- "",
- 50
- );
+ // 检查OneAPI - 只有当文本和音频都准备好时才开始输出
+ if (canStartFirstOutput() && !apiStatus.one.executed) {
+ apiStatus.one.executed = true;
+ if (apiStatus.one.result) {
+ console.log("执行OneAPI代码(文本和音频同步开始):", apiStatus.one.result);
+
+ // 将第一个音频添加到播放队列
+ if (audioPreloadStatus.one.url) {
+ addToAudioQueue(audioPreloadStatus.one.url, "第一个");
+ }
+
+ // 在这里添加OneAPI成功后需要执行的代码
+ // 删除正在为您生成信息
+ chatStore.messages.pop();
+ // 添加报告头和时间
+ addTypingTask(
+ {
+ sender: "ai",
+ class: "title1",
+ type: "title1",
+ content: codeData.value.name + "全景作战报告",
+ date: moment().format("DD/MM/YYYY"),
+ },
+ "",
+ 50
+ );
// chatStore.messages.push({
// sender: "ai",
// class: "title1",
@@ -690,7 +870,7 @@ watch(
// }
// }, 50); // 调整速度为50ms/字符
- addTypingTask(aiMessage1, ["", ac1], 50);
+ addTypingTask(aiMessage1, ["", ac1], 130);
// chatStore.messages.push({
// sender: "ai",
@@ -866,6 +1046,12 @@ watch(
apiStatus.two.executed = true;
if (apiStatus.two.result) {
console.log("执行TwoAPI代码:", apiStatus.two.result);
+
+ // 将第二个音频添加到播放队列
+ if (audioPreloadStatus.two.url) {
+ addToAudioQueue(audioPreloadStatus.two.url, "第二个");
+ }
+
// 在这里添加TwoAPI成功后需要执行的代码
// 添加标题2
addTypingTask(
@@ -918,7 +1104,7 @@ watch(
// aiMessage2.isTyping = false;
// }
// }, 50); // 调整速度为50ms/字符
- addTypingTask(aiMessage2, ["", ac2], 50);
+ addTypingTask(aiMessage2, ["", ac2], 130);
// chatStore.messages.push({
// sender: "ai",
@@ -938,6 +1124,12 @@ watch(
apiStatus.three.executed = true;
if (apiStatus.three.result) {
console.log("执行ThreeAPI代码:", apiStatus.three.result);
+
+ // 将第三个音频添加到播放队列
+ if (audioPreloadStatus.three.url) {
+ addToAudioQueue(audioPreloadStatus.three.url, "第三个");
+ }
+
// 在这里添加ThreeAPI成功后需要执行的代码
// 添加标题3-2
addTypingTask(
@@ -994,7 +1186,7 @@ watch(
// }
// }, 50); // 调整速度为50ms/字符
- addTypingTask(aiMessage3, [ac31, ac32], 50);
+ addTypingTask(aiMessage3, [ac31, ac32], 180);
// chatStore.messages.push({
// sender: "ai",
@@ -1075,7 +1267,7 @@ watch(
addTypingTask(
aiMessage4,
[ac41, ac42, ac43, ac44, ac45, ac46, ac47, ac48],
- 50
+ 180
);
// chatStore.messages.push({
@@ -1096,6 +1288,12 @@ watch(
apiStatus.four.executed = true;
if (apiStatus.four.result) {
console.log("执行FourAPI代码:", apiStatus.four.result);
+
+ // 将第四个音频添加到播放队列
+ if (audioPreloadStatus.four.url) {
+ addToAudioQueue(audioPreloadStatus.four.url, "第四个");
+ }
+
// 在这里添加FourAPI成功后需要执行的代码
// 添加标题3-4
addTypingTask(
@@ -1153,7 +1351,7 @@ watch(
// }
// }, 50); // 调整速度为50ms/字符
- addTypingTask(aiMessage5, [ac51, ac52, ac53, ac54], 50);
+ addTypingTask(aiMessage5, [ac51, ac52, ac53, ac54], 180);
// chatStore.messages.push({
// sender: "ai",
@@ -1184,7 +1382,7 @@ watch(
// }
// }, 50); // 调整速度为50ms/字符
- addTypingTask(aiMessage6, ["", ac6], 100);
+ addTypingTask(aiMessage6, ["", ac6], 180);
// chatStore.messages.push({
// sender: "ai",
@@ -1203,47 +1401,34 @@ watch(
apiStatus.four.completed &&
apiStatus.four.executed
) {
- console.log("所有API已完成,开始收集音频URL");
- // 收集所有音频URL
+ console.log("所有API已完成,开始收集预加载的音频URL");
+ // 收集所有预加载的音频URL
const audioUrls = [];
- console.log("API返回结果检查:");
- console.log("result21:", result21);
- console.log("result22:", result22);
- console.log("result23:", result23);
- console.log("result24:", result24);
+ console.log("预加载音频状态检查:");
+ console.log("audioPreloadStatus:", audioPreloadStatus);
- if (result21?.data?.url) {
- console.log("添加result21音频URL:", result21.data.url);
- audioUrls.push(result21.data.url.trim());
+ if (audioPreloadStatus.one.url) {
+ console.log("添加预加载音频URL one:", audioPreloadStatus.one.url);
+ audioUrls.push(audioPreloadStatus.one.url);
}
- if (result22?.data?.url) {
- console.log("添加result22音频URL:", result22.data.url);
- audioUrls.push(result22.data.url.trim());
+ if (audioPreloadStatus.two.url) {
+ console.log("添加预加载音频URL two:", audioPreloadStatus.two.url);
+ audioUrls.push(audioPreloadStatus.two.url);
}
- if (result23?.data?.url) {
- console.log("添加result23音频URL:", result23.data.url);
- audioUrls.push(result23.data.url.trim());
+ if (audioPreloadStatus.three.url) {
+ console.log("添加预加载音频URL three:", audioPreloadStatus.three.url);
+ audioUrls.push(audioPreloadStatus.three.url);
}
- if (result24?.data?.url) {
- console.log("添加result24音频URL:", result24.data.url);
- audioUrls.push(result24.data.url.trim());
+ if (audioPreloadStatus.four.url) {
+ console.log("添加预加载音频URL four:", audioPreloadStatus.four.url);
+ audioUrls.push(audioPreloadStatus.four.url);
}
- console.log("收集到的音频URLs:", audioUrls);
+ console.log("收集到的预加载音频URLs:", audioUrls);
console.log("语音是否启用:", audioStore.isVoiceEnabled);
- // 开始轮流播放音频
- if (audioUrls.length > 0 && audioStore.isVoiceEnabled) {
- console.log("开始播放音频序列");
- playAudioSequence(audioUrls);
- } else {
- console.log(
- "跳过音频播放 - audioUrls长度:",
- audioUrls.length,
- "语音启用状态:",
- audioStore.isVoiceEnabled
- );
- }
+ // 音频播放逻辑已移至各个接口的执行代码中
+ console.log("所有接口执行完成,音频已在各接口中单独播放");
}
};
@@ -1255,12 +1440,20 @@ watch(
apiStatus.one.completed = true;
apiStatus.one.result = result21;
+ // 预加载第一个接口的音频
+ if (result21?.data?.url) {
+ await preloadAudio(result21.data.url.trim(), 'one');
+ } else {
+ audioPreloadStatus.one.loaded = true;
+ }
+
// 检查是否可以执行
checkAndExecuteInOrder();
} catch (error) {
console.error("OneAPI失败:", error);
apiStatus.one.completed = true;
apiStatus.one.error = error;
+ audioPreloadStatus.one.loaded = true; // 失败时也标记为已处理
// 即使失败也要检查后续执行
checkAndExecuteInOrder();
}
@@ -1274,12 +1467,20 @@ watch(
apiStatus.two.completed = true;
apiStatus.two.result = result22;
+ // 预加载第二个接口的音频
+ if (result22?.data?.url) {
+ await preloadAudio(result22.data.url.trim(), 'two');
+ } else {
+ audioPreloadStatus.two.loaded = true;
+ }
+
// 检查是否可以执行
checkAndExecuteInOrder();
} catch (error) {
console.error("TwoAPI失败:", error);
apiStatus.two.completed = true;
apiStatus.two.error = error;
+ audioPreloadStatus.two.loaded = true;
checkAndExecuteInOrder();
}
};
@@ -1292,12 +1493,20 @@ watch(
apiStatus.three.completed = true;
apiStatus.three.result = result23;
+ // 预加载第三个接口的音频
+ if (result23?.data?.url) {
+ await preloadAudio(result23.data.url.trim(), 'three');
+ } else {
+ audioPreloadStatus.three.loaded = true;
+ }
+
// 检查是否可以执行
checkAndExecuteInOrder();
} catch (error) {
console.error("ThreeAPI失败:", error);
apiStatus.three.completed = true;
apiStatus.three.error = error;
+ audioPreloadStatus.three.loaded = true;
checkAndExecuteInOrder();
}
};
@@ -1310,12 +1519,20 @@ watch(
apiStatus.four.completed = true;
apiStatus.four.result = result24;
+ // 预加载第四个接口的音频
+ if (result24?.data?.url) {
+ await preloadAudio(result24.data.url.trim(), 'four');
+ } else {
+ audioPreloadStatus.four.loaded = true;
+ }
+
// 检查是否可以执行
checkAndExecuteInOrder();
} catch (error) {
console.error("FourAPI失败:", error);
apiStatus.four.completed = true;
apiStatus.four.error = error;
+ audioPreloadStatus.four.loaded = true;
checkAndExecuteInOrder();
}
};
diff --git a/src/views/AiEmotion.vue b/src/views/AiEmotion.vue
index c0be8d2..ca207e3 100644
--- a/src/views/AiEmotion.vue
+++ b/src/views/AiEmotion.vue
@@ -20,10 +20,6 @@
-
-
-