Question

Below are some code snippets from three of my functions to start, pause, and resume a readable stream in Node.js. However, I would like a better way to control the Speaker() object besides initiating another one.

I am using the spotify-web module to get an audio stream from spotify. Could I just call new Speaker() each time instead of using a dedicated object? How can I address new Speaker() after the decoded stream has been piped to it?

The code below works for what I would like to do but I feel like there is a better way. I am new to Node.js and the idea of Passthrough Streams so any ideas or alternatives for stream control would be appreciated. Thanks in advance for any and all help!

// 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());
Was it helpful?

Solution

I ran into this same issue recently with the spotify-web module. The problem is that when you pipe it, the stream is no longer in flowing mode, so it can't be paused. One solution is to write each chunk of data to the decoder manually (essentially what piping would do automatically), as follows:

// 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);
}

This way, you're free to call stream.pause() and stream.resume() without worrying about piping and unpiping.

If you're working with a spotify track and want to implement pause/play functionality, I would recommend using node-throttle to control the flow of the stream. Here's a simple example script:

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(); }

Hope this was helpful. Here's a reference on streams in Node; it has some good information.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top