这是关于系统级优化的概念性查询。通过阅读NodeJS文档,我的理解是管道可以方便地对流进行流量控制。
背景:我有麦克风流进来,我想避免额外的复制操作,以节省整体系统MIPS。据我所知,对于音频流来说,即使在引擎盖下有记忆镜,也不会花费大量的MIPS,但我也计划在30fps和UHD分辨率下以相机帧流式传输。以30fps制作UHD分辨率像素数据的多个副本是非常低效的,因此需要一些建议。
示例代码:
var spawn = require('child_process').spawn
var PassThrough = require('stream').PassThrough;
var ps = null;
//var audioStream = new PassThrough;
//var infoStream = new PassThrough;
var start = function() {
if(ps == null) {
ps = spawn('rec', ['-b', 16, '--endian', 'little', '-c', 1, '-r', 16000, '-e', 'signed-integer', '-t', 'raw', '-']);
//ps.stdout.pipe(audioStream);
//ps.stderr.pipe(infoStream);
exports.audioStream = ps.stdout;
exports.infoStream = ps.stderr;
}
};
var stop = function() {
if(ps) {
ps.kill();
ps = null;
}
};
//exports.audioStream = audioStream;
//exports.infoStream = infoStream;
exports.startCapture = start;
exports.stopCapture = stop;
以下是问题:
提前感谢您的帮助。它将对我的架构有很大的帮助。
答案 0 :(得分:4)
一些网址供参考:https://github.com/nodejs/node/
https://github.com/nodejs/node/blob/master/src/stream_wrap.cc
https://github.com/nodejs/node/blob/master/src/stream_base.cc
https://github.com/libuv/libuv/blob/v1.x/src/unix/stream.c
https://github.com/libuv/libuv/blob/v1.x/src/win/stream.c
我尝试根据theese和其他一些文件写一个复杂/巨大的解释但是我得出的结论是,最好给你一个关于我的经验/阅读如何告诉我节点内部工作的总结:
管道只是简单地连接流,使.on("data", …)
调用.write(…)
,而.on("data", …)
之间没有任何膨胀。
现在我们需要将js世界与c ++ / c世界分开
在处理js中的数据时,我们使用缓冲区。 https://github.com/nodejs/node/blob/master/src/node_buffer.cc
它们只是代表分配的内存,顶部带有一些糖果来操作它。
如果将进程的stdout连接到某个.pause()
侦听器,它会将传入的块复制到Buffer对象中,以便在js世界中进一步使用。
在js世界中你有TWTRLogInButton was created with no completionBlock set
之类的方法(正如你在节点中的蒸汽api文档中看到的那样),以防止进程占用内存,以防传入数据的流速超过其处理速度。
连接进程的stdout,例如通过管道传出tcp端口将导致类似于nginx操作的连接。它将连接theese流,就像通过将传入数据直接复制到传出流来直接相互通信一样。
一旦暂停流,节点将使用内部缓冲,以防无法暂停传入流。
因此,对于您的方案,您应该进行测试
尝试通过节点中的传入流接收数据,暂停流并查看发生的情况
我不确定节点是否会使用内部缓冲,或者您尝试运行的进程是否会暂停,直到它可以继续发送数据。
我希望这个过程停止,直到你继续流。
为了传输巨大的图像,我建议将它们分块传输或直接传输到传出端口。
chunk方式允许您一次将数据发送到多个客户端,并将内存占用空间保持在相当低的水平。
PS你应该看看我刚发现的这个要点:https://gist.github.com/joyrexus/10026630
它深入解释了如何与流进行交互