Browse Source

fix(音频控制): 修复音频加载过程中参数不一致问题

在音频加载前对关键参数做快照,确保整个流程参数一致
添加元素位置缓存优化滚动性能
修复duration未定义时的默认值处理
main
前端-胡立永 3 days ago
parent
commit
3cf55eb7f2
2 changed files with 50 additions and 41 deletions
  1. +17
    -15
      subPages/home/AudioControls.vue
  2. +33
    -26
      subPages/home/book.vue

+ 17
- 15
subPages/home/AudioControls.vue View File

@ -581,7 +581,12 @@ export default {
console.log('this.audioCache:', this.audioCache); console.log('this.audioCache:', this.audioCache);
// //
const cacheKey = generateCacheKey(this.courseId, this.currentPage, this.localVoiceId);
//
const loadCourseId = this.courseId;
const loadPage = this.currentPage;
const loadVoiceId = this.localVoiceId;
const cacheKey = generateCacheKey(loadCourseId, loadPage, loadVoiceId);
if (this.audioCache[cacheKey]) { if (this.audioCache[cacheKey]) {
// //
@ -633,15 +638,15 @@ export default {
try { try {
// [] text // [] text
const currentPageData = this.bookPages[this.currentPage - 1];
console.log(`🎵 getCurrentPageAudio: 当前页面=${this.currentPage}, 音色ID=${this.localVoiceId}, 课程ID=${this.courseId}`);
const currentPageData = this.bookPages[loadPage - 1];
console.log(`🎵 getCurrentPageAudio: 当前页面=${loadPage}, 音色ID=${loadVoiceId}, 课程ID=${loadCourseId}`);
console.log(`🎵 getCurrentPageAudio: bookPages长度=${this.bookPages.length}, 当前页面数据:`, currentPageData); console.log(`🎵 getCurrentPageAudio: bookPages长度=${this.bookPages.length}, 当前页面数据:`, currentPageData);
// //
if (!currentPageData || currentPageData.length === 0) { if (!currentPageData || currentPageData.length === 0) {
console.log(`🎵 getCurrentPageAudio: 当前页面数据为空,可能还在加载中`); console.log(`🎵 getCurrentPageAudio: 当前页面数据为空,可能还在加载中`);
// //
this.$emit('page-data-needed', this.currentPage);
this.$emit('page-data-needed', loadPage);
// //
this.isAudioLoading = false; this.isAudioLoading = false;
@ -681,7 +686,7 @@ export default {
// 使 // 使
const batchResult = await this.requestAudioInBatches(item.content, this.localVoiceId);
const batchResult = await this.requestAudioInBatches(item.content, loadVoiceId);
// //
if (batchResult === null) { if (batchResult === null) {
@ -703,7 +708,7 @@ export default {
isLead : item.isLead, isLead : item.isLead,
url: segment.url, url: segment.url,
text: segment.text, text: segment.text,
duration: segment.duration,
duration: segment.duration || 0,
startIndex: segment.startIndex, startIndex: segment.startIndex,
endIndex: segment.endIndex, endIndex: segment.endIndex,
segmentIndex: segment.segmentIndex, segmentIndex: segment.segmentIndex,
@ -759,19 +764,17 @@ export default {
} }
} }
// //
if (this.currentPageAudios.length > 0) { if (this.currentPageAudios.length > 0) {
await this.calculateTotalDuration(); await this.calculateTotalDuration();
// //
const cacheKey = generateCacheKey(this.courseId, this.currentPage, this.localVoiceId);
const cacheKey = generateCacheKey(loadCourseId, loadPage, loadVoiceId);
this.audioCache[cacheKey] = { this.audioCache[cacheKey] = {
audios: [...this.currentPageAudios], // audios: [...this.currentPageAudios], //
totalDuration: this.totalTime, totalDuration: this.totalTime,
voiceId: this.localVoiceId, // ID
pageNumber: this.currentPage, //
voiceId: loadVoiceId, // ID
pageNumber: loadPage, //
timestamp: Date.now() // timestamp: Date.now() //
}; };
@ -1620,7 +1623,7 @@ export default {
const highlightData = { const highlightData = {
highlightIndex: currentAudioData.originalTextIndex !== undefined ? currentAudioData.originalTextIndex : highlightIndex, highlightIndex: currentAudioData.originalTextIndex !== undefined ? currentAudioData.originalTextIndex : highlightIndex,
isSegmented: currentAudioData.isSegmented || false, isSegmented: currentAudioData.isSegmented || false,
segmentIndex: currentAudioData.segmentIndex || 0,
segmentIndex: currentAudioData.segmentIndex,
startIndex: currentAudioData.startIndex || 0, startIndex: currentAudioData.startIndex || 0,
endIndex: currentAudioData.endIndex || 0, endIndex: currentAudioData.endIndex || 0,
currentText: currentAudioData.text || '' currentText: currentAudioData.text || ''
@ -2244,7 +2247,6 @@ export default {
// //
clearAudioCache() { clearAudioCache() {
this.audioCache = {}; this.audioCache = {};
}, },
// 访 // 访
@ -2717,7 +2719,7 @@ export default {
isLead: item.isLead, isLead: item.isLead,
url: segment.url, url: segment.url,
text: segment.text, text: segment.text,
duration: segment.duration,
duration: segment.duration || 0,
startIndex: segment.startIndex, startIndex: segment.startIndex,
endIndex: segment.endIndex, endIndex: segment.endIndex,
segmentIndex: segment.segmentIndex, segmentIndex: segment.segmentIndex,
@ -2725,7 +2727,7 @@ export default {
isSegmented: batchResult.audioSegments.length > 1 // isSegmented: batchResult.audioSegments.length > 1 //
}); });
totalDuration += segment.duration;
totalDuration += segment.duration || 0;
} }
} }


+ 33
- 26
subPages/home/book.vue View File

@ -57,6 +57,7 @@
'lead-text': isCardTextHighlighted(page, itemIndex), 'lead-text': isCardTextHighlighted(page, itemIndex),
'introduction-text' : item.isLead, 'introduction-text' : item.isLead,
}" }"
:id="`text-${itemIndex}`"
v-else-if="item && item.type === 'text' && item.content" v-else-if="item && item.type === 'text' && item.content"
@click.stop="handleTextClick(item.content, item, index)"> @click.stop="handleTextClick(item.content, item, index)">
<text v-for="(segment, segmentIndex) in processChineseText(item.content)" <text v-for="(segment, segmentIndex) in processChineseText(item.content)"
@ -211,6 +212,8 @@ export default {
pageWords: [], pageWords: [],
// //
pagePay: [], pagePay: [],
elementPositionsCache: {}, //
} }
}, },
onShow() { onShow() {
@ -519,19 +522,6 @@ export default {
}); });
}, },
//
// onScrollToText(refName) {
// try {
// console.log('🎯 onScrollToText :', refName);
//
// // scrollTo
// this.$scrollTo(refName);
//
// } catch (error) {
// console.error(' onScrollToText :', error);
// }
// },
// //
handleTextClick(textContent, item, pageIndex) { handleTextClick(textContent, item, pageIndex) {
@ -724,7 +714,7 @@ export default {
// //
if (this.shouldPreventAutoScroll()) { if (this.shouldPreventAutoScroll()) {
console.log('🚫 用户正在手动滚动,跳过自动滚动到文本');
// console.log('🚫 ');
return; return;
} }
@ -736,7 +726,7 @@ export default {
this.scrollDebounceTimer = setTimeout(() => { this.scrollDebounceTimer = setTimeout(() => {
// //
if (this.shouldPreventAutoScroll()) { if (this.shouldPreventAutoScroll()) {
console.log('🚫 防抖延迟后检测到用户手动滚动,跳过自动滚动到文本');
// console.log('🚫 ');
return; return;
} }
this.performScrollToText(scrollData); this.performScrollToText(scrollData);
@ -747,7 +737,7 @@ export default {
performScrollToText(scrollData) { performScrollToText(scrollData) {
// //
if (this.shouldPreventAutoScroll()) { if (this.shouldPreventAutoScroll()) {
console.log('🚫 执行滚动前检测到用户手动操作,取消自动滚动');
// console.log('🚫 ');
return; return;
} }
@ -845,13 +835,13 @@ export default {
} }
} else { } else {
// 使 // 使
console.log('🔄 精确计算失败,使用备用查询方法');
this.fallbackScrollToText(selector, resetScrollingState, safetyTimeout);
console.error('🔄 精确计算失败,使用备用查询方法');
//this.fallbackScrollToText(selector, resetScrollingState, safetyTimeout);
} }
} catch (error) { } catch (error) {
console.error('❌ 精确滚动计算失败:', error); console.error('❌ 精确滚动计算失败:', error);
// 使 // 使
this.fallbackScrollToText(selector, resetScrollingState, safetyTimeout);
//this.fallbackScrollToText(selector, resetScrollingState, safetyTimeout);
} }
}); });
}, },
@ -966,6 +956,13 @@ export default {
// //
async getAllElementPositions() { async getAllElementPositions() {
return new Promise((resolve) => { return new Promise((resolve) => {
//
if (this.elementPositionsCache[this.currentPage - 1]) {
resolve(this.elementPositionsCache[this.currentPage - 1]);
return;
}
const currentPageData = this.bookPages[this.currentPage - 1]; const currentPageData = this.bookPages[this.currentPage - 1];
if (!currentPageData || !Array.isArray(currentPageData)) { if (!currentPageData || !Array.isArray(currentPageData)) {
resolve([]); resolve([]);
@ -993,6 +990,7 @@ export default {
query.exec((res) => { query.exec((res) => {
const containerRect = res[0]; const containerRect = res[0];
console.log('getAllElementPositions res:', res, this.scrollTops[this.currentPage - 1]);
if (!containerRect) { if (!containerRect) {
resolve([]); resolve([]);
return; return;
@ -1004,12 +1002,14 @@ export default {
if (item && (item.type === 'text' || item.type === 'image' || item.type === 'video')) { if (item && (item.type === 'text' || item.type === 'image' || item.type === 'video')) {
const elementRect = res[resultIndex]; const elementRect = res[resultIndex];
if (elementRect) { if (elementRect) {
let top = elementRect.top - (containerRect.height / 2);
elementPositions.push({ elementPositions.push({
id : elementRect.id,
index: index, index: index,
type: item.type, type: item.type,
top: elementRect.top - containerRect.top,
top: top,
height: elementRect.height, height: elementRect.height,
bottom: elementRect.top - containerRect.top + elementRect.height
bottom: top + elementRect.height
}); });
} }
resultIndex++; resultIndex++;
@ -1018,6 +1018,12 @@ export default {
resolve(elementPositions); resolve(elementPositions);
}); });
}).then((elementPositions) => {
//
if (elementPositions.length > 0) {
this.elementPositionsCache[this.currentPage - 1] = elementPositions;
}
return elementPositions;
}); });
}, },
@ -1098,10 +1104,10 @@ export default {
let targetElementIndex = -1; let targetElementIndex = -1;
if (scrollData.segmentIndex !== undefined) {
//
targetElementIndex = scrollData.segmentIndex;
} else if (scrollData.highlightIndex !== undefined) {
// if (scrollData.segmentIndex !== undefined) {
// //
// targetElementIndex = scrollData.segmentIndex;
if (scrollData.highlightIndex !== undefined) {
// //
targetElementIndex = this.findTextItemIndex(scrollData.highlightIndex); targetElementIndex = this.findTextItemIndex(scrollData.highlightIndex);
} }
@ -1114,7 +1120,7 @@ export default {
const targetElement = elementPositions.find(pos => pos.index === targetElementIndex && pos.type === 'text'); const targetElement = elementPositions.find(pos => pos.index === targetElementIndex && pos.type === 'text');
if (!targetElement) { if (!targetElement) {
console.warn('未找到目标元素位置信息:', targetElementIndex);
console.error('未找到目标元素位置信息:', elementPositions, targetElementIndex);
return null; return null;
} }
@ -1859,6 +1865,7 @@ export default {
console.error('课程切换后音频加载失败:', error); console.error('课程切换后音频加载失败:', error);
} }
} }
this.getAllElementPositions()
}); });
// //


Loading…
Cancel
Save