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