mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-12 06:26:16 -08:00
refactor(audio): [PKG-AUDIO-03] separate track ownership and native lifecycle
This commit is contained in:
1 parent
803e87252e
commit
9c07ea830c
20 files changed
+12654
-250
No files matched your search
+31
-20
@@ -1,10 +1,27 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { Buffer } from 'node:buffer'
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import process from 'node:process'
|
||||
import vm from 'node:vm'
|
||||
import { ensureArchive, hash, readMember } from '../../refactor/scripts/releases.mjs'
|
||||
import { loadPackage } from './load.js'
|
||||
|
||||
async function readFactory(bytes, esm) {
|
||||
if (esm)
|
||||
return (await import(`data:text/javascript;base64,${Buffer.from(bytes).toString('base64')}`)).default
|
||||
const context = {
|
||||
module: { exports: {} },
|
||||
Audio: function Audio() {
|
||||
return new globalThis.Audio()
|
||||
},
|
||||
console,
|
||||
}
|
||||
context.exports = context.module.exports
|
||||
vm.runInNewContext(bytes.toString(), context, { timeout: 5000 })
|
||||
return context.module.exports
|
||||
}
|
||||
|
||||
export async function audioImplementations() {
|
||||
const { release } = JSON.parse(fs.readFileSync(new URL('../../refactor/baselines/audio-track-release.json', import.meta.url)))
|
||||
const archive = await ensureArchive(release)
|
||||
@@ -13,29 +30,16 @@ export async function audioImplementations() {
|
||||
const member = `package/${release.manifest[format].replace(/^\.\//, '')}`
|
||||
const bytes = readMember(archive, member)
|
||||
assert.equal(hash(bytes), release.files[member])
|
||||
let factory
|
||||
if (format === 'module') {
|
||||
factory = (await import(`data:text/javascript;base64,${Buffer.from(bytes).toString('base64')}`)).default
|
||||
}
|
||||
else {
|
||||
const context = {
|
||||
module: { exports: {} },
|
||||
Audio: function Audio() {
|
||||
return new globalThis.Audio()
|
||||
},
|
||||
console,
|
||||
}
|
||||
context.exports = context.module.exports
|
||||
vm.runInNewContext(bytes.toString(), context, { timeout: 5000 })
|
||||
factory = context.module.exports
|
||||
}
|
||||
const factory = await readFactory(bytes, format === 'module')
|
||||
implementations.push({ name: `published-${format}`, factory })
|
||||
}
|
||||
for (const file of (process.env.ARTPLAYER_TEST_AUDIO || '').split(path.delimiter).filter(Boolean))
|
||||
implementations.push({ name: `artifact-${path.basename(file)}`, factory: await readFactory(fs.readFileSync(file), file.endsWith('.mjs')) })
|
||||
return implementations
|
||||
}
|
||||
|
||||
// Records plugin intent only. It does not decode media or emulate browser timing.
|
||||
export function audioHost(t) {
|
||||
export function audioHost(t, initialize = () => {}) {
|
||||
const instances = []
|
||||
const warnings = []
|
||||
let play = () => Promise.resolve()
|
||||
@@ -43,17 +47,20 @@ export function audioHost(t) {
|
||||
constructor() {
|
||||
instances.push(this)
|
||||
this.calls = []
|
||||
this.values = new Map()
|
||||
this.paused = true
|
||||
for (const [name, initial] of Object.entries({ src: '', preload: '', currentTime: 0, playbackRate: 1, volume: 1, muted: false })) {
|
||||
let value = initial
|
||||
this.values.set(name, initial)
|
||||
Object.defineProperty(this, name, {
|
||||
get: () => value,
|
||||
configurable: true,
|
||||
get: () => this.values.get(name),
|
||||
set: (next) => {
|
||||
this.calls.push([name, next])
|
||||
value = next
|
||||
this.values.set(name, next)
|
||||
},
|
||||
})
|
||||
}
|
||||
initialize(this)
|
||||
}
|
||||
|
||||
play() {
|
||||
@@ -63,6 +70,10 @@ export function audioHost(t) {
|
||||
|
||||
pause() { this.calls.push(['pause']) }
|
||||
load() { this.calls.push(['load']) }
|
||||
removeAttribute(name) {
|
||||
this.calls.push(['removeAttribute', name])
|
||||
this.values.set(name, '')
|
||||
}
|
||||
}
|
||||
const descriptor = Object.getOwnPropertyDescriptor(globalThis, 'Audio')
|
||||
Object.defineProperty(globalThis, 'Audio', { configurable: true, value: Audio })
|
||||
|
||||
Reference in new issue
Block a user