【问题标题】:Piping a series of node JS buffers to ffmpeg将一系列节点 JS 缓冲区通过管道传输到 ffmpeg
【发布时间】:2019-03-31 20:34:55
【问题描述】:

我正在生成一系列帧并将它们作为缓冲区保存在 Redis 数据库中。目前,我正在努力找出如何将它们导入 FFmpeg 以创建视频。使用这种方法来支持将帧保存在磁盘上的目的是提高性能。生成的视频时长不超过 3 分钟。

在以下函数中,我尝试从 Redis 收集所有帧,将它们连接在一起并使用 stream-buffers 将它们保存到临时缓冲区中。然后我尝试使用fluent-ffmpeg 最终输出视频。

let renderVideo = async () => {
  let data

  let frames = []

  for (let i = 0; i <= readyFrames.length - 1; i++) {
    data = await cache.get(`frame_${i}`)
    frames.push(data)
  }

  let allFramesTogether = Buffer.concat(frames) // Does
  tempReadableBuffer.put(allFramesTogether)     // not
  ffmpeg().input(tempReadableBuffer)            // work

  ffmpeg()
    .outputOptions(['-f image2pipe', '-pix_fmt yuv420p'])
    .videoCodec('libx264')
    .size(`${dimensions.width}x${dimensions.height}`)
    .format('mp4')
    .fps(FPS)
    .on('progress', function(progress) {
      console.log('Processing: ' + progress.percent + '% done')
    })
    .on('end', function() {
      console.log('Processing finished !')
    })
    .on('stderr', function(stderrLine) {
      console.log('Stderr output: ' + stderrLine)
    })
    .on('error', function(err, stdout, stderr) {
      console.log('Cannot process video: ' + err.message)
    })
    .save('test.mp4')
}

【问题讨论】:

  • 您能否提供您在“不起作用”部分遇到的任何错误?
  • 我的应用卡住了,不会输出任何错误。我可以在块之前记录,但不能在块的第一行之后
  • cache.get(...)返回的数据类型是什么?你的框架数组被填满了吗?
  • 我收到了字符串,这可能是问题所在。
  • 将数据转换为缓冲区data = Buffer.from(data)后,代码运行并退出并出现错误:TypeError: Cannot read property 'isStream' of undefined at runFfprobe

标签: javascript node.js ffmpeg redis fluent-ffmpeg


【解决方案1】:

感谢 cmets 和一些研究,我能够将一些东西放在一起:

Redis需要配置,所以输出的是缓冲区,而不是字符串

return_buffers: true

为了连接保存为单独缓冲区的图像,我这样做

let allFramesTogether = Buffer.concat(frames)

ffmpeg 可以使用 spawn 作为子进程运行,而 -f 必须设置为 image2pipe-i 设置为 -,因此图像可以通过管道传输

const ffmpeg = spawn('ffmpeg', [
  '-r',
  `${FPS}`,
  '-f',
  'image2pipe',
  '-s',
  `${dimensions.width}x${dimensions.height}`,
  '-i',
  '-',
  '-vcodec',
  'libx264',
  '-crf',
  '25',
  '-pix_fmt',
  'yuv420p',
  'test.mp4'
])

为了最终在上面的代码之后通过ffmpeg.stdin.write(allFramesTogether) 处理图像,然后是ffmpeg.stdin.end()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-21
    • 2011-07-21
    • 1970-01-01
    • 2015-03-30
    相关资源
    最近更新 更多