javascript - 将一系列 Node JS 缓冲区通过管道传输到 ffmpeg

标签 javascript node.js ffmpeg redis fluent-ffmpeg

我正在生成一系列帧并将它们保存为 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')
}

最佳答案

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

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()

关于javascript - 将一系列 Node JS 缓冲区通过管道传输到 ffmpeg,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53019625/

相关文章:

javascript - Angular 2 : Populating components to template

javascript - 我们可以从 requirejs 中的模块导出多个非 AMD 函数吗?

javascript - 更改 :focus property of an element using JavaScript

node.js - Angular 6 应用程序对本地主机上的 API 的调用被 CORS 阻止

javascript - 如何在原生 JavaScript 和 node.js 中使用长轮询?

ffmpeg - 这是 ffmpeg 流到 Periscope 的正确关键帧间隔设置

javascript - 如何在for循环javascript中合并重复值

node.js - 在高流量期间阻塞 ClientRead 上的空闲连接以进行参数化查询(绑定(bind))

node.js - Fluent ffmpeg如何用户保存回调

audio - 在停止/断开连接时重新启动 ffmpeg