feat: support render to offscreen canvas

This commit is contained in:
三三 2024-06-18 12:20:46 +08:00 committed by Simon Chan
parent b62419fa3e
commit 5ca67b8ada
4 changed files with 15 additions and 6 deletions

View file

@ -11,7 +11,7 @@ export interface ScrcpyVideoDecoderCapability {
} }
export interface ScrcpyVideoDecoder extends Disposable { export interface ScrcpyVideoDecoder extends Disposable {
readonly renderer: HTMLElement; readonly renderer: HTMLElement | OffscreenCanvas;
readonly sizeChanged: Event<{ width: number; height: number }>; readonly sizeChanged: Event<{ width: number; height: number }>;
readonly framesRendered: number; readonly framesRendered: number;
readonly framesSkipped: number; readonly framesSkipped: number;

View file

@ -36,7 +36,7 @@ export class WebCodecsVideoDecoder implements ScrcpyVideoDecoder {
return this.#writable; return this.#writable;
} }
#canvas: HTMLCanvasElement; #canvas: HTMLCanvasElement | OffscreenCanvas;
get renderer() { get renderer() {
return this.#canvas; return this.#canvas;
} }
@ -68,11 +68,20 @@ export class WebCodecsVideoDecoder implements ScrcpyVideoDecoder {
* @param enableCapture * @param enableCapture
* Whether to allow capturing the canvas content using APIs like `readPixels` and `toDataURL`. * Whether to allow capturing the canvas content using APIs like `readPixels` and `toDataURL`.
* Enable this option may reduce performance. * Enable this option may reduce performance.
* @param canvas Optional render target cavas element or offscreen canvas
*/ */
constructor(codec: ScrcpyVideoCodecId, enableCapture: boolean) { constructor(codec: ScrcpyVideoCodecId, enableCapture: boolean, canvas?: HTMLCanvasElement | OffscreenCanvas) {
this.#codec = codec; this.#codec = codec;
this.#canvas = document.createElement("canvas"); if (canvas) {
this.#canvas = canvas
} else if (typeof document !== 'undefined') {
this.#canvas = document.createElement("canvas");
} else if (typeof OffscreenCanvas !== 'undefined') {
this.#canvas = new OffscreenCanvas(0, 0);
} else {
throw new Error('no canvas input found nor any canvas can be created');
}
try { try {
this.#renderer = new WebGLFrameRenderer( this.#renderer = new WebGLFrameRenderer(

View file

@ -3,7 +3,7 @@ import type { FrameRenderer } from "./type.js";
export class BitmapFrameRenderer implements FrameRenderer { export class BitmapFrameRenderer implements FrameRenderer {
#context: ImageBitmapRenderingContext; #context: ImageBitmapRenderingContext;
constructor(canvas: HTMLCanvasElement) { constructor(canvas: HTMLCanvasElement | OffscreenCanvas) {
this.#context = canvas.getContext("bitmaprenderer", { alpha: false })!; this.#context = canvas.getContext("bitmaprenderer", { alpha: false })!;
} }

View file

@ -33,7 +33,7 @@ export class WebGLFrameRenderer implements FrameRenderer {
* Whether to allow capturing the canvas content using APIs like `readPixels` and `toDataURL`. * Whether to allow capturing the canvas content using APIs like `readPixels` and `toDataURL`.
* Enable this option may reduce performance. * Enable this option may reduce performance.
*/ */
constructor(canvas: HTMLCanvasElement, enableCapture: boolean) { constructor(canvas: HTMLCanvasElement | OffscreenCanvas, enableCapture: boolean) {
const gl = const gl =
canvas.getContext("webgl2", { canvas.getContext("webgl2", {
alpha: false, alpha: false,