I use Vanta js to create an animation background and use mediaRecorder to capture the canvas as webm. The page will be recorded from the beginning and stop and export the webm after 1 sec.
However, nothing is stored in blob, the webm exported is empty.
Any suggestions? Thank you!
<body id="ele">
<div><canvas id="canvas"></canvas></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.clouds.min.js"></script>
<script>
VANTA.CLOUDS("#ele");
</script>
<script>
const startRecording = () => {
const newcanvas = document.querySelector("canvas");
const chunks = []; // here we will store our recorded media chunks (Blobs)
const stream = newcanvas.captureStream(30); // grab our canvas MediaStream
const rec = new MediaRecorder(stream); // init the recorder
// every time the recorder has new data, we will store it in our array
rec.ondataavailable = (e) => chunks.push(e.data);
// only when the recorder stops, we construct a complete Blob from all the chunks
rec.onstop = (e) =>
downloadVideo(new Blob(chunks, { type: "video/webm;codecs=h264" }));
rec.start();
setTimeout(() => {
rec.stop();
}, 1000); // stop recording in 1s
};
const downloadVideo = async (blob) => {
const div = document.querySelector("div");
var url = URL.createObjectURL(blob);
console.log(url);
var a = document.createElement("a");
a.href = url;
a.download = "test.webm";
a.className = "button";
a.innerText = "click here to download";
div.appendChild(a);
};
startRecording();
</script>
</body>
Just remove the <canvas id="canvas"></canvas>
from your html.
VANTA.CLOUDS inserts a canvas element of it's own.
Your Javascript code for querying your canvas element results in fetching the element with no data in it.
VANTA.CLOUDS("#ele");
const startRecording = () => {
const newcanvas = document.querySelector("canvas");
const chunks = []; // here we will store our recorded media chunks (Blobs)
const stream = newcanvas.captureStream(60); // grab our canvas MediaStream
const rec = new MediaRecorder(stream); // init the recorder
// every time the recorder has new data, we will store it in our array
rec.ondataavailable = (e) => {
chunks.push(e.data);
};
// only when the recorder stops, we construct a complete Blob from all the chunks
rec.onstop = (e) =>
downloadVideo(new Blob(chunks, { type: "video/webm" }));
rec.start(100);
setTimeout(() => {
rec.stop();
// alert("wow");
}, 2000); // stop recording in 1s
};
const downloadVideo = async (blob) => {
const div = document.querySelector("div#link");
var url = URL.createObjectURL(blob);
var a = document.createElement("a");
var span = document.createElement("span");
a.href = url;
a.download = "test.webm";
a.innerText = `Click to download`;
span.innerHTML = ` Link is <b>${url}</b>`;
div.appendChild(a);
div.appendChild(span)
};
startRecording();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.clouds.min.js"></script>
<div style="display: flex; flex-direction: column;">
<div id="link" style="height: 20px;"></div>
<div id="ele"></div>
</div>
The null blob url is because this code is running inside the browser file system environment.