mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-08 19:06:15 -08:00
114 lines
4.0 KiB
JavaScript
114 lines
4.0 KiB
JavaScript
import fs from 'node:fs'
|
|
import process from 'node:process'
|
|
import vm from 'node:vm'
|
|
import { verifyThumbnailContract } from '../../refactor/scripts/thumbnail-contract.mjs'
|
|
import { compilePackage } from './load.js'
|
|
|
|
export async function thumbnailCandidate() {
|
|
if (process.env.ARTPLAYER_THUMBNAIL_BASELINE === '1')
|
|
return thumbnailHistorical().find(item => item.name === 'workspace.js')
|
|
return { name: process.env.ARTPLAYER_THUMBNAIL_ARTIFACT ? 'candidate-artifact' : 'candidate-source', code: process.env.ARTPLAYER_THUMBNAIL_ARTIFACT ? fs.readFileSync(process.env.ARTPLAYER_THUMBNAIL_ARTIFACT, 'utf8') : await compilePackage('artplayer-tool-thumbnail', 'umd') }
|
|
}
|
|
|
|
export function thumbnailHistorical() {
|
|
const { source, historical } = verifyThumbnailContract()
|
|
return [
|
|
{ name: 'cdn-3.5.31', code: historical.get('packages/artplayer-tool-thumbnail/dist/artplayer-tool-thumbnail.js'), legacy: true },
|
|
...['.js', '.legacy.js'].map(suffix => ({ name: `workspace${suffix}`, code: source.get(`packages/artplayer-tool-thumbnail/dist/artplayer-tool-thumbnail${suffix}`), legacy: false })),
|
|
]
|
|
}
|
|
|
|
export function thumbnailEnvironment(implementation, script = false) {
|
|
const operations = []
|
|
const timers = new Map()
|
|
const blobs = []
|
|
const controls = { deferBlobs: false }
|
|
let nextTimer = 0
|
|
let nextUrl = 0
|
|
const context2D = Object.fromEntries(['fillRect', 'fillText', 'drawImage'].map(name => [name, (...args) => operations.push({ name, args })]))
|
|
class Element {
|
|
constructor(tagName = 'div') {
|
|
this.tagName = tagName.toUpperCase()
|
|
this.type = this.tagName === 'INPUT' ? 'file' : ''
|
|
this.style = {}
|
|
this.children = []
|
|
this.handlers = new Map()
|
|
this.files = []
|
|
if (this.tagName === 'VIDEO') {
|
|
this.duration = 0
|
|
this.videoWidth = 160
|
|
this.videoHeight = 90
|
|
this.currentTime = 0
|
|
this.canPlayType = () => 'probably'
|
|
}
|
|
}
|
|
|
|
appendChild(child) {
|
|
child.parentNode = this
|
|
this.children.push(child)
|
|
operations.push({ name: 'append', parent: this.tagName, child: child.tagName })
|
|
return child
|
|
}
|
|
|
|
removeChild(child) {
|
|
const index = this.children.indexOf(child)
|
|
if (index === -1)
|
|
throw new Error('NotFoundError')
|
|
this.children.splice(index, 1)
|
|
child.parentNode = null
|
|
return child
|
|
}
|
|
|
|
addEventListener(name, callback) {
|
|
operations.push({ name: 'listen', type: name, callback })
|
|
if (!callback)
|
|
return
|
|
const list = this.handlers.get(name) || new Set()
|
|
list.add(callback)
|
|
this.handlers.set(name, list)
|
|
}
|
|
|
|
removeEventListener(name, callback) { this.handlers.get(name)?.delete(callback) }
|
|
getContext() { return context2D }
|
|
click() { operations.push({ name: 'click', download: this.download, href: this.href }) }
|
|
toBlob(callback) {
|
|
if (controls.deferBlobs)
|
|
blobs.push(callback)
|
|
else
|
|
callback({ kind: 'image/png' })
|
|
}
|
|
}
|
|
const body = new Element('body')
|
|
const module = { exports: {} }
|
|
const box = {
|
|
Element,
|
|
document: { body, createElement: tag => new Element(tag) },
|
|
URL: {
|
|
createObjectURL(value) {
|
|
if (value == null)
|
|
throw new TypeError('Blob required')
|
|
const url = `blob:thumbnail-${++nextUrl}`
|
|
operations.push({ name: 'createURL', value, url })
|
|
return url
|
|
},
|
|
revokeObjectURL(url) { operations.push({ name: 'revokeURL', url }) },
|
|
},
|
|
setTimeout(callback, delay) {
|
|
const id = ++nextTimer
|
|
timers.set(id, { callback, delay })
|
|
return id
|
|
},
|
|
clearTimeout(id) { timers.delete(id) },
|
|
}
|
|
box.window = box
|
|
box.self = box
|
|
if (!script) {
|
|
box.module = module
|
|
box.exports = module.exports
|
|
}
|
|
vm.runInNewContext(implementation.code, box)
|
|
const exported = script ? box.ArtplayerToolThumbnail : module.exports
|
|
const Factory = exported.default || exported
|
|
return { box, Element, body, Factory, exported, operations, context2D, timers, blobs, controls }
|
|
}
|