-
Notifications
You must be signed in to change notification settings - Fork 127
/
track.js
99 lines (83 loc) · 2.5 KB
/
track.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
/**
* Module dependencies.
*/
var util = require('./util');
var Track = require('./schemas').metadata['spotify.metadata.proto.Track'];
var PassThrough = require('stream').PassThrough;
var debug = require('debug')('spotify-web:track');
// node v0.8.x compat
if (!PassThrough) PassThrough = require('readable-stream/passthrough');
/**
* Module exports.
*/
exports = module.exports = Track;
/**
* Track URI getter.
*/
Object.defineProperty(Track.prototype, 'uri', {
get: function () {
return util.gid2uri('track', this.gid);
},
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.
*
* @param {Function} fn callback function
* @api public
*/
Track.prototype.get =
Track.prototype.metadata = function (fn) {
if (this._loaded) {
// already been loaded...
debug('track already loaded');
return process.nextTick(fn.bind(null, null, this));
}
var spotify = this._spotify;
var self = this;
spotify.get(this.uri, function (err, track) {
if (err) return fn(err);
// extend this Track instance with the new one's properties
Object.keys(track).forEach(function (key) {
if (!self.hasOwnProperty(key)) {
self[key] = track[key];
}
});
fn(null, self);
});
};
/**
* Begins playing this track, returns a Readable stream that outputs MP3 data.
*
* @api public
*/
Track.prototype.play = function () {
// TODO: add formatting options once we figure that out
var spotify = this._spotify;
var stream = new PassThrough();
// if a song was playing before this, the "track_end" command needs to be sent
var track = spotify.currentTrack;
if (track) {
spotify.sendTrackEnd(track._playSession.lid, track.uri, track.duration);
track._playSession = null;
}
// set this Track instance as the "currentTrack"
spotify.currentTrack = track = this;
// initiate a "play session" for this Track
spotify.trackUri(track, function (err, res) {
if (err) return stream.emit('error', err);
if (!res.uri) return stream.emit('error', new Error('response contained no "uri"'));
debug('GET %s', res.uri);
track._playSession = res;
var req = spotify.agent.get(res.uri).end().request();
req.on('response', response);
});
function response (res) {
debug('HTTP/%s %s', res.httpVersion, res.statusCode);
res.pipe(stream);
}
// return stream immediately so it can be .pipe()'d
return stream;
};