]>
git.wh0rd.org - chrome-ext/music-player-client.git/blob - js/mpc.js
1 // Written by Mike Frysinger <vapier@gmail.com>. Released into the public domain. Suck it.
3 function Mpc(socket
, cb_update_state
, debug_enabled
) {
5 this._cb_update_state
= cb_update_state
;
6 this._debug_enabled
= debug_enabled
;
7 this._queue
= ['init'];
11 Mpc
.prototype.log = function(lvl
, msg
, obj
) {
12 if (this._debug_enabled
& lvl
)
13 console
.log('mpc: ' + msg
, obj
);
16 Mpc
.prototype.err = function(msg
, obj
) {
17 console
.error('mpc: ' + msg
, obj
);
20 Mpc
.prototype.set_debug = function(val
) {
21 this._debug_enabled
= val
;
24 Mpc
.prototype.send = function(msg
) {
26 this._queue
.push(msg
);
27 this._socket
.send(msg
, function(x
) {
28 _this
.log(0x1, 'send: ' + msg
+ ':', x
);
32 Mpc
.prototype.recv_msg = function(lines
) {
33 curr
= this._queue
.shift();
34 this.log(0x2, 'recv: [' + curr
+ ']:', lines
.join('\n'));
35 curr
= curr
.split(' ');
38 // Needs to return a list of dicts (see above for dicts).
39 //case 'playlistinfo':
44 lines
.forEach(function(line
) {
45 i
= line
.indexOf(':');
47 return; // Ignores the OK line
48 key
= line
.substr(0, i
);
49 val
= line
.substr(i
+ 2);
53 this._cb_update_state(state
);
56 this._cb_update_state(lines
, curr
);
61 Mpc
.prototype.recv = function(msg
) {
62 /* We can get back a bunch of responses in a row, so parse them out */
63 /* XXX: Do we have to handle partial reads ? like long playlists ... */
64 lines
= msg
.split('\n');
66 while (i
< lines
.length
) {
67 if (lines
[i
] == 'OK' || lines
[i
].substr(0, 3) == 'OK ') {
68 this.recv_msg(lines
.splice(0, i
+ 1));
76 * Command generator helpers.
79 Mpc
.__make_send_void = function(cmd
) {
80 return function() { this.send(cmd
); }
83 Mpc
.__make_send_arg1 = function(cmd
) {
86 this.err(cmd
+ ': function requires one argument');
88 this.send(cmd
+ ' ' + a1
);
92 Mpc
.__make_send_arg2 = function(cmd
) {
93 return function(a1
, a2
) {
94 if (a1
=== undefined || a2
=== undefined)
95 this.err(cmd
+ ': function requires two arguments');
97 this.send(cmd
+ ' ' + a1
+ ' ' + a2
);
101 Mpc
.__make_send_opt = function(cmd
) {
102 return function(arg
) {
103 if (arg
=== undefined)
105 this.send(cmd
+ ' ' + arg
);
109 Mpc
.__make_send_range = function(cmd
, min
, max
, def
) {
110 return function(arg
) {
111 if (arg
=== undefined)
113 if (arg
>= min
&& arg
<= max
)
114 this.send(cmd
+ ' ' + arg
);
116 this.err(cmd
+ ': arg must be [' + min
+ ',' + max
+ '] but got "' + arg
+ '"');
121 * Querying MPD's status
122 * http://www.musicpd.org/doc/protocol/ch03.html#idp118752
126 Mpc
.prototype.clearerror
= Mpc
.__make_send_void('clearerror');
128 Mpc
.prototype.currentsong
= Mpc
.__make_send_void('currentsong');
129 // idle [SUBSYSTEMS...]
132 Mpc
.prototype.status
= Mpc
.__make_send_void('status');
134 Mpc
.prototype.stats
= Mpc
.__make_send_void('stats');
138 * http://www.musicpd.org/doc/protocol/ch03s02.html
142 Mpc
.prototype.consume
= Mpc
.__make_send_range('consume', 0, 1, 1);
143 // crossfade {SECONDS}
144 Mpc
.prototype.crossfade
= Mpc
.__make_send_arg1('crossfade');
145 // mixrampdb {deciBels}
146 Mpc
.prototype.mixrampdb
= Mpc
.__make_send_arg1('mixrampdb');
147 // mixrampdelay {SECONDS|nan}
148 // Note: Probably should handle javascript NaN here.
149 Mpc
.prototype.mixrampdelay
= Mpc
.__make_send_arg1('mixrampdelay');
151 Mpc
.prototype.random
= Mpc
.__make_send_range('random', 0, 1, 1);
153 Mpc
.prototype.repeat
= Mpc
.__make_send_range('repeat', 0, 1, 1);
155 Mpc
.prototype.setvol
= Mpc
.__make_send_range('setvol', 0, 100);
157 Mpc
.prototype.single
= Mpc
.__make_send_range('single', 0, 1, 1);
158 // replay_gain_mode {MODE}
159 Mpc
.prototype.replay_gain_mode
= Mpc
.__make_send_arg1('replay_gain_mode');
160 // replay_gain_status
163 * Controlling playback
164 * http://www.musicpd.org/doc/protocol/ch03s03.html
168 Mpc
.prototype.next
= Mpc
.__make_send_void('next');
170 Mpc
.prototype.pause
= Mpc
.__make_send_range('pause', 0, 1, 1);
172 Mpc
.prototype.play
= Mpc
.__make_send_opt('play');
174 Mpc
.prototype.playid
= Mpc
.__make_send_opt('playid');
176 Mpc
.prototype.previous
= Mpc
.__make_send_void('previous');
177 // seek {SONGPOS} {TIME}
178 Mpc
.prototype.seek
= Mpc
.__make_send_arg2('seek');
179 // seekid {SONGID} {TIME}
180 Mpc
.prototype.seekid
= Mpc
.__make_send_arg2('seekid');
182 Mpc
.prototype.seekcur
= Mpc
.__make_send_arg1('seek');
184 Mpc
.prototype.stop
= Mpc
.__make_send_void('stop');
187 * Connection settings
188 * http://www.musicpd.org/doc/protocol/ch03s08.html
192 Mpc
.prototype.close
= Mpc
.__make_send_void('close');
194 Mpc
.prototype.kill
= Mpc
.__make_send_void('kill');
195 // password {PASSWORD}
196 Mpc
.prototype.password
= Mpc
.__make_send_arg1('password');
198 Mpc
.prototype.ping
= Mpc
.__make_send_void('ping');
201 * Audio output devices
202 * http://www.musicpd.org/doc/protocol/ch03s09.html
205 // disableoutput {ID}
206 Mpc
.prototype.disableoutput
= Mpc
.__make_send_arg1('disableoutput');
208 Mpc
.prototype.enableoutput
= Mpc
.__make_send_arg1('enableoutput');
210 Mpc
.prototype.outputs
= Mpc
.__make_send_void('outputs');
214 * http://www.musicpd.org/doc/protocol/ch03s10.html
218 Mpc
.prototype.config
= Mpc
.__make_send_void('config');
220 Mpc
.prototype.commands
= Mpc
.__make_send_void('commands');
222 Mpc
.prototype.notcommands
= Mpc
.__make_send_void('notcommands');
224 Mpc
.prototype.tagtypes
= Mpc
.__make_send_void('tagtypes');
226 Mpc
.prototype.urlhandlers
= Mpc
.__make_send_void('urlhandlers');
228 Mpc
.prototype.decoders
= Mpc
.__make_send_void('decoders');
232 * http://www.musicpd.org/doc/protocol/ch03s11.html
236 Mpc
.prototype.subscribe
= Mpc
.__make_send_arg1('subscribe');
237 // unsubscribe {NAME}
238 Mpc
.prototype.unsubscribe
= Mpc
.__make_send_arg1('unsubscribe');
240 Mpc
.prototype.channels
= Mpc
.__make_send_void('channels');
242 Mpc
.prototype.readmessages
= Mpc
.__make_send_void('readmessages');
243 // sendmessage {CHANNEL} {TEXT}
244 Mpc
.prototype.sendmessage
= Mpc
.__make_send_arg2('sendmessage');