3 * mpd.class.php - PHP Object Interface to the MPD Music Player Daemon
\r
4 * Version 1.2, Released 05/05/2004
\r
5 * Copyright (C) 2003-2004 Benjamin Carlisle (bcarlisle@24oz.com)
\r
6 * http://mpd.24oz.com/ | http://www.musicpd.org/
\r
8 * This program is free software; you can redistribute it and/or modify
\r
9 * it under the terms of the GNU General Public License as published by
\r
10 * the Free Software Foundation; either version 2 of the License, or
\r
11 * (at your option) any later version.
\r
13 * This program is distributed in the hope that it will be useful,
\r
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
16 * GNU General Public License for more details.
\r
18 * You should have received a copy of the GNU General Public License
\r
19 * along with this program; if not, write to the Free Software
\r
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
23 // Create common command definitions for MPD to use
\r
24 define("MPD_CMD_STATUS", "status");
\r
25 define("MPD_CMD_STATISTICS", "stats");
\r
26 define("MPD_CMD_VOLUME", "volume");
\r
27 define("MPD_CMD_SETVOL", "setvol");
\r
28 define("MPD_CMD_PLAY", "play");
\r
29 define("MPD_CMD_STOP", "stop");
\r
30 define("MPD_CMD_PAUSE", "pause");
\r
31 define("MPD_CMD_NEXT", "next");
\r
32 define("MPD_CMD_PREV", "previous");
\r
33 define("MPD_CMD_PLLIST", "playlistinfo");
\r
34 define("MPD_CMD_PLADD", "add");
\r
35 define("MPD_CMD_PLREMOVE", "delete");
\r
36 define("MPD_CMD_PLCLEAR", "clear");
\r
37 define("MPD_CMD_PLSHUFFLE", "shuffle");
\r
38 define("MPD_CMD_PLLOAD", "load");
\r
39 define("MPD_CMD_PLSAVE", "save");
\r
40 define("MPD_CMD_KILL", "kill");
\r
41 define("MPD_CMD_REFRESH", "update");
\r
42 define("MPD_CMD_REPEAT", "repeat");
\r
43 define("MPD_CMD_LSDIR", "lsinfo");
\r
44 define("MPD_CMD_SEARCH", "search");
\r
45 define("MPD_CMD_START_BULK", "command_list_begin");
\r
46 define("MPD_CMD_END_BULK", "command_list_end");
\r
47 define("MPD_CMD_FIND", "find");
\r
48 define("MPD_CMD_RANDOM", "random");
\r
49 define("MPD_CMD_SEEK", "seek");
\r
50 define("MPD_CMD_PLSWAPTRACK", "swap");
\r
51 define("MPD_CMD_PLMOVETRACK", "move");
\r
52 define("MPD_CMD_PASSWORD", "password");
\r
53 define("MPD_CMD_TABLE", "list");
\r
54 define("MPD_CMD_LISTS", "listplaylists");
\r
56 // Predefined MPD Response messages
\r
57 define("MPD_RESPONSE_ERR", "ACK");
\r
58 define("MPD_RESPONSE_OK", "OK");
\r
60 // MPD State Constants
\r
61 define("MPD_STATE_PLAYING", "play");
\r
62 define("MPD_STATE_STOPPED", "stop");
\r
63 define("MPD_STATE_PAUSED", "pause");
\r
65 // MPD Searching Constants
\r
66 define("MPD_SEARCH_ARTIST", "artist");
\r
67 define("MPD_SEARCH_TITLE", "title");
\r
68 define("MPD_SEARCH_ALBUM", "album");
\r
71 define("MPD_TBL_ARTIST","artist");
\r
72 define("MPD_TBL_ALBUM","album");
\r
75 // TCP/Connection variables
\r
80 var $mpd_sock = NULL;
\r
81 var $connected = FALSE;
\r
83 // MPD Status variables
\r
84 var $mpd_version = "(unknown)";
\r
87 var $current_track_position;
\r
88 var $current_track_length;
\r
89 var $current_track_id;
\r
96 var $db_last_refreshed;
\r
97 var $num_songs_played;
\r
98 var $playlist_count;
\r
104 var $playlist = array();
\r
106 // Misc Other Vars
\r
107 var $mpd_class_version = "1.2";
\r
109 var $debugging = TRUE; // Set to TRUE to turn extended debugging on.
\r
110 var $errStr = ""; // Used for maintaining information about the last error message
\r
112 var $command_queue; // The list of commands for bulk command sending
\r
114 // =================== BEGIN OBJECT METHODS ================
\r
116 /* mpd() : Constructor
\r
118 * Builds the MPD object, connects to the server, and refreshes all local object properties.
\r
120 function mpd($srv,$port,$pwd = NULL) {
\r
121 $this->host = $srv;
\r
122 $this->port = $port;
\r
123 $this->password = $pwd;
\r
125 $resp = $this->Connect();
\r
126 if ( is_null($resp) ) {
\r
127 $this->errStr = "Could not connect";
\r
130 list ( $this->mpd_version ) = sscanf($resp, MPD_RESPONSE_OK . " MPD %s\n");
\r
131 if ( ! is_null($pwd) ) {
\r
132 if ( is_null($this->SendCommand(MPD_CMD_PASSWORD,$pwd)) ) {
\r
133 $this->connected = FALSE;
\r
134 return; // bad password or command
\r
136 if ( is_null($this->RefreshInfo()) ) { // no read access -- might as well be disconnected!
\r
137 $this->connected = FALSE;
\r
138 $this->errStr = "Password supplied does not have read access";
\r
142 if ( is_null($this->RefreshInfo()) ) { // no read access -- might as well be disconnected!
\r
143 $this->connected = FALSE;
\r
144 $this->errStr = "Password required to access server";
\r
153 * Connects to the MPD server.
\r
155 * NOTE: This is called automatically upon object instantiation; you should not need to call this directly.
\r
157 function Connect() {
\r
158 if ( $this->debugging ) echo "mpd->Connect() / host: ".$this->host.", port: ".$this->port."\n";
\r
159 $this->mpd_sock = fsockopen($this->host,$this->port,$errNo,$errStr,10);
\r
160 if (!$this->mpd_sock) {
\r
161 $this->errStr = "Socket Error: $errStr ($errNo)";
\r
164 while(!feof($this->mpd_sock)) {
\r
165 $response = fgets($this->mpd_sock,1024);
\r
166 if (strncmp(MPD_RESPONSE_OK,$response,strlen(MPD_RESPONSE_OK)) == 0) {
\r
167 $this->connected = TRUE;
\r
171 if (strncmp(MPD_RESPONSE_ERR,$response,strlen(MPD_RESPONSE_ERR)) == 0) {
\r
172 $this->errStr = "Server responded with: $response";
\r
176 // Generic response
\r
177 $this->errStr = "Connection not available";
\r
184 * Sends a generic command to the MPD server. Several command constants are pre-defined for
\r
185 * use (see MPD_CMD_* constant definitions above).
\r
187 function SendCommand($cmdStr,$arg1 = "",$arg2 = "") {
\r
188 if ( $this->debugging ) echo "mpd->SendCommand() / cmd: ".$cmdStr.", args: ".$arg1." ".$arg2."\n";
\r
190 if ( ! $this->connected ) {
\r
191 echo "mpd->SendCommand() / Error: Not connected\n";
\r
193 // Clear out the error String
\r
194 $this->errStr = "";
\r
197 // Check the command compatibility:
\r
198 if ( ! $this->_checkCompatibility($cmdStr) ) {
\r
199 echo "Not compatible command!";
\r
203 if (strlen($arg1) > 0) $cmdStr .= " \"$arg1\"";
\r
205 if (strlen($arg2) > 0) $cmdStr .= " \"$arg2\"";
\r
206 if ( $this->debugging ) echo "mpd-> ".$cmdStr."\n";
\r
207 fputs($this->mpd_sock,"$cmdStr\n");
\r
208 while(!feof($this->mpd_sock)) {
\r
209 $response = fgets($this->mpd_sock,1024);
\r
210 if ( $this->debugging ) echo "mpd.response-> ".$response."\n";
\r
212 // An OK signals the end of transmission -- we'll ignore it
\r
213 if (strncmp(MPD_RESPONSE_OK,$response,strlen(MPD_RESPONSE_OK)) == 0) {
\r
217 // An ERR signals the end of transmission with an error! Let's grab the single-line message.
\r
218 if (strncmp(MPD_RESPONSE_ERR,$response,strlen(MPD_RESPONSE_ERR)) == 0) {
\r
219 list ( $junk, $errTmp ) = explode(MPD_RESPONSE_ERR . " ",$response );
\r
220 $this->errStr = strtok($errTmp,"\n");
\r
223 if ( strlen($this->errStr) > 0 ) {
\r
227 // Build the response string
\r
228 $respStr .= $response;
\r
230 if ( $this->debugging ) echo "mpd->SendCommand() / response: '".$respStr."'\n";
\r
237 * Queues a generic command for later sending to the MPD server. The CommandQueue can hold
\r
238 * as many commands as needed, and are sent all at once, in the order they are queued, using
\r
239 * the SendCommandQueue() method. The syntax for queueing commands is identical to SendCommand().
\r
241 function QueueCommand($cmdStr,$arg1 = "",$arg2 = "") {
\r
242 if ( $this->debugging ) echo "mpd->QueueCommand() / cmd: ".$cmdStr.", args: ".$arg1." ".$arg2."\n";
\r
243 if ( ! $this->connected ) {
\r
244 echo "mpd->QueueCommand() / Error: Not connected\n";
\r
247 if ( strlen($this->command_queue) == 0 ) {
\r
248 $this->command_queue = MPD_CMD_START_BULK . "\n";
\r
250 if (strlen($arg1) > 0) $cmdStr .= " \"$arg1\"";
\r
251 if (strlen($arg2) > 0) $cmdStr .= " \"$arg2\"";
\r
253 $this->command_queue .= $cmdStr ."\n";
\r
255 if ( $this->debugging ) echo "mpd->QueueCommand() / return\n";
\r
260 /* SendCommandQueue()
\r
262 * Sends all commands in the Command Queue to the MPD server. See also QueueCommand().
\r
264 function SendCommandQueue() {
\r
265 if ( $this->debugging ) echo "mpd->SendCommandQueue()\n";
\r
266 if ( ! $this->connected ) {
\r
267 echo "mpd->SendCommandQueue() / Error: Not connected\n";
\r
270 $this->command_queue .= MPD_CMD_END_BULK . "\n";
\r
271 if ( is_null($respStr = $this->SendCommand($this->command_queue)) ) {
\r
274 $this->command_queue = NULL;
\r
275 if ( $this->debugging ) echo "mpd->SendCommandQueue() / response: '".$respStr."'\n";
\r
283 * Adjusts the mixer volume on the MPD by <modifier>, which can be a positive (volume increase),
\r
284 * or negative (volume decrease) value.
\r
286 function AdjustVolume($modifier) {
\r
287 if ( $this->debugging ) echo "mpd->AdjustVolume()\n";
\r
288 if ( ! is_numeric($modifier) ) {
\r
289 $this->errStr = "AdjustVolume() : argument 1 must be a numeric value";
\r
293 $this->RefreshInfo();
\r
294 $newVol = $this->volume + $modifier;
\r
295 $ret = $this->SetVolume($newVol);
\r
297 if ( $this->debugging ) echo "mpd->AdjustVolume() / return\n";
\r
303 * Sets the mixer volume to <newVol>, which should be between 1 - 100.
\r
305 function SetVolume($newVol) {
\r
306 if ( $this->debugging ) echo "mpd->SetVolume()\n";
\r
307 if ( ! is_numeric($newVol) ) {
\r
308 $this->errStr = "SetVolume() : argument 1 must be a numeric value";
\r
312 // Forcibly prevent out of range errors
\r
313 if ( $newVol < 0 ) $newVol = 0;
\r
314 if ( $newVol > 100 ) $newVol = 100;
\r
316 // If we're not compatible with SETVOL, we'll try adjusting using VOLUME
\r
317 if ( $this->_checkCompatibility(MPD_CMD_SETVOL) ) {
\r
318 if ( ! is_null($ret = $this->SendCommand(MPD_CMD_SETVOL,$newVol))) $this->volume = $newVol;
\r
320 $this->RefreshInfo(); // Get the latest volume
\r
321 if ( is_null($this->volume) ) {
\r
324 $modifier = ( $newVol - $this->volume );
\r
325 if ( ! is_null($ret = $this->SendCommand(MPD_CMD_VOLUME,$modifier))) $this->volume = $newVol;
\r
329 if ( $this->debugging ) echo "mpd->SetVolume() / return\n";
\r
335 * Retrieves a database directory listing of the <dir> directory and places the results into
\r
336 * a multidimensional array. If no directory is specified, the directory listing is at the
\r
337 * base of the MPD music path.
\r
339 function GetDir($dir = "") {
\r
340 if ( $this->debugging ) echo "mpd->GetDir()\n";
\r
341 $resp = $this->SendCommand(MPD_CMD_LSDIR,$dir);
\r
342 $dirlist = $this->_parseFileListResponse($resp);
\r
343 if ( $this->debugging ) echo "mpd->GetDir() / return ".print_r($dirlist)."\n";
\r
349 * Adds each track listed in a single-dimensional <trackArray>, which contains filenames
\r
350 * of tracks to add, to the end of the playlist. This is used to add many, many tracks to
\r
351 * the playlist in one swoop.
\r
353 function PLAddBulk($trackArray) {
\r
354 if ( $this->debugging ) echo "mpd->PLAddBulk()\n";
\r
355 $num_files = count($trackArray);
\r
356 for ( $i = 0; $i < $num_files; $i++ ) {
\r
357 $this->QueueCommand(MPD_CMD_PLADD,$trackArray[$i]);
\r
359 $resp = $this->SendCommandQueue();
\r
360 $this->RefreshInfo();
\r
361 if ( $this->debugging ) echo "mpd->PLAddBulk() / return\n";
\r
367 * Adds the file <file> to the end of the playlist. <file> must be a track in the MPD database.
\r
369 function PLAdd($fileName) {
\r
370 if ( $this->debugging ) echo "mpd->PLAdd()\n";
\r
371 if ( ! is_null($resp = $this->SendCommand(MPD_CMD_PLADD,$fileName))) $this->RefreshInfo();
\r
372 if ( $this->debugging ) echo "mpd->PLAdd() / return\n";
\r
378 * Moves track number <origPos> to position <newPos> in the playlist. This is used to reorder
\r
379 * the songs in the playlist.
\r
381 function PLMoveTrack($origPos, $newPos) {
\r
382 if ( $this->debugging ) echo "mpd->PLMoveTrack()\n";
\r
383 if ( ! is_numeric($origPos) ) {
\r
384 $this->errStr = "PLMoveTrack(): argument 1 must be numeric";
\r
387 if ( $origPos < 0 or $origPos > $this->playlist_count ) {
\r
388 $this->errStr = "PLMoveTrack(): argument 1 out of range";
\r
391 if ( $newPos < 0 ) $newPos = 0;
\r
392 if ( $newPos > $this->playlist_count ) $newPos = $this->playlist_count;
\r
394 if ( ! is_null($resp = $this->SendCommand(MPD_CMD_PLMOVETRACK,$origPos,$newPos))) $this->RefreshInfo();
\r
395 if ( $this->debugging ) echo "mpd->PLMoveTrack() / return\n";
\r
401 * Randomly reorders the songs in the playlist.
\r
403 function PLShuffle() {
\r
404 if ( $this->debugging ) echo "mpd->PLShuffle()\n";
\r
405 if ( ! is_null($resp = $this->SendCommand(MPD_CMD_PLSHUFFLE))) $this->RefreshInfo();
\r
406 if ( $this->debugging ) echo "mpd->PLShuffle() / return\n";
\r
412 * Retrieves the playlist from <file>.m3u and loads it into the current playlist.
\r
414 function PLLoad($file) {
\r
415 if ( $this->debugging ) echo "mpd->PLLoad()\n";
\r
416 if ( ! is_null($resp = $this->SendCommand(MPD_CMD_PLLOAD,$file))) $this->RefreshInfo();
\r
417 if ( $this->debugging ) echo "mpd->PLLoad() / return\n";
\r
423 * Retrieves the playlists info.
\r
425 function PLList() {
\r
426 if ( $this->debugging ) echo "mpd->PLList()\n";
\r
427 if ( ! is_null($resp = $this->SendCommand(MPD_CMD_LISTS))) $this->RefreshInfo();
\r
428 if ( $this->debugging ) echo "mpd->PLList() / return\n";
\r
434 * Saves the playlist to <file>.m3u for later retrieval. The file is saved in the MPD playlist
\r
437 function PLSave($file) {
\r
438 if ( $this->debugging ) echo "mpd->PLSave()\n";
\r
439 $resp = $this->SendCommand(MPD_CMD_PLSAVE,$file);
\r
440 if ( $this->debugging ) echo "mpd->PLSave() / return\n";
\r
446 * Empties the playlist.
\r
448 function PLClear() {
\r
449 if ( $this->debugging ) echo "mpd->PLClear()\n";
\r
450 if ( ! is_null($resp = $this->SendCommand(MPD_CMD_PLCLEAR))) $this->RefreshInfo();
\r
451 if ( $this->debugging ) echo "mpd->PLClear() / return\n";
\r
458 * Move song from pos to the other
\r
460 function Move ($from,$to) {
\r
461 if ( ! is_null($resp = $this->SendCommand(MPD_CMD_PLMOVETRACK,$from,$to))) $this->RefreshInfo();
\r
462 //die(print_r($resp));
\r
469 * Removes track <id> from the playlist.
\r
471 function PLRemove($id) {
\r
472 if ( $this->debugging ) echo "mpd->PLRemove()\n";
\r
473 if ( ! is_numeric($id) ) {
\r
474 $this->errStr = "PLRemove() : argument 1 must be a numeric value";
\r
477 if ( ! is_null($resp = $this->SendCommand(MPD_CMD_PLREMOVE,$id))) $this->RefreshInfo();
\r
478 if ( $this->debugging ) echo "mpd->PLRemove() / return\n";
\r
484 * Enables 'loop' mode -- tells MPD continually loop the playlist. The <repVal> parameter
\r
485 * is either 1 (on) or 0 (off).
\r
487 function SetRepeat($repVal) {
\r
488 if ( $this->debugging ) echo "mpd->SetRepeat()\n";
\r
489 $rpt = $this->SendCommand(MPD_CMD_REPEAT,$repVal);
\r
490 $this->repeat = $repVal;
\r
491 if ( $this->debugging ) echo "mpd->SetRepeat() / return\n";
\r
497 * Enables 'randomize' mode -- tells MPD to play songs in the playlist in random order. The
\r
498 * <rndVal> parameter is either 1 (on) or 0 (off).
\r
500 function SetRandom($rndVal) {
\r
501 if ( $this->debugging ) echo "mpd->SetRandom()\n";
\r
502 $resp = $this->SendCommand(MPD_CMD_RANDOM,$rndVal);
\r
503 $this->random = $rndVal;
\r
504 if ( $this->debugging ) echo "mpd->SetRandom() / return\n";
\r
510 * Shuts down the MPD server (aka sends the KILL command). This closes the current connection,
\r
511 * and prevents future communication with the server.
\r
513 function Shutdown() {
\r
514 if ( $this->debugging ) echo "mpd->Shutdown()\n";
\r
515 $resp = $this->SendCommand(MPD_CMD_SHUTDOWN);
\r
517 $this->connected = FALSE;
\r
518 unset($this->mpd_version);
\r
519 unset($this->errStr);
\r
520 unset($this->mpd_sock);
\r
522 if ( $this->debugging ) echo "mpd->Shutdown() / return\n";
\r
528 * Tells MPD to rescan the music directory for new tracks, and to refresh the Database. Tracks
\r
529 * cannot be played unless they are in the MPD database.
\r
531 function DBRefresh() {
\r
532 if ( $this->debugging ) echo "mpd->DBRefresh()\n";
\r
533 $resp = $this->SendCommand(MPD_CMD_REFRESH);
\r
535 // Update local variables
\r
536 $this->RefreshInfo();
\r
538 if ( $this->debugging ) echo "mpd->DBRefresh() / return\n";
\r
544 * Begins playing the songs in the MPD playlist.
\r
547 if ( $this->debugging ) echo "mpd->Play()\n";
\r
548 if ( ! is_null($rpt = $this->SendCommand(MPD_CMD_PLAY) )) $this->RefreshInfo();
\r
549 if ( $this->debugging ) echo "mpd->Play() / return\n";
\r
555 * Stops playing the MPD.
\r
558 if ( $this->debugging ) echo "mpd->Stop()\n";
\r
559 if ( ! is_null($rpt = $this->SendCommand(MPD_CMD_STOP) )) $this->RefreshInfo();
\r
560 if ( $this->debugging ) echo "mpd->Stop() / return\n";
\r
566 * Toggles pausing on the MPD. Calling it once will pause the player, calling it again
\r
570 if ( $this->debugging ) echo "mpd->Pause()\n";
\r
571 if ( ! is_null($rpt = $this->SendCommand(MPD_CMD_PAUSE) )) $this->RefreshInfo();
\r
572 if ( $this->debugging ) echo "mpd->Pause() / return\n";
\r
578 * Skips directly to the <idx> song in the MPD playlist.
\r
580 function SkipTo($idx) {
\r
581 if ( $this->debugging ) echo "mpd->SkipTo()\n";
\r
582 if ( ! is_numeric($idx) ) {
\r
583 $this->errStr = "SkipTo() : argument 1 must be a numeric value";
\r
586 if ( ! is_null($rpt = $this->SendCommand(MPD_CMD_PLAY,$idx))) $this->RefreshInfo();
\r
587 if ( $this->debugging ) echo "mpd->SkipTo() / return\n";
\r
593 * Skips directly to a given position within a track in the MPD playlist. The <pos> argument,
\r
594 * given in seconds, is the track position to locate. The <track> argument, if supplied is
\r
595 * the track number in the playlist. If <track> is not specified, the current track is assumed.
\r
597 function SeekTo($pos, $track = -1) {
\r
598 if ( $this->debugging ) echo "mpd->SeekTo()\n";
\r
599 if ( ! is_numeric($pos) ) {
\r
600 $this->errStr = "SeekTo() : argument 1 must be a numeric value";
\r
603 if ( ! is_numeric($track) ) {
\r
604 $this->errStr = "SeekTo() : argument 2 must be a numeric value";
\r
607 if ( $track == -1 ) {
\r
608 $track = $this->current_track_id;
\r
611 if ( ! is_null($rpt = $this->SendCommand(MPD_CMD_SEEK,$track,$pos))) $this->RefreshInfo();
\r
612 if ( $this->debugging ) echo "mpd->SeekTo() / return\n";
\r
618 * Skips to the next song in the MPD playlist. If not playing, returns an error.
\r
621 if ( $this->debugging ) echo "mpd->Next()\n";
\r
622 if ( ! is_null($rpt = $this->SendCommand(MPD_CMD_NEXT))) $this->RefreshInfo();
\r
623 if ( $this->debugging ) echo "mpd->Next() / return\n";
\r
629 * Skips to the previous song in the MPD playlist. If not playing, returns an error.
\r
631 function Previous() {
\r
632 if ( $this->debugging ) echo "mpd->Previous()\n";
\r
633 if ( ! is_null($rpt = $this->SendCommand(MPD_CMD_PREV))) $this->RefreshInfo();
\r
634 if ( $this->debugging ) echo "mpd->Previous() / return\n";
\r
640 * Searches the MPD database. The search <type> should be one of the following:
\r
641 * MPD_SEARCH_ARTIST, MPD_SEARCH_TITLE, MPD_SEARCH_ALBUM
\r
642 * The search <string> is a case-insensitive locator string. Anything that contains
\r
643 * <string> will be returned in the results.
\r
645 function Search($type,$string) {
\r
646 if ( $this->debugging ) echo "mpd->Search()\n";
\r
647 if ( $type != MPD_SEARCH_ARTIST and
\r
648 $type != MPD_SEARCH_ALBUM and
\r
649 $type != MPD_SEARCH_TITLE ) {
\r
650 $this->errStr = "mpd->Search(): invalid search type";
\r
653 if ( is_null($resp = $this->SendCommand(MPD_CMD_SEARCH,$type,$string))) return NULL;
\r
654 $searchlist = $this->_parseFileListResponse($resp);
\r
656 if ( $this->debugging ) echo "mpd->Search() / return ".print_r($searchlist)."\n";
\r
657 return $searchlist;
\r
662 * Find() looks for exact matches in the MPD database. The find <type> should be one of
\r
664 * MPD_SEARCH_ARTIST, MPD_SEARCH_TITLE, MPD_SEARCH_ALBUM
\r
665 * The find <string> is a case-insensitive locator string. Anything that exactly matches
\r
666 * <string> will be returned in the results.
\r
668 function Find($type,$string) {
\r
669 if ( $this->debugging ) echo "mpd->Find()\n";
\r
670 if ( $type != MPD_SEARCH_ARTIST and
\r
671 $type != MPD_SEARCH_ALBUM and
\r
672 $type != MPD_SEARCH_TITLE ) {
\r
673 $this->errStr = "mpd->Find(): invalid find type";
\r
676 if ( is_null($resp = $this->SendCommand(MPD_CMD_FIND,$type,$string))) return NULL;
\r
677 $searchlist = $this->_parseFileListResponse($resp);
\r
679 if ( $this->debugging ) echo "mpd->Find() / return ".print_r($searchlist)."\n";
\r
680 return $searchlist;
\r
685 * Closes the connection to the MPD server.
\r
687 function Disconnect() {
\r
688 if ( $this->debugging ) echo "mpd->Disconnect()\n";
\r
689 fclose($this->mpd_sock);
\r
691 $this->connected = FALSE;
\r
692 unset($this->mpd_version);
\r
693 unset($this->errStr);
\r
694 unset($this->mpd_sock);
\r
699 * Returns the list of artists in the database in an associative array.
\r
701 function GetArtists() {
\r
702 if ( $this->debugging ) echo "mpd->GetArtists()\n";
\r
703 if ( is_null($resp = $this->SendCommand(MPD_CMD_TABLE, MPD_TBL_ARTIST))) return NULL;
\r
704 $arArray = array();
\r
706 $arLine = strtok($resp,"\n");
\r
709 while ( $arLine ) {
\r
710 list ( $element, $value ) = explode(": ",$arLine);
\r
711 if ( $element == "Artist" ) {
\r
714 $arArray[$arCounter] = $arName;
\r
717 $arLine = strtok("\n");
\r
719 if ( $this->debugging ) echo "mpd->GetArtists()\n";
\r
725 * Returns the list of albums in the database in an associative array. Optional parameter
\r
726 * is an artist Name which will list all albums by a particular artist.
\r
728 function GetAlbums( $ar = NULL) {
\r
729 if ( $this->debugging ) echo "mpd->GetAlbums()\n";
\r
730 if ( is_null($resp = $this->SendCommand(MPD_CMD_TABLE, MPD_TBL_ALBUM, $ar ))) return NULL;
\r
731 $alArray = array();
\r
733 $alLine = strtok($resp,"\n");
\r
736 while ( $alLine ) {
\r
737 list ( $element, $value ) = explode(": ",$alLine);
\r
738 if ( $element == "Album" ) {
\r
741 $alArray[$alCounter] = $alName;
\r
744 $alLine = strtok("\n");
\r
746 if ( $this->debugging ) echo "mpd->GetAlbums()\n";
\r
750 //*******************************************************************************//
\r
751 //***************************** INTERNAL FUNCTIONS ******************************//
\r
752 //*******************************************************************************//
\r
754 /* _computeVersionValue()
\r
756 * Computes a compatibility value from a version string
\r
759 function _computeVersionValue($verStr) {
\r
760 list ($ver_maj, $ver_min, $ver_rel ) = explode("\.",$verStr);
\r
761 return ( 100 * $ver_maj ) + ( 10 * $ver_min ) + ( $ver_rel );
\r
764 /* _checkCompatibility()
\r
766 * Check MPD command compatibility against our internal table. If there is no version
\r
767 * listed in the table, allow it by default.
\r
769 function _checkCompatibility($cmd) {
\r
770 // Check minimum compatibility
\r
771 $req_ver_low = $this->COMPATIBILITY_MIN_TBL[$cmd];
\r
772 $req_ver_hi = $this->COMPATIBILITY_MAX_TBL[$cmd];
\r
774 $mpd_ver = $this->_computeVersionValue($this->mpd_version);
\r
776 if ( $req_ver_low ) {
\r
777 $req_ver = $this->_computeVersionValue($req_ver_low);
\r
779 if ( $mpd_ver < $req_ver ) {
\r
780 $this->errStr = "Command '$cmd' is not compatible with this version of MPD, version ".$req_ver_low." required";
\r
785 // Check maxmum compatibility -- this will check for deprecations
\r
786 if ( $req_ver_hi ) {
\r
787 $req_ver = $this->_computeVersionValue($req_ver_hi);
\r
789 if ( $mpd_ver > $req_ver ) {
\r
790 $this->errStr = "Command '$cmd' has been deprecated in this version of MPD.";
\r
798 /* _parseFileListResponse()
\r
800 * Builds a multidimensional array with MPD response lists.
\r
802 * NOTE: This function is used internally within the class. It should not be used.
\r
804 function _parseFileListResponse($resp) {
\r
805 if ( is_null($resp) ) {
\r
808 $plistArray = array();
\r
809 $plistLine = strtok($resp,"\n");
\r
812 while ( $plistLine ) {
\r
813 list ( $element, $value ) = explode(": ",$plistLine);
\r
814 if($element == "file" || $element=="directory") {
\r
816 $plistArray[$plCounter]['name']=$value;
\r
817 $plistArray[$plCounter]['type']=$element;
\r
818 $plistArray[$plCounter]['title']=$value;
\r
820 if($element == "Name") {
\r
821 $plistArray[$plCounter]['title']=$value;
\r
823 $plistLine = strtok("\n");
\r
826 return $plistArray;
\r
829 /* _parsePlayListsResponse()
\r
831 * Builds a multidimensional array with MPD response lists.
\r
833 * NOTE: This function is used internally within the class. It should not be used.
\r
835 function _parsePlayListsResponse($resp) {
\r
836 if ( is_null($resp) ) {
\r
839 $plistArray = array();
\r
840 $plistLine = strtok($resp,"\n");
\r
843 while ( $plistLine ) {
\r
844 list ( $element, $value ) = explode(": ",$plistLine);
\r
845 if($element == "playlist") {
\r
847 $plistArray[$plCounter]['name']=$value;
\r
849 if($element == "Last-Modified") {
\r
850 $plistArray[$plCounter]['timestamp']=$value;
\r
852 $plistLine = strtok("\n");
\r
855 return $plistArray;
\r
860 * Updates all class properties with the values from the MPD server.
\r
862 * NOTE: This function is automatically called upon Connect() as of v1.1.
\r
864 function RefreshInfo() {
\r
865 // Get the Server Statistics
\r
866 $statStr = $this->SendCommand(MPD_CMD_STATISTICS);
\r
871 $statLine = strtok($statStr,"\n");
\r
872 while ( $statLine ) {
\r
873 list ( $element, $value ) = explode(": ",$statLine);
\r
874 $stats[$element] = $value;
\r
875 $statLine = strtok("\n");
\r
879 // Get the Server Status
\r
880 $statusStr = $this->SendCommand(MPD_CMD_STATUS);
\r
881 if ( ! $statusStr ) {
\r
885 $statusLine = strtok($statusStr,"\n");
\r
886 while ( $statusLine ) {
\r
887 list ( $element, $value ) = explode(": ",$statusLine);
\r
888 $status[$element] = $value;
\r
889 $statusLine = strtok("\n");
\r
893 // Get list of lists
\r
894 $plStr = $this->SendCommand(MPD_CMD_LISTS);
\r
895 $this->playlists = $this->_parsePlayListsResponse($plStr);
\r
897 // Get the Playlist
\r
898 $plStr = $this->SendCommand(MPD_CMD_PLLIST);
\r
899 $this->playlist = $this->_parseFileListResponse($plStr);
\r
900 $this->playlist_count = count($this->playlist);
\r
902 // Set Misc Other Variables
\r
903 $this->state = $status['state'];
\r
904 if ( ($this->state == MPD_STATE_PLAYING) || ($this->state == MPD_STATE_PAUSED) ) {
\r
905 $this->current_track_id = $status['song'];
\r
906 list ($this->current_track_position, $this->current_track_length ) = explode(":",$status['time']);
\r
908 $this->current_track_id = -1;
\r
909 $this->current_track_position = -1;
\r
910 $this->current_track_length = -1;
\r
913 $this->repeat = $status['repeat'];
\r
914 $this->random = $status['random'];
\r
916 $this->db_last_refreshed = $stats['db_update'];
\r
918 $this->volume = $status['volume'];
\r
919 $this->uptime = $stats['uptime'];
\r
920 $this->playtime = $stats['playtime'];
\r
921 $this->num_songs_played = $stats['songs_played'];
\r
922 $this->num_artists = $stats['num_artists'];
\r
923 $this->num_songs = $stats['num_songs'];
\r
924 $this->num_albums = $stats['num_albums'];
\r
928 /* ------------------ DEPRECATED METHODS -------------------*/
\r
929 /* GetStatistics()
\r
931 * Retrieves the 'statistics' variables from the server and tosses them into an array.
\r
933 * NOTE: This function really should not be used. Instead, use $this->[variable]. The function
\r
934 * will most likely be deprecated in future releases.
\r
936 function GetStatistics() {
\r
937 if ( $this->debugging ) echo "mpd->GetStatistics()\n";
\r
938 $stats = $this->SendCommand(MPD_CMD_STATISTICS);
\r
942 $statsArray = array();
\r
943 $statsLine = strtok($stats,"\n");
\r
944 while ( $statsLine ) {
\r
945 list ( $element, $value ) = explode(": ",$statsLine);
\r
946 $statsArray[$element] = $value;
\r
947 $statsLine = strtok("\n");
\r
950 if ( $this->debugging ) echo "mpd->GetStatistics() / return: " . print_r($statsArray) ."\n";
\r
951 return $statsArray;
\r
956 * Retrieves the 'status' variables from the server and tosses them into an array.
\r
958 * NOTE: This function really should not be used. Instead, use $this->[variable]. The function
\r
959 * will most likely be deprecated in future releases.
\r
961 function GetStatus() {
\r
962 if ( $this->debugging ) echo "mpd->GetStatus()\n";
\r
963 $status = $this->SendCommand(MPD_CMD_STATUS);
\r
967 $statusArray = array();
\r
968 $statusLine = strtok($status,"\n");
\r
969 while ( $statusLine ) {
\r
970 list ( $element, $value ) = explode(": ",$statusLine);
\r
971 $statusArray[$element] = $value;
\r
972 $statusLine = strtok("\n");
\r
975 if ( $this->debugging ) echo "mpd->GetStatus() / return: " . print_r($statusArray) ."\n";
\r
976 return $statusArray;
\r
981 * Retrieves the mixer volume from the server.
\r
983 * NOTE: This function really should not be used. Instead, use $this->volume. The function
\r
984 * will most likely be deprecated in future releases.
\r
986 function GetVolume() {
\r
987 if ( $this->debugging ) echo "mpd->GetVolume()\n";
\r
988 $volLine = $this->SendCommand(MPD_CMD_STATUS);
\r
989 if ( ! $volLine ) {
\r
992 list ($vol) = sscanf($volLine,"volume: %d");
\r
994 if ( $this->debugging ) echo "mpd->GetVolume() / return: $vol\n";
\r
1000 * Retrieves the playlist from the server and tosses it into a multidimensional array.
\r
1002 * NOTE: This function really should not be used. Instead, use $this->playlist. The function
\r
1003 * will most likely be deprecated in future releases.
\r
1005 function GetPlaylist() {
\r
1006 if ( $this->debugging ) echo "mpd->GetPlaylist()\n";
\r
1007 $resp = $this->SendCommand(MPD_CMD_PLLIST);
\r
1008 $playlist = $this->_parseFileListResponse($resp);
\r
1009 if ( $this->debugging ) echo "mpd->GetPlaylist() / return ".print_r($playlist)."\n";
\r
1013 /* ----------------- Command compatibility tables --------------------- */
\r
1014 var $COMPATIBILITY_MIN_TBL = array(
\r
1017 var $COMPATIBILITY_MAX_TBL = array(
\r
1020 } // ---------------------------- end of class ------------------------------
\r