Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

视频稍长,就出现text node设置的起止时间实际生成的视频不匹配的问题,大约每300秒差3秒。 #156

Open
penghui opened this issue Dec 5, 2021 · 0 comments

Comments

@penghui
Copy link
Contributor

penghui commented Dec 5, 2021

起因是,视频稍长就会出现音画不同步的问题。手动添加text,通过addEffect设置的出现和消失的时间,实际生成的视频,误差1%逐渐累积,到300秒,那一秒的text会延迟3秒出现:

可重现问题的demo代码(修改自example/text.js):

  const cover = path.join(__dirname, './assets/imgs/cover/cover2.jpg');
  const font1 = path.join(__dirname, './assets/font/font1.ttf');
  const outputDir = path.join(__dirname, './output/');
  const cacheDir = path.join(__dirname, './cache/');

  // create creator instance
  const width = 800;
  const height = 600;
  const creator = new FFCreator({
    cover,
    cacheDir,
    outputDir,
    width,
    height,
    parallel: 8,
    // fps:25
  });


  const scene3 = new FFScene();
  for (let i=0; i< 360; i++) {
    const textNode = new FFText({ text: 'FFText组件demo'+i, x: width / 2, y: 130, fontSize: 40 });
    textNode.setColor('#ffffff');
    textNode.setBackgroundColor('#bc05a9');
    textNode.alignCenter();
    textNode.setFont(font1);
    textNode.setStyle({ padding: 10 });

    textNode.addEffect('fadeInUp', 0, i)
    textNode.addEffect('fadeOutUp', 0, i+1)
    scene3.addChild(textNode)
  }
  scene3.setDuration(360);
  creator.addChild(scene3);

  creator.start();

上述代码如果加上fps:25,结果完全正确没有误差。

经过查找,发现可能跟lib/timeline/update.js的这段代码有关:

  update(fps = 60) {
    const delta = (1000 / fps) >> 0;

    if (!this.time) {
      this.time = TWEEN.now();
      TWEEN.now = () => this.time;
    } else {
      this.time += delta;
    }

    TWEEN.update(this.time);
    
    forEach(this.cbs, cb => cb(this.time, delta));
    this.delta = delta;
  },

这里,delta被取整了,33.33333...变为了33。1%的误差应该由此而得。而如果1000/fps刚好是个整数(如fps=25),则没有问题。

由于this.time和delta被其他地方引用,没敢乱改,所以增加了两个变量,startTime和frame,完整update.js的代码如下:

'use strict';

/**
 * TimelineUpdate - Simple timeline management tool
 *
 * ####Example:
 *
 *     TimelineUpdate.addFrameCallback(this.drawing);
 *
 * @class
 */
const forEach = require('lodash/forEach');
const TWEEN = require('@tweenjs/tween.js');

TWEEN.now = () => new Date().getTime();

const TimelineUpdate = {
  delta: 0,
  time: 0,
  startTime: 0,
  frame: 0,
  cbs: [],

  /**
   * TimelineUpdate update function
   * @param {number} fps - Frame rate
   * @public
   */
  update(fps = 60) {
    const delta = (1000 / fps);

    if (!this.startTime) {
      this.startTime = TWEEN.now();
      TWEEN.now = () => this.startTime;
    } else {
      this.frame += 1
      // this.time += delta;
    }

    this.time = this.startTime + this.frame * delta

    TWEEN.update(this.time);
    forEach(this.cbs, cb => cb(this.time, delta));
    this.delta = delta;
  },

  /**
   * Add callback hook
   * @param {function} callback - callback function
   * @public
   */
  addFrameCallback(callback) {
    if (!callback) return;
    this.cbs.push(callback);
  },

  /**
   * Remove callback hook
   * @param {function} callback - callback function
   * @public
   */
  removeFrameCallback(callback) {
    if (!callback) return;

    const index = this.cbs.indexOf(callback);
    if (index > -1) this.cbs.splice(index, 1);
  },
};

module.exports = TimelineUpdate;

不确认这样的思路是否正确,有没有更好的方式呢?

penghui added a commit to penghui/FFCreator that referenced this issue Dec 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant