Browse Source

feat(音频控制): 优化音频播放逻辑,支持跳过导语音频

- 缩短滚动安全超时时间从2秒到1.5秒
- 添加findFirstNonLeadAudioIndex方法查找非导语音频
- 修改音频播放逻辑,自动跳过导语音频
- 改进滚动位置估算算法,使用智能高度计算
- 更新音频加载条件判断,使用shouldLoadAudio替代isTextPage
hfll
hflllll 1 week ago
parent
commit
5fd6100fdd
2 changed files with 95 additions and 20 deletions
  1. +82
    -14
      subPages/home/AudioControls.vue
  2. +13
    -6
      subPages/home/book.vue

+ 82
- 14
subPages/home/AudioControls.vue View File

@ -6,13 +6,13 @@
</view> </view>
<!-- 音频加载中 --> <!-- 音频加载中 -->
<view v-else-if="isTextPage && isAudioLoading" class="audio-loading-container">
<view v-else-if="shouldLoadAudio && isAudioLoading" class="audio-loading-container">
<uv-loading-icon mode="spinner" size="30" color="#06DADC"></uv-loading-icon> <uv-loading-icon mode="spinner" size="30" color="#06DADC"></uv-loading-icon>
<text class="loading-text">{{currentPage}}页音频加载中请稍等...</text> <text class="loading-text">{{currentPage}}页音频加载中请稍等...</text>
</view> </view>
<!-- 正常音频控制栏 --> <!-- 正常音频控制栏 -->
<view v-else-if="isTextPage && hasAudioData" class="audio-controls">
<view v-else-if="shouldLoadAudio && hasAudioData" class="audio-controls">
<!-- 加载指示器 --> <!-- 加载指示器 -->
<view v-if="isAudioLoading" class="loading-indicator"> <view v-if="isAudioLoading" class="loading-indicator">
<uv-loading-icon mode="spinner" size="16" color="#06DADC"></uv-loading-icon> <uv-loading-icon mode="spinner" size="16" color="#06DADC"></uv-loading-icon>
@ -274,6 +274,16 @@ export default {
} }
}, },
methods: { methods: {
//
findFirstNonLeadAudioIndex() {
for (let i = 0; i < this.currentPageAudios.length; i++) {
if (!this.currentPageAudios[i].isLead) {
return i;
}
}
return -1; // -1
},
// HTML5 Audiouni-app // HTML5 Audiouni-app
createHTML5Audio() { createHTML5Audio() {
const audio = new Audio(); const audio = new Audio();
@ -426,7 +436,9 @@ export default {
this.totalTime = cachedAudio.totalDuration || 0; this.totalTime = cachedAudio.totalDuration || 0;
this.hasAudioData = true; this.hasAudioData = true;
this.isAudioLoading = false; this.isAudioLoading = false;
this.currentAudioIndex = 0;
//
const firstNonLeadIndex = this.findFirstNonLeadAudioIndex();
this.currentAudioIndex = firstNonLeadIndex >= 0 ? firstNonLeadIndex : 0;
this.currentTime = 0; this.currentTime = 0;
this.currentHighlightIndex = -1; this.currentHighlightIndex = -1;
@ -768,9 +780,27 @@ export default {
} }
if (currentPageData) { if (currentPageData) {
// text
const textItems = currentPageData.filter(item => item.type === 'text');
console.log(`🎵 getCurrentPageAudio: 找到${textItems.length}个文本项:`, textItems.map(item => item.content?.substring(0, 50) + '...'));
// text(isLeadtrue)
// language
const textItems = currentPageData.filter(item => {
if (item.type !== 'text' || item.isLead) {
return false;
}
//
const currentPageType = this.bookPages && this.bookPages[this.currentPage - 1]
? (this.bookPages[this.currentPage - 1].some(pageItem => pageItem.type === 'image') ? '1' : '0')
: '0';
// language
if (currentPageType === '1') {
return item.content && (item.language === 'en' || item.language === 'zh');
}
// content
return item.content;
});
console.log(`🎵 getCurrentPageAudio: 找到${textItems.length}个文本项(已排除导语):`, textItems.map(item => item.content?.substring(0, 50) + '...'));
if (textItems.length > 0) { if (textItems.length > 0) {
let firstAudioPlayed = false; // let firstAudioPlayed = false; //
@ -811,7 +841,8 @@ export default {
endIndex: segment.endIndex, endIndex: segment.endIndex,
segmentIndex: segment.segmentIndex, segmentIndex: segment.segmentIndex,
originalTextIndex: index, // originalTextIndex: index, //
isSegmented: batchResult.audioSegments.length > 1 //
isSegmented: batchResult.audioSegments.length > 1, //
isLead: item.isLead || false //
}; };
this.currentPageAudios.push(audioData); this.currentPageAudios.push(audioData);
loadedAudiosCount++; loadedAudiosCount++;
@ -822,7 +853,9 @@ export default {
if (!firstAudioPlayed && this.currentPageAudios.length > 0) { if (!firstAudioPlayed && this.currentPageAudios.length > 0) {
firstAudioPlayed = true; firstAudioPlayed = true;
this.hasAudioData = true; this.hasAudioData = true;
this.currentAudioIndex = 0;
//
const firstNonLeadIndex = this.findFirstNonLeadAudioIndex();
this.currentAudioIndex = firstNonLeadIndex >= 0 ? firstNonLeadIndex : 0;
@ -1828,6 +1861,13 @@ export default {
return; return;
} }
//
if (currentAudio.isLead) {
this.currentHighlightIndex = -1;
this.emitHighlightChange(-1);
return;
}
// //
const audioCacheKey = `${this.courseId}_${this.currentPage}_${this.localVoiceId}`; const audioCacheKey = `${this.courseId}_${this.currentPage}_${this.localVoiceId}`;
const currentPageCache = this.audioCache[audioCacheKey]; const currentPageCache = this.audioCache[audioCacheKey];
@ -1921,9 +1961,24 @@ export default {
// //
onAudioEnded() { onAudioEnded() {
if (this.currentAudioIndex < this.currentPageAudios.length - 1) { if (this.currentAudioIndex < this.currentPageAudios.length - 1) {
//
this.currentAudioIndex++;
this.playAudio();
//
let nextIndex = this.currentAudioIndex + 1;
while (nextIndex < this.currentPageAudios.length && this.currentPageAudios[nextIndex].isLead) {
console.log(`🎵 跳过导语音频: ${this.currentPageAudios[nextIndex].text}`);
nextIndex++;
}
if (nextIndex < this.currentPageAudios.length) {
//
this.currentAudioIndex = nextIndex;
this.playAudio();
} else {
//
this.isPlaying = false;
this.currentTime = this.totalTime;
this.currentHighlightIndex = -1;
this.$emit('highlight-change', -1);
}
// //
// setTimeout(() => { // setTimeout(() => {
@ -1933,9 +1988,22 @@ export default {
} else { } else {
// //
if (this.isLoop) { if (this.isLoop) {
//
this.currentAudioIndex = 0;
this.playAudio();
//
let firstNonLeadIndex = 0;
while (firstNonLeadIndex < this.currentPageAudios.length && this.currentPageAudios[firstNonLeadIndex].isLead) {
firstNonLeadIndex++;
}
if (firstNonLeadIndex < this.currentPageAudios.length) {
this.currentAudioIndex = firstNonLeadIndex;
this.playAudio();
} else {
//
this.isPlaying = false;
this.currentTime = this.totalTime;
this.currentHighlightIndex = -1;
this.$emit('highlight-change', -1);
}
// //
// setTimeout(() => { // setTimeout(() => {


+ 13
- 6
subPages/home/book.vue View File

@ -795,7 +795,7 @@ export default {
console.warn('⚠️ 滚动状态安全超时,强制重置'); console.warn('⚠️ 滚动状态安全超时,强制重置');
resetScrollingState(); resetScrollingState();
} }
}, 2000); // 2
}, 1500); // 1.5
if (!scrollData || typeof scrollData.highlightIndex !== 'number' || scrollData.highlightIndex < 0) { if (!scrollData || typeof scrollData.highlightIndex !== 'number' || scrollData.highlightIndex < 0) {
console.warn('滚动数据无效:', scrollData); console.warn('滚动数据无效:', scrollData);
@ -827,13 +827,14 @@ export default {
selector = `#text-segment-${scrollData.segmentIndex}`; selector = `#text-segment-${scrollData.segmentIndex}`;
} else { } else {
// //
// originalTextIndexDOM
// highlightIndex
const targetItemIndex = this.findTextItemIndex(scrollData.highlightIndex); const targetItemIndex = this.findTextItemIndex(scrollData.highlightIndex);
if (targetItemIndex !== -1) { if (targetItemIndex !== -1) {
selector = `#text-${targetItemIndex}`; selector = `#text-${targetItemIndex}`;
} else { } else {
console.warn('无法找到对应的文本元素索引:', scrollData.highlightIndex); console.warn('无法找到对应的文本元素索引:', scrollData.highlightIndex);
selector = `#text-${scrollData.highlightIndex}`; //
// 使highlightIndex
selector = `#text-${scrollData.highlightIndex}`;
} }
} }
@ -910,11 +911,17 @@ export default {
highlightIndex: scrollData.highlightIndex highlightIndex: scrollData.highlightIndex
}); });
//
//
if (!targetRect) { if (!targetRect) {
console.log('🔄 尝试备用滚动方案'); console.log('🔄 尝试备用滚动方案');
const fallbackScrollTop = scrollData.highlightIndex * 100; //
this.$set(this.scrollTops, this.currentPage - 1, fallbackScrollTop);
//
const currentPageData = this.bookPages[this.currentPage - 1];
if (currentPageData && Array.isArray(currentPageData)) {
//
const estimatedItemHeight = 80; //
const fallbackScrollTop = scrollData.highlightIndex * estimatedItemHeight;
this.$set(this.scrollTops, this.currentPage - 1, Math.max(0, fallbackScrollTop));
}
setTimeout(() => { setTimeout(() => {
resetScrollingState(); resetScrollingState();
}, 300); }, 300);


Loading…
Cancel
Save