-
Notifications
You must be signed in to change notification settings - Fork 2
/
sonos_additions.js
126 lines (96 loc) · 5.22 KB
/
sonos_additions.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
var sonos = require('sonos'),
Q = require('q'),
_ = require('underscore'),
xml2js = require('xml2js');
sonos.Sonos.prototype.browse = function(){
var RENDERING_ENDPOINT = '/MediaServer/ContentDirectory/Control';
var action = '"urn:schemas-upnp-org:service:ContentDirectory:1#Browse"';
var body = '<u:Browse xmlns:u="urn:schemas-upnp-org:service:ContentDirectory:1"><ObjectID>Q:0</ObjectID><BrowseFlag>BrowseDirectChildren</BrowseFlag><Filter>dc:title,res,dc:creator,upnp:artist,upnp:album,upnp:albumArtURI</Filter><StartingIndex>0</StartingIndex><RequestedCount>100</RequestedCount><SortCriteria></SortCriteria></u:Browse>';
var defer = Q.defer();
this.request(RENDERING_ENDPOINT, action, body, 'u:BrowseResponse', function(err, data){
new xml2js.Parser().parseString(data[0].Result, function(err, didl) {
var items = [];
_.each(didl['DIDL-Lite'].item, function(item, index){
items.push({"title": item['dc:title'][0], "artist": item['dc:creator'][0], "index": index+1});
});
defer.resolve(items);
});
});
return defer.promise;
};
sonos.Sonos.prototype.enqueueSpotify = function(uri, playAfter){
var encodedUri = encodeURIComponent(uri);
var isAlbum = uri.indexOf('spotify:album') > -1;
var audioClass = isAlbum ? 'object.container.album.musicAlbum' : 'object.item.audioItem.musicTrack';
var enqueuedURI = isAlbum ? 'x-rincon-cpcontainer:0004006c' + encodedUri : 'x-sonos-spotify:' + encodedUri;
var code = isAlbum ? '0004006c' : '00030000';
var RENDERING_ENDPOINT = '/MediaRenderer/AVTransport/Control';
var action = '"urn:schemas-upnp-org:service:AVTransport:1#AddURIToQueue"';
var sPlaynext = playAfter ? 1 : 0;
var sPlayAfter = playAfter + 1;
var body = '<u:AddURIToQueue xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"> \
<InstanceID>0</InstanceID> \
<EnqueuedURI>' + enqueuedURI + '</EnqueuedURI> \
<EnqueuedURIMetaData> \
<DIDL-Lite xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:upnp="urn:schemas-upnp-org:metadata-1-0/upnp/" \
xmlns:r="urn:schemas-rinconnetworks-com:metadata-1-0/" \
xmlns="urn:schemas-upnp-org:metadata-1-0/DIDL-Lite/"><item id="' + code + encodedUri + '" \
restricted="true"><dc:title>America</dc:title> \
<upnp:class>' + audioClass + '</upnp:class><desc id="cdudn" \
nameSpace="urn:schemas-rinconnetworks-com:metadata-1-0/">SA_RINCON2311_X_#Svc2311-0-Token</desc></item></DIDL-Lite> \
</EnqueuedURIMetaData> \
<DesiredFirstTrackNumberEnqueued>' + sPlayAfter + '</DesiredFirstTrackNumberEnqueued> \
<EnqueueAsNext>' + sPlaynext + '</EnqueueAsNext> \
</u:AddURIToQueue>';
var defer = Q.defer();
this.request(RENDERING_ENDPOINT, action, body, 'u:AddURIToQueueResponse', function(err, data){
var newIndex = _.reduce(data[0].FirstTrackNumberEnqueued, function(it, num){
return parseInt(num);
}, 0);
defer.resolve(newIndex);
});
return defer.promise;
}
sonos.Sonos.prototype.seekTrackNr = function(nr){
var RENDERING_ENDPOINT = '/MediaRenderer/AVTransport/Control';
var action = '"urn:schemas-upnp-org:service:AVTransport:1#Seek"';
var body = '<s:Body><u:Seek xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID><Unit>TRACK_NR</Unit><Target>' + nr + '</Target></u:Seek>';
var defer = Q.defer();
this.request(RENDERING_ENDPOINT, action, body, 'u:AddURIToQueueResponse', function(err, data){
defer.resolve();
});
return defer.promise;
}
sonos.Sonos.prototype.currentTrackWithPlaylistData = function() {
var _this = this;
var RENDERING_ENDPOINT = '/MediaRenderer/AVTransport/Control';
var action = '"urn:schemas-upnp-org:service:AVTransport:1#GetPositionInfo"';
var body = '<u:GetPositionInfo xmlns:u="urn:schemas-upnp-org:service:AVTransport:1"><InstanceID>0</InstanceID><Channel>Master</Channel></u:GetPositionInfo>';
var responseTag = 'u:GetPositionInfoResponse';
var defer = Q.defer();
this.request(RENDERING_ENDPOINT, action, body, responseTag, function(err, data) {
var metadata = data[0].TrackMetaData;
var position = (parseInt(data[0].RelTime[0].split(':')[0], 10) * 60 * 60) +
(parseInt(data[0].RelTime[0].split(':')[1], 10) * 60) +
parseInt(data[0].RelTime[0].split(':')[2], 10);
var duration = (parseInt(data[0].TrackDuration[0].split(':')[0], 10) * 60 * 60) +
(parseInt(data[0].TrackDuration[0].split(':')[1], 10) * 60) +
parseInt(data[0].TrackDuration[0].split(':')[2], 10);
var trackNr = parseInt(_.first(data[0].Track));
if (metadata) {
new xml2js.Parser().parseString(metadata, function(err, data) {
var track;
track = _this.parseDIDL(data);
track.position = position;
track.duration = duration;
track.trackNr = trackNr;
track.albumArtURL = !track.albumArtURI ? null
: (track.albumArtURI.indexOf('http') !== -1) ? track.albumArtURI
: 'http://' + _this.host + ':' + _this.port + track.albumArtURI;
defer.resolve(track);
});
}
});
return defer.promise;
};
module.exports.sonos = sonos;