节点 - 如何管道到新的READABLE流?

时间:2016-08-02 09:29:15

标签: node.js websocket stream pipe duplex

我的应用程序应该从客户端传输Web音频,将其编码为MP3,然后通过WebSocket将其发送回客户端。

我现在可以编码并管道到这样的文件:

inbound_stream.pipe(encoder).pipe(fs.createWriteStream('audio.mp3'));

如果我已经在服务器上有文件,我可以这样做:

var mp3File = fs.createReadStream('audio.mp3');

            mp3File.on('data', function(buffer){
                io.sockets.emit('audio', { buffer: buffer });
            });

但是,我想实时访问编码的块,并将它们发送给客户端 - 写入文件。

我想要的是这样,有效:

inbound_stream.pipe(encoder).pipe(newReadStream);

        newReadStream.on('data', function(buffer){
            io.sockets.emit('audio', { buffer: buffer });
        });

我看过Duplex和Transform流,但坦率地说我还在学习,Prototyping让我头晕目眩。

我该怎么做?感谢。

更新

以下来自@Nazar Sakharenko的解决方案当然可以做我想要的,但是实时编码的开销似乎使这个变得不可能,所以写入编码的MP3,并预先缓冲它似乎是唯一的方法(感谢各种各样的人)建议。)

但是我仍然遇到这种方法的问题。这里有一个新问题:

node.js - create a new ReadStream for a new file, when that file reaches a certain size

1 个答案:

答案 0 :(得分:0)

根据文档readable.pipe(destination[, options]),目的地应为 stream.Writable

您可以做的是实现自己的可写流:

const Writable = require('stream').Writable;

var buffer = [];
//in bytes
const CHUNK_SIZE = 102400; //100kb

const myWritable = new Writable({
  write(chunk, encoding, callback) {
    buffer += chunk;
    if(buffer.length >= CHUNK_SIZE) {
       io.sockets.emit('audio', { buffer: buffer});
       buffer = [];
    }

    callback();
  }
});

myWritable.on('finish', () => {
   //emit final part if there is data to emit
   if(buffer.length) {
       io.sockets.emit('audio', { buffer: buffer});
   }
});


inbound_stream.pipe(encoder).pipe(myWritable);

这就是全部。