web-dev-qa-db-fra.com

Comment enregistrer une animation de canevas au format gif ou webm?

j'ai écrit cette fonction pour capturer chaque image pour le GIF mais la sortie est très lente et se bloque lorsque les données augmentent. Aucune suggestion ?

Code:

    function createGifFromPng(list, framerate, fileName, gifScale) {
            gifshot.createGIF({
                'images': list,
                'gifWidth': wWidth * gifScale,
                'gifHeight': wHeight * gifScale,
                'interval': 1 / framerate,
            }, function(obj) {
                if (!obj.error) {
                    var image = obj.image;
                    var a = document.createElement('a');
                    document.body.append(a);
                    a.download = fileName;
                    a.href = image;
                    a.click();
                    a.remove();
                }
            });
        }
/////////////////////////////////////////////////////////////////////////

function getGifFromCanvas(renderer, Sprite, fileName, gifScale, framesCount, framerate) {
            var listImgs = [];
            var saving = false;
            var interval = setInterval(function() {
                renderer.extract.canvas(Sprite).toBlob(function(b) {
                    if (listImgs.length >= framesCount) {
                        clearInterval(interval);
                        if (!saving) {
                        createGifFromPng(listImgs, framerate, fileName,gifScale);
                            saving = true;
                        }
                    }
                    else {
                        listImgs.Push(URL.createObjectURL(b));
                    }
                }, 'image/gif');
            }, 1000 / framerate);
        }
10
Hashir Salam

Dans les navigateurs modernes, vous pouvez utiliser une combinaison de la méthode MediaRecorder API et HTMLCanvasElement.captureStream .

L'API MediaRecorder sera en mesure de coder un MediaStream dans un fichier multimédia vidéo ou audio à la volée, résultant en beaucoup moins de mémoire nécessaire que lorsque vous prenez des images fixes.

const ctx = canvas.getContext('2d');
var x = 0;
anim();
startRecording();

function startRecording() {
  const chunks = []; // here we will store our recorded media chunks (Blobs)
  const stream = canvas.captureStream(); // 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 => exportVid(new Blob(chunks, {type: 'video/webm'}));
  
  rec.start();
  setTimeout(()=>rec.stop(), 3000); // stop recording in 3s
}

function exportVid(blob) {
  const vid = document.createElement('video');
  vid.src = URL.createObjectURL(blob);
  vid.controls = true;
  document.body.appendChild(vid);
  const a = document.createElement('a');
  a.download = 'myvid.webm';
  a.href = vid.src;
  a.textContent = 'download the video';
  document.body.appendChild(a);
}

function anim(){
  x = (x + 1) % canvas.width;
  ctx.fillStyle = 'white';
  ctx.fillRect(0,0,canvas.width,canvas.height);
  ctx.fillStyle = 'black';
  ctx.fillRect(x - 20, 0, 40, 40);
  requestAnimationFrame(anim);
}
<canvas id="canvas"></canvas>
14
Kaiido

Vous pouvez également utiliser https://github.com/spite/ccapture.js/ pour capturer en gif ou en vidéo.

2
SMUsamaShah