tnfe / FFCreator

A fast video processing library based on node.js (一个基于node.js的高速视频制作库)
http://tnfe.github.io/FFCreator/
MIT License
2.86k stars 407 forks source link

Trying to add Skottie but having no luck :( #346

Open galipmedia opened 1 year ago

galipmedia commented 1 year ago

Hello, thanks for the awesome library, I am so impressed how fast it is! I have a requirement to use lottie in my animations however the canvas version of lottie as used in lottie-nodejs is very restricted. There are many features missing and its difficult to use scripts and fonts. Therefore I am trying to introduce Skottie the most powerful version of lottie available from Skia / canvasKit.

You can see my implementation here ... https://github.com/clippatv/FFCreator/blob/dev/lib/node/skottie.js I am not getting any errors but the resulting canvas is blank. Could anyone help explain what I might have done wrong?

https://skia.org/docs/user/modules/canvaskit/ this is the link to canvasKit Skia Wasm

galipmedia commented 1 year ago

After playing around a lot it seems like this internally perhaps has its own canvas not the same as node-canvas.

drawcall commented 1 year ago

great work, Maybe you can render skcanvas every frame

galipmedia commented 1 year ago

Finally I got it to work but its very very slow compared to lottie-node and also only runs in good sequence if the pool is 1, it seems so inefficient to encode it to an image and decode it back to the texture :(

  async updateCallback(time, delta) {

    if(!this.firstTime){
      this.firstTime = time;
    }

    this.currentFrame =  Math.floor((time - this.firstTime) / this.fps)
    console.log('cf', this.currentFrame)

    this.canvas.clear(this.CanvasKit.TRANSPARENT);
    this.ani.seekFrame(this.currentFrame);
    this.ani.render(this.canvas, this.bounds);

      const pixels = this.surface.makeImageSnapshot();
      const px = pixels.encodeToBytes(this.CanvasKit.ImageFormat.PNG, 100);

      const imgPath = `./temp/tmp_${this.currentFrame}.png`;
      let that = this;
      fs.writeFile(imgPath, px, (err) => {
        if (err)
          console.log(err);
        else {
          that.display.texture = Texture.fromImage(fs.readFileSync(imgPath))
          fs.unlinkSync(imgPath)
        }
      });

    this.surface.flush();
  }