UNPKG

p5.record.js

Version:

p5.js addon providing functions to record HTML canvas based sketches

105 lines (87 loc) 2.61 kB
import { SequenceRecorder, imageTypesMap } from "./SequenceRecorder"; interface RecorderOptions { frameRate: "manual" | number, source: HTMLCanvasElement | { canvas: HTMLCanvasElement }, mimeType?: string, stopCallback?: (blob: Blob) => void } export class Recorder { #stream: MediaStream; #recorder: MediaRecorder | SequenceRecorder; constructor(options: RecorderOptions) { const frameRate = options.frameRate === "manual" ? 0 : options.frameRate; const chunks = []; const canvas = ( options.source instanceof HTMLCanvasElement ? options.source : options.source.canvas ); const stream = canvas.captureStream(frameRate); let recorder: MediaRecorder | SequenceRecorder; if(Object.keys(imageTypesMap).includes(options.mimeType)){ recorder = new SequenceRecorder(canvas, options.mimeType, frameRate); }else{ recorder = new MediaRecorder(stream, { mimeType: options.mimeType ?? "video/webm;codecs=vp8" }); } recorder.addEventListener("start", () => { console.log("recording started"); }); recorder.addEventListener("stop", (e: Event) => { let blob: Blob, filename: string; if(this.#recorder instanceof SequenceRecorder){ blob = (e as CustomEvent).detail.blob; filename = "recording.zip"; }else{ blob = new Blob(chunks); filename = "recording.webm"; } const executeDefault = typeof options?.stopCallback === "function" ? options?.stopCallback(blob) : true; if(executeDefault){ const blobUrl = URL.createObjectURL(blob); const link = document.createElement("a"); link.href = blobUrl; link.download = filename; link.click(); } }); (recorder as MediaRecorder).addEventListener("dataavailable", (e: BlobEvent) => { chunks.push(e.data); }); recorder.addEventListener("pause", () => { console.log("recording paused"); }); recorder.addEventListener("resume", () => { console.log("recording resumed"); }); this.#recorder = recorder; this.#stream = stream; } get state() { return this.#recorder.state; } start() { this.#recorder.start(); } stop() { this.#recorder.stop(); } pause() { this.#recorder.pause(); } resume() { this.#recorder.resume(); } frame() { if(this.#recorder instanceof SequenceRecorder){ this.#recorder.frame(); }else{ (this.#stream.getVideoTracks()[0] as CanvasCaptureMediaStreamTrack).requestFrame(); } } }