Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Node.js-将数据缓冲到Ffmpeg_Javascript_Node.js_Windows_Ffmpeg_Ecmascript 2016 - Fatal编程技术网

Javascript Node.js-将数据缓冲到Ffmpeg

Javascript Node.js-将数据缓冲到Ffmpeg,javascript,node.js,windows,ffmpeg,ecmascript-2016,Javascript,Node.js,Windows,Ffmpeg,Ecmascript 2016,我使用Node.js和Ffmpeg创建动画。因为我试图避免使用第三方avi/mp4解析器,所以我决定将动画作为原始rgb24数据文件输出,然后使用一些程序将其转换为mp4文件 我发现Ffmpeg是免费的、开源的,可以做到这一点。因此,我制作了一个Node.js应用程序,它分配一个大小为1920 x 1080 x 3的缓冲区(宽度乘以高度乘以每个像素的字节数),然后我创建了一个渲染上下文库,最后我逐帧设置动画,并将每一帧连续保存在一个二进制文件中(使用fs模块) 然后我调用Ffmpeg将其转换为m

我使用Node.js和Ffmpeg创建动画。因为我试图避免使用第三方avi/mp4解析器,所以我决定将动画作为原始rgb24数据文件输出,然后使用一些程序将其转换为mp4文件

我发现Ffmpeg是免费的、开源的,可以做到这一点。因此,我制作了一个Node.js应用程序,它分配一个大小为1920 x 1080 x 3的
缓冲区(宽度乘以高度乘以每个像素的字节数),然后我创建了一个渲染上下文库,最后我逐帧设置动画,并将每一帧连续保存在一个二进制文件中(使用
fs
模块)

然后我调用Ffmpeg将其转换为mp4文件,效果非常好。动画制作非常简单,Ffmpeg也能正确地完成它的工作

然而,唯一的问题是,它速度非常慢,占用硬盘空间。我想创建非常长的动画(超过一个小时)。最终的mp4文件相对较小,但原始视频文件非常大。大约90%的每帧都是黑色像素,因此Ffmpeg压缩效果非常好,但原始文件无法压缩,有时需要100千兆字节。此外,对同一数据进行非常不必要的双重处理。首先,我在Node.js中处理它以将数据保存到文件中,然后Ffmpeg读取它以将其转换为mp4。有很多不必要的工作

因此,我正在寻找一种方法(我非常确定这是可能的,但我还没有找到一种方法)将原始视频数据(一次一帧)输出到Ffmpeg过程(而不将任何内容保存到硬盘)

我的目标是做到以下几点:

  • 开放Ffmpeg过程
  • 在Node.js中渲染帧
  • 将原始字节流输出到Ffmpeg
  • 等待Ffmpeg对其进行编码并附加到mp4文件
  • 让Ffmpeg等待my Node.js进程渲染下一帧

  • 有没有办法做到这一点我真的看不到发布代码的理由,因为我当前的代码与我在这里提出的问题无关我不会遇到语法错误或实现问题。不,相反,我只是不知道传递给Ffmpeg过程的参数是什么,以实现我已经解释过的

    我在文档中搜索了需要传递给Ffmpeg进程的参数,以便让它从stdin而不是文件中读取原始数据,并等待Node.js进程渲染下一帧(以便禁用时间限制),因为渲染一帧可能需要24小时以上。因此,Ffmpeg进程应该无时间限制地等待。然而,我在文档中没有找到任何关于它的信息

    我知道如何从Node.js和类似的技术资料编写stdin,所以不需要解释。这里唯一的问题是:

  • 哪些参数要传递到Ffmpeg
  • 我是否需要创建带有一些特殊选项的Ffmpeg进程(使用
    子进程


  • 先谢谢你。请别紧张,这是我的第一个问题!:)

    正如@Mulvya和@estus所建议的,正确的参数是
    -i-
    (以启用标准输入法的输入):

    它生成以下图像:

    它也适用于动画


    谢谢你们的帮助

    它将遵循
    ffmpeg-f rawvideo-s 1920x1080-framerate R-pixel_格式rgb24-i-output.mp4
    @Mulvya。那么,
    -i-
    是答案吗?只是想知道为什么我没有在文件里找到它。Thanks@estus. 也谢谢。如上所述,它是
    ffmpeg-i-…
    从标准输入读取。是的,您需要创建一个进程,child_进程默认为流的管道,比如
    let ffmpegProcess=child_进程.spawn(…);ffmpegProcess.stdin(…).pipe(…)
    。如果你对这种方法有问题,我建议你提供(回购或其他),这会增加获得正确答案的机会。希望这能有所帮助。现在无法检查节点中ffmpeg的流传输是否顺畅
    'use strict';
    
    var cp = require('child_process');
    
    var proc = cp.spawn('ffmpeg', [
      '-hide_banner',
      '-f', 'rawvideo',
      '-pix_fmt', 'rgb24',
      '-s', '2x2',
      '-i', '-',
      '1.png'
    ]);
    
    proc.stdin.write(Buffer.from([
      255, 0, 0,
      0, 255, 0,
      0, 255, 255,
      255, 0, 255
    ]));
    
    proc.stdin.end();
    
    proc.stderr.pipe(process.stdout);