UNPKG

canvas-record

Version:

Record a video in the browser or directly on the File System from a canvas region (2D/WebGL/WebGPU) as MP4, WebM, MKV, MOV, GIF, PNG/JPG Sequence using WebCodecs and wasm when available.

101 lines (85 loc) 2.37 kB
/** * @typedef {"mp4" | "webm" | "png" | "jpg" | "gif" | "mkv" | "mov"} EncoderExtensions */ /** * @typedef {"in-browser" | "file-system"} EncoderTarget */ class Encoder { /** * The extension the encoder supports * @type {Extensions[]} */ static supportedExtensions = ["mp4", "webm"]; /** * The target to download the file to. * @type {EncoderTarget[]} */ static supportedTargets = ["in-browser"]; static defaultOptions = { frameMethod: "blob", extension: Encoder.supportedExtensions[0], target: Encoder.supportedTargets[0], }; /** * Base Encoder class. All Encoders extend it and its methods are called by the Recorder. * @class Encoder * @param {object} options * * @property {EncoderTarget} target * @property {EncoderExtensions} extension * @property {object} [encoderOptions] * @property {object} [muxerOptions] */ constructor(options) { Object.assign(this, options); } /** * Setup the encoder: load binary, instantiate muxers, setup file system target... * @param {object} options */ async init(options) { Object.assign(this, options); } // File System API async getDirectory() { if (!("showDirectoryPicker" in window)) return; return await window.showDirectoryPicker(); } async getDirectoryHandle(directory, name) { return await directory.getDirectoryHandle(name, { create: true }); } async getFileHandle(name, options) { if (this.directoryHandle) { return await this.directoryHandle.getFileHandle(name, { create: true }); } if (!("showSaveFilePicker" in window)) return; return await window.showSaveFilePicker({ suggestedName: name, ...options, }); } async getWritableFileStream(fileHandle) { if ( (await fileHandle.queryPermission({ mode: "readwrite" })) === "granted" ) { return await fileHandle.createWritable(); } } // Override methods /** * Encode a single frame. The frameNumber is usually used for GOP (Group Of Pictures). * @param {number} frame * @param {number} [frameNumber] */ async encode() {} /** * Stop the encoding process and cleanup the temporary data. * @returns {(ArrayBuffer|Uint8Array|Blob[]|undefined)} */ async stop() {} /** * Clean up the encoder */ dispose() {} } export default Encoder;