diff --git a/subPages/home/AudioControls.vue b/subPages/home/AudioControls.vue index b7c88df..2412684 100644 --- a/subPages/home/AudioControls.vue +++ b/subPages/home/AudioControls.vue @@ -272,6 +272,26 @@ export default { } }, methods: { + // 辅助方法:查找第一个非导语音频的索引 + findFirstNonLeadAudio() { + if (!this.currentPageAudios || this.currentPageAudios.length === 0) { + return -1; + } + + // 从第一个音频开始查找非导语音频 + for (let i = 0; i < this.currentPageAudios.length; i++) { + const audioData = this.currentPageAudios[i]; + if (audioData && !audioData.isLead) { + console.log(`🎵 findFirstNonLeadAudio: 找到第一个非导语音频,索引=${i}, isLead=${audioData.isLead}`); + return i; + } + } + + // 如果所有音频都是导语,返回第一个音频的索引 + console.log('🎵 findFirstNonLeadAudio: 所有音频都是导语,返回第一个音频索引=0'); + return 0; + }, + // 检查并自动加载预加载完成的音频 checkAndLoadPreloadedAudio() { // 只在需要加载音频的页面检查 @@ -317,22 +337,29 @@ export default { // 自动播放缓存的音频 this.$nextTick(() => { if (this.currentPageAudios.length > 0 && !this.isVoiceChanging) { - const firstAudioData = this.currentPageAudios[0]; - console.log(`🎵 自动播放缓存音频: ${firstAudioData.url}`); - audioManager.playAudio(firstAudioData.url, 'sentence', { playbackRate: this.playSpeed }); - this.isPlaying = true; - - // 页面切换时需要立即更新高亮和滚动,不受防抖机制影响 - const highlightIndex = firstAudioData.originalTextIndex !== undefined ? firstAudioData.originalTextIndex : 0; - this.currentHighlightIndex = highlightIndex; - - // 立即发送高亮变化事件 - this.emitHighlightChange(highlightIndex, firstAudioData); - - // 立即发送滚动事件,传入音频数据 - this.emitScrollToText(highlightIndex, firstAudioData); - - console.log(`🎵 页面切换自动播放: 高亮索引=${highlightIndex}, 页面=${this.currentPage}`); + // 查找第一个非导语音频 + const firstNonLeadIndex = this.findFirstNonLeadAudio(); + if (firstNonLeadIndex >= 0 && firstNonLeadIndex < this.currentPageAudios.length) { + // 设置当前音频索引为第一个非导语音频 + this.currentAudioIndex = firstNonLeadIndex; + const firstAudioData = this.currentPageAudios[firstNonLeadIndex]; + + console.log(`🎵 自动播放缓存音频(跳过导语): 索引=${firstNonLeadIndex}, isLead=${firstAudioData.isLead}, url=${firstAudioData.url}`); + audioManager.playAudio(firstAudioData.url, 'sentence', { playbackRate: this.playSpeed }); + this.isPlaying = true; + + // 页面切换时需要立即更新高亮和滚动,不受防抖机制影响 + const highlightIndex = firstAudioData.originalTextIndex !== undefined ? firstAudioData.originalTextIndex : firstNonLeadIndex; + this.currentHighlightIndex = highlightIndex; + + // 立即发送高亮变化事件 + this.emitHighlightChange(highlightIndex, firstAudioData); + + // 立即发送滚动事件,传入音频数据 + this.emitScrollToText(highlightIndex, firstAudioData); + + console.log(`🎵 页面切换自动播放(跳过导语): 高亮索引=${highlightIndex}, 页面=${this.currentPage}`); + } } }); } else { @@ -431,8 +458,6 @@ export default { let totalDuration = 0; const requestId = this.currentRequestId; // 保存当前请求ID - - for (let i = 0; i < segments.length; i++) { // 检查是否应该取消请求 if (this.shouldCancelRequest || this.currentRequestId !== requestId) { @@ -518,9 +543,6 @@ export default { // 🎯 确保音色ID已加载完成后再获取音频 if (!this.localVoiceId || this.localVoiceId === '' || this.localVoiceId === null || this.localVoiceId === undefined) { - - - // 设置加载失败状态 this.isAudioLoading = false; this.audioLoadFailed = true; @@ -732,12 +754,20 @@ export default { currentHighlightIndex: this.currentHighlightIndex }); - // 立即使用audioManager播放第一个音频 - const firstAudioData = this.currentPageAudios[0]; + // 立即使用audioManager播放第一个非导语音频 if (autoPlay || !this.isVoiceChanging) { - audioManager.playAudio(firstAudioData.url, 'sentence', { playbackRate: this.playSpeed }); - this.isPlaying = true; - this.updateHighlightIndex(); + // 查找第一个非导语音频 + const firstNonLeadIndex = this.findFirstNonLeadAudio(); + if (firstNonLeadIndex >= 0 && firstNonLeadIndex < this.currentPageAudios.length) { + // 设置当前音频索引为第一个非导语音频 + this.currentAudioIndex = firstNonLeadIndex; + const firstAudioData = this.currentPageAudios[firstNonLeadIndex]; + + console.log(`🎵 getCurrentPageAudio 自动播放(跳过导语): 索引=${firstNonLeadIndex}, isLead=${firstAudioData.isLead}`); + audioManager.playAudio(firstAudioData.url, 'sentence', { playbackRate: this.playSpeed }); + this.isPlaying = true; + this.updateHighlightIndex(); + } } } @@ -1098,14 +1128,40 @@ export default { return; } + // 如果当前索引无效,重置为第一个非导语音频 if (this.currentAudioIndex < 0 || this.currentAudioIndex >= this.currentPageAudios.length) { - console.error('🎵 playAudio: 音频索引无效', this.currentAudioIndex); - return; + console.log('🎵 playAudio: 音频索引无效,重置为第一个非导语音频'); + this.currentAudioIndex = this.findFirstNonLeadAudio(); + if (this.currentAudioIndex < 0) { + console.error('🎵 playAudio: 找不到有效的音频'); + return; + } } let currentAudioData = this.currentPageAudios[this.currentAudioIndex]; - + // 如果当前音频是导语,跳转到下一个非导语音频 + if (currentAudioData && currentAudioData.isLead) { + console.log(`🎵 playAudio: 当前音频是导语(索引=${this.currentAudioIndex}),查找下一个非导语音频`); + + // 从当前索引开始查找下一个非导语音频 + let nextNonLeadIndex = -1; + for (let i = this.currentAudioIndex; i < this.currentPageAudios.length; i++) { + const audioData = this.currentPageAudios[i]; + if (audioData && !audioData.isLead) { + nextNonLeadIndex = i; + break; + } + } + + if (nextNonLeadIndex >= 0) { + this.currentAudioIndex = nextNonLeadIndex; + currentAudioData = this.currentPageAudios[this.currentAudioIndex]; + console.log(`🎵 playAudio: 跳转到非导语音频,新索引=${this.currentAudioIndex}, isLead=${currentAudioData.isLead}`); + } else { + console.warn('🎵 playAudio: 没有找到非导语音频,播放当前音频'); + } + } if (!currentAudioData || !currentAudioData.url) { console.error('🎵 playAudio: 音频数据无效', currentAudioData); @@ -2518,7 +2574,7 @@ export default { // 添加小延迟,避免请求过于频繁 if (i < allTextPages.length - 1) { - await new Promise(resolve => setTimeout(resolve, 200)); + await new Promise(resolve => setTimeout(resolve, 100)); } } catch (error) { console.error(`预加载第 ${pageInfo.pageIndex} 页音频失败:`, error); @@ -2572,7 +2628,7 @@ export default { // 延迟一下,避免请求过于频繁 - await new Promise(resolve => setTimeout(resolve, 300)); + await new Promise(resolve => setTimeout(resolve, 150)); } catch (error) { console.error(`预加载第${pageInfo.pageIndex + 1}页音频失败:`, error); @@ -2693,9 +2749,9 @@ export default { console.error(`第${pageIndex + 1}页第${i + 1}个文本项处理异常:`, error); } - // 每个文本项处理之间间隔300ms,避免请求过于频繁 + // 每个文本项处理之间间隔150ms,避免请求过于频繁 if (i < textItems.length - 1) { - await new Promise(resolve => setTimeout(resolve, 300)); + await new Promise(resolve => setTimeout(resolve, 150)); } } diff --git a/subPages/home/book.vue b/subPages/home/book.vue index 70ba6f3..50990cd 100644 --- a/subPages/home/book.vue +++ b/subPages/home/book.vue @@ -1941,12 +1941,10 @@ export default { for (let i = 1; i <= preloadCount; i++) { if (i < this.courseIdList.length && this.bookPages[i].length === 0) { try { - await this.preloadSinglePage(this.courseIdList[i], i); - - // 每页之间间隔800ms,给服务器更多缓冲时间 + // 每页之间间隔400ms,提高预加载效率 if (i < preloadCount) { - await new Promise(resolve => setTimeout(resolve, 800)); + await new Promise(resolve => setTimeout(resolve, 0)); } } catch (error) { console.error(`预加载第${i + 1}页失败:`, error); @@ -1957,12 +1955,12 @@ export default { - // 延迟1.5秒后再通知AudioControls组件开始预加载音频,避免接口冲突 + // 延迟800ms后再通知AudioControls组件开始预加载音频,提高响应速度 setTimeout(() => { if (this.$refs.customTabbar && this.$refs.customTabbar.$refs.audioControls) { this.$refs.customTabbar.$refs.audioControls.startPreloadAudio(); } - }, 1500); + }, 800); } catch (error) { console.error('预加载页面内容失败:', error);