|
@@ -152,8 +152,10 @@ const _sfc_main = {
|
|
|
// 标记是否有待处理的自动跳转
|
|
|
hasTriedFallbackMethod: false,
|
|
|
// 标记是否尝试过备选方法播放音频
|
|
|
- hasShownTextFallbackToast: false
|
|
|
+ hasShownTextFallbackToast: false,
|
|
|
// 标记是否已显示文本回退提示
|
|
|
+ showNextButton: false
|
|
|
+ // 添加一个变量控制按钮显示
|
|
|
};
|
|
|
},
|
|
|
onLoad(options) {
|
|
@@ -1496,42 +1498,25 @@ const _sfc_main = {
|
|
|
},
|
|
|
// 修改 navigateToNextPage 方法
|
|
|
navigateToNextPage() {
|
|
|
- console.log("准备导航到下一个页面");
|
|
|
- if (this.isPlayingAiVoice) {
|
|
|
- console.log("AI语音正在播放,等待播放完成后再跳转");
|
|
|
- return;
|
|
|
- }
|
|
|
- console.log("导航到下一个页面");
|
|
|
- try {
|
|
|
- const currentJobDetail = common_vendor.index.getStorageSync("selectedJob");
|
|
|
- const jobId = currentJobDetail ? JSON.parse(currentJobDetail).id : null;
|
|
|
- if (jobId === 9 || jobId === 10) {
|
|
|
- common_vendor.index.navigateTo({
|
|
|
- url: "/pages/success/success",
|
|
|
- success: () => {
|
|
|
- console.log("成功跳转到成功页面");
|
|
|
- },
|
|
|
- fail: (err) => {
|
|
|
- console.error("跳转失败:", err);
|
|
|
- this.handleNavigationFailure();
|
|
|
- }
|
|
|
- });
|
|
|
- return;
|
|
|
- }
|
|
|
- } catch (e) {
|
|
|
- console.error("解析 selectedJob 失败:", e);
|
|
|
- }
|
|
|
- common_vendor.index.navigateTo({
|
|
|
- url: "/pages/success/success",
|
|
|
- //'/pages/posture-guide/posture-guide?uploading=' + (this.uploadQueue.length > 0 ? 'true' : 'false'),
|
|
|
- success: () => {
|
|
|
- console.log("成功跳转到结果页面");
|
|
|
- },
|
|
|
- fail: (err) => {
|
|
|
- console.error("跳转失败:", err);
|
|
|
- this.handleNavigationFailure();
|
|
|
- }
|
|
|
- });
|
|
|
+ console.log("执行页面跳转");
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
+ this.currentSubtitle = "";
|
|
|
+ setTimeout(() => {
|
|
|
+ common_vendor.index.navigateTo({
|
|
|
+ url: "/pages/success/success",
|
|
|
+ success: () => {
|
|
|
+ console.log("页面跳转成功");
|
|
|
+ },
|
|
|
+ fail: (err) => {
|
|
|
+ console.error("页面跳转失败:", err);
|
|
|
+ common_vendor.index.showToast({
|
|
|
+ title: "页面跳转失败",
|
|
|
+ icon: "none",
|
|
|
+ duration: 2e3
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }, 100);
|
|
|
},
|
|
|
// 添加处理导航失败的方法
|
|
|
handleNavigationFailure() {
|
|
@@ -2065,7 +2050,7 @@ const _sfc_main = {
|
|
|
this.showContinueQuestionOptions();
|
|
|
},
|
|
|
// 添加新方法:播放AI语音
|
|
|
- playAiVoice() {
|
|
|
+ async playAiVoice() {
|
|
|
console.log("开始播放AI语音:", this.aiVoiceUrl);
|
|
|
this.hasShownTextFallbackToast = false;
|
|
|
this.isPlayingAiVoice = true;
|
|
@@ -2077,19 +2062,25 @@ const _sfc_main = {
|
|
|
this.useTextFallbackAndNavigate();
|
|
|
return;
|
|
|
}
|
|
|
- const systemInfo = common_vendor.index.getSystemInfoSync();
|
|
|
- const isMiniProgram = systemInfo.uniPlatform && systemInfo.uniPlatform.startsWith("mp-");
|
|
|
- const isIOS = systemInfo.platform === "ios";
|
|
|
- if (isMiniProgram) {
|
|
|
- if (isIOS) {
|
|
|
- this.playIOSMiniProgramAudio();
|
|
|
+ try {
|
|
|
+ const systemInfo = common_vendor.index.getSystemInfoSync();
|
|
|
+ const isMiniProgram = systemInfo.uniPlatform && systemInfo.uniPlatform.startsWith("mp-");
|
|
|
+ const isIOS = systemInfo.platform === "ios";
|
|
|
+ if (isMiniProgram) {
|
|
|
+ if (isIOS) {
|
|
|
+ await this.playIOSMiniProgramAudio();
|
|
|
+ } else {
|
|
|
+ await this.playMiniProgramAudio();
|
|
|
+ }
|
|
|
+ } else if (isIOS) {
|
|
|
+ await this.playAiVoiceForIOS();
|
|
|
} else {
|
|
|
- this.playMiniProgramAudio();
|
|
|
+ await this.playAiVoiceForAndroid();
|
|
|
}
|
|
|
- } else if (isIOS) {
|
|
|
- this.playAiVoiceForIOS();
|
|
|
- } else {
|
|
|
- this.playAiVoiceForAndroid();
|
|
|
+ this.navigateToNextPage();
|
|
|
+ } catch (error) {
|
|
|
+ console.error("音频播放失败:", error);
|
|
|
+ this.useTextFallbackAndNavigate();
|
|
|
}
|
|
|
},
|
|
|
// 新增方法:文本回退并导航
|
|
@@ -2127,91 +2118,169 @@ const _sfc_main = {
|
|
|
},
|
|
|
// 修改 playMiniProgramAudio 方法
|
|
|
playMiniProgramAudio() {
|
|
|
- console.log("使用小程序原生音频API播放:", this.aiVoiceUrl);
|
|
|
- try {
|
|
|
- const audioContext = common_vendor.wx$1.createInnerAudioContext();
|
|
|
- audioContext.autoplay = true;
|
|
|
- audioContext.src = this.aiVoiceUrl;
|
|
|
- audioContext.onPlay(() => {
|
|
|
- console.log("AI语音开始播放");
|
|
|
- this.currentSubtitle = this.aiText;
|
|
|
- });
|
|
|
- audioContext.onEnded(() => {
|
|
|
- console.log("AI语音播放结束");
|
|
|
- this.isPlayingAiVoice = false;
|
|
|
- this.currentSubtitle = "";
|
|
|
- audioContext.destroy();
|
|
|
- this.navigateToNextPage();
|
|
|
- });
|
|
|
- audioContext.onError((err) => {
|
|
|
- console.error("AI语音播放错误:", err);
|
|
|
- audioContext.destroy();
|
|
|
- this.useTextFallbackAndNavigate();
|
|
|
- });
|
|
|
- setTimeout(() => {
|
|
|
- if (this.isPlayingAiVoice) {
|
|
|
- console.warn("音频播放超时,使用文本回退");
|
|
|
- this.useTextFallbackAndNavigate();
|
|
|
- }
|
|
|
- }, 5e3);
|
|
|
- } catch (e) {
|
|
|
- console.error("小程序播放AI语音失败:", e);
|
|
|
- this.useTextFallbackAndNavigate();
|
|
|
- }
|
|
|
+ return new Promise(async (resolve, reject) => {
|
|
|
+ try {
|
|
|
+ common_vendor.index.showLoading({
|
|
|
+ title: "音频加载中...",
|
|
|
+ mask: true
|
|
|
+ });
|
|
|
+ const localAudioPath = await this.preloadAudio(this.aiVoiceUrl);
|
|
|
+ common_vendor.index.hideLoading();
|
|
|
+ const audioContext = common_vendor.wx$1.createInnerAudioContext();
|
|
|
+ audioContext.src = localAudioPath;
|
|
|
+ audioContext.autoplay = true;
|
|
|
+ audioContext.bufferSize = 4096;
|
|
|
+ let hasStarted = false;
|
|
|
+ let hasError = false;
|
|
|
+ audioContext.onPlay(() => {
|
|
|
+ console.log("AI语音开始播放");
|
|
|
+ hasStarted = true;
|
|
|
+ this.currentSubtitle = this.aiText;
|
|
|
+ });
|
|
|
+ audioContext.onEnded(() => {
|
|
|
+ console.log("AI语音播放结束");
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
+ this.currentSubtitle = "";
|
|
|
+ audioContext.destroy();
|
|
|
+ if (!hasError) {
|
|
|
+ console.log("准备跳转到下一页");
|
|
|
+ this.navigateToNextPage();
|
|
|
+ resolve();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ audioContext.onStop(() => {
|
|
|
+ console.log("AI语音播放停止");
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
+ this.currentSubtitle = "";
|
|
|
+ audioContext.destroy();
|
|
|
+ if (!hasError) {
|
|
|
+ console.log("播放停止,准备跳转到下一页");
|
|
|
+ this.navigateToNextPage();
|
|
|
+ resolve();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ audioContext.onError((err) => {
|
|
|
+ hasError = true;
|
|
|
+ console.error("AI语音播放错误:", err);
|
|
|
+ audioContext.destroy();
|
|
|
+ common_vendor.index.showToast({
|
|
|
+ title: "音频播放异常,将显示文字",
|
|
|
+ icon: "none",
|
|
|
+ duration: 2e3
|
|
|
+ });
|
|
|
+ if (this.aiVoiceUrl.endsWith(".mp3")) {
|
|
|
+ const wavUrl = this.aiVoiceUrl.replace(".mp3", ".wav");
|
|
|
+ console.log("尝试使用WAV格式:", wavUrl);
|
|
|
+ this.aiVoiceUrl = wavUrl;
|
|
|
+ this.playMiniProgramAudio().then(resolve).catch(reject);
|
|
|
+ } else {
|
|
|
+ reject(err);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ setTimeout(() => {
|
|
|
+ if (!hasStarted && !hasError) {
|
|
|
+ console.error("音频播放启动超时");
|
|
|
+ audioContext.destroy();
|
|
|
+ reject(new Error("音频播放启动超时"));
|
|
|
+ }
|
|
|
+ }, 5e3);
|
|
|
+ } catch (error) {
|
|
|
+ common_vendor.index.hideLoading();
|
|
|
+ console.error("音频播放初始化失败:", error);
|
|
|
+ reject(error);
|
|
|
+ }
|
|
|
+ });
|
|
|
},
|
|
|
// 新增方法:导航到下一页
|
|
|
navigateToNextPage() {
|
|
|
- console.log("准备导航到下一页");
|
|
|
- common_vendor.index.navigateTo({
|
|
|
- url: "/pages/success/success",
|
|
|
- //'/pages/posture-guide/posture-guide',
|
|
|
- fail: (err) => {
|
|
|
- console.error("导航失败:", err);
|
|
|
- common_vendor.index.showToast({
|
|
|
- title: "页面跳转失败",
|
|
|
- icon: "none",
|
|
|
- duration: 2e3
|
|
|
+ console.log("执行页面跳转");
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
+ this.currentSubtitle = "";
|
|
|
+ setTimeout(() => {
|
|
|
+ common_vendor.index.navigateTo({
|
|
|
+ url: "/pages/success/success",
|
|
|
+ success: () => {
|
|
|
+ console.log("页面跳转成功");
|
|
|
+ },
|
|
|
+ fail: (err) => {
|
|
|
+ console.error("页面跳转失败:", err);
|
|
|
+ common_vendor.index.showToast({
|
|
|
+ title: "页面跳转失败",
|
|
|
+ icon: "none",
|
|
|
+ duration: 2e3
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }, 100);
|
|
|
+ },
|
|
|
+ // 新增方法:专门处理iOS小程序音频播放
|
|
|
+ playIOSMiniProgramAudio() {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ try {
|
|
|
+ const audioContext = common_vendor.wx$1.createInnerAudioContext();
|
|
|
+ audioContext.src = this.aiVoiceUrl;
|
|
|
+ audioContext.autoplay = true;
|
|
|
+ audioContext.onPlay(() => {
|
|
|
+ console.log("iOS小程序音频开始播放");
|
|
|
});
|
|
|
+ audioContext.onEnded(() => {
|
|
|
+ console.log("iOS小程序音频播放完成");
|
|
|
+ audioContext.destroy();
|
|
|
+ resolve();
|
|
|
+ });
|
|
|
+ audioContext.onError((err) => {
|
|
|
+ console.error("iOS小程序音频播放错误:", err);
|
|
|
+ audioContext.destroy();
|
|
|
+ reject(err);
|
|
|
+ });
|
|
|
+ } catch (error) {
|
|
|
+ reject(error);
|
|
|
}
|
|
|
});
|
|
|
},
|
|
|
- // 新增方法:专门处理iOS小程序音频播放
|
|
|
- playIOSMiniProgramAudio() {
|
|
|
- console.log("iOS小程序环境:使用增强的音频处理方法");
|
|
|
- this.hasShownTextFallbackToast = false;
|
|
|
- try {
|
|
|
- const audioContext = common_vendor.wx$1.createInnerAudioContext();
|
|
|
- audioContext.autoplay = false;
|
|
|
- audioContext.obeyMuteSwitch = true;
|
|
|
- audioContext.volume = 1;
|
|
|
- audioContext.onPlay(() => {
|
|
|
- console.log("iOS小程序音频开始播放");
|
|
|
- this.currentSubtitle = this.aiText;
|
|
|
- });
|
|
|
- audioContext.onEnded(() => {
|
|
|
- console.log("iOS小程序音频播放结束");
|
|
|
- this.handleIOSAudioComplete(audioContext);
|
|
|
- });
|
|
|
- audioContext.onStop(() => {
|
|
|
- console.log("iOS小程序音频播放停止");
|
|
|
- this.handleIOSAudioComplete(audioContext);
|
|
|
- });
|
|
|
- audioContext.onError((err) => {
|
|
|
- console.error("iOS小程序音频播放错误:", err);
|
|
|
- this.handleIOSMiniProgramError(audioContext, err);
|
|
|
- });
|
|
|
- this.preloadIOSMiniProgramAudio(this.aiVoiceUrl).then((localPath) => {
|
|
|
- console.log("iOS小程序音频预下载成功:", localPath);
|
|
|
- audioContext.src = localPath;
|
|
|
- audioContext.play();
|
|
|
- }).catch((error) => {
|
|
|
- console.error("iOS小程序音频预下载失败:", error);
|
|
|
- this.fallbackIOSMiniProgramPlay(audioContext);
|
|
|
- });
|
|
|
- } catch (e) {
|
|
|
- console.error("iOS小程序音频初始化失败:", e);
|
|
|
- this.useIOSTextFallback();
|
|
|
- }
|
|
|
+ playAiVoiceForIOS() {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ try {
|
|
|
+ const audioContext = new Audio();
|
|
|
+ audioContext.src = this.aiVoiceUrl;
|
|
|
+ audioContext.autoplay = true;
|
|
|
+ audioContext.addEventListener("play", () => {
|
|
|
+ console.log("iOS音频开始播放");
|
|
|
+ });
|
|
|
+ audioContext.addEventListener("ended", () => {
|
|
|
+ console.log("iOS音频播放完成");
|
|
|
+ resolve();
|
|
|
+ });
|
|
|
+ audioContext.addEventListener("error", (err) => {
|
|
|
+ console.error("iOS音频播放错误:", err);
|
|
|
+ reject(err);
|
|
|
+ });
|
|
|
+ } catch (error) {
|
|
|
+ reject(error);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ playAiVoiceForAndroid() {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ try {
|
|
|
+ const audioContext = new Audio();
|
|
|
+ audioContext.src = this.aiVoiceUrl;
|
|
|
+ audioContext.autoplay = true;
|
|
|
+ audioContext.addEventListener("play", () => {
|
|
|
+ console.log("Android音频开始播放");
|
|
|
+ });
|
|
|
+ audioContext.addEventListener("ended", () => {
|
|
|
+ console.log("Android音频播放完成");
|
|
|
+ resolve();
|
|
|
+ });
|
|
|
+ audioContext.addEventListener("error", (err) => {
|
|
|
+ console.error("Android音频播放错误:", err);
|
|
|
+ reject(err);
|
|
|
+ });
|
|
|
+ } catch (error) {
|
|
|
+ reject(error);
|
|
|
+ }
|
|
|
+ });
|
|
|
},
|
|
|
// 新增方法:iOS小程序音频预下载
|
|
|
preloadIOSMiniProgramAudio(audioUrl) {
|
|
@@ -2328,12 +2397,12 @@ const _sfc_main = {
|
|
|
this.hasShownTextFallbackToast = true;
|
|
|
}
|
|
|
this.currentSubtitle = this.aiText || "抱歉,AI回复内容加载失败";
|
|
|
- const textLength = this.aiText ? this.aiText.length : 20;
|
|
|
- const readingTime = Math.max(5e3, Math.min(textLength * 100, 15e3));
|
|
|
- console.log(`文本长度: ${textLength}, 预计阅读时间: ${readingTime}ms`);
|
|
|
- setTimeout(() => {
|
|
|
- this.handleIOSAudioComplete(null);
|
|
|
- }, readingTime);
|
|
|
+ this.showNextButton = true;
|
|
|
+ },
|
|
|
+ // 添加处理继续按钮点击的方法
|
|
|
+ handleNextButtonClick() {
|
|
|
+ this.showNextButton = false;
|
|
|
+ this.handleIOSAudioComplete(null);
|
|
|
},
|
|
|
// 添加新方法:iOS音频播放完成处理
|
|
|
handleIOSAudioPlaybackComplete() {
|
|
@@ -2426,60 +2495,113 @@ const _sfc_main = {
|
|
|
}
|
|
|
},
|
|
|
// 修改 playMiniProgramAudio 方法,添加iOS特殊处理
|
|
|
- playMiniProgramAudio() {
|
|
|
- console.log("使用小程序原生音频API播放:", this.aiVoiceUrl);
|
|
|
- this.isPlayingAiVoice = true;
|
|
|
- this.showContinueQuestionButton = false;
|
|
|
- this.showEndInterviewButton = false;
|
|
|
- if (!this.aiVoiceUrl || this.aiVoiceUrl.trim() === "") {
|
|
|
- console.error("无效的音频URL");
|
|
|
- this.handleAudioPlaybackFailure();
|
|
|
- return;
|
|
|
- }
|
|
|
- const systemInfo = common_vendor.index.getSystemInfoSync();
|
|
|
- const isIOS = systemInfo.platform === "ios";
|
|
|
- if (isIOS) {
|
|
|
- this.playMiniProgramAudioForIOS();
|
|
|
- return;
|
|
|
- }
|
|
|
- try {
|
|
|
- const audioContext = common_vendor.wx$1.createInnerAudioContext();
|
|
|
- audioContext.autoplay = false;
|
|
|
- audioContext.obeyMuteSwitch = false;
|
|
|
- audioContext.onPlay(() => {
|
|
|
- console.log("AI语音开始播放");
|
|
|
- });
|
|
|
- audioContext.onEnded(() => {
|
|
|
- console.log("AI语音播放结束");
|
|
|
- this.isPlayingAiVoice = false;
|
|
|
- this.currentSubtitle = "";
|
|
|
- audioContext.destroy();
|
|
|
- this.showContinueQuestionOptions();
|
|
|
- });
|
|
|
- audioContext.onError((err) => {
|
|
|
- console.error("AI语音播放错误:", err);
|
|
|
- this.isPlayingAiVoice = false;
|
|
|
- this.currentSubtitle = "";
|
|
|
- audioContext.destroy();
|
|
|
- this.showContinueQuestionOptions();
|
|
|
- });
|
|
|
- audioContext.src = this.aiVoiceUrl;
|
|
|
- const playTimeout = setTimeout(() => {
|
|
|
- if (this.isPlayingAiVoice) {
|
|
|
- console.warn("小程序音频播放超时,尝试备选方法");
|
|
|
- this.tryMiniProgramFallbackAudioPlay();
|
|
|
+ /* playMiniProgramAudio() {
|
|
|
+ console.log('使用小程序原生音频API播放:', this.aiVoiceUrl);
|
|
|
+
|
|
|
+ // 标记正在播放AI语音
|
|
|
+ this.isPlayingAiVoice = true;
|
|
|
+
|
|
|
+ // 确保在播放期间不显示继续提问按钮
|
|
|
+ this.showContinueQuestionButton = false;
|
|
|
+ this.showEndInterviewButton = false;
|
|
|
+
|
|
|
+ // 检查音频URL是否有效
|
|
|
+ if (!this.aiVoiceUrl || this.aiVoiceUrl.trim() === '') {
|
|
|
+ console.error('无效的音频URL');
|
|
|
+ this.handleAudioPlaybackFailure();
|
|
|
+ return;
|
|
|
}
|
|
|
- }, 5e3);
|
|
|
- setTimeout(() => {
|
|
|
- audioContext.play();
|
|
|
- clearTimeout(playTimeout);
|
|
|
- }, 300);
|
|
|
- } catch (e) {
|
|
|
- console.error("小程序播放AI语音时发生错误:", e);
|
|
|
- this.isPlayingAiVoice = false;
|
|
|
- this.handleAudioPlaybackFailure();
|
|
|
- }
|
|
|
- },
|
|
|
+
|
|
|
+ // 检查平台
|
|
|
+ const systemInfo = uni.getSystemInfoSync();
|
|
|
+ const isIOS = systemInfo.platform === 'ios';
|
|
|
+
|
|
|
+ // iOS小程序特殊处理
|
|
|
+ if (isIOS) {
|
|
|
+ this.playMiniProgramAudioForIOS();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 非iOS平台的原有逻辑
|
|
|
+ try {
|
|
|
+ // 使用wx.createInnerAudioContext API (微信小程序)
|
|
|
+ const audioContext = wx.createInnerAudioContext();
|
|
|
+
|
|
|
+ // 设置音频属性
|
|
|
+ audioContext.autoplay = false;
|
|
|
+ audioContext.obeyMuteSwitch = false; // 忽略静音开关
|
|
|
+
|
|
|
+ // 监听播放开始事件
|
|
|
+ audioContext.onPlay(() => {
|
|
|
+ console.log('AI语音开始播放');
|
|
|
+
|
|
|
+ // 显示正在播放提示
|
|
|
+ });
|
|
|
+
|
|
|
+ // 监听播放结束事件
|
|
|
+ audioContext.onEnded(() => {
|
|
|
+ console.log('AI语音播放结束');
|
|
|
+
|
|
|
+ // 标记播放结束
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
+
|
|
|
+ // 清空字幕
|
|
|
+ this.currentSubtitle = '';
|
|
|
+
|
|
|
+ // 销毁音频播放器
|
|
|
+ audioContext.destroy();
|
|
|
+
|
|
|
+ // 播放结束后显示继续提问选项,而不是直接跳转
|
|
|
+ this.showContinueQuestionOptions();
|
|
|
+ });
|
|
|
+
|
|
|
+ // 监听播放错误事件
|
|
|
+ audioContext.onError((err) => {
|
|
|
+ console.error('AI语音播放错误:', err);
|
|
|
+
|
|
|
+ // 标记播放结束
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
+
|
|
|
+ // 清空字幕
|
|
|
+ this.currentSubtitle = '';
|
|
|
+
|
|
|
+ // 销毁音频播放器
|
|
|
+ audioContext.destroy();
|
|
|
+
|
|
|
+ // 播放错误时也显示继续提问选项
|
|
|
+ this.showContinueQuestionOptions();
|
|
|
+ });
|
|
|
+
|
|
|
+ // 设置音频源
|
|
|
+ audioContext.src = this.aiVoiceUrl;
|
|
|
+
|
|
|
+ // 添加超时处理,如果5秒内没有开始播放,则认为出错
|
|
|
+ const playTimeout = setTimeout(() => {
|
|
|
+ if (this.isPlayingAiVoice) {
|
|
|
+ console.warn('小程序音频播放超时,尝试备选方法');
|
|
|
+ this.tryMiniProgramFallbackAudioPlay();
|
|
|
+ }
|
|
|
+ }, 5000);
|
|
|
+
|
|
|
+ // 延迟一小段时间再播放,确保src已经设置完成
|
|
|
+ setTimeout(() => {
|
|
|
+ audioContext.play();
|
|
|
+ // 播放开始后清除超时
|
|
|
+ clearTimeout(playTimeout);
|
|
|
+ }, 300);
|
|
|
+ } catch (e) {
|
|
|
+ console.error('小程序播放AI语音时发生错误:', e);
|
|
|
+
|
|
|
+ // 标记播放结束
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
+
|
|
|
+ // 显示错误提示
|
|
|
+
|
|
|
+
|
|
|
+ // 使用文本显示方式作为备选方案
|
|
|
+ this.handleAudioPlaybackFailure();
|
|
|
+ }
|
|
|
+ }, */
|
|
|
// 添加新方法:iOS小程序音频播放
|
|
|
playMiniProgramAudioForIOS() {
|
|
|
console.log("iOS小程序环境:开始播放AI语音");
|
|
@@ -2722,55 +2844,107 @@ const _sfc_main = {
|
|
|
});
|
|
|
},
|
|
|
// 添加一个新方法:使用小程序原生音频API
|
|
|
- playMiniProgramAudio() {
|
|
|
- console.log("使用小程序原生音频API播放:", this.aiVoiceUrl);
|
|
|
- this.isPlayingAiVoice = true;
|
|
|
- this.showContinueQuestionButton = false;
|
|
|
- this.showEndInterviewButton = false;
|
|
|
- if (!this.aiVoiceUrl || this.aiVoiceUrl.trim() === "") {
|
|
|
- console.error("无效的音频URL");
|
|
|
- this.isPlayingAiVoice = false;
|
|
|
- this.showContinueQuestionOptions();
|
|
|
- return;
|
|
|
- }
|
|
|
- try {
|
|
|
- const audioContext = common_vendor.wx$1.createInnerAudioContext();
|
|
|
- audioContext.autoplay = false;
|
|
|
- audioContext.obeyMuteSwitch = false;
|
|
|
- audioContext.onPlay(() => {
|
|
|
- console.log("AI语音开始播放");
|
|
|
- });
|
|
|
- audioContext.onEnded(() => {
|
|
|
- console.log("AI语音播放结束");
|
|
|
+ /* playMiniProgramAudio() {
|
|
|
+ console.log('使用小程序原生音频API播放:', this.aiVoiceUrl);
|
|
|
+
|
|
|
+ // 标记正在播放AI语音
|
|
|
+ this.isPlayingAiVoice = true;
|
|
|
+
|
|
|
+ // 确保在播放期间不显示继续提问按钮
|
|
|
+ this.showContinueQuestionButton = false;
|
|
|
+ this.showEndInterviewButton = false;
|
|
|
+
|
|
|
+ // 检查音频URL是否有效
|
|
|
+ if (!this.aiVoiceUrl || this.aiVoiceUrl.trim() === '') {
|
|
|
+ console.error('无效的音频URL');
|
|
|
+ // 显示错误提示
|
|
|
+
|
|
|
+ // 标记播放结束
|
|
|
this.isPlayingAiVoice = false;
|
|
|
- this.currentSubtitle = "";
|
|
|
- audioContext.destroy();
|
|
|
+
|
|
|
+ // 显示继续提问选项
|
|
|
this.showContinueQuestionOptions();
|
|
|
- });
|
|
|
- audioContext.onError((err) => {
|
|
|
- console.error("AI语音播放错误:", err);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 使用wx.createInnerAudioContext API (微信小程序)
|
|
|
+ const audioContext = wx.createInnerAudioContext();
|
|
|
+
|
|
|
+ // 设置音频属性
|
|
|
+ audioContext.autoplay = false;
|
|
|
+ audioContext.obeyMuteSwitch = false; // 忽略静音开关
|
|
|
+
|
|
|
+ // 监听播放开始事件
|
|
|
+ audioContext.onPlay(() => {
|
|
|
+ console.log('AI语音开始播放');
|
|
|
+
|
|
|
+ // 显示正在播放提
|
|
|
+ });
|
|
|
+
|
|
|
+ // 监听播放结束事件
|
|
|
+ audioContext.onEnded(() => {
|
|
|
+ console.log('AI语音播放结束');
|
|
|
+
|
|
|
+ // 标记播放结束
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
+
|
|
|
+ // 清空字幕
|
|
|
+ this.currentSubtitle = '';
|
|
|
+
|
|
|
+ // 销毁音频播放器
|
|
|
+ audioContext.destroy();
|
|
|
+
|
|
|
+ // 播放结束后显示继续提问选项,而不是直接跳转
|
|
|
+ this.showContinueQuestionOptions();
|
|
|
+ });
|
|
|
+
|
|
|
+ // 监听播放错误事件
|
|
|
+ audioContext.onError((err) => {
|
|
|
+ console.error('AI语音播放错误:', err);
|
|
|
+
|
|
|
+ // 标记播放结束
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
+
|
|
|
+ // 清空字幕
|
|
|
+ this.currentSubtitle = '';
|
|
|
+
|
|
|
+ // 销毁音频播放器
|
|
|
+ audioContext.destroy();
|
|
|
+
|
|
|
+ // 播放错误时也显示继续提问选项
|
|
|
+ this.showContinueQuestionOptions();
|
|
|
+ });
|
|
|
+
|
|
|
+ // 设置音频源
|
|
|
+ audioContext.src = this.aiVoiceUrl;
|
|
|
+
|
|
|
+ // 添加超时处理,如果5秒内没有开始播放,则认为出错
|
|
|
+ const playTimeout = setTimeout(() => {
|
|
|
+ if (this.isPlayingAiVoice) {
|
|
|
+ console.warn('小程序音频播放超时,尝试备选方法');
|
|
|
+ this.tryMiniProgramFallbackAudioPlay();
|
|
|
+ }
|
|
|
+ }, 5000);
|
|
|
+
|
|
|
+ // 延迟一小段时间再播放,确保src已经设置完成
|
|
|
+ setTimeout(() => {
|
|
|
+ audioContext.play();
|
|
|
+ // 播放开始后清除超时
|
|
|
+ clearTimeout(playTimeout);
|
|
|
+ }, 300);
|
|
|
+ } catch (e) {
|
|
|
+ console.error('小程序播放AI语音时发生错误:', e);
|
|
|
+
|
|
|
+ // 标记播放结束
|
|
|
this.isPlayingAiVoice = false;
|
|
|
- this.currentSubtitle = "";
|
|
|
- audioContext.destroy();
|
|
|
- this.showContinueQuestionOptions();
|
|
|
- });
|
|
|
- audioContext.src = this.aiVoiceUrl;
|
|
|
- const playTimeout = setTimeout(() => {
|
|
|
- if (this.isPlayingAiVoice) {
|
|
|
- console.warn("小程序音频播放超时,尝试备选方法");
|
|
|
- this.tryMiniProgramFallbackAudioPlay();
|
|
|
- }
|
|
|
- }, 5e3);
|
|
|
- setTimeout(() => {
|
|
|
- audioContext.play();
|
|
|
- clearTimeout(playTimeout);
|
|
|
- }, 300);
|
|
|
- } catch (e) {
|
|
|
- console.error("小程序播放AI语音时发生错误:", e);
|
|
|
- this.isPlayingAiVoice = false;
|
|
|
- this.handleAudioPlaybackFailure();
|
|
|
- }
|
|
|
- },
|
|
|
+
|
|
|
+ // 显示错误提示
|
|
|
+
|
|
|
+ // 使用文本显示方式作为备选方案
|
|
|
+ this.handleAudioPlaybackFailure();
|
|
|
+ }
|
|
|
+ }, */
|
|
|
// 添加新方法:小程序环境的备选音频播放方法
|
|
|
tryMiniProgramFallbackAudioPlay() {
|
|
|
console.log("使用小程序备选方法播放音频:", this.aiVoiceUrl);
|
|
@@ -2980,6 +3154,154 @@ const _sfc_main = {
|
|
|
setTimeout(() => {
|
|
|
this.navigateToNextPage();
|
|
|
}, readingTime);
|
|
|
+ },
|
|
|
+ // 添加音频预加载方法
|
|
|
+ preloadAudio(audioUrl) {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ console.log("开始预加载音频:", audioUrl);
|
|
|
+ const downloadTask = common_vendor.wx$1.downloadFile({
|
|
|
+ url: audioUrl,
|
|
|
+ success: (res) => {
|
|
|
+ if (res.statusCode === 200) {
|
|
|
+ console.log("音频文件下载成功,临时路径:", res.tempFilePath);
|
|
|
+ resolve(res.tempFilePath);
|
|
|
+ } else {
|
|
|
+ console.error("音频文件下载失败,状态码:", res.statusCode);
|
|
|
+ reject(new Error(`下载失败,状态码: ${res.statusCode}`));
|
|
|
+ }
|
|
|
+ },
|
|
|
+ fail: (error) => {
|
|
|
+ console.error("音频文件下载失败:", error);
|
|
|
+ reject(error);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ downloadTask.onProgressUpdate((res) => {
|
|
|
+ console.log("音频下载进度:", res.progress);
|
|
|
+ });
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 修改音频播放方法
|
|
|
+ playMiniProgramAudio() {
|
|
|
+ return new Promise(async (resolve, reject) => {
|
|
|
+ try {
|
|
|
+ common_vendor.index.showLoading({
|
|
|
+ title: "音频加载中...",
|
|
|
+ mask: true
|
|
|
+ });
|
|
|
+ const localAudioPath = await this.preloadAudio(this.aiVoiceUrl);
|
|
|
+ common_vendor.index.hideLoading();
|
|
|
+ const audioContext = common_vendor.wx$1.createInnerAudioContext();
|
|
|
+ audioContext.src = localAudioPath;
|
|
|
+ audioContext.autoplay = true;
|
|
|
+ audioContext.bufferSize = 4096;
|
|
|
+ let hasStarted = false;
|
|
|
+ let hasError = false;
|
|
|
+ audioContext.onPlay(() => {
|
|
|
+ console.log("AI语音开始播放");
|
|
|
+ hasStarted = true;
|
|
|
+ this.currentSubtitle = this.aiText;
|
|
|
+ });
|
|
|
+ audioContext.onEnded(() => {
|
|
|
+ console.log("AI语音播放结束");
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
+ this.currentSubtitle = "";
|
|
|
+ audioContext.destroy();
|
|
|
+ if (!hasError) {
|
|
|
+ console.log("准备跳转到下一页");
|
|
|
+ this.navigateToNextPage();
|
|
|
+ resolve();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ audioContext.onStop(() => {
|
|
|
+ console.log("AI语音播放停止");
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
+ this.currentSubtitle = "";
|
|
|
+ audioContext.destroy();
|
|
|
+ if (!hasError) {
|
|
|
+ console.log("播放停止,准备跳转到下一页");
|
|
|
+ this.navigateToNextPage();
|
|
|
+ resolve();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ audioContext.onError((err) => {
|
|
|
+ hasError = true;
|
|
|
+ console.error("AI语音播放错误:", err);
|
|
|
+ audioContext.destroy();
|
|
|
+ common_vendor.index.showToast({
|
|
|
+ title: "音频播放异常,将显示文字",
|
|
|
+ icon: "none",
|
|
|
+ duration: 2e3
|
|
|
+ });
|
|
|
+ if (this.aiVoiceUrl.endsWith(".mp3")) {
|
|
|
+ const wavUrl = this.aiVoiceUrl.replace(".mp3", ".wav");
|
|
|
+ console.log("尝试使用WAV格式:", wavUrl);
|
|
|
+ this.aiVoiceUrl = wavUrl;
|
|
|
+ this.playMiniProgramAudio().then(resolve).catch(reject);
|
|
|
+ } else {
|
|
|
+ reject(err);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ setTimeout(() => {
|
|
|
+ if (!hasStarted && !hasError) {
|
|
|
+ console.error("音频播放启动超时");
|
|
|
+ audioContext.destroy();
|
|
|
+ reject(new Error("音频播放启动超时"));
|
|
|
+ }
|
|
|
+ }, 5e3);
|
|
|
+ } catch (error) {
|
|
|
+ common_vendor.index.hideLoading();
|
|
|
+ console.error("音频播放初始化失败:", error);
|
|
|
+ reject(error);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 添加备选的音频播放方法
|
|
|
+ async playFallbackAudio() {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ try {
|
|
|
+ const audio = common_vendor.wx$1.createInnerAudioContext();
|
|
|
+ audio.volume = 1;
|
|
|
+ audio.playbackRate = 1;
|
|
|
+ audio.src = this.aiVoiceUrl;
|
|
|
+ audio.autoplay = true;
|
|
|
+ audio.onPlay(() => {
|
|
|
+ console.log("备选音频开始播放");
|
|
|
+ });
|
|
|
+ audio.onEnded(() => {
|
|
|
+ console.log("备选音频播放完成");
|
|
|
+ audio.destroy();
|
|
|
+ resolve();
|
|
|
+ });
|
|
|
+ audio.onError((err) => {
|
|
|
+ console.error("备选音频播放失败:", err);
|
|
|
+ audio.destroy();
|
|
|
+ reject(err);
|
|
|
+ });
|
|
|
+ } catch (error) {
|
|
|
+ reject(error);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ // 修改主音频播放方法
|
|
|
+ async playAiVoice() {
|
|
|
+ console.log("开始播放AI语音:", this.aiVoiceUrl);
|
|
|
+ this.isPlayingAiVoice = true;
|
|
|
+ this.currentSubtitle = this.aiText;
|
|
|
+ try {
|
|
|
+ await this.playMiniProgramAudio();
|
|
|
+ console.log("音频播放完成,准备跳转");
|
|
|
+ this.navigateToNextPage();
|
|
|
+ } catch (error) {
|
|
|
+ console.error("主要播放方法失败,尝试备选方法:", error);
|
|
|
+ try {
|
|
|
+ await this.playFallbackAudio();
|
|
|
+ console.log("备选音频播放完成,准备跳转");
|
|
|
+ this.navigateToNextPage();
|
|
|
+ } catch (fallbackError) {
|
|
|
+ console.error("备选播放方法也失败:", fallbackError);
|
|
|
+ this.useTextFallbackAndNavigate();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
};
|