修复讲解语音切换后播放器未刷新

- 暂停时切换语言或男女声同步刷新音轨、时长和进度
- 保持暂停状态,播放中继续自动切换新音轨
- 补充语音切换播放器刷新回归测试

Made-with: Proma
This commit is contained in:
lyf
2026-08-27 11:00:45 +08:00
parent 130f155bdf
commit ed52d22b63
3 changed files with 144 additions and 23 deletions

View File

@@ -695,10 +695,10 @@ const handleLanguageChange = async (lang: AudioLanguage, options: { syncAudio?:
}
}
void loadFullDetailTextForLanguage(request, lang, exhibit.value)
if (shouldContinueAudio) {
// The player must become actionable before resuming with the new language track.
if (options.syncAudio !== false && isCurrentDetailAudioTarget.value) {
// 语言切换后立即刷新播放器;原先暂停时不会更新音轨,导致组件仍显示旧内容。
languageSwitchLoading.value = false
await handlePlayAudio()
await handlePlayAudio({ autoplay: shouldContinueAudio })
}
} catch (error) {
if (requestSequence !== languageSwitchSequence) return
@@ -730,11 +730,12 @@ const handleLanguageChange = async (lang: AudioLanguage, options: { syncAudio?:
const handleToggleDetailAudioVoice = async () => {
if (audioDockState.value !== 'playable' || !canSwitchDetailAudioVoice.value) return
const shouldContinueAudio = isCurrentDetailAudioTarget.value && globalAudioPlayer.playing.value
const hasCurrentDetailAudio = isCurrentDetailAudioTarget.value
const shouldContinueAudio = hasCurrentDetailAudio && globalAudioPlayer.playing.value
selectedAudioGender.value = currentDetailAudioGender.value === 'male' ? 'female' : 'male'
if (shouldContinueAudio) {
await handlePlayAudio()
if (hasCurrentDetailAudio) {
await handlePlayAudio({ autoplay: shouldContinueAudio })
}
}
@@ -821,24 +822,30 @@ const refreshCurrentAudioOnce = async (message: string) => {
return null
}
const detailAudioPlayOptions = (audio: AudioItem) => ({
source: {
exhibitId: exhibit.value.id,
stopId: currentAudioTarget.value.stopId,
lang: selectedAudioLanguage.value,
channelCode: selectedDetailAudioOption.value?.channelCode,
voiceGender: currentDetailAudioGender.value,
audioOptions: activeDetailAudioOptions.value,
title: audio.name,
detailRoute: buildDetailRoute()
},
retryOnError: refreshCurrentAudioOnce,
displayMode: 'mini' as const
})
const playDetailAudio = async (audio: AudioItem) => {
await globalAudioPlayer.play(audio, {
source: {
exhibitId: exhibit.value.id,
stopId: currentAudioTarget.value.stopId,
lang: selectedAudioLanguage.value,
channelCode: selectedDetailAudioOption.value?.channelCode,
voiceGender: currentDetailAudioGender.value,
audioOptions: activeDetailAudioOptions.value,
title: audio.name,
detailRoute: buildDetailRoute()
},
retryOnError: refreshCurrentAudioOnce,
displayMode: 'mini'
})
await globalAudioPlayer.play(audio, detailAudioPlayOptions(audio))
}
const handlePlayAudio = async (options: { forceRefresh?: boolean } = {}) => {
const prepareDetailAudio = (audio: AudioItem) => {
globalAudioPlayer.prepare(audio, detailAudioPlayOptions(audio))
}
const handlePlayAudio = async (options: { forceRefresh?: boolean; autoplay?: boolean } = {}) => {
if (audioDockState.value === 'unavailable' || audioDockState.value === 'loading') return
if (audioDockState.value === 'failed' && !options.forceRefresh) {
@@ -859,7 +866,8 @@ const handlePlayAudio = async (options: { forceRefresh?: boolean } = {}) => {
? await refreshCurrentAudioOnce(globalAudioPlayer.error.value)
: null
if (refreshedAudio) {
await playDetailAudio(refreshedAudio)
if (options.autoplay === false) prepareDetailAudio(refreshedAudio)
else await playDetailAudio(refreshedAudio)
return
}
@@ -895,6 +903,10 @@ const handlePlayAudio = async (options: { forceRefresh?: boolean } = {}) => {
const audio = toAudioItem(selection)
if (!audio) return
if (options.autoplay === false) {
prepareDetailAudio(audio)
return
}
await playDetailAudio(audio)
}