mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-12 06:26:16 -08:00
56 lines
2.0 KiB
TypeScript
56 lines
2.0 KiB
TypeScript
import { hasDimensions } from './geometry'
|
|
|
|
export type DrawCallback = (context: CanvasRenderingContext2D, video: HTMLVideoElement) => void
|
|
|
|
export function createRenderer(canvas: HTMLCanvasElement, video: HTMLVideoElement, callback: DrawCallback | undefined, notify: DrawCallback, error: (failure: unknown) => void) {
|
|
const context = canvas.getContext('2d')
|
|
let reported = false
|
|
return {
|
|
available() {
|
|
if (context)
|
|
return true
|
|
if (!reported) {
|
|
reported = true
|
|
error(new Error('Canvas 2D context is unavailable'))
|
|
}
|
|
return false
|
|
},
|
|
async draw(valid: () => boolean): Promise<void> {
|
|
const usable = () => valid() && video.readyState >= 2 && !video.seeking
|
|
if (!context || !usable() || !hasDimensions(video) || !canvas.width || !canvas.height)
|
|
return
|
|
let acquiring = false
|
|
try {
|
|
if (typeof createImageBitmap !== 'undefined') {
|
|
acquiring = true
|
|
const bitmap = await createImageBitmap(video)
|
|
acquiring = false
|
|
try {
|
|
if (usable())
|
|
context.drawImage(bitmap, 0, 0, canvas.width, canvas.height)
|
|
}
|
|
finally { bitmap.close() }
|
|
}
|
|
else {
|
|
context.drawImage(video, 0, 0, canvas.width, canvas.height)
|
|
}
|
|
if (!usable())
|
|
return
|
|
if (callback)
|
|
callback(context, video)
|
|
if (usable())
|
|
notify(context, video)
|
|
}
|
|
catch (failure) {
|
|
// Chromium can expose readyState 4 before its first frame is usable.
|
|
// Other engines report zero frame counts even while drawing successfully.
|
|
const awaitingFirstFrame = acquiring && typeof failure === 'object' && failure !== null && 'name' in failure
|
|
&& failure.name === 'InvalidStateError' && video.currentTime === 0
|
|
&& typeof video.getVideoPlaybackQuality === 'function' && video.getVideoPlaybackQuality().totalVideoFrames === 0
|
|
if (usable() && !awaitingFirstFrame)
|
|
error(failure)
|
|
}
|
|
},
|
|
}
|
|
}
|