39
loading...
This website collects cookies to deliver better user experience
video
and audio
elements too.const canvas = document.querySelector("canvas");
const recordBtn = document.querySelector("button");
let recording = false;
let mediaRecorder;
let recordedChunks;
recordBtn.addEventListener("click", () => {
recording = !recording;
if(recording){
recordBtn.textContent = "Stop";
const stream = canvas.captureStream(25);
mediaRecorder = new MediaRecorder(stream, {
mimeType: 'video/webm;codecs=vp9'
ignoreMutedMedia: true
});
recordedChunks = [];
mediaRecorder.ondataavailable = e => {
if(e.data.size > 0){
recordedChunks.push(e.data);
}
};
mediaRecorder.start();
} else {
recordBtn.textContent = "Record"
mediaRecorder.stop();
setTimeout(() => {
const blob = new Blob(recordedChunks, {
type: "video/webm"
});
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "recording.webm";
a.click();
URL.revokeObjectURL(url);
},0);
}
});
canvas.captureStream(25)
. The parameter is the max framerate, you can change less but if it animates more than that you'll drop frames.MediaRecorder
. This takes two parameters a stream, which comes from the canvas (or video
, audio
etc) and some options which include the bitrate and which codec you want to use. The list of options can be found on MDN but I use 2:dataavailable
event that triggers every time the stream has a new chunk for you. So we inspect size
to make sure it has something and then append it to the array with our other chunks. To start this whole process we use start()
.ignoreMutedMedia
as it doesn't seem to work in Firefox and will just cause the whole canvas to not produce chunks. You'll also need to use the VP8 codec video/webm;codecs=vp8
as Firefox doesn't yet support VP9.video/webm
. If you use a different codec that is not webm you need to change it. href
to the object URL, add a download
attribute so that the browser triggers downloading with the filename suggestion and then programmatically click it. After that clean up the object URL otherwise you'll have a memory leak.ffmpeg -y -i input.webm -vf palettegen palette.png
./ffmpeg.exe
)-y
says to overwrite the output file without asking. -i
marks an input and -vf
means to export a filtergraph (I don't exactly know but it has something to do with pallets)ffmpeg -y -i input.webm -i palette.png -filter_complex paletteuse -r 10 output.gif
-filter_complex palettuse
option which is again some filtergraph thing I don't fully understand but seems to amount to "use the pallet." The last parameter -r
is the framerate. You can match the video for better results or lower it for reduced file size.-loop
parameter. By default it is 0 which means loop forever but you can have it stop as well.