Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions example/playPreview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

/**
* Example script that retrieves a preview of the specified Track through Spotify,
* then decodes the MP3 data through node-lame, and fianally plays the decoded PCM
* data through the speakers using node-speaker.
*/

var Spotify = require('../');
var login = require('../login');
var lame = require('lame');
var Speaker = require('speaker');

// determine the URI to play, ensure it's a "track" URI
var uri = process.argv[2] || 'spotify:track:6tdp8sdXrXlPV6AZZN2PE8';
var type = Spotify.uriType(uri);
if ('track' != type) {
throw new Error('Must pass a "track" URI, got ' + JSON.stringify(type));
}

// initiate the Spotify session
Spotify.login(login.username, login.password, function (err, spotify) {
if (err) throw err;

// first get a "Track" instance from the track URI
spotify.get(uri, function (err, track) {
if (err) throw err;
console.log('Playing 30 second preview of: %s - %s', track.artist[0].name, track.name);

track.playPreview()
.pipe(new lame.Decoder())
.pipe(new Speaker())
.on('finish', function () {
spotify.disconnect();
});

});
});
50 changes: 50 additions & 0 deletions lib/track.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ Object.defineProperty(Track.prototype, 'uri', {
configurable: true
});

/**
* Track Preview URL getter
*/
Object.defineProperty(Track.prototype, 'previewUrl', {
get: function () {
var previewUrlBase = 'http://d318706lgtcm8e.cloudfront.net/mp3-preview/'
return this.preview.length && (previewUrlBase + util.gid2id(this.preview[0].fileId));
},
enumerable: true,
configurable: true
})

/**
* Loads all the metadata for this Track instance. Useful for when you get an only
* partially filled Track instance from an Album instance for example.
Expand Down Expand Up @@ -100,3 +112,41 @@ Track.prototype.play = function () {
// return stream immediately so it can be .pipe()'d
return stream;
};

/**
* Begins playing a preview of the track, returns a Readable stream that outputs MP3 data.
*
* @api public
*/

Track.prototype.playPreview = function () {
var spotify = this._spotify;
var stream = new PassThrough();
var previewUrl = this.previewUrl;

if (!previewUrl) {
process.nextTick(function() {
stream.emit('error', new Error('Track does not have preview available'));
});
return stream;
}

debug('GET %s', previewUrl);
var req = spotify.agent.get(previewUrl)
.set({ 'User-Agent': spotify.userAgent })
.end()
.request();
req.on('response', response);

function response (res) {
debug('HTTP/%s %s', res.httpVersion, res.statusCode);
if (res.statusCode == 200) {
res.pipe(stream);
} else {
stream.emit('error', new Error('HTTP Status Code ' + res.statusCode));
}
}

// return stream immediately so it can be .pipe()'d
return stream;
};