【问题标题】:How to manipulate large media files in Node.js in a non-blocking way如何以非阻塞方式在 Node.js 中操作大型媒体文件
【发布时间】:2017-08-23 16:14:42
【问题描述】:

我目前正在创建一个 Node.js 应用程序,它接收音频/视频流,将其逐步写入磁盘,然后在流结束后使用 ffmpeg 对其进行转码,并将其发送到其他地方进行存储,并在本地删除它。

除了我可以在编写流之前对流进行转码以简化整个事情(此功能已计划),在潜在的大文件上处理这些操作的最佳方法是什么?

我知道产生子进程(我目前正在使用的方法),但我不确定它们的实际功能,即使经过大量阅读。我什至不确定使用“spawn”是否正是我想要的(“fork”是更好的选择吗?)。

本质上,我想知道如何在不阻塞 Node.js 的情况下转码 -> 上传 -> 删除文件,以便多个用户可以同时执行相同的操作。另外,我正在考虑将所有 3 个操作放在一个 bash 脚本中,以便它们按顺序同步发生,这样可以吗?

【问题讨论】:

    标签: node.js asynchronous ffmpeg file-handling child-process


    【解决方案1】:

    处理这个问题的正确方法是使用Streams - NodeJS 中的一个内置类。

    streams 允许逐渐管道数据并一次处理 1 个块。这允许处理大于计算机 RAM 的文件或无尽的数据流,就像您的情况一样。

    因此,您可以在不阻塞线程的情况下即时处理数据,而不是将数据写入磁盘(可以同时对多个流进行转码)。
    您尚未共享任何代码,但这里是一个通用示例。

    const spawn = require('child_process').spawn;
    
    const ffmpeg = spawn('ffmpeg -y -hide_banner -f mpegts -i pipe: -codec copy -f mpegts pipe:');
    ffmpeg.stdout.on('data', chunk => {
        // upload a transcoded chunk
    });
    
    // if the source is also a stream you can pipe it directly like so
    // sourceStream.pipe(ffmpeg.stdin);
    
    function onAudioVideoChunkReceived(chunk) {
        // handle audio/video input to nodejs server
        ffmpeg.stdin.write(chunk)
    }
    

    注意 ffmpeg 的特殊输入/输出pipe: 的使用,它允许通过 stdin 和 stdout 进行管道输入和输出

    【讨论】:

    • 谢谢,但我现在关心的不是即时转码,而是了解 spawn 在对文件进行转码时是否支持事件循环。本质上,我想知道多个用户是否可以连接到我制作的这个 Node.js 服务器,其中文件在子进程中通过使用 spawn 进行转码,或者 Node.js 进程是否会被阻止(忽略外部限制,像可用内存等)?
    • 它不会阻塞线程,您可以同时运行多个管道。编辑答案以反映这一点。显然,这只能扩展到您的 CPU/内存/网络饱和的程度。
    • 谢谢,这正是我想知道的!
    猜你喜欢
    • 1970-01-01
    • 2023-04-07
    • 2014-01-11
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 2013-01-25
    相关资源
    最近更新 更多