Generate video from Canvas
Will generate a video of the recorded animation in the canvas. If the drawImage is set to true, the Image will be used as a background for the canvas using drawImage. In this case the video generation will fail and produce a 0 byte file only.
by keyboardsamurai
July 11, 2019
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="panel">
<div id="recording_status" style="color: white; background-color: green; width: 150px;" class="panel-item">
Not recording
</div>
<label for="toggle" class="panel-item">
<input type="checkbox" checked onclick="toggleDrawImage();" id="toggle">
<span>Use drawImage() = </span>
<span id="imageState">undefined</span>
</label>
<div class="panel-item">
<button onclick="renderVideo();">Render Video</button>
</div>
<div class="panel-item">
<span id="panel-result-size"></span>
</div>
</div>
<canvas id="drawing_canvas" width="1280" height="720"></canvas>
<script></script>
</body>
</html>
CSS
body {
font-family: 'Arial', cursive;
}
#panel {
display: inline-block;
width: 100%;
margin-bottom: 20px;
}
.panel-item {
float: left;
margin-left: 50px;
}
JavaScript
let drawImage = true;
document.getElementById("imageState").innerText = drawImage;
const image = new Image();
image.src = 'https://66.media.tumblr.com/84d332cafeb1052c477c979281e5713b/tumblr_owe3l0tkCj1wxdq3zo1_1280.jpg';
let allChunks, canvas, recorder;
function renderVideo() {
if (recorder && recorder.state === 'recording') {
console.log('Wait until recorder is inactive');
return;
}
document.getElementById('panel-result-size').innerText = '';
// during rendering canvas becomes tainted, so we have to recreate the canvas each time
document.body.removeChild(document.getElementById("drawing_canvas"));
const c = document.createElement('canvas');
c.width = 1280;
c.height = 720;
c.id = 'drawing_canvas';
document.body.appendChild(c);
allChunks = [];
window.requestAnimationFrame(animation);
canvas = document.getElementById('drawing_canvas');
recorder = initMediaRecorder(canvas);
recorder.start();
setTimeout(function (e) {
console.log("Video ended");
recorder.stop();
}, 5000);
}
function toggleDrawImage() {
drawImage = !drawImage;
document.getElementById("imageState").innerText = drawImage
}
function initMediaRecorder(canvasElement) {
const stream = canvasElement.captureStream(60);
const recorder = new MediaRecorder(stream, {mimeType: 'video/webm'});
recorder.ondataavailable = function (e) {
console.log("data handler called");
if (e.data) {
console.log("data available: " + e.data.size)
if (e.data.size > 0) {
console.log("data added");
allChunks.push(e.data);
}
} else {
console.error("Data handler received no data in event: " + JSON.stringify(e))
}
...