×
  1. 第一步调用creator.start()开始执行。
  2. 在creator.start()中调用了renderer.start()
  3. 在renderer.start()中有三个关键方法:
    1. preProcessing()会预处理,抽帧。
    2. createStream方法创建一个FFStream实例并绑到this.stream
    3. createSynthesis方法开始执行合成
  4. 在createSynthesis方法中调用了 synthesis.addStream(stream)。将stream加入其中。
    1. 在这个方法里,调用了command.addInput(stream)
      1. 这个方法的本质是将ffstream流添加到ffmpeg。之后ffmpeg命令执行时会从这个流读数据。这个实现是另外一个第三方库fluent-ffmpeg
        1. https://github.com/fluent-ffmpeg/node-fluent-ffmpeg
      2. 而这个command实际上也是由fluent-ffmpeg创建的
  5. 在createSynthesis方法中最后调用了synthesis.start()
    1. 在synthesis.start()中调用了command.run()
      1. 这个方法本质上是调用了fluent-ffmpeg 的run方法。在这个方法里。ffmpeg开始执行。开始读取流数据了。这样就会触发ffstream._read方法(ffstream继承自nodejs的Readable流,_read是一个内置方法。会在消费端读取数据时触发,而ffstream把这个_read方法重写,用来读取ffcreater创建的数据)
      2. pipe()方法会读取stream流,触发stream._read(),ffmpegProc.stdin是ffmpeg自己的输入流。这个相当于把inputStream中读到的数据做为ffmpegProc的输入传给ffmpeg。
  6. 如何将自己的数据传给stream
    1. 在createStream方法中。有stream.addPullFunc方法,它会将renderFrame绑定到stream
      1. 顺便一提。这个fillNewData方法,实现了并行处理。就是最后一行
    2. 在FFStream中重写了Readable._read方法,并在这个方法里读取renderFrame数据。在ffmpeg调用pip()方法时。将数据传过去
    3. renderFrame如何读取画面信息:
      1. 渲染封面:
        1. 在renderFrame中调用了secne.start()。这个方法最终会调用FFVideo的start方法。在ffvideo.start里会调用drawCoverImage()
        2. 在drawCoverImage()里调用了drawing()
          1. 值得一提这里第一行的display就是用inkpaint创建的 https://github.com/drawcall/inkpaint
        3. drawing里调用了getFrame方法得到当前帧需要的图片,并调用display的updateBaseTexture添加进去。
      2. 画动画帧:
        1. 在renderFrame中调用nextFrame方法后,同样会调用drawing方法。这个方法是在Tween里被调用的(ffcreator绑了tween的事件),renderFrame方法会在每一帧绘制时调用,这样会把把最终渲染的图像传给ffmpeg
          1. 这里绑的事件就是drawing
          2. 这个事件是在TWEEN.update中绑定的
            1. 当前时间超过对应的开始时间(delay设定的时间)后,会调用onStartCallback。事件在这里绑定。
              1. 在TWEEN的onstart事件里调用了ffvideo.addTimelineCallback,把事件绑到了tween上。
            2. 绑定之后就会每一帧处理都调用drawing了。
      3. 在renderFrame中调用了 snapshotToBuffer()方法。
        1. 这个方法用inkpaint渲染,并将渲染结果并写入buffer。
          1. creator.render调用了inkpaint的render(),这样会把在preProcessing中载入的资源进行渲染,并创建了一个view。再用creator.app.view拿到
          2. 这个buff会随着renderFrame方法传到FFStream._read()中
          3. 这样ffmpeg就会读到ffstream流中的数据。直到读到null为止,会一直执行。

作者

admin@example.com