mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-23 13:51:20 -08:00
84 lines
2.3 KiB
TypeScript
84 lines
2.3 KiB
TypeScript
import type { SubtitleView } from './types'
|
|
import { releaseSubtitleURL, subtitleState } from './state'
|
|
|
|
export function replaceSubtitleTrack(subtitle: SubtitleView, kind: string, url: string): void {
|
|
const state = subtitleState(subtitle)
|
|
if (state.scope.closed)
|
|
return
|
|
const revision = ++state.trackRevision
|
|
const { art } = subtitle
|
|
const { template } = art
|
|
const previous = template.$track
|
|
const parent = previous.parentNode
|
|
const next = previous.nextSibling
|
|
const track = document.createElement('track')
|
|
const scope = state.scope.child()
|
|
scope.add(() => {
|
|
track.onload = null
|
|
track.onerror = null
|
|
})
|
|
let committed = false
|
|
try {
|
|
track.default = true
|
|
track.kind = kind
|
|
track.src = url
|
|
track.label = art.option.subtitle.name || 'Artplayer'
|
|
track.track.mode = 'hidden'
|
|
track.onload = () => {
|
|
if (!scope.closed && template.$track === track)
|
|
art.emit('subtitleLoad', subtitle.cues, subtitle.option)
|
|
}
|
|
track.onerror = () => {
|
|
if (!scope.closed && template.$track === track)
|
|
art.notice.show = new Error('Failed to load subtitle track')
|
|
}
|
|
if (scope.closed || state.trackRevision !== revision) {
|
|
scope.dispose()
|
|
return
|
|
}
|
|
previous.remove()
|
|
template.$video.appendChild(track)
|
|
template.$track = track
|
|
const textTrack = subtitle.textTrack
|
|
const cleanup = textTrack
|
|
? art.proxy(textTrack, 'cuechange', () => {
|
|
if (!scope.closed && template.$track === track)
|
|
subtitle.update()
|
|
})
|
|
: () => {}
|
|
scope.add(() => {
|
|
art.events.remove(cleanup)
|
|
})
|
|
if (scope.closed || state.trackRevision !== revision) {
|
|
scope.dispose()
|
|
track.remove()
|
|
return
|
|
}
|
|
const previousScope = state.track
|
|
state.track = scope
|
|
subtitle.destroyEvent = cleanup
|
|
previous.onload = null
|
|
previous.onerror = null
|
|
committed = true
|
|
try {
|
|
previousScope?.dispose()
|
|
}
|
|
finally {
|
|
if (state.ownedURL && state.ownedURL !== url)
|
|
releaseSubtitleURL(state)
|
|
}
|
|
}
|
|
catch (error) {
|
|
if (committed)
|
|
throw error
|
|
scope.dispose()
|
|
track.remove()
|
|
if (state.scope.closed || state.trackRevision !== revision)
|
|
throw error
|
|
template.$track = previous
|
|
if (parent)
|
|
parent.insertBefore(previous, next?.parentNode === parent ? next : null)
|
|
throw error
|
|
}
|
|
}
|