|
@@ -144,14 +144,16 @@ const _sfc_main = {
|
|
// 控制"结束面试"按钮显示
|
|
// 控制"结束面试"按钮显示
|
|
questionRound: 0,
|
|
questionRound: 0,
|
|
// 当前提问轮次
|
|
// 当前提问轮次
|
|
- maxQuestionRounds: 2,
|
|
|
|
|
|
+ maxQuestionRounds: 1,
|
|
// 最大提问轮次(可配置)
|
|
// 最大提问轮次(可配置)
|
|
conversationHistory: [],
|
|
conversationHistory: [],
|
|
// 对话历史记录
|
|
// 对话历史记录
|
|
pendingAutoNavigation: false,
|
|
pendingAutoNavigation: false,
|
|
// 标记是否有待处理的自动跳转
|
|
// 标记是否有待处理的自动跳转
|
|
- hasTriedFallbackMethod: false
|
|
|
|
|
|
+ hasTriedFallbackMethod: false,
|
|
// 标记是否尝试过备选方法播放音频
|
|
// 标记是否尝试过备选方法播放音频
|
|
|
|
+ hasShownTextFallbackToast: false
|
|
|
|
+ // 标记是否已显示文本回退提示
|
|
};
|
|
};
|
|
},
|
|
},
|
|
onLoad(options) {
|
|
onLoad(options) {
|
|
@@ -1950,7 +1952,11 @@ const _sfc_main = {
|
|
// 修改为JSON格式
|
|
// 修改为JSON格式
|
|
},
|
|
},
|
|
success: (res) => {
|
|
success: (res) => {
|
|
- this.handleAiInteractionResponse(res.data);
|
|
|
|
|
|
+ if (res.statusCode === 200) {
|
|
|
|
+ this.handleAiInteractionResponse(res.data);
|
|
|
|
+ } else {
|
|
|
|
+ this.handleAiInteractionError(res.data);
|
|
|
|
+ }
|
|
},
|
|
},
|
|
fail: (err) => {
|
|
fail: (err) => {
|
|
this.handleAiInteractionError(err);
|
|
this.handleAiInteractionError(err);
|
|
@@ -1986,6 +1992,9 @@ const _sfc_main = {
|
|
// 添加处理AI交互响应的方法
|
|
// 添加处理AI交互响应的方法
|
|
handleAiInteractionResponse(data) {
|
|
handleAiInteractionResponse(data) {
|
|
console.log("AI语音交互接口响应:", data);
|
|
console.log("AI语音交互接口响应:", data);
|
|
|
|
+ const systemInfo = common_vendor.index.getSystemInfoSync();
|
|
|
|
+ const isIOS = systemInfo.platform === "ios";
|
|
|
|
+ this.isPlayingAiVoice = true;
|
|
common_vendor.index.hideLoading();
|
|
common_vendor.index.hideLoading();
|
|
this.hasTriedFallbackMethod = false;
|
|
this.hasTriedFallbackMethod = false;
|
|
if (data && data.success) {
|
|
if (data && data.success) {
|
|
@@ -2004,8 +2013,8 @@ const _sfc_main = {
|
|
this.aiVoiceUrl = aiVoiceUrl.startsWith("http") ? aiVoiceUrl : `${common_config.apiBaseUrl}${aiVoiceUrl}`;
|
|
this.aiVoiceUrl = aiVoiceUrl.startsWith("http") ? aiVoiceUrl : `${common_config.apiBaseUrl}${aiVoiceUrl}`;
|
|
console.log("AI语音URL:", this.aiVoiceUrl);
|
|
console.log("AI语音URL:", this.aiVoiceUrl);
|
|
this.currentSubtitle = this.aiText;
|
|
this.currentSubtitle = this.aiText;
|
|
- const systemInfo = common_vendor.index.getSystemInfoSync();
|
|
|
|
- const isMiniProgram = systemInfo.uniPlatform && systemInfo.uniPlatform.startsWith("mp-");
|
|
|
|
|
|
+ const systemInfo2 = common_vendor.index.getSystemInfoSync();
|
|
|
|
+ const isMiniProgram = systemInfo2.uniPlatform && systemInfo2.uniPlatform.startsWith("mp-");
|
|
const isUnsupportedFormat = this.checkUnsupportedAudioFormat(this.aiVoiceUrl);
|
|
const isUnsupportedFormat = this.checkUnsupportedAudioFormat(this.aiVoiceUrl);
|
|
if (isUnsupportedFormat && isMiniProgram) {
|
|
if (isUnsupportedFormat && isMiniProgram) {
|
|
console.warn("检测到小程序不支持的音频格式,直接使用文本显示");
|
|
console.warn("检测到小程序不支持的音频格式,直接使用文本显示");
|
|
@@ -2013,7 +2022,11 @@ const _sfc_main = {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
if (isMiniProgram) {
|
|
if (isMiniProgram) {
|
|
- this.playMiniProgramAudio();
|
|
|
|
|
|
+ if (isIOS) {
|
|
|
|
+ this.playIOSMiniProgramAudio();
|
|
|
|
+ } else {
|
|
|
|
+ this.playMiniProgramAudio();
|
|
|
|
+ }
|
|
} else {
|
|
} else {
|
|
this.playAiVoice();
|
|
this.playAiVoice();
|
|
}
|
|
}
|
|
@@ -2043,59 +2056,547 @@ const _sfc_main = {
|
|
// 添加新方法:播放AI语音
|
|
// 添加新方法:播放AI语音
|
|
playAiVoice() {
|
|
playAiVoice() {
|
|
console.log("开始播放AI语音:", this.aiVoiceUrl);
|
|
console.log("开始播放AI语音:", this.aiVoiceUrl);
|
|
|
|
+ this.hasShownTextFallbackToast = false;
|
|
this.isPlayingAiVoice = true;
|
|
this.isPlayingAiVoice = true;
|
|
this.showContinueQuestionButton = false;
|
|
this.showContinueQuestionButton = false;
|
|
this.showEndInterviewButton = false;
|
|
this.showEndInterviewButton = false;
|
|
|
|
+ this.currentSubtitle = this.aiText;
|
|
if (!this.aiVoiceUrl || this.aiVoiceUrl.trim() === "") {
|
|
if (!this.aiVoiceUrl || this.aiVoiceUrl.trim() === "") {
|
|
- console.error("无效的音频URL");
|
|
|
|
- this.handleAudioPlaybackFailure();
|
|
|
|
|
|
+ console.error("无效的音频URL,直接显示文本");
|
|
|
|
+ this.useTextFallbackAndNavigate();
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- try {
|
|
|
|
- if (this.aiAudioPlayer) {
|
|
|
|
|
|
+ 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();
|
|
|
|
+ } else {
|
|
|
|
+ this.playMiniProgramAudio();
|
|
|
|
+ }
|
|
|
|
+ } else if (isIOS) {
|
|
|
|
+ this.playAiVoiceForIOS();
|
|
|
|
+ } else {
|
|
|
|
+ this.playAiVoiceForAndroid();
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 新增方法:文本回退并导航
|
|
|
|
+ useTextFallbackAndNavigate() {
|
|
|
|
+ console.log("使用文本回退并准备导航");
|
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
|
+ if (!this.hasShownTextFallbackToast) {
|
|
|
|
+ this.hasShownTextFallbackToast = true;
|
|
|
|
+ common_vendor.index.showToast({
|
|
|
|
+ title: "为您显示文字回复",
|
|
|
|
+ icon: "none",
|
|
|
|
+ duration: 2e3
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ this.currentSubtitle = this.aiText || "抱歉,AI回复内容加载失败";
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ this.navigateToNextPage();
|
|
|
|
+ }, 5e3);
|
|
|
|
+ },
|
|
|
|
+ // 修改 handleIOSAudioPlaybackComplete 方法
|
|
|
|
+ handleIOSAudioPlaybackComplete() {
|
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ this.currentSubtitle = "";
|
|
|
|
+ }, 1e3);
|
|
|
|
+ if (this.aiAudioPlayer) {
|
|
|
|
+ try {
|
|
this.aiAudioPlayer.destroy();
|
|
this.aiAudioPlayer.destroy();
|
|
|
|
+ } catch (e) {
|
|
|
|
+ console.error("销毁iOS音频播放器失败:", e);
|
|
}
|
|
}
|
|
- this.aiAudioPlayer = common_vendor.index.createInnerAudioContext();
|
|
|
|
- this.aiAudioPlayer.autoplay = false;
|
|
|
|
- this.aiAudioPlayer.obeyMuteSwitch = false;
|
|
|
|
- this.aiAudioPlayer.onCanplay(() => {
|
|
|
|
- console.log("音频已加载完成,准备播放");
|
|
|
|
- const duration = this.aiAudioPlayer.duration;
|
|
|
|
- console.log("音频时长:", duration);
|
|
|
|
- this.aiAudioPlayer.play();
|
|
|
|
|
|
+ this.aiAudioPlayer = null;
|
|
|
|
+ }
|
|
|
|
+ this.navigateToNextPage();
|
|
|
|
+ },
|
|
|
|
+ // 修改 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;
|
|
});
|
|
});
|
|
- this.aiAudioPlayer.onTimeUpdate(() => {
|
|
|
|
- const currentTime = this.aiAudioPlayer.currentTime;
|
|
|
|
- const duration = this.aiAudioPlayer.duration;
|
|
|
|
- console.log(`播放进度: ${currentTime}/${duration}`);
|
|
|
|
- if (this.aiText) {
|
|
|
|
- const textProgress = Math.floor(currentTime / duration * this.aiText.length);
|
|
|
|
- this.currentSubtitle = this.aiText.substring(0, textProgress);
|
|
|
|
- }
|
|
|
|
|
|
+ audioContext.onEnded(() => {
|
|
|
|
+ console.log("AI语音播放结束");
|
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
|
+ this.currentSubtitle = "";
|
|
|
|
+ audioContext.destroy();
|
|
|
|
+ this.navigateToNextPage();
|
|
});
|
|
});
|
|
- this.aiAudioPlayer.onEnded(() => {
|
|
|
|
- console.log("AI语音播放完成");
|
|
|
|
|
|
+ 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();
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 新增方法:导航到下一页
|
|
|
|
+ navigateToNextPage() {
|
|
|
|
+ console.log("准备导航到下一页");
|
|
|
|
+ common_vendor.index.navigateTo({
|
|
|
|
+ url: "/pages/posture-guide/posture-guide",
|
|
|
|
+ fail: (err) => {
|
|
|
|
+ console.error("导航失败:", err);
|
|
|
|
+ common_vendor.index.showToast({
|
|
|
|
+ title: "页面跳转失败",
|
|
|
|
+ icon: "none",
|
|
|
|
+ duration: 2e3
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ // 新增方法:专门处理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;
|
|
this.currentSubtitle = this.aiText;
|
|
- setTimeout(() => {
|
|
|
|
- this.isPlayingAiVoice = false;
|
|
|
|
- this.currentSubtitle = "";
|
|
|
|
- if (this.aiAudioPlayer) {
|
|
|
|
- this.aiAudioPlayer.destroy();
|
|
|
|
- this.aiAudioPlayer = null;
|
|
|
|
|
|
+ common_vendor.index.showToast({
|
|
|
|
+ title: "正在播放AI回复",
|
|
|
|
+ icon: "none",
|
|
|
|
+ duration: 1500
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+ 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();
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 新增方法:iOS小程序音频预下载
|
|
|
|
+ preloadIOSMiniProgramAudio(audioUrl) {
|
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
|
+ console.log("开始预下载iOS小程序音频:", audioUrl);
|
|
|
|
+ common_vendor.index.downloadFile({
|
|
|
|
+ url: audioUrl,
|
|
|
|
+ timeout: 15e3,
|
|
|
|
+ // 15秒超时
|
|
|
|
+ success: (res) => {
|
|
|
|
+ if (res.statusCode === 200) {
|
|
|
|
+ console.log("iOS小程序音频下载成功:", res.tempFilePath);
|
|
|
|
+ resolve(res.tempFilePath);
|
|
|
|
+ } else {
|
|
|
|
+ console.error("iOS小程序音频下载失败,状态码:", res.statusCode);
|
|
|
|
+ reject(new Error(`下载失败,状态码: ${res.statusCode}`));
|
|
}
|
|
}
|
|
- this.showContinueQuestionOptions();
|
|
|
|
- this.checkPendingNavigation();
|
|
|
|
- }, 2e3);
|
|
|
|
|
|
+ },
|
|
|
|
+ fail: (err) => {
|
|
|
|
+ console.error("iOS小程序音频下载请求失败:", err);
|
|
|
|
+ reject(err);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+ },
|
|
|
|
+ // 新增方法:iOS小程序错误处理
|
|
|
|
+ handleIOSMiniProgramError(audioContext, error) {
|
|
|
|
+ console.error("处理iOS小程序音频错误:", error);
|
|
|
|
+ if (audioContext) {
|
|
|
|
+ try {
|
|
|
|
+ audioContext.destroy();
|
|
|
|
+ } catch (e) {
|
|
|
|
+ console.error("销毁音频播放器失败:", e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ let errorMessage = "音频播放异常,显示文字";
|
|
|
|
+ if (error.errMsg && error.errMsg.includes("-11850")) {
|
|
|
|
+ console.log("iOS小程序检测到系统音频错误(-11850)");
|
|
|
|
+ errorMessage = "系统音频服务暂停,显示文字";
|
|
|
|
+ } else if (error.errCode === 10002) {
|
|
|
|
+ console.log("iOS小程序检测到errCode:10002,网络或资源问题");
|
|
|
|
+ errorMessage = "音频加载中断,显示文字";
|
|
|
|
+ } else if (error.errCode === 10001) {
|
|
|
|
+ console.log("iOS小程序检测到errCode:10001,系统错误");
|
|
|
|
+ errorMessage = "系统音频错误,显示文字";
|
|
|
|
+ } else if (error.errCode === 10003) {
|
|
|
|
+ console.log("iOS小程序检测到errCode:10003,文件错误");
|
|
|
|
+ errorMessage = "音频文件错误,显示文字";
|
|
|
|
+ } else if (error.errCode === 10004) {
|
|
|
|
+ console.log("iOS小程序检测到errCode:10004,格式不支持");
|
|
|
|
+ errorMessage = "音频格式不支持,显示文字";
|
|
|
|
+ }
|
|
|
|
+ common_vendor.index.showToast({
|
|
|
|
+ title: errorMessage,
|
|
|
|
+ icon: "none",
|
|
|
|
+ duration: 2e3
|
|
|
|
+ });
|
|
|
|
+ this.useIOSTextFallback();
|
|
|
|
+ },
|
|
|
|
+ // 新增方法:iOS小程序播放超时处理
|
|
|
|
+ handleIOSPlaybackTimeout(audioContext) {
|
|
|
|
+ console.log("iOS小程序音频播放超时处理");
|
|
|
|
+ if (audioContext) {
|
|
|
|
+ try {
|
|
|
|
+ audioContext.destroy();
|
|
|
|
+ } catch (e) {
|
|
|
|
+ console.error("销毁超时音频播放器失败:", e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ common_vendor.index.showToast({
|
|
|
|
+ title: "音频加载超时,显示文字",
|
|
|
|
+ icon: "none",
|
|
|
|
+ duration: 2e3
|
|
|
|
+ });
|
|
|
|
+ this.useIOSTextFallback();
|
|
|
|
+ },
|
|
|
|
+ // 新增方法:iOS小程序备选播放方法
|
|
|
|
+ fallbackIOSMiniProgramPlay(audioContext) {
|
|
|
|
+ console.log("iOS小程序使用备选播放方法");
|
|
|
|
+ try {
|
|
|
|
+ audioContext.src = this.aiVoiceUrl;
|
|
|
|
+ const fallbackTimeout = setTimeout(() => {
|
|
|
|
+ if (this.isPlayingAiVoice) {
|
|
|
|
+ console.log("iOS小程序备选方法也超时");
|
|
|
|
+ clearTimeout(fallbackTimeout);
|
|
|
|
+ this.handleIOSPlaybackTimeout(audioContext);
|
|
|
|
+ }
|
|
|
|
+ }, 3e3);
|
|
|
|
+ audioContext.play();
|
|
|
|
+ } catch (e) {
|
|
|
|
+ console.error("iOS小程序备选播放方法失败:", e);
|
|
|
|
+ this.handleIOSPlaybackTimeout(audioContext);
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 新增方法:统一的iOS音频完成处理
|
|
|
|
+ handleIOSAudioComplete(audioContext) {
|
|
|
|
+ console.log("iOS音频播放完成");
|
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ this.currentSubtitle = "";
|
|
|
|
+ }, 2e3);
|
|
|
|
+ if (audioContext) {
|
|
|
|
+ try {
|
|
|
|
+ audioContext.destroy();
|
|
|
|
+ } catch (e) {
|
|
|
|
+ console.error("销毁iOS音频播放器失败:", e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ this.showContinueQuestionOptions();
|
|
|
|
+ this.checkPendingNavigation();
|
|
|
|
+ },
|
|
|
|
+ // 移除原来的 playMiniProgramAudioForIOS 方法,因为已经被新的 playIOSMiniProgramAudio 替代
|
|
|
|
+ // playMiniProgramAudioForIOS() 方法可以删除或注释掉
|
|
|
|
+ // 保留原有的 useIOSTextFallback 方法,但确保它能正确处理所有iOS场景
|
|
|
|
+ useIOSTextFallback() {
|
|
|
|
+ console.log("iOS使用文本回退方案");
|
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
|
+ if (!this.hasShownTextFallbackToast) {
|
|
|
|
+ this.hasShownTextFallbackToast = true;
|
|
|
|
+ common_vendor.index.showToast({
|
|
|
|
+ title: "为您显示文字回复",
|
|
|
|
+ icon: "none",
|
|
|
|
+ duration: 2e3
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ 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);
|
|
|
|
+ },
|
|
|
|
+ // 添加新方法:iOS音频播放完成处理
|
|
|
|
+ handleIOSAudioPlaybackComplete() {
|
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ this.currentSubtitle = "";
|
|
|
|
+ }, 2e3);
|
|
|
|
+ if (this.aiAudioPlayer) {
|
|
|
|
+ try {
|
|
|
|
+ this.aiAudioPlayer.destroy();
|
|
|
|
+ } catch (e) {
|
|
|
|
+ console.error("销毁iOS音频播放器失败:", e);
|
|
|
|
+ }
|
|
|
|
+ this.aiAudioPlayer = null;
|
|
|
|
+ }
|
|
|
|
+ this.showContinueQuestionOptions();
|
|
|
|
+ this.checkPendingNavigation();
|
|
|
|
+ },
|
|
|
|
+ // 添加新方法:iOS音频错误处理
|
|
|
|
+ handleIOSAudioError(error) {
|
|
|
|
+ console.error("iOS音频播放错误:", error);
|
|
|
|
+ switch (error.errCode) {
|
|
|
|
+ case 10001:
|
|
|
|
+ console.log("iOS音频系统错误,尝试重新播放");
|
|
|
|
+ this.retryIOSAudioPlay();
|
|
|
|
+ break;
|
|
|
|
+ case 10002:
|
|
|
|
+ console.log("iOS音频网络错误,使用备选方案");
|
|
|
|
+ this.handleIOS10002Error();
|
|
|
|
+ break;
|
|
|
|
+ case 10003:
|
|
|
|
+ console.log("iOS音频文件错误,使用文本回退");
|
|
|
|
+ this.useIOSTextFallback();
|
|
|
|
+ break;
|
|
|
|
+ case 10004:
|
|
|
|
+ console.log("iOS音频格式不支持,使用文本回退");
|
|
|
|
+ this.useIOSTextFallback();
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ console.log("iOS音频未知错误,使用文本回退");
|
|
|
|
+ this.useIOSTextFallback();
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 添加新方法:重试iOS音频播放
|
|
|
|
+ retryIOSAudioPlay() {
|
|
|
|
+ console.log("重试iOS音频播放");
|
|
|
|
+ if (this.aiAudioPlayer) {
|
|
|
|
+ try {
|
|
|
|
+ this.aiAudioPlayer.destroy();
|
|
|
|
+ } catch (e) {
|
|
|
|
+ console.error("销毁播放器失败:", e);
|
|
|
|
+ }
|
|
|
|
+ this.aiAudioPlayer = null;
|
|
|
|
+ }
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ this.fallbackIOSAudioPlay();
|
|
|
|
+ }, 1e3);
|
|
|
|
+ },
|
|
|
|
+ // 添加新方法:iOS备选音频播放
|
|
|
|
+ fallbackIOSAudioPlay() {
|
|
|
|
+ console.log("iOS备选音频播放方案");
|
|
|
|
+ try {
|
|
|
|
+ this.aiAudioPlayer = common_vendor.index.createInnerAudioContext();
|
|
|
|
+ this.aiAudioPlayer.autoplay = true;
|
|
|
|
+ this.aiAudioPlayer.obeyMuteSwitch = true;
|
|
|
|
+ this.aiAudioPlayer.volume = 0.8;
|
|
|
|
+ this.aiAudioPlayer.src = this.aiVoiceUrl;
|
|
|
|
+ this.aiAudioPlayer.onPlay(() => {
|
|
|
|
+ console.log("iOS备选方案:音频开始播放");
|
|
|
|
+ this.currentSubtitle = this.aiText;
|
|
|
|
+ });
|
|
|
|
+ this.aiAudioPlayer.onEnded(() => {
|
|
|
|
+ console.log("iOS备选方案:音频播放结束");
|
|
|
|
+ this.handleIOSAudioPlaybackComplete();
|
|
});
|
|
});
|
|
this.aiAudioPlayer.onError((err) => {
|
|
this.aiAudioPlayer.onError((err) => {
|
|
|
|
+ console.error("iOS备选方案:音频播放错误:", err);
|
|
|
|
+ this.useIOSTextFallback();
|
|
|
|
+ });
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ if (this.isPlayingAiVoice && this.aiAudioPlayer) {
|
|
|
|
+ console.log("iOS音频播放超时,使用文本回退");
|
|
|
|
+ this.useIOSTextFallback();
|
|
|
|
+ }
|
|
|
|
+ }, 5e3);
|
|
|
|
+ } catch (e) {
|
|
|
|
+ console.error("iOS备选音频播放失败:", e);
|
|
|
|
+ this.useIOSTextFallback();
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 修改 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语音开始播放");
|
|
|
|
+ common_vendor.index.showToast({
|
|
|
|
+ title: "正在播放AI回复",
|
|
|
|
+ icon: "none",
|
|
|
|
+ duration: 2e3
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+ audioContext.onEnded(() => {
|
|
|
|
+ console.log("AI语音播放结束");
|
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
|
+ this.currentSubtitle = "";
|
|
|
|
+ audioContext.destroy();
|
|
|
|
+ this.showContinueQuestionOptions();
|
|
|
|
+ });
|
|
|
|
+ audioContext.onError((err) => {
|
|
console.error("AI语音播放错误:", err);
|
|
console.error("AI语音播放错误:", err);
|
|
- this.handleAudioPlaybackError(err);
|
|
|
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
|
+ this.currentSubtitle = "";
|
|
|
|
+ audioContext.destroy();
|
|
|
|
+ this.showContinueQuestionOptions();
|
|
});
|
|
});
|
|
- this.aiAudioPlayer.src = this.aiVoiceUrl;
|
|
|
|
|
|
+ audioContext.src = this.aiVoiceUrl;
|
|
|
|
+ const playTimeout = setTimeout(() => {
|
|
|
|
+ if (this.isPlayingAiVoice) {
|
|
|
|
+ console.warn("小程序音频播放超时,尝试备选方法");
|
|
|
|
+ this.tryMiniProgramFallbackAudioPlay();
|
|
|
|
+ }
|
|
|
|
+ }, 5e3);
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ audioContext.play();
|
|
|
|
+ clearTimeout(playTimeout);
|
|
|
|
+ }, 300);
|
|
} catch (e) {
|
|
} catch (e) {
|
|
- console.error("播放AI语音时发生错误:", e);
|
|
|
|
- this.handleAudioPlaybackError(e);
|
|
|
|
|
|
+ console.error("小程序播放AI语音时发生错误:", e);
|
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
|
+ common_vendor.index.showToast({
|
|
|
|
+ title: "音频播放失败,请查看文字回复",
|
|
|
|
+ icon: "none",
|
|
|
|
+ duration: 2e3
|
|
|
|
+ });
|
|
|
|
+ this.handleAudioPlaybackFailure();
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 添加新方法:iOS小程序音频播放
|
|
|
|
+ playMiniProgramAudioForIOS() {
|
|
|
|
+ console.log("iOS小程序环境:开始播放AI语音");
|
|
|
|
+ this.hasShownTextFallbackToast = false;
|
|
|
|
+ try {
|
|
|
|
+ const audioContext = common_vendor.wx$1.createInnerAudioContext();
|
|
|
|
+ audioContext.autoplay = false;
|
|
|
|
+ audioContext.obeyMuteSwitch = true;
|
|
|
|
+ audioContext.volume = 1;
|
|
|
|
+ audioContext.onError((err) => {
|
|
|
|
+ console.error("iOS小程序音频播放错误:", err);
|
|
|
|
+ if (err.errMsg && err.errMsg.includes("-11850")) {
|
|
|
|
+ console.log("iOS小程序检测到系统音频错误(-11850)");
|
|
|
|
+ common_vendor.index.showToast({
|
|
|
|
+ title: "系统音频暂停,显示文字",
|
|
|
|
+ icon: "none",
|
|
|
|
+ duration: 2e3
|
|
|
|
+ });
|
|
|
|
+ } else if (err.errCode === 10002) {
|
|
|
|
+ console.log("iOS小程序检测到errCode:10002,网络或资源问题");
|
|
|
|
+ common_vendor.index.showToast({
|
|
|
|
+ title: "音频加载中断,显示文字",
|
|
|
|
+ icon: "none",
|
|
|
|
+ duration: 2e3
|
|
|
|
+ });
|
|
|
|
+ } else {
|
|
|
|
+ console.log("iOS小程序其他音频错误:", err.errCode);
|
|
|
|
+ common_vendor.index.showToast({
|
|
|
|
+ title: "音频播放异常,显示文字",
|
|
|
|
+ icon: "none",
|
|
|
|
+ duration: 2e3
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ this.useIOSMiniProgramTextFallback(audioContext);
|
|
|
|
+ });
|
|
|
|
+ audioContext.src = this.aiVoiceUrl;
|
|
|
|
+ audioContext.onPlay(() => {
|
|
|
|
+ console.log("iOS小程序音频开始播放");
|
|
|
|
+ this.currentSubtitle = this.aiText;
|
|
|
|
+ common_vendor.index.showToast({
|
|
|
|
+ title: "正在播放AI回复",
|
|
|
|
+ icon: "none",
|
|
|
|
+ duration: 1500
|
|
|
|
+ });
|
|
|
|
+ });
|
|
|
|
+ audioContext.onEnded(() => {
|
|
|
|
+ console.log("iOS小程序音频播放结束");
|
|
|
|
+ this.handleIOSMiniProgramAudioComplete(audioContext);
|
|
|
|
+ });
|
|
|
|
+ const playTimeout = setTimeout(() => {
|
|
|
|
+ if (this.isPlayingAiVoice) {
|
|
|
|
+ console.log("iOS小程序音频播放超时,切换到文本显示");
|
|
|
|
+ clearTimeout(playTimeout);
|
|
|
|
+ this.useIOSMiniProgramTextFallback(audioContext);
|
|
|
|
+ }
|
|
|
|
+ }, 3e3);
|
|
|
|
+ audioContext.play();
|
|
|
|
+ } catch (e) {
|
|
|
|
+ console.error("iOS小程序音频播放初始化失败:", e);
|
|
|
|
+ this.handleAudioPlaybackFailure();
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 添加新方法:iOS小程序音频播放完成
|
|
|
|
+ handleIOSMiniProgramAudioComplete(audioContext) {
|
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ this.currentSubtitle = "";
|
|
|
|
+ }, 2e3);
|
|
|
|
+ if (audioContext) {
|
|
|
|
+ try {
|
|
|
|
+ audioContext.destroy();
|
|
|
|
+ } catch (e) {
|
|
|
|
+ console.error("销毁iOS小程序音频播放器失败:", e);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
+ this.showContinueQuestionOptions();
|
|
|
|
+ this.checkPendingNavigation();
|
|
|
|
+ },
|
|
|
|
+ // 添加新方法:iOS小程序音频错误处理
|
|
|
|
+ handleIOSMiniProgramAudioError(audioContext, error) {
|
|
|
|
+ console.error("iOS小程序音频错误:", error);
|
|
|
|
+ if (error.errCode === 10002) {
|
|
|
|
+ this.useIOSMiniProgramTextFallback(audioContext);
|
|
|
|
+ } else {
|
|
|
|
+ this.useIOSMiniProgramTextFallback(audioContext);
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 添加新方法:iOS小程序文本回退
|
|
|
|
+ useIOSMiniProgramTextFallback(audioContext) {
|
|
|
|
+ console.log("iOS小程序使用文本回退方案");
|
|
|
|
+ if (audioContext) {
|
|
|
|
+ try {
|
|
|
|
+ audioContext.destroy();
|
|
|
|
+ } catch (e) {
|
|
|
|
+ console.error("销毁音频播放器失败:", e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
|
+ this.currentSubtitle = this.aiText || "抱歉,AI回复内容加载失败";
|
|
|
|
+ const textLength = this.aiText ? this.aiText.length : 20;
|
|
|
|
+ const readingTime = Math.max(6e3, Math.min(textLength * 120, 18e3));
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ this.handleIOSMiniProgramAudioComplete(null);
|
|
|
|
+ }, readingTime);
|
|
},
|
|
},
|
|
// 添加新方法:处理音频播放错误
|
|
// 添加新方法:处理音频播放错误
|
|
handleAudioPlaybackError(error) {
|
|
handleAudioPlaybackError(error) {
|
|
@@ -2424,26 +2925,10 @@ const _sfc_main = {
|
|
}
|
|
}
|
|
this.questionRound++;
|
|
this.questionRound++;
|
|
this.currentSubtitle = "";
|
|
this.currentSubtitle = "";
|
|
- if (this.questionRound < this.maxQuestionRounds) {
|
|
|
|
- this.showContinueQuestionButton = true;
|
|
|
|
- this.showEndInterviewButton = true;
|
|
|
|
- common_vendor.index.showToast({
|
|
|
|
- title: `第${this.questionRound}轮提问完成`,
|
|
|
|
- icon: "none",
|
|
|
|
- duration: 2e3
|
|
|
|
- });
|
|
|
|
- } else {
|
|
|
|
- this.showContinueQuestionButton = false;
|
|
|
|
- this.showEndInterviewButton = false;
|
|
|
|
- if (this.isPlayingAiVoice || this.isUploading) {
|
|
|
|
- console.log("等待AI回复或上传完成后再跳转");
|
|
|
|
- this.pendingAutoNavigation = true;
|
|
|
|
- } else {
|
|
|
|
- setTimeout(() => {
|
|
|
|
- this.navigateToNextPage();
|
|
|
|
- }, 3e3);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ console.log("准备跳转到下一页面");
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ this.navigateToNextPage();
|
|
|
|
+ }, 3e3);
|
|
this.isRecording = false;
|
|
this.isRecording = false;
|
|
if (this.recordingTimer) {
|
|
if (this.recordingTimer) {
|
|
clearInterval(this.recordingTimer);
|
|
clearInterval(this.recordingTimer);
|
|
@@ -2558,6 +3043,26 @@ const _sfc_main = {
|
|
return unsupportedFormats.includes(extension);
|
|
return unsupportedFormats.includes(extension);
|
|
}
|
|
}
|
|
return false;
|
|
return false;
|
|
|
|
+ },
|
|
|
|
+ // 修改文本回退方法
|
|
|
|
+ useIOSTextFallback() {
|
|
|
|
+ console.log("切换到文本显示模式");
|
|
|
|
+ this.isPlayingAiVoice = false;
|
|
|
|
+ if (!this.hasShownTextFallbackToast) {
|
|
|
|
+ this.hasShownTextFallbackToast = true;
|
|
|
|
+ common_vendor.index.showToast({
|
|
|
|
+ title: "已切换为文字显示",
|
|
|
|
+ icon: "none",
|
|
|
|
+ duration: 2e3
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ this.currentSubtitle = this.aiText || "抱歉,无法获取AI回复内容";
|
|
|
|
+ const textLength = this.aiText ? this.aiText.length : 20;
|
|
|
|
+ const readingTime = Math.max(8e3, Math.min(textLength * 150, 2e4));
|
|
|
|
+ console.log(`文本长度: ${textLength}字,预计阅读时间: ${readingTime / 1e3}秒`);
|
|
|
|
+ setTimeout(() => {
|
|
|
|
+ this.navigateToNextPage();
|
|
|
|
+ }, readingTime);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|