mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-24 06:31:20 -08:00
refactor(thumbnail): [PKG-TOOL-THUMB-04] type runtime modules and retain emitter attribution
This commit is contained in:
1 parent
efd9f42fb9
commit
15485b6420
37 files changed
+8446
-152
No files matched your search
@@ -0,0 +1,115 @@
|
||||
import type ArtplayerToolThumbnail from './index'
|
||||
import type { Cleanup } from './types'
|
||||
import { cleanupAll, revoke, stateFor } from './lifecycle'
|
||||
|
||||
export function loadSource(tool: ArtplayerToolThumbnail, file?: File | null) {
|
||||
const state = stateFor(tool)
|
||||
if (!file || state.closed)
|
||||
return
|
||||
const initialEpoch = state.epoch
|
||||
const video = tool.video
|
||||
const support = video.canPlayType(file.type)
|
||||
tool.errorHandle(support === 'maybe' || support === 'probably', `Playback of this file format is not supported: ${file.type}`)
|
||||
if (state.closed || state.epoch !== initialEpoch)
|
||||
return
|
||||
const url = URL.createObjectURL(file)
|
||||
state.sourceUrls.add(url)
|
||||
if (state.closed || state.epoch !== initialEpoch) {
|
||||
revoke(state.sourceUrls, url)
|
||||
return
|
||||
}
|
||||
const epoch = ++state.epoch
|
||||
const initialWait = !state.sourceUrl && !tool.file && state.job?.adopt(epoch)
|
||||
if (!initialWait)
|
||||
state.job?.cancel('source changed')
|
||||
state.loading = true
|
||||
const current = () => !state.closed && state.epoch === epoch
|
||||
const previousListeners = state.sourceListeners
|
||||
const listeners: Cleanup[] = []
|
||||
state.sourceListeners = listeners
|
||||
let pendingCleanup = () => {}
|
||||
let reported = false
|
||||
const error = () => {
|
||||
if (!current() || reported || (video.currentSrc && video.currentSrc !== url))
|
||||
return
|
||||
reported = true
|
||||
state.loading = false
|
||||
const failure = new Error(`Unable to load video: media error ${video.error?.code || 0}`)
|
||||
if (state.job)
|
||||
state.job.fail(failure)
|
||||
else
|
||||
tool.emit('error', failure.message)
|
||||
}
|
||||
const ready = () => {
|
||||
if (current() && (!video.currentSrc || video.currentSrc === url)) {
|
||||
state.loading = false
|
||||
state.job?.ready()
|
||||
}
|
||||
}
|
||||
try {
|
||||
cleanupAll(previousListeners.splice(0))
|
||||
if (!current()) {
|
||||
revoke(state.sourceUrls, url)
|
||||
return
|
||||
}
|
||||
for (const [name, callback] of [['error', error], ['loadedmetadata', ready]] as const) {
|
||||
pendingCleanup = () => video.removeEventListener(name, callback)
|
||||
listeners.push(pendingCleanup)
|
||||
video.addEventListener(name, callback)
|
||||
if (!current()) {
|
||||
cleanupAll([pendingCleanup, ...listeners.splice(0)])
|
||||
revoke(state.sourceUrls, url)
|
||||
return
|
||||
}
|
||||
}
|
||||
tool.videoUrl = url
|
||||
tool.file = file
|
||||
tool.emit('file', file)
|
||||
if (!current()) {
|
||||
revoke(state.sourceUrls, url)
|
||||
return
|
||||
}
|
||||
video.src = url
|
||||
if (!current()) {
|
||||
revoke(state.sourceUrls, url)
|
||||
return
|
||||
}
|
||||
state.sourceUrl = url
|
||||
for (const previous of [...state.sourceUrls]) {
|
||||
if (previous !== url)
|
||||
revoke(state.sourceUrls, previous)
|
||||
}
|
||||
if (current())
|
||||
tool.emit('video', video)
|
||||
}
|
||||
catch (error) {
|
||||
if (current()) {
|
||||
state.loading = false
|
||||
state.job?.cancel('source setup failed')
|
||||
}
|
||||
try {
|
||||
cleanupAll([pendingCleanup, ...listeners.splice(0)])
|
||||
}
|
||||
catch {}
|
||||
revoke(state.sourceUrls, url)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
export function replaceThumbnail(tool: ArtplayerToolThumbnail, blob: Blob, live: () => boolean) {
|
||||
const state = stateFor(tool)
|
||||
const url = URL.createObjectURL(blob)
|
||||
state.thumbnailUrls.add(url)
|
||||
if (!live()) {
|
||||
revoke(state.thumbnailUrls, url)
|
||||
return null
|
||||
}
|
||||
const previous = new Set([...state.thumbnailUrls, tool.thumbnailUrl])
|
||||
state.thumbnailUrl = url
|
||||
tool.thumbnailUrl = url
|
||||
for (const old of previous) {
|
||||
if (old && old !== url)
|
||||
revoke(state.thumbnailUrls, old)
|
||||
}
|
||||
return live() ? url : null
|
||||
}
|
||||
Reference in new issue
Block a user