mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-18 19:01:20 -08:00
38 lines
1.4 KiB
TypeScript
38 lines
1.4 KiB
TypeScript
import type { WrappedCanvas } from 'mediabunny'
|
|
|
|
export type FrameIterator = Pick<AsyncGenerator<WrappedCanvas, void, unknown>, 'next' | 'return'>
|
|
const closing = new WeakMap<FrameIterator, Promise<void>>()
|
|
const reading = new WeakMap<FrameIterator, Promise<WrappedCanvas | null>>()
|
|
|
|
export function releaseIterator(iterator: FrameIterator | null): Promise<void> {
|
|
if (!iterator)
|
|
return Promise.resolve()
|
|
const previous = closing.get(iterator)
|
|
if (previous)
|
|
return previous
|
|
const pending = Promise.resolve().then(() => iterator.return()).then(() => {})
|
|
closing.set(iterator, pending)
|
|
return pending
|
|
}
|
|
|
|
export function readCanvas(iterator: FrameIterator): Promise<WrappedCanvas | null> {
|
|
const previous = reading.get(iterator)
|
|
if (previous)
|
|
return previous
|
|
const pending = Promise.resolve().then(() => iterator.next()).then(result => result.value ?? null)
|
|
reading.set(iterator, pending)
|
|
const clear = () => {
|
|
if (reading.get(iterator) === pending)
|
|
reading.delete(iterator)
|
|
}
|
|
pending.then(clear, clear)
|
|
return pending
|
|
}
|
|
|
|
export function frameAction(timestamp: number, time: number, dropLateFrames: boolean, avSyncTolerance: number, playbackRate: number): 'skip' | 'draw' | 'queue' {
|
|
const tolerance = dropLateFrames ? Math.max(0.06, avSyncTolerance / Math.max(1, playbackRate)) : 0
|
|
if (dropLateFrames && timestamp < time - tolerance)
|
|
return 'skip'
|
|
return timestamp <= time + tolerance ? 'draw' : 'queue'
|
|
}
|