|
|
|
@ -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)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|