diff --git a/main.js b/main.js index f5e53f4..c9b50be 100644 --- a/main.js +++ b/main.js @@ -8,7 +8,7 @@ import * as api from '@/api' import utils from '@/utils' import config from '@/config' import MixinConfig from '@/mixins/config' - +import scrollTo from '@/plugins/scrollTo' import store from '@/stores' Vue.config.productionTip = false @@ -19,6 +19,8 @@ Vue.mixin(MixinConfig) // 全局注册弹窗组件 // Vue.component('GlobalPopup', GlobalPopup) +// 将插件挂载到Vue中 +Vue.use(scrollTo) // 将api挂载到Vue的原型 Vue.prototype.$api = api Vue.prototype.$utils = utils diff --git a/pages/components/SplashScreen.vue b/pages/components/SplashScreen.vue index 3e123d7..a5b6c78 100644 --- a/pages/components/SplashScreen.vue +++ b/pages/components/SplashScreen.vue @@ -4,7 +4,7 @@ { + this.$scrollTo(el, behavior, retryCount + 1) + }, retryDelay) + return + } + + // 如果重试次数用完仍未找到元素,输出详细信息 + if (!targetEL) { + console.error(`scrollTo: 经过${maxRetries + 1}次尝试仍未找到元素 "${el}"`) + console.log('当前可用的refs:', Object.keys(this.$refs)) + return + } + + // 如果targetEL是数组,取第一个元素 + if (Array.isArray(targetEL) && targetEL.length > 0) { + targetEL = targetEL[0] + console.log('检测到数组,取第一个元素:', targetEL) + } else if (Array.isArray(targetEL) && targetEL.length === 0) { + console.error('scrollTo: 找到的是空数组') + return + } + + if (targetEL) { + // #ifdef H5 + console.log('进h5环境的滚动插件了'); + console.log('targetEL类型:', typeof targetEL); + console.log('targetEL是否有$el属性:', !!targetEL.$el); + console.log('targetEL是否有scrollIntoView方法:', !!targetEL.scrollIntoView); + + try { + // H5环境下使用原生的scrollIntoView方法 + if (targetEL.$el) { + // 如果是Vue组件(uni-app的view等组件),获取其DOM元素 + console.log('检测到uni-app Vue组件,使用$el获取DOM元素'); + console.log('DOM元素:', targetEL.$el); + + targetEL.$el.scrollIntoView({ + behavior: behavior, + block: 'start', + inline: 'nearest' + }) + console.log('✅ 滚动成功') + } else if (targetEL.scrollIntoView) { + console.log('检测到原生DOM元素'); + // 如果是原生DOM元素 + targetEL.scrollIntoView({ + behavior: behavior, + block: 'start', + inline: 'nearest' + }) + console.log('✅ 滚动成功') + } else { + console.log('无法识别的元素类型,尝试其他方法'); + // 如果都不是,可能需要其他处理方式 + } + } catch (error) { + console.error('scrollTo 执行失败:', error) + } + // #endif + + // #ifndef H5 + // 非H5环境(小程序等)使用uni.pageScrollTo + const query = uni.createSelectorQuery().in(this) + query.select(`[ref="${el}"]`).boundingClientRect((data) => { + console.log('element position:', data) + if (data) { + uni.pageScrollTo({ + scrollTop: data.top, + duration: behavior === 'smooth' ? 300 : 0 + }) + console.log('✅ 滚动成功') + } else { + console.error('scrollTo: 未找到元素位置信息') + } + }).exec() + // #endif + } + } + } +} + +// 使用方式 +// 在 main.js 中引入:Vue.use(require('./plugins/scrollTo')) +// 然后在组件中:this.$scrollTo('targetRef') \ No newline at end of file diff --git a/subPages/home/AudioControls.vue b/subPages/home/AudioControls.vue index bc3eba8..2db3513 100644 --- a/subPages/home/AudioControls.vue +++ b/subPages/home/AudioControls.vue @@ -84,7 +84,7 @@ export default { default: '' }, voiceId: { - type: String, + type: [String, Number], default: '' }, bookPages: { @@ -255,6 +255,22 @@ export default { } }, immediate: true // 立即执行,用于初始化 + }, + // 监听页面数据变化,当页面数据重新加载后自动获取音频 + bookPages: { + handler(newBookPages, oldBookPages) { + // 检查当前页面数据是否从无到有 + const currentPageData = newBookPages && newBookPages[this.currentPage - 1]; + const oldCurrentPageData = oldBookPages && oldBookPages[this.currentPage - 1]; + + if (currentPageData && !oldCurrentPageData && this.shouldLoadAudio && this.courseId) { + console.log(`🎵 bookPages监听: 当前页面数据已加载,自动获取音频,页面=${this.currentPage}`); + this.$nextTick(() => { + this.getCurrentPageAudio(); + }); + } + }, + deep: true // 深度监听数组变化 } }, methods: { @@ -377,7 +393,7 @@ export default { } }; - console.log('🎧 创建HTML5 Audio包装实例,支持倍速播放'); + return wrappedAudio; }, @@ -398,10 +414,10 @@ export default { this.totalTime = cachedAudio.totalDuration || 0; this.hasAudioData = true; this.isAudioLoading = false; - console.log('检测到缓存音频,显示控制栏'); + } else { // 没有缓存:自动开始加载音频 - console.log('没有缓存音频,开始加载当前页面音频'); + this.getCurrentPageAudio(); } }, @@ -484,7 +500,7 @@ export default { globalStartIndex += bestSplitIndex; } - console.log(`文本分割完成,原长度: ${text.length},分割为 ${segments.length} 段:`, segments); + return segments; }, @@ -495,12 +511,12 @@ export default { let totalDuration = 0; const requestId = this.currentRequestId; // 保存当前请求ID - console.log(`开始分批次请求音频,共 ${segments.length} 段,请求ID: ${requestId}`); + for (let i = 0; i < segments.length; i++) { // 检查是否应该取消请求 if (this.shouldCancelRequest || this.currentRequestId !== requestId) { - console.log(`请求已取消,停止音频加载,请求ID: ${requestId}`); + return null; // 返回null表示请求被取消 } @@ -531,7 +547,7 @@ export default { totalDuration += duration; - console.log(`第 ${i + 1} 段音频请求成功,时长: ${duration}秒`); + } else { console.error(`第 ${i + 1} 段音频请求失败:`, radioRes); // 即使某段失败,也继续处理其他段 @@ -581,9 +597,9 @@ export default { async getCurrentPageAudio(autoPlay = false) { // 🎯 确保音色ID已加载完成后再获取音频 if (!this.localVoiceId || this.localVoiceId === '' || this.localVoiceId === null || this.localVoiceId === undefined) { - console.log('⚠️ 音色ID未加载,无法获取音频'); - console.log(' localVoiceId:', this.localVoiceId); - console.log(' 类型:', typeof this.localVoiceId); + + + // 设置加载失败状态 this.isAudioLoading = false; @@ -605,17 +621,17 @@ export default { return; } - console.log('✅ 音色ID验证通过:', this.localVoiceId); + // 检查是否正在页面切换中,如果是则不加载音频 if (this.isPageChanging) { - console.log('页面切换中,跳过音频加载'); + return; } // 检查是否需要加载音频 if (!this.shouldLoadAudio) { - console.log('当前页面不需要加载音频'); + // 清空音频状态 this.currentPageAudios = []; this.hasAudioData = false; @@ -642,14 +658,14 @@ export default { // 检查是否已经在加载中,防止重复加载(音色切换时除外) if (this.isAudioLoading && !this.isVoiceChanging) { - console.log('音频已在加载中,跳过重复加载'); + return; } // 检查缓存中是否已有当前页面的音频数据 const cacheKey = `${this.courseId}_${this.currentPage}_${this.localVoiceId}`; if (this.audioCache[cacheKey]) { - console.log('从缓存加载音频数据:', cacheKey); + // 从缓存加载音频数据 this.currentPageAudios = this.audioCache[cacheKey].audios; this.totalTime = this.audioCache[cacheKey].totalDuration; @@ -680,7 +696,7 @@ export default { // 重置请求取消标识并生成新的请求ID this.shouldCancelRequest = false; this.currentRequestId = Date.now() + '_' + Math.random().toString(36).substr(2, 9); - console.log('开始新的音频请求,ID:', this.currentRequestId); + // 清空当前页面音频数组 this.currentPageAudios = []; @@ -699,9 +715,39 @@ export default { try { // 对着当前页面的每一个[]元素进行切割 如果是文本text类型则进行音频请求 const currentPageData = this.bookPages[this.currentPage - 1]; + console.log(`🎵 getCurrentPageAudio: 当前页面=${this.currentPage}, 音色ID=${this.localVoiceId}, 课程ID=${this.courseId}`); + console.log(`🎵 getCurrentPageAudio: bookPages长度=${this.bookPages.length}, 当前页面数据:`, currentPageData); + + // 检查页面数据是否存在且不为空 + if (!currentPageData || currentPageData.length === 0) { + console.log(`🎵 getCurrentPageAudio: 当前页面数据为空,可能还在加载中`); + // 通知父组件页面数据需要加载 + this.$emit('page-data-needed', this.currentPage); + + // 设置加载失败状态 + this.isAudioLoading = false; + this.audioLoadFailed = true; + this.hasAudioData = false; + + // 通知父组件音频状态变化 + this.$emit('audio-state-change', { + hasAudioData: false, + isLoading: false, + currentHighlightIndex: -1 + }); + + uni.showToast({ + title: '页面数据加载中,请稍后重试', + icon: 'none', + duration: 2000 + }); + return; + } + if (currentPageData) { // 收集所有text类型的元素 const textItems = currentPageData.filter(item => item.type === 'text'); + console.log(`🎵 getCurrentPageAudio: 找到${textItems.length}个文本项:`, textItems.map(item => item.content?.substring(0, 50) + '...')); if (textItems.length > 0) { let firstAudioPlayed = false; // 标记是否已播放第一个音频 @@ -712,15 +758,15 @@ export default { const item = textItems[index]; try { - console.log(`处理第 ${index + 1}/${textItems.length} 个文本项,长度: ${item.content.length}`); + // 使用分批次请求音频 - console.log('🎵 请求音频 - 当前音色ID:', this.localVoiceId); + const batchResult = await this.requestAudioInBatches(item.content, this.localVoiceId); // 检查请求是否被取消 if (batchResult === null) { - console.log('音频请求被取消,停止处理'); + return; } @@ -755,7 +801,7 @@ export default { this.hasAudioData = true; this.currentAudioIndex = 0; - console.log(`第一个音频时长: ${this.currentPageAudios[0].duration}秒`); + // 通知父组件有音频数据了,但仍在加载中 this.$emit('audio-state-change', { @@ -765,14 +811,14 @@ export default { }); // 立即创建音频实例并开始播放 - console.log('创建第一个音频实例并开始播放'); + this.createAudioInstance(); // 等待音频实例准备好后开始播放(仅在非音色切换时或明确要求自动播放时) setTimeout(() => { if (this.currentAudio && !this.isPlaying && (!this.isVoiceChanging || autoPlay)) { if (autoPlay || !this.isVoiceChanging) { - console.log('自动播放第一个音频,autoPlay:', autoPlay); + this.currentAudio.play(); // isPlaying状态会在onPlay事件中自动设置 this.updateHighlightIndex(); @@ -790,7 +836,7 @@ export default { } } - console.log('所有音频请求完成,共获取', this.currentPageAudios.length, '个音频'); + // 如果有音频,重新计算精确的总时长 if (this.currentPageAudios.length > 0) { @@ -804,7 +850,7 @@ export default { voiceId: this.localVoiceId, // 保存音色ID用于验证 timestamp: Date.now() // 保存时间戳 }; - console.log('音频数据已缓存:', cacheKey, this.audioCache[cacheKey]); + // 限制缓存大小 this.limitCacheSize(10); @@ -861,11 +907,11 @@ export default { // 重新获取音频 retryGetAudio() { - console.log('用户点击重新获取音频'); + // 检查是否需要加载音频 if (!this.shouldLoadAudio) { - console.log('当前页面不支持音频功能'); + return; } @@ -875,7 +921,7 @@ export default { const pageKey = `${this.courseId}_${this.currentPage}_${this.localVoiceId}`; if (this.audioCache[pageKey]) { delete this.audioCache[pageKey]; - console.log('清除失败页面的音频缓存:', pageKey); + } // 重新获取音频 this.getCurrentPageAudio(); @@ -885,17 +931,17 @@ export default { resetAudioState() { // 取消当前正在进行的音频请求 this.shouldCancelRequest = true; - console.log('页面切换:标记取消当前音频请求'); + // 立即停止并销毁当前音频实例,防止穿音 if (this.currentAudio) { if (this.isPlaying) { this.currentAudio.pause(); - console.log('页面切换:立即停止音频播放'); + } this.currentAudio.destroy(); this.currentAudio = null; - console.log('页面切换:销毁音频实例'); + } // 重置播放状态 @@ -911,7 +957,7 @@ export default { // 如果不需要加载音频,直接重置为初始状态 if (!this.shouldLoadAudio) { - console.log('不需要音频的页面:重置音频状态'); + this.currentPageAudios = []; this.totalTime = 0; this.hasAudioData = false; @@ -925,13 +971,13 @@ export default { this.currentPageAudios = cachedAudio.audios; this.totalTime = cachedAudio.totalDuration || 0; this.hasAudioData = true; - console.log('检测到缓存音频,显示控制栏'); + } else { // 没有缓存:重置为初始状态,但不立即加载(由checkAndLoadPreloadedAudio处理) this.currentPageAudios = []; this.totalTime = 0; this.hasAudioData = false; - console.log('没有缓存音频,重置状态'); + } } @@ -979,7 +1025,7 @@ export default { return; } - console.log('手动加载缓存音频数据:', cacheKey); + // 从缓存加载音频数据 this.currentPageAudios = cachedData.audios; @@ -999,7 +1045,7 @@ export default { currentHighlightIndex: this.currentHighlightIndex }); - console.log('缓存音频加载完成,播放控制栏已显示'); + }, // 手动获取音频 @@ -1044,7 +1090,7 @@ export default { // 使用API返回的准确时长信息 if (audio.duration && audio.duration > 0) { - console.log(`使用API返回的准确时长 ${i + 1}:`, audio.duration, '秒'); + totalDuration += audio.duration; } else { // 如果没有时长信息,使用文字长度估算(备用方案) @@ -1057,7 +1103,7 @@ export default { } } this.totalTime = totalDuration; - console.log('音频总时长:', totalDuration, '秒'); + }, // 获取音频时长 @@ -1070,7 +1116,7 @@ export default { // 监听音频加载完成事件 audio.onCanplay(() => { - console.log('音频可以播放,duration:', audio.duration); + if (!resolved && audio.duration && audio.duration > 0) { resolved = true; resolve(audio.duration); @@ -1080,7 +1126,7 @@ export default { // 监听音频元数据加载完成事件 audio.onLoadedmetadata = () => { - console.log('音频元数据加载完成,duration:', audio.duration); + if (!resolved && audio.duration && audio.duration > 0) { resolved = true; resolve(audio.duration); @@ -1090,7 +1136,7 @@ export default { // 监听音频时长更新事件 audio.onDurationChange = () => { - console.log('音频时长更新,duration:', audio.duration); + if (!resolved && audio.duration && audio.duration > 0) { resolved = true; resolve(audio.duration); @@ -1112,7 +1158,7 @@ export default { // 設置較長的超時時間,但不播放音頻 setTimeout(() => { if (!resolved) { - console.log('無法獲取音頻時長,使用默認值'); + resolved = true; reject(new Error('無法獲取音頻時長')); audio.destroy(); @@ -1215,7 +1261,7 @@ export default { // 备用方案:使用 TTS API 实时生成并播放音频 async playTextWithTTS(textContent) { try { - console.log('🔊 使用 TTS 实时生成音频:', textContent); + // 停止当前播放的音频 if (this.currentAudio) { @@ -1237,7 +1283,7 @@ export default { uni.hideLoading(); - console.log('🔊 TTS API 响应:', audioRes); + if (audioRes && audioRes.result && audioRes.result.url) { const audioUrl = audioRes.result.url; @@ -1247,12 +1293,12 @@ export default { audio.src = audioUrl; audio.onPlay(() => { - console.log('🔊 TTS 音频开始播放'); + this.isPlaying = true; }); audio.onEnded(() => { - console.log('🔊 TTS 音频播放完成'); + this.isPlaying = false; audio.destroy(); if (this.currentAudio === audio) { @@ -1277,7 +1323,7 @@ export default { this.currentAudio = audio; audio.play(); - console.log('✅ TTS 音频播放成功'); + return true; } else { console.error('❌ TTS API 请求失败:', audioRes); @@ -1300,14 +1346,14 @@ export default { // 播放指定的音频段落(通过文本内容匹配) playSpecificAudio(textContent) { - console.log('🎯 尝试播放指定音频段落:', textContent); - console.log('📊 当前页面音频数组长度:', this.currentPageAudios.length); - console.log('📋 音频加载状态:', this.isAudioLoading); + + + // 检查单词音频播放状态 - console.log('🎵 检查单词音频播放状态:', this.isWordAudioPlaying); + if (this.isWordAudioPlaying) { - console.log('⚠️ 单词音频正在播放,阻止句子音频播放'); + uni.showToast({ title: '请等待单词音频播放完成', icon: 'none' @@ -1337,15 +1383,15 @@ export default { // 标准化目标文本 const normalizedTarget = this.normalizeText(textContent); - console.log('🔍 标准化后的目标文本:', normalizedTarget); + // 打印所有音频文本用于调试 - console.log('📝 当前页面所有音频文本:'); + this.currentPageAudios.forEach((audio, index) => { - console.log(` [${index}] 原始文本: "${audio.text}"`); + console.log(` [${index}] 标准化文本: "${this.normalizeText(audio.text)}"`); if (audio.originalText) { - console.log(` [${index}] 原始完整文本: "${audio.originalText}"`); + } }); @@ -1359,9 +1405,9 @@ export default { }); if (audioIndex !== -1) { - console.log('✅ 精确匹配成功,索引:', audioIndex); + } else { - console.log('❌ 精确匹配失败,尝试模糊匹配'); + // 第二步:包含匹配 audioIndex = this.currentPageAudios.findIndex(audio => { @@ -1373,9 +1419,9 @@ export default { }); if (audioIndex !== -1) { - console.log('✅ 包含匹配成功,索引:', audioIndex); + } else { - console.log('❌ 包含匹配失败,尝试分段音频匹配'); + // 第三步:分段音频匹配 audioIndex = this.currentPageAudios.findIndex(audio => { @@ -1393,16 +1439,16 @@ export default { }); if (audioIndex !== -1) { - console.log('✅ 分段音频匹配成功,索引:', audioIndex); + } else { - console.log('❌ 所有匹配方式都失败'); + // 第四步:句子分割匹配(针对长句子) - console.log('❌ 尝试句子分割匹配...'); + // 将目标句子按标点符号分割 const targetSentences = normalizedTarget.split(/[,。!?;:,!?;:]/).filter(s => s.trim().length > 0); - console.log('🔪 目标句子分割结果:', targetSentences); + if (targetSentences.length > 1) { // 尝试匹配分割后的句子片段 @@ -1417,18 +1463,18 @@ export default { }); if (audioIndex !== -1) { - console.log(`✅ 句子片段匹配成功,片段: "${sentence}", 索引: ${audioIndex}`); + break; } } } if (audioIndex === -1) { - console.log('❌ 句子分割匹配失败,尝试关键词匹配...'); + // 第五步:关键词匹配(提取关键词进行匹配) const keywords = normalizedTarget.split(/\s+/).filter(word => word.length > 2); - console.log('🔑 提取的关键词:', keywords); + let bestKeywordMatch = -1; let bestKeywordCount = 0; @@ -1450,9 +1496,9 @@ export default { if (bestKeywordMatch !== -1) { audioIndex = bestKeywordMatch; - console.log(`✅ 关键词匹配成功,索引: ${audioIndex}, 匹配数: ${bestKeywordCount}/${keywords.length}`); + } else { - console.log('❌ 关键词匹配失败,尝试相似度匹配...'); + // 第六步:相似度匹配(最后的尝试) let bestMatch = -1; @@ -1478,7 +1524,7 @@ export default { if (bestMatch !== -1) { audioIndex = bestMatch; - console.log(`✅ 相似度匹配成功,索引: ${audioIndex}, 相似度: ${bestSimilarity.toFixed(2)}`); + } } } @@ -1487,8 +1533,8 @@ export default { } if (audioIndex !== -1) { - console.log('🎵 找到匹配的音频,开始播放,索引:', audioIndex); - console.log('🎵 匹配的音频文本:', this.currentPageAudios[audioIndex].text); + + // 停止当前播放的音频 if (this.currentAudio) { @@ -1516,7 +1562,7 @@ export default { setTimeout(() => { if (this.currentAudio) { this.currentAudio.play(); - console.log('🎵 开始播放指定音频段落'); + } else { console.error('❌ 音频实例创建失败'); } @@ -1525,12 +1571,12 @@ export default { return true; // 成功找到并播放 } else { console.error('❌ 未找到匹配的音频段落:', textContent); - console.log('💡 尝试最后的匹配策略:首字符匹配'); + // 最后的尝试:首字符匹配(针对划线重点等特殊情况) if (normalizedTarget.length > 5) { const firstChars = normalizedTarget.substring(0, Math.min(10, normalizedTarget.length)); - console.log('🔍 尝试首字符匹配:', firstChars); + audioIndex = this.currentPageAudios.findIndex(audio => { if (!audio.text) return false; @@ -1539,7 +1585,7 @@ export default { }); if (audioIndex !== -1) { - console.log('✅ 首字符匹配成功,索引:', audioIndex); + // 停止当前播放的音频 if (this.currentAudio) { @@ -1567,7 +1613,7 @@ export default { setTimeout(() => { if (this.currentAudio) { this.currentAudio.play(); - console.log('🎵 开始播放首字符匹配的音频段落'); + } else { console.error('❌ 音频实例创建失败'); } @@ -1577,7 +1623,7 @@ export default { } } - console.log('💡 所有匹配策略都失败,尝试使用备用方案:实时生成音频'); + // 备用方案:使用 textToVoice API 实时生成音频 return this.playTextWithTTS(textContent); @@ -1614,27 +1660,22 @@ export default { const audioUrl = this.currentPageAudios[this.currentAudioIndex].url; audio.src = audioUrl; - console.log('🎵 创建音频实例 - 当前音色ID:', this.voiceId); - console.log('🎵 创建音频实例 - 音频URL:', audioUrl); - console.log('🎵 创建音频实例 - 音频索引:', this.currentAudioIndex); + + + console.log('🎵 创建音频实例 - 音频文本:', this.currentPageAudios[this.currentAudioIndex].text?.substring(0, 50) + '...'); // 在音頻可以播放時檢測playbackRate支持 audio.onCanplay(() => { - console.log('🎵 音頻可以播放事件觸發,開始檢測playbackRate支持'); - console.log('🔍 音頻實例基本信息:', { - src: audio.src, - duration: audio.duration, - readyState: audio.readyState || '未知', - constructor: audio.constructor.name - }); + + this.checkPlaybackRateSupport(audio); }); // 音频事件监听 audio.onPlay(() => { - console.log('🎵 音频开始播放'); + this.isPlaying = true; // 在播放开始时立即设置倍速 @@ -1642,7 +1683,7 @@ export default { }); audio.onPause(() => { - console.log('⏸️ 音频暂停'); + console.log('📊 暫停時倍速狀態:', { 當前播放速度: audio.playbackRate + 'x', 期望播放速度: this.playSpeed + 'x' @@ -1658,14 +1699,14 @@ export default { this.lastSpeedCheckTime = Math.floor(audio.currentTime); const rateDifference = Math.abs(audio.playbackRate - this.playSpeed); if (rateDifference > 0.01) { - console.log('⚠️ 检测到倍速偏差,重新应用倍速设置'); + this.applyPlaybackRate(audio); } } }); audio.onEnded(() => { - console.log('当前音频播放结束'); + this.onAudioEnded(); }); @@ -1734,15 +1775,15 @@ export default { if (currentAudio.isSegmented && typeof currentAudio.originalTextIndex !== 'undefined') { // 使用原始文本项的索引作为高亮索引 this.currentHighlightIndex = currentAudio.originalTextIndex; - console.log('分段音频高亮索引:', this.currentHighlightIndex, '原始文本索引:', currentAudio.originalTextIndex, '段索引:', currentAudio.segmentIndex); + } else { // 非分段音频,使用音频索引 this.currentHighlightIndex = this.currentAudioIndex; - console.log('普通音频高亮索引:', this.currentHighlightIndex, '当前音频索引:', this.currentAudioIndex); + } // 使用辅助方法发送高亮变化事件 - this.emitHighlightChange(this.currentAudioIndex); + this.emitHighlightChange(this.currentHighlightIndex); }, // 发送高亮变化事件的辅助方法 @@ -1753,22 +1794,24 @@ export default { return; } - // 获取对应的音频数据 - const audioData = this.currentPageAudios[highlightIndex]; + // 获取当前播放的音频数据(使用currentAudioIndex而不是highlightIndex) + const audioData = this.currentPageAudios[this.currentAudioIndex]; if (!audioData) { this.$emit('highlight-change', -1); return; } - // 发送详细的高亮信息 - this.$emit('highlight-change', { + const highlightData = { highlightIndex: audioData.originalTextIndex !== undefined ? audioData.originalTextIndex : highlightIndex, isSegmented: audioData.isSegmented || false, segmentIndex: audioData.segmentIndex || 0, startIndex: audioData.startIndex || 0, endIndex: audioData.endIndex || 0, currentText: audioData.text || '' - }); + }; + + // 发送详细的高亮信息 + this.$emit('highlight-change', highlightData); }, // 音频播放结束处理 @@ -1777,12 +1820,24 @@ export default { // 播放下一个音频 this.currentAudioIndex++; this.playAudio(); + + // 滚动到下一段音频对应的文字 + // setTimeout(() => { + // this.scrollToCurrentAudio(); + // }, 300); // 延迟300ms确保音频切换完成 + } else { // 所有音频播放完毕 if (this.isLoop) { // 循环播放 this.currentAudioIndex = 0; this.playAudio(); + + // 滚动到第一段音频对应的文字 + // setTimeout(() => { + // this.scrollToCurrentAudio(); + // }, 300); + } else { // 停止播放 this.isPlaying = false; @@ -1793,22 +1848,74 @@ export default { } }, + // 滚动到当前播放音频对应的文字 + // scrollToCurrentAudio() { + // try { + // // 获取当前播放的音频数据 + // const currentAudio = this.currentPageAudios[this.currentAudioIndex]; + // if (!currentAudio) { + // console.log('🔍 scrollToCurrentAudio: 没有当前音频数据'); + // return; + // } + // + // // 确定要滚动到的文字索引 + // let targetTextIndex = this.currentAudioIndex; + // + // // 如果是分段音频,使用原始文本索引 + // if (currentAudio.isSegmented && typeof currentAudio.originalTextIndex !== 'undefined') { + // targetTextIndex = currentAudio.originalTextIndex; + // } + // + // // 获取当前页面数据 + // const currentPageData = this.bookPages[this.currentPage - 1]; + // if (!currentPageData || !Array.isArray(currentPageData)) { + // console.warn('⚠️ scrollToCurrentAudio: 无法获取当前页面数据'); + // return; + // } + // + // // 判断目标索引位置的元素类型 + // const targetElement = currentPageData[targetTextIndex]; + // let refPrefix = 'textRef'; // 默认为文本 + // + // if (targetElement && targetElement.type === 'image') { + // refPrefix = 'imageRef'; + // } + // + // // 构建ref名称:根据元素类型使用不同前缀 + // const refName = `${refPrefix}_${this.currentPage - 1}_${targetTextIndex}`; + // + // console.log('🎯 scrollToCurrentAudio:', { + // currentAudioIndex: this.currentAudioIndex, + // targetTextIndex: targetTextIndex, + // targetElementType: targetElement?.type || 'unknown', + // refPrefix: refPrefix, + // refName: refName, + // isSegmented: currentAudio.isSegmented, + // originalTextIndex: currentAudio.originalTextIndex, + // audioText: currentAudio.text?.substring(0, 50) + '...' + // }); + // + // // 通过父组件调用scrollTo插件 + // this.$emit('scroll-to-text', refName); + // + // } catch (error) { + // console.error('❌ scrollToCurrentAudio 执行失败:', error); + // } + // }, + toggleLoop() { this.isLoop = !this.isLoop; }, toggleSpeed() { - console.log('🎛️ 用户点击倍速切换按钮...'); + // 简化检测:只在极少数情况下阻止倍速切换 - console.log('🔍 检查倍速支持状态:', { - playbackRateSupported: this.playbackRateSupported, - 当前状态: this.playbackRateSupported ? '✅ 支持' : '⚠️ 受限' - }); + // 只有在明确禁用的情况下才阻止(比如Android 4.x) if (!this.playbackRateSupported) { - console.log('⚠️ 倍速功能受限,但仍尝试切换'); + // 不再直接返回,而是继续尝试 } @@ -1848,12 +1955,12 @@ export default { // 如果正在播放,需要重启播放才能使播放速度生效 if (wasPlaying) { - console.log('🔄 重启播放以应用新速度...'); + this.currentAudio.pause(); setTimeout(() => { // 不使用seek方法,直接重新播放 this.currentAudio.play(); - console.log('▶️ 播放已重启,新速度已生效'); + }, 100); } @@ -1870,9 +1977,9 @@ export default { duration: 1000 }); - console.log('🎉 倍速切换完成!新速度:', this.playSpeed + 'x'); + } else { - console.log('⚠️ 没有音频实例,仅更新速度设置'); + uni.showToast({ title: `⚡ 速度设为: ${this.playSpeed}x`, icon: 'none', @@ -1887,7 +1994,7 @@ export default { if (this.isDragging) { // 可以在這裡實時更新顯示時間,讓用戶看到拖動到的時間點 // 但不改變實際的 currentTime,避免影響播放邏輯 - console.log('實時更新滑動條值:', value); + } }, @@ -1897,24 +2004,24 @@ export default { if (!this.isDragging) { if (this.isPlaying) { this.pauseAudio(); - console.log('開始拖動滑動條,暫停播放'); + } this.isDragging = true; } // 更新滑動條的值,但不改變實際播放位置 this.sliderValue = value; - console.log('拖動中,滑動條值:', value); + }, // 滑動條拖動結束的處理 (@change 事件) onSliderChange(value) { - console.log('滑動條變化,跳轉到位置:', value, '是否為拖動:', this.isDragging); + // 如果不是拖動狀態(即單點),需要先暫停播放 if (!this.isDragging && this.isPlaying) { this.pauseAudio(); - console.log('單點滑動條,暫停播放'); + } // 重置拖動狀態 @@ -1924,19 +2031,19 @@ export default { // 跳轉到指定位置,但不自動恢復播放 this.seekToTime(value, false); - console.log('滑動條操作完成,保持暫停狀態,需要手動點擊播放'); + }, // 跳轉到指定時間 seekToTime(targetTime, shouldResume = false) { if (!this.currentPageAudios || this.currentPageAudios.length === 0) { - console.log('沒有音頻數據,無法跳轉'); + return; } // 確保目標時間在有效範圍內 targetTime = Math.max(0, Math.min(targetTime, this.totalTime)); - console.log('跳轉到時間:', targetTime, '秒', '總時長:', this.totalTime, '是否恢復播放:', shouldResume); + let accumulatedTime = 0; let targetAudioIndex = -1; @@ -1945,7 +2052,7 @@ export default { // 找到目標時間對應的音頻片段 for (let i = 0; i < this.currentPageAudios.length; i++) { const audioDuration = this.currentPageAudios[i].duration || 0; - console.log(`音頻片段 ${i}: 時長=${audioDuration}, 累計時間=${accumulatedTime}, 範圍=[${accumulatedTime}, ${accumulatedTime + audioDuration}]`); + if (targetTime >= accumulatedTime && targetTime <= accumulatedTime + audioDuration) { targetAudioIndex = i; @@ -1959,10 +2066,10 @@ export default { if (targetAudioIndex === -1 && this.currentPageAudios.length > 0) { targetAudioIndex = this.currentPageAudios.length - 1; targetAudioTime = this.currentPageAudios[targetAudioIndex].duration || 0; - console.log('使用最後一個音頻片段作為目標'); + } - console.log('目標音頻索引:', targetAudioIndex, '目標音頻時間:', targetAudioTime); + if (targetAudioIndex === -1) { console.error('無法找到目標音頻片段'); @@ -1971,7 +2078,7 @@ export default { // 如果需要切換到不同的音頻片段 if (targetAudioIndex !== this.currentAudioIndex) { - console.log(`切換音頻片段: ${this.currentAudioIndex} -> ${targetAudioIndex}`); + this.currentAudioIndex = targetAudioIndex; this.createAudioInstance(); @@ -1980,13 +2087,13 @@ export default { if (this.currentAudio) { this.currentAudio.seek(targetAudioTime); this.currentTime = targetTime; - console.log('切換音頻並跳轉到:', targetAudioTime, '秒'); + // 如果拖動前正在播放,則恢復播放 if (shouldResume) { this.currentAudio.play(); this.isPlaying = true; - console.log('恢復播放狀態'); + } } }); @@ -1995,13 +2102,13 @@ export default { if (this.currentAudio) { this.currentAudio.seek(targetAudioTime); this.currentTime = targetTime; - console.log('在當前音頻內跳轉到:', targetAudioTime, '秒'); + // 如果拖動前正在播放,則恢復播放 if (shouldResume) { this.currentAudio.play(); this.isPlaying = true; - console.log('恢復播放狀態'); + } } } @@ -2027,7 +2134,7 @@ export default { // 初始检测播放速度支持(简化版本,默认启用) checkInitialPlaybackRateSupport() { - console.log('🚀 开始初始倍速播放支持检测...'); + try { const systemInfo = uni.getSystemInfoSync(); console.log('📱 系统信息:', { @@ -2057,9 +2164,9 @@ export default { } } - console.log('✅ 倍速功能已启用!'); - console.log('📊 可用倍速选项:', this.speedOptions); - console.log('⚡ 当前播放速度:', this.playSpeed + 'x'); + + + // 显示成功提示 uni.showToast({ @@ -2072,7 +2179,7 @@ export default { console.error('💥 检测播放速度支持时出错:', error); // 即使出错也默认启用 this.playbackRateSupported = true; - console.log('⚠️ 检测出错,但仍启用倍速功能'); + } }, @@ -2080,7 +2187,7 @@ export default { applyPlaybackRate(audio) { if (!audio) return; - console.log('⚙️ 开始应用播放速度设置...'); + console.log('📊 当前状态检查:', { playbackRateSupported: this.playbackRateSupported, 期望速度: this.playSpeed + 'x', @@ -2102,20 +2209,15 @@ export default { const actualRate = audio.playbackRate; const rateDifference = Math.abs(actualRate - this.playSpeed); - console.log(`🔍 倍速设置尝试 ${attempt}/${maxAttempts}:`, { - 期望速度: this.playSpeed, - 实际速度: actualRate, - 差值: rateDifference, - 设置成功: rateDifference < 0.01 - }); + if (rateDifference >= 0.01 && attempt < maxAttempts) { - console.log(`⚠️ 倍速设置未完全生效,进行第 ${attempt + 1} 次尝试...`); + setTimeout(trySetRate, 100); } else if (rateDifference < 0.01) { - console.log('✅ 倍速设置成功!'); + } else { - console.log('⚠️ 倍速设置可能不完全支持,但已尽力尝试'); + } }, 50); }; @@ -2123,20 +2225,20 @@ export default { trySetRate(); } catch (error) { - console.log('💥 设置播放速度时出错:', error); + } } else { - console.log('❌ 当前环境不支持播放速度控制'); + } }, // 检查播放速度控制支持(简化版本) checkPlaybackRateSupport(audio) { - console.log('🎵 开始音频实例倍速支持检测...'); + try { // 如果初始检测已经禁用,直接返回 if (!this.playbackRateSupported) { - console.log('⚠️ 初始检测已禁用倍速功能,跳过音频实例检测'); + return; } @@ -2155,20 +2257,20 @@ export default { if (audio._nativeAudio && audio._nativeAudio instanceof Audio) { isHTML5Audio = true; supportsPlaybackRate = true; - console.log('✅ 检测到HTML5 Audio包装实例,完全支持倍速播放'); + } // 检查是否为原生HTML5 Audio else if (audio instanceof Audio) { isHTML5Audio = true; supportsPlaybackRate = true; - console.log('✅ 检测到原生HTML5 Audio实例,完全支持倍速播放'); + } // 检查uni-app音频实例的playbackRate属性 else if (typeof audio.playbackRate !== 'undefined') { supportsPlaybackRate = true; - console.log('✅ 音频实例支持playbackRate属性'); + } else { - console.log('⚠️ 音频实例不支持playbackRate属性'); + } // console.log('🔍 音频实例分析:', { @@ -2196,20 +2298,20 @@ export default { // }, 50); } catch (error) { - console.log('⚠️ 设置播放速度时出现错误:', error.message); + } } } else { - console.log('⚠️ 音频实例不存在'); + } // 保持倍速功能启用状态 - console.log('✅ 音频实例检测完成,倍速功能保持启用'); + } catch (error) { console.error('💥 检查播放速度支持时出错:', error); // 即使出错也保持启用状态 - console.log('⚠️ 检测出错,但保持倍速功能启用'); + } }, @@ -2222,7 +2324,7 @@ export default { // 清理音频缓存 clearAudioCache() { this.audioCache = {}; - console.log('音频缓存已清理'); + }, // 限制缓存大小,保留最近访问的页面 @@ -2234,31 +2336,31 @@ export default { keysToDelete.forEach(key => { delete this.audioCache[key]; }); - console.log('缓存大小已限制,删除了', keysToDelete.length, '个缓存项'); + } }, // 自動加載第一頁音頻並播放 async autoLoadAndPlayFirstPage() { try { - console.log('開始自動加載第一頁音頻'); + // 確保當前是第一頁且需要加載音頻 if (this.currentPage === 1 && this.shouldLoadAudio) { - console.log('當前是第一頁且需要音頻,開始加載音頻'); + // 加載音頻 await this.getCurrentPageAudio(); // 檢查是否成功加載音頻 if (this.currentPageAudios && this.currentPageAudios.length > 0) { - console.log('音頻加載成功,getCurrentPageAudio已經自動播放第一個音頻'); + // getCurrentPageAudio方法已經處理了第一個音頻的播放,這裡不需要再次調用playAudio } else { - console.log('第一頁沒有音頻數據'); + } } else { - console.log('當前頁面不是第一頁文字頁面,跳過自動播放'); + } } catch (error) { console.error('自動加載和播放音頻失敗:', error); @@ -2267,11 +2369,11 @@ export default { // 清理音频资源 destroyAudio() { - console.log('🧹 AudioControls: 开始清理音频资源'); + // 1. 停止并销毁当前音频实例 if (this.currentAudio) { - console.log('🧹 销毁当前音频实例'); + try { // 先暂停再销毁 if (this.isPlaying) { @@ -2301,7 +2403,7 @@ export default { this.isVoiceChanging = false; this.audioLoadFailed = false; - console.log('✅ AudioControls: 音频资源清理完成'); + }, // 停止单词音频播放(全局音频管理) @@ -2314,22 +2416,22 @@ export default { if (currentPage && currentPage.$vm) { const bookVm = currentPage.$vm; if (bookVm.currentWordAudio) { - console.log('🔄 AudioControls: 停止单词音频播放'); + bookVm.currentWordAudio.pause(); bookVm.currentWordAudio.destroy(); bookVm.currentWordAudio = null; bookVm.isWordAudioPlaying = false; - console.log('✅ AudioControls: 单词音频已停止'); + } } } catch (error) { - console.log('⚠️ AudioControls: 停止单词音频时出现异常:', error); + } }, // 课程切换时的完整数据清理(保留音色设置) resetForCourseChange() { - console.log('课程切换:开始清理所有数据,保留音色设置'); + // 1. 停止并销毁当前音频 if (this.isPlaying && this.currentAudio) { @@ -2374,7 +2476,7 @@ export default { // 注意:不清空 voiceId,保留用户的音色选择 - console.log('课程切换:数据清理完成,音色保持为:', this.voiceId); + // 7. 通知父组件状态变化 this.$emit('audio-state-change', { @@ -2387,17 +2489,17 @@ export default { // 自动加载并播放音频(课程切换后调用) async autoLoadAndPlayAudio() { - console.log('开始自动加载音频'); + // 检查是否需要加载音频 if (!this.shouldLoadAudio) { - console.log('当前页面不需要加载音频,跳过音频加载'); + return; } // 检查必要条件 if (!this.courseId || !this.currentPage) { - console.log('缺少必要参数,跳过音频加载'); + return; } @@ -2408,7 +2510,7 @@ export default { // 开始加载音频 await this.getCurrentPageAudio(); - console.log('音频自动加载完成,hasAudioData:', this.hasAudioData); + } catch (error) { console.error('自动加载音频失败:', error); this.isAudioLoading = false; @@ -2422,11 +2524,12 @@ export default { // 处理音色切换(由父组件调用) async handleVoiceChange(newVoiceId, options = {}) { - console.log('🎵 AudioControls: 开始处理音色切换', this.voiceId, '->', newVoiceId); + console.log(`🎵 handleVoiceChange: 开始音色切换 ${this.localVoiceId} -> ${newVoiceId}`); + console.log(`🎵 handleVoiceChange: 当前页面=${this.currentPage}, 课程ID=${this.courseId}, bookPages长度=${this.bookPages.length}`); // 检查是否正在加载音频,如果是则阻止音色切换 if (this.isAudioLoading) { - console.log('🎵 音频正在加载中,阻止音色切换'); + console.log(`🎵 handleVoiceChange: 音频正在加载中,阻止音色切换`); throw new Error('音频加载中,请稍后再试'); } @@ -2446,7 +2549,7 @@ export default { // 3. 清理所有音频缓存(因为音色变了,所有缓存都无效) this.clearAudioCache(); - console.log('🎵 AudioControls: 已清理所有音频缓存'); + // 4. 重置音频状态 this.currentPageAudios = []; @@ -2474,13 +2577,13 @@ export default { // 8. 如果当前页面需要加载音频,优先获取当前页面音频 if (this.shouldLoadAudio && this.courseId && this.currentPage) { - console.log('🎵 AudioControls: 优先获取当前页面音频,使用新音色:', newVoiceId); + console.log(`🎵 handleVoiceChange: 开始获取当前页面音频,页面=${this.currentPage}, 课程=${this.courseId}`); await this.getCurrentPageAudio(); - console.log('🎵 AudioControls: 当前页面音频获取完成'); + console.log(`🎵 handleVoiceChange: 当前页面音频获取完成,hasAudioData=${this.hasAudioData}`); } else { // 如果不需要加载音频,直接清除加载状态 + console.log(`🎵 handleVoiceChange: 不需要加载音频,shouldLoadAudio=${this.shouldLoadAudio}, courseId=${this.courseId}, currentPage=${this.currentPage}`); this.isAudioLoading = false; - console.log('🎵 AudioControls: 不需要音频的页面,直接清除加载状态'); } // 9. 清除音色切换加载状态 @@ -2488,7 +2591,7 @@ export default { // 10. 如果需要预加载其他页面,启动预加载 if (preloadAllPages) { - console.log('🎵 AudioControls: 开始预加载其他页面音频,使用新音色:', newVoiceId); + // 延迟启动预加载,确保当前页面音频加载完成 setTimeout(() => { this.preloadAllPagesAudio(); @@ -2509,7 +2612,7 @@ export default { preloadAllPages: preloadAllPages }); - console.log('🎵 AudioControls: 音色切换处理完成'); + } catch (error) { console.error('🎵 AudioControls: 音色切换处理失败:', error); // 清除加载状态 @@ -2530,12 +2633,12 @@ export default { // 预加载所有页面音频(音色切换时使用) async preloadAllPagesAudio() { if (this.isPreloading) { - console.log('已在预加载中,跳过'); + return; } try { - console.log('开始预加载所有页面音频'); + this.isPreloading = true; this.preloadProgress = 0; @@ -2554,12 +2657,12 @@ export default { } if (allTextPages.length === 0) { - console.log('没有需要预加载的页面'); + this.isPreloading = false; return; } - console.log(`需要预加载 ${allTextPages.length} 个页面的音频`); + // 逐页预加载音频 for (let i = 0; i < allTextPages.length; i++) { @@ -2571,7 +2674,7 @@ export default { // 更新进度 this.preloadProgress = Math.round(((i + 1) / allTextPages.length) * 100); - console.log(`预加载进度: ${this.preloadProgress}%`); + // 添加小延迟,避免请求过于频繁 if (i < allTextPages.length - 1) { @@ -2583,25 +2686,25 @@ export default { } } - console.log('所有页面音频预加载完成'); + } catch (error) { console.error('预加载所有页面音频失败:', error); } finally { this.isPreloading = false; this.preloadProgress = 100; - console.log('音色切换后的音频预加载任务结束'); + } }, // 开始预加载音频(由父组件调用) async startPreloadAudio() { if (this.isPreloading) { - console.log('已在预加载中,跳过'); + return; } try { - console.log('开始预加载音频数据'); + this.isPreloading = true; this.preloadProgress = 0; @@ -2609,24 +2712,24 @@ export default { const preloadPages = this.getPreloadPageList(); if (preloadPages.length === 0) { - console.log('没有需要预加载的页面'); + this.isPreloading = false; return; } - console.log('需要预加载的页面:', preloadPages); + // 逐个预加载页面音频 for (let i = 0; i < preloadPages.length; i++) { const pageInfo = preloadPages[i]; try { - console.log(`开始预加载第${pageInfo.pageIndex + 1}页音频`); + await this.preloadPageAudio(pageInfo.pageIndex, pageInfo.pageData); // 更新预加载进度 this.preloadProgress = Math.round(((i + 1) / preloadPages.length) * 100); - console.log(`预加载进度: ${this.preloadProgress}%`); + // 延迟一下,避免请求过于频繁 await new Promise(resolve => setTimeout(resolve, 300)); @@ -2637,7 +2740,7 @@ export default { } } - console.log('音频预加载完成'); + } catch (error) { console.error('预加载音频失败:', error); @@ -2659,7 +2762,7 @@ export default { // 检查页面是否需要会员且用户非会员,如果是则跳过 const pageRequiresMember = this.pagePay[i] === 'Y'; if (pageRequiresMember && !this.isMember) { - console.log(`第${i + 1}页需要会员,跳过预加载`); + continue; } @@ -2687,7 +2790,7 @@ export default { // 检查是否已经缓存 if (this.audioCache[cacheKey]) { - console.log(`第${pageIndex + 1}页音频已缓存,跳过`); + return; } @@ -2695,11 +2798,11 @@ export default { const textItems = pageData.filter(item => item.type === 'text' && item.content); if (textItems.length === 0) { - console.log(`第${pageIndex + 1}页没有文本内容,跳过`); + return; } - console.log(`第${pageIndex + 1}页有${textItems.length}个文本段落需要预加载`); + const audioArray = []; let totalDuration = 0; @@ -2709,14 +2812,14 @@ export default { const item = textItems[i]; try { - console.log(`第${pageIndex + 1}页处理第 ${i + 1}/${textItems.length} 个文本项,长度: ${item.content.length}`); + // 使用分批次请求音频 const batchResult = await this.requestAudioInBatches(item.content, this.localVoiceId); // 检查请求是否被取消 if (batchResult === null) { - console.log(`第${pageIndex + 1}页预加载被取消`); + return; } @@ -2762,7 +2865,7 @@ export default { timestamp: Date.now() // 保存时间戳 }; - console.log(`第${pageIndex + 1}页音频预加载完成,共${audioArray.length}个音频,总时长: ${totalDuration}秒`); + // 限制缓存大小 this.limitCacheSize(10); @@ -2775,11 +2878,11 @@ export default { const cachedData = this.audioCache[cacheKey]; if (cachedData && cachedData.audios && cachedData.audios.length > 0) { - console.log(`第${pageNumber}页音频已缓存,共${cachedData.audios.length}个音频`); + return true; } - console.log(`第${pageNumber}页音频未缓存`); + return false; }, @@ -2788,7 +2891,7 @@ export default { try { // 如果正在音色切换中,不自动播放 if (this.isVoiceChanging) { - console.log('音色切换中,跳过自动播放'); + return; } @@ -2796,11 +2899,11 @@ export default { const cachedData = this.audioCache[cacheKey]; if (!cachedData || !cachedData.audios || cachedData.audios.length === 0) { - console.log('当前页面没有缓存的音频'); + return; } - console.log(`开始自动播放第${this.currentPage}页的缓存音频`); + // 停止当前播放的音频 this.pauseAudio(); @@ -2825,7 +2928,7 @@ export default { } }, mounted() { - console.log('🎛️ AudioControls組件初始化開始'); + console.log('⚙️ 初始倍速配置:', { 默認播放速度: this.playSpeed + 'x', 可選速度選項: this.speedOptions.map(s => s + 'x'), @@ -2833,10 +2936,10 @@ export default { }); // 初始檢測播放速度支持 - console.log('🔍 開始檢測播放速度支持...'); + this.checkInitialPlaybackRateSupport(); - console.log('✅ AudioControls組件初始化完成'); + }, // 自动播放预加载的音频 @@ -2844,24 +2947,24 @@ export default { try { // 如果正在音色切换中,不自动播放 if (this.isVoiceChanging) { - console.log('音色切换中,跳过预加载音频自动播放'); + return; } // 检查是否有音频数据 if (!this.hasAudioData || this.currentPageAudios.length === 0) { - console.log('没有可播放的音频数据'); + return; } // 检查第一个音频是否有效 const firstAudio = this.currentPageAudios[0]; if (!firstAudio || !firstAudio.url) { - console.log('第一个音频无效'); + return; } - console.log('开始自动播放预加载音频'); + // 重置播放状态 this.currentAudioIndex = 0; @@ -2876,7 +2979,7 @@ export default { setTimeout(() => { if (this.currentAudio && !this.isPlaying) { this.currentAudio.play(); - console.log('预加载音频自动播放成功'); + } }, 200); @@ -2895,7 +2998,7 @@ export default { // 清理音频资源 this.destroyAudio(); - console.log('AudioControls组件已销毁,清理所有资源'); + } } diff --git a/subPages/home/book.vue b/subPages/home/book.vue index 7db149d..5079030 100644 --- a/subPages/home/book.vue +++ b/subPages/home/book.vue @@ -1,4 +1,4 @@ -