html5-canvasframe-ratetodataurl

Capture frames from a canvas at 60 fps


Hey everyone so I have a canvas that I write a rather complex animation to. Let's say I want to take screenshots of the canvas at 60 frames a second. The canvas doesn't have to play in real-time I just need it to capture 60 frames a second so I can send the screenshots to FFmpeg and make a video. I know I can use canvas.toDataURL but how do I capture the frames smoothly?


Solution

  • Use this code to pause the video and lottie animations if you are using lottie-web for after effects content in the browser. Than take screenshots and use Whammy to compile a webm file which you can than run through ffmpeg to get your desired output.

      generateVideo(){
                const vid = new Whammy.fromImageArray(this.captures, 30);
                vid.name = "project_id_238.webm";
                vid.lastModifiedDate = new Date();
    
                this.file = URL.createObjectURL(vid);
        },
        async pauseAll(){
           this.pauseVideo();
          if(this.animations.length){
           this.pauseLotties()
          }
                this.captures.push(this.canvas.toDataURL('image/webp'));
                if(!this.ended){
                  setTimeout(()=>{
                    this.pauseAll();
                  }, 500);
                } 
        },
        async pauseVideo(){
          console.log("curretTime",this.video.currentTime);
          console.log("duration", this.video.duration);
            this.video.pause();
           const oneFrame = 1/30;
          this.video.currentTime += oneFrame;
        },
        async pauseLotties(){
          lottie.freeze();
            for(let i =0; i<this.animations.length; i++){
              let step =0;
              let animation = this.animations[i].lottie;
              if(animation.currentFrame<=animation.totalFrames){
                step = animation.currentFrame + animation.totalFrames/30;
              }
              lottie.goToAndStop(step, true, animation.name); 
            }
          }