@@ -4,19 +4,20 @@ import type {
|
||||
AudioItem
|
||||
} from '@/components/audio/AudioPlayer.vue'
|
||||
import {
|
||||
audioPlayInfoRepository,
|
||||
audioReasonToText,
|
||||
type AudioLanguage
|
||||
} from '@/repositories/AudioPlayInfoRepository'
|
||||
import type { AudioPlayTargetType } from '@/domain/museum'
|
||||
import type { AudioPlayTargetType, MuseumGuideAudioOption } from '@/domain/museum'
|
||||
import { resolveGuideAudioOption } from '@/domain/guideAudioOptions'
|
||||
|
||||
export interface GlobalAudioSource {
|
||||
exhibitId?: string
|
||||
stopId?: string
|
||||
targetType?: AudioPlayTargetType
|
||||
targetId?: string
|
||||
lang?: AudioLanguage | string
|
||||
channelCode?: string
|
||||
voiceGender?: 'male' | 'female'
|
||||
audioOptions?: MuseumGuideAudioOption[]
|
||||
detailRoute?: string
|
||||
title?: string
|
||||
}
|
||||
@@ -192,14 +193,14 @@ const updateDetailRouteLanguage = (route: string | undefined, lang: AudioLanguag
|
||||
}
|
||||
|
||||
const toSwitchedAudioItem = (
|
||||
playInfo: Awaited<ReturnType<typeof audioPlayInfoRepository.getPlayInfo>>,
|
||||
audioOption: MuseumGuideAudioOption,
|
||||
lang: AudioLanguage
|
||||
): AudioItem => ({
|
||||
id: `play-${playInfo.audioId || `${playInfo.targetType}-${playInfo.targetId}-${lang}`}`,
|
||||
name: currentAudio.value?.name || currentSource.value?.title || playInfo.title || '讲解音频',
|
||||
audioUrl: playInfo.playUrl || '',
|
||||
id: `channel-${audioOption.channelCode}`,
|
||||
name: currentAudio.value?.name || currentSource.value?.title || audioOption.displayName || '讲解音频',
|
||||
audioUrl: audioOption.playUrl,
|
||||
image: currentAudio.value?.image,
|
||||
duration: typeof playInfo.duration === 'number' ? playInfo.duration : currentAudio.value?.duration,
|
||||
duration: audioOption.duration || currentAudio.value?.duration,
|
||||
language: lang,
|
||||
supportedLanguages: currentAudio.value?.supportedLanguages
|
||||
})
|
||||
@@ -292,7 +293,7 @@ const switchLanguage = async (lang: AudioLanguage) => {
|
||||
}
|
||||
|
||||
const source = currentSource.value
|
||||
if (!source?.targetType || !source.targetId) {
|
||||
if (!source?.audioOptions?.length) {
|
||||
error.value = '当前讲解暂不支持语言切换'
|
||||
showToast(error.value)
|
||||
return false
|
||||
@@ -318,20 +319,19 @@ const switchLanguage = async (lang: AudioLanguage) => {
|
||||
}
|
||||
|
||||
try {
|
||||
const playInfo = await audioPlayInfoRepository.getPlayInfo({
|
||||
targetType: source.targetType,
|
||||
targetId: source.targetId,
|
||||
const audioOption = resolveGuideAudioOption(
|
||||
source.audioOptions,
|
||||
lang,
|
||||
refresh: true
|
||||
})
|
||||
source.voiceGender || 'female'
|
||||
)
|
||||
|
||||
if (!playInfo.playable || !playInfo.playUrl) {
|
||||
if (!audioOption?.playUrl) {
|
||||
stopAudioElement()
|
||||
currentSource.value = nextSource
|
||||
currentAudio.value = currentAudio.value
|
||||
? {
|
||||
...currentAudio.value,
|
||||
id: `unavailable-${source.targetType}-${source.targetId}-${lang}`,
|
||||
id: `unavailable-${source.stopId || source.targetId || source.exhibitId || 'detail'}-${lang}`,
|
||||
audioUrl: '',
|
||||
duration: 0,
|
||||
language: lang
|
||||
@@ -343,14 +343,19 @@ const switchLanguage = async (lang: AudioLanguage) => {
|
||||
loading.value = false
|
||||
currentTime.value = 0
|
||||
duration.value = 0
|
||||
error.value = audioReasonToText(playInfo.reason || 'NO_PUBLISHED_AUDIO')
|
||||
error.value = '当前语言暂无语音讲解'
|
||||
showToast(error.value)
|
||||
return false
|
||||
}
|
||||
|
||||
currentSource.value = nextSource
|
||||
return await play(toSwitchedAudioItem(playInfo, lang), {
|
||||
source: nextSource,
|
||||
const nextTrackSource: GlobalAudioSource = {
|
||||
...nextSource,
|
||||
channelCode: audioOption.channelCode,
|
||||
voiceGender: audioOption.gender
|
||||
}
|
||||
currentSource.value = nextTrackSource
|
||||
return await play(toSwitchedAudioItem(audioOption, lang), {
|
||||
source: nextTrackSource,
|
||||
retryOnError: retryOnError || undefined,
|
||||
displayMode: preservedMode
|
||||
})
|
||||
@@ -361,7 +366,7 @@ const switchLanguage = async (lang: AudioLanguage) => {
|
||||
if (currentAudio.value) {
|
||||
currentAudio.value = {
|
||||
...currentAudio.value,
|
||||
id: `unavailable-${source.targetType}-${source.targetId}-${lang}`,
|
||||
id: `unavailable-${source.stopId || source.targetId || source.exhibitId || 'detail'}-${lang}`,
|
||||
audioUrl: '',
|
||||
duration: 0,
|
||||
language: lang
|
||||
@@ -462,14 +467,16 @@ const unregisterHost = (hostId: string) => {
|
||||
}
|
||||
}
|
||||
|
||||
const isCurrentSource = (source: Pick<GlobalAudioSource, 'targetType' | 'targetId' | 'lang' | 'channelCode'>) => {
|
||||
const isCurrentSource = (source: Pick<GlobalAudioSource, 'stopId' | 'targetType' | 'targetId' | 'lang' | 'channelCode'>) => {
|
||||
if (!currentAudio.value || !currentSource.value) return false
|
||||
|
||||
return Boolean(
|
||||
source.targetType
|
||||
&& source.targetId
|
||||
&& currentSource.value.targetType === source.targetType
|
||||
&& currentSource.value.targetId === source.targetId
|
||||
(source.stopId
|
||||
? currentSource.value.stopId === source.stopId || currentSource.value.targetId === source.stopId
|
||||
: source.targetType
|
||||
&& source.targetId
|
||||
&& currentSource.value.targetType === source.targetType
|
||||
&& currentSource.value.targetId === source.targetId)
|
||||
&& (!source.lang || !currentSource.value.lang || currentSource.value.lang === source.lang)
|
||||
&& (!source.channelCode || currentSource.value.channelCode === source.channelCode)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user