Передача серии буферов JS узла в ffmpeg - PullRequest
0 голосов
/ 27 октября 2018

Я генерирую серию кадров и сохраняю их как буферы в базе данных 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')
}

1 Ответ

0 голосов
/ 27 октября 2018

Благодаря комментариям и некоторым исследованиям я смог что-то собрать:

Необходимо настроить 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()

...