mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-08 10:56:15 -08:00
91 lines
4.4 KiB
JavaScript
91 lines
4.4 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import fs from 'node:fs'
|
|
import process from 'node:process'
|
|
// eslint-disable-next-line test/no-import-node-test -- Exercise cancellation after a native media error without depending on browser timing.
|
|
import test from 'node:test'
|
|
import { asrAudioEnvironment, deferredAudio } from './helpers/asr-audio.js'
|
|
import { compilePackage } from './helpers/load.js'
|
|
|
|
const artifact = process.env.ARTPLAYER_ASR_ARTIFACT
|
|
const implementation = { name: artifact || 'candidate-asr', code: artifact ? fs.readFileSync(artifact, 'utf8') : await compilePackage('artplayer-plugin-asr', 'umd') }
|
|
|
|
for (const capture of [false, true]) {
|
|
const option = capture ? { audioInput: { type: 'capture' } } : {}
|
|
test(`ASR media error cancels pending recognition and permits ${capture ? 'capture' : 'direct'} recovery`, async () => {
|
|
const pending = deferredAudio()
|
|
let calls = 0
|
|
const environment = asrAudioEnvironment(implementation, { ...option, sampleRate: 8000, interval: 1, onAudioChunk: () => ++calls === 1 ? pending.promise : 'Recovered' })
|
|
await environment.emit('play')
|
|
environment.send(new Float32Array(8).fill(0.5))
|
|
const recognizing = environment.tick()
|
|
assert.equal(calls, 1)
|
|
const oldMessage = environment.recorders[0].port.onmessage
|
|
await environment.emit('video:error')
|
|
assert.equal(environment.intervals.size, 0, 'Media error must stop collection even without a pause event')
|
|
assert.equal(environment.recorders[0].port.onmessage, null)
|
|
pending.resolve('Obsolete')
|
|
await recognizing
|
|
assert.equal(environment.layer.innerHTML, '')
|
|
assert.equal(environment.timeouts.size, 0)
|
|
assert.equal(environment.contexts[0].state, capture ? 'closed' : 'running')
|
|
assert.equal(environment.tracks[0].stops, capture ? 1 : 0)
|
|
oldMessage({ data: new Float32Array(8).fill(1) })
|
|
assert.equal(calls, 1)
|
|
await environment.emit('play')
|
|
assert.equal(environment.contexts.length, capture ? 2 : 1)
|
|
assert.equal(environment.intervals.size, 1)
|
|
environment.send(new Float32Array(8).fill(0.25))
|
|
await environment.tick()
|
|
assert.match(environment.layer.innerHTML, /Recovered/)
|
|
await environment.emit('destroy')
|
|
assert(environment.contexts.every(context => context.state === 'closed'))
|
|
assert.equal(environment.listeners.get('video:error').length, 0)
|
|
})
|
|
|
|
test(`ASR media error during ${capture ? 'capture' : 'direct'} worklet loading cancels late initialization`, async () => {
|
|
const moduleGate = deferredAudio()
|
|
const moduleEntered = deferredAudio()
|
|
const environment = asrAudioEnvironment(implementation, option, { moduleGate, moduleEntered })
|
|
const starting = environment.emit('play')
|
|
await moduleEntered.promise
|
|
await environment.emit('video:error')
|
|
moduleGate.resolve()
|
|
await starting
|
|
assert.equal(environment.contexts[0].state, 'closed')
|
|
assert.equal(environment.recorders.length, 0)
|
|
assert.equal(environment.nodes.filter(node => ['element', 'stream'].includes(node.kind)).length, 0)
|
|
assert.equal(environment.intervals.size, 0)
|
|
assert.equal(environment.blobs.size, 0)
|
|
assert.equal(environment.errors.length, 0)
|
|
await environment.emit('play')
|
|
assert.equal(environment.intervals.size, 1)
|
|
await environment.emit('destroy')
|
|
assert(environment.contexts.every(context => context.state === 'closed'))
|
|
})
|
|
}
|
|
|
|
test('ASR media error cancels a capture restart waiting for close without hiding an existing subtitle', async () => {
|
|
const environment = asrAudioEnvironment(implementation, { audioInput: { type: 'capture' } })
|
|
environment.plugin.append('Existing')
|
|
const timers = [...environment.timeouts.keys()]
|
|
await environment.emit('play')
|
|
const closing = deferredAudio()
|
|
const close = environment.contexts[0].close.bind(environment.contexts[0])
|
|
environment.contexts[0].close = async () => {
|
|
await close()
|
|
await closing.promise
|
|
}
|
|
const restarting = environment.emit('restart')
|
|
const failing = environment.emit('video:error')
|
|
closing.resolve()
|
|
await Promise.all([restarting, failing])
|
|
assert.equal(environment.captures(), 1)
|
|
assert.equal(environment.intervals.size, 0)
|
|
assert.match(environment.layer.innerHTML, /Existing/)
|
|
assert.deepEqual([...environment.timeouts.keys()], timers)
|
|
await environment.emit('destroy')
|
|
await environment.emit('video:error')
|
|
assert.equal(environment.timeouts.size, 0)
|
|
assert.equal(environment.contexts.length, 1)
|
|
})
|