Node Passthrough Stream,如何正确处理管道对象?

时间:2014-03-06 20:17:45

标签: node.js stream pipe spotify node-speaker

以下是我的三个函数中的一些代码片段,用于启动,暂停和恢复Node.js中的可读流。但是,我希望有一种更好的方法来控制Speaker()对象,除了启动另一个对象。

我正在使用spotify-web模块从spotify获取音频流。我可以每次只调用new Speaker()而不是使用专用对象吗?在解码后的流传输到它之后,如何解决new Speaker()

下面的代码适用于我想做的事情,但我觉得有更好的方法。我是Node.js的新手和Passthrough Streams的想法,所以任何想法或流控制的替代方案都将受到赞赏。在此先感谢您的帮助!

// Lame decoder & speaker objects
var lame = new Lame.Decoder();
var spkr = new Speaker();

/* pipe a readable passthrough stream to the decoder
 * and then to coreaudio via speaker obj.
 *
 * snippet from start stream function()
 */ 
stream
 .pipe(lame)
 .pipe(spkr)


/* unpipe the stream
 * pause the stream at current position
 */
stream
 .unpipe(lame)
 .unpipe(spkr.end());
stream.pause();


/* stream from its last position
 * how can I reuse spkr()?
 */
stream
 .pipe(lame)
 .pipe(new Speaker());

1 个答案:

答案 0 :(得分:2)

我最近使用spotify-web模块遇到了同样的问题。问题是当你管道它时,流不再处于流动模式,因此它不能被暂停。一种解决方案是手动将每个数据块写入解码器(基本上是管道自动执行的操作),如下所示:

// Lame decoder & speaker objects
var lame = new Lame.Decoder();

// pipe() returns destination stream
var spkr = lame.pipe(new Speaker());

// manually write data to the decoder stream,
// which is a writeable stream
stream.on('data', function (chunk) {
    lame.write(chunk);
}

通过这种方式,您可以免费拨打stream.pause()stream.resume(),而无需担心管道和管道。

如果您正在使用spotify轨道并希望实现暂停/播放功能,我建议使用node-throttle来控制流的流量。这是一个简单的示例脚本:

var Lame = require('lame');
var Speaker = require('speaker');
var Throttle = require('throttle');

var BIT_RATE = 160000; // Spotify web standard bit rate

// Lame decoder & speaker objects
var lame = new Lame.Decoder();

// pipe() returns destination stream
var spkr = lame.pipe(new Speaker());

// pipe the stream to a Throttle and
// set the stream as the Throttle
stream = stream.pipe(new Throttle(BIT_RATE/8)); // convert to bytes per second

// manually write data to the decoder stream,
// which is a writeable stream
stream.on('data', function (chunk) {
    lame.write(chunk);
}

function pause() { stream.pause(); }

function resume() { stream.resume(); }

希望这有用。 Here's节点中对流的引用;它有一些很好的信息。