p5.record.js
Version:
p5.js addon providing functions to record HTML canvas based sketches
138 lines (111 loc) • 3.12 kB
JavaScript
class Recorder {
#stream;
#recorder;
constructor(options) {
const frameRate = options.frameRate === "manual" ? 0 : options.frameRate;
const chunks = [];
const stream = (
options.source instanceof HTMLCanvasElement ?
options.source :
options.source.canvas
).captureStream(frameRate);
const recorder = new MediaRecorder(stream, {
mimeType: options.mimeType ?? "video/webm;codecs=vp8"
});
recorder.addEventListener("start", (e) => {
console.log("recording started");
});
recorder.addEventListener("stop", (e) => {
const blob = new Blob(chunks);
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 = "recording.webm";
link.click();
}
});
recorder.addEventListener("dataavailable", (e) => {
chunks.push(e.data);
});
recorder.addEventListener("pause", (e) => {
console.log("recording paused");
});
recorder.addEventListener("resume", (e) => {
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() {
this.#stream.getVideoTracks()[0].requestFrame();
}
}
function p5Record(p5, fn, lifecycles){
let recorder, options;
const p5VersionSemver = p5.VERSION.split(".")
.map((n) => parseInt(n));
if(!(
p5VersionSemver[0] > 2 ||
(p5VersionSemver[0] > 2 && p5VersionSemver[1] > 0) ||
(p5VersionSemver[0] === 2 && p5VersionSemver[1] === 0 && p5VersionSemver[2] >= 3)
)){
console.error(`p5.record.js requires p5.js >= 2.0.3`);
return;
}
p5.Recorder = Recorder;
lifecycles.postdraw = function() {
if(recorder && recorder.state === "recording" && options?.frameRate === "manual"){
recorder.frame();
}
};
fn.setRecording = function(opt) {
if(opt.frameRate === "manual" && !("CanvasCaptureMediaStreamTrack" in window)){
console.error("Your browser does not support directly specifying frame capture timing with { frameRate: 'manual' }.");
return;
}
options = opt;
};
fn.startRecording = function() {
options = Object.assign({
source: this.canvas,
frameRate: this.getTargetFrameRate()
}, options);
recorder = new Recorder(options);
recorder.start();
};
fn.stopRecording = function() {
recorder.stop();
};
fn.pauseRecording = function() {
recorder.pause();
};
fn.resumeRecording = function() {
recorder.resume();
};
fn.createRecording = function(options) {
return new Recorder(options);
};
}
if(typeof p5 !== "undefined"){
p5.registerAddon(p5Record);
}
export { Recorder, p5Record };