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
55 // Predefined MPD Response messages
\r
56 define("MPD_RESPONSE_ERR", "ACK");
\r
57 define("MPD_RESPONSE_OK", "OK");
\r
59 // MPD State Constants
\r
60 define("MPD_STATE_PLAYING", "play");
\r
61 define("MPD_STATE_STOPPED", "stop");
\r
62 define("MPD_STATE_PAUSED", "pause");
\r
64 // MPD Searching Constants
\r
65 define("MPD_SEARCH_ARTIST", "artist");
\r
66 define("MPD_SEARCH_TITLE", "title");
\r
67 define("MPD_SEARCH_ALBUM", "album");
\r
70 define("MPD_TBL_ARTIST","artist");
\r
71 define("MPD_TBL_ALBUM","album");
\r
74 // TCP/Connection variables
\r
79 var $mpd_sock = NULL;
\r
80 var $connected = FALSE;
\r
82 // MPD Status variables
\r
83 var $mpd_version = "(unknown)";
\r
86 var $current_track_position;
\r
87 var $current_track_length;
\r
88 var $current_track_id;
\r
95 var $db_last_refreshed;
\r
96 var $num_songs_played;
\r
97 var $playlist_count;
\r
103 var $playlist = array();
\r
105 // Misc Other Vars
\r
106 var $mpd_class_version = "1.2";
\r
108 var $debugging = FALSE; // Set to TRUE to turn extended debugging on.
\r
109 var $errStr = ""; // Used for maintaining information about the last error message
\r
111 var $command_queue; // The list of commands for bulk command sending
\r
113 // =================== BEGIN OBJECT METHODS ================
\r
115 /* mpd() : Constructor
\r
117 * Builds the MPD object, connects to the server, and refreshes all local object properties.
\r
119 function mpd($srv,$port,$pwd = NULL) {
\r
120 $this->host = $srv;
\r
121 $this->port = $port;
\r
122 $this->password = $pwd;
\r
124 $resp = $this->Connect();
\r
125 if ( is_null($resp) ) {
\r
126 $this->errStr = "Could not connect";
\r
129 list ( $this->mpd_version ) = sscanf($resp, MPD_RESPONSE_OK . " MPD %s\n");
\r
130 if ( ! is_null($pwd) ) {
\r
131 if ( is_null($this->SendCommand(MPD_CMD_PASSWORD,$pwd)) ) {
\r
132 $this->connected = FALSE;
\r
133 return; // bad password or command
\r
135 if ( is_null($this->RefreshInfo()) ) { // no read access -- might as well be disconnected!
\r
136 $this->connected = FALSE;
\r
137 $this->errStr = "Password supplied does not have read access";
\r
141 if ( is_null($this->RefreshInfo()) ) { // no read access -- might as well be disconnected!
\r
142 $this->connected = FALSE;
\r
143 $this->errStr = "Password required to access server";
\r
152 * Connects to the MPD server.
\r
154 * NOTE: This is called automatically upon object instantiation; you should not need to call this directly.
\r
156 function Connect() {
\r
157 if ( $this->debugging ) echo "mpd->Connect() / host: ".$this->host.", port: ".$this->port."\n";
\r
158 $this->mpd_sock = fsockopen($this->host,$this->port,$errNo,$errStr,10);
\r
159 if (!$this->mpd_sock) {
\r
160 $this->errStr = "Socket Error: $errStr ($errNo)";
\r
163 while(!feof($this->mpd_sock)) {
\r
164 $response = fgets($this->mpd_sock,1024);
\r
165 if (strncmp(MPD_RESPONSE_OK,$response,strlen(MPD_RESPONSE_OK)) == 0) {
\r
166 $this->connected = TRUE;
\r
170 if (strncmp(MPD_RESPONSE_ERR,$response,strlen(MPD_RESPONSE_ERR)) == 0) {
\r
171 $this->errStr = "Server responded with: $response";
\r
175 // Generic response
\r
176 $this->errStr = "Connection not available";
\r
183 * Sends a generic command to the MPD server. Several command constants are pre-defined for
\r
184 * use (see MPD_CMD_* constant definitions above).
\r
186 function SendCommand($cmdStr,$arg1 = "",$arg2 = "") {
\r
187 if ( $this->debugging ) echo "mpd->SendCommand() / cmd: ".$cmdStr.", args: ".$arg1." ".$arg2."\n";
\r
189 if ( ! $this->connected ) {
\r
190 echo "mpd->SendCommand() / Error: Not connected\n";
\r
192 // Clear out the error String
\r
193 $this->errStr = "";
\r
196 // Check the command compatibility:
\r
197 if ( ! $this->_checkCompatibility($cmdStr) ) {
\r
198 echo "Not compatible command!";
\r
202 if (strlen($arg1) > 0) $cmdStr .= " \"$arg1\"";
\r
204 if (strlen($arg2) > 0) $cmdStr .= " \"$arg2\"";
\r
205 if ( $this->debugging ) echo "mpd-> ".$cmdStr."\n";
\r
206 fputs($this->mpd_sock,"$cmdStr\n");
\r
207 while(!feof($this->mpd_sock)) {
\r
208 $response = fgets($this->mpd_sock,1024);
\r
209 if ( $this->debugging ) echo "mpd.response-> ".$response."\n";
\r
211 // An OK signals the end of transmission -- we'll ignore it
\r
212 if (strncmp(MPD_RESPONSE_OK,$response,strlen(MPD_RESPONSE_OK)) == 0) {
\r
216 // An ERR signals the end of transmission with an error! Let's grab the single-line message.
\r
217 if (strncmp(MPD_RESPONSE_ERR,$response,strlen(MPD_RESPONSE_ERR)) == 0) {
\r
218 list ( $junk, $errTmp ) = explode(MPD_RESPONSE_ERR . " ",$response );
\r
219 $this->errStr = strtok($errTmp,"\n");
\r
222 if ( strlen($this->errStr) > 0 ) {
\r
226 // Build the response string
\r
227 $respStr .= $response;
\r
229 if ( $this->debugging ) echo "mpd->SendCommand() / response: '".$respStr."'\n";
\r
236 * Queues a generic command for later sending to the MPD server. The CommandQueue can hold
\r
237 * as many commands as needed, and are sent all at once, in the order they are queued, using
\r
238 * the SendCommandQueue() method. The syntax for queueing commands is identical to SendCommand().
\r
240 function QueueCommand($cmdStr,$arg1 = "",$arg2 = "") {
\r
241 if ( $this->debugging ) echo "mpd->QueueCommand() / cmd: ".$cmdStr.", args: ".$arg1." ".$arg2."\n";
\r
242 if ( ! $this->connected ) {
\r
243 echo "mpd->QueueCommand() / Error: Not connected\n";
\r
246 if ( strlen($this->command_queue) == 0 ) {
\r
247 $this->command_queue = MPD_CMD_START_BULK . "\n";
\r
249 if (strlen($arg1) > 0) $cmdStr .= " \"$arg1\"";
\r
250 if (strlen($arg2) > 0) $cmdStr .= " \"$arg2\"";
\r
252 $this->command_queue .= $cmdStr ."\n";
\r
254 if ( $this->debugging ) echo "mpd->QueueCommand() / return\n";
\r
259 /* SendCommandQueue()
\r
261 * Sends all commands in the Command Queue to the MPD server. See also QueueCommand().
\r
263 function SendCommandQueue() {
\r
264 if ( $this->debugging ) echo "mpd->SendCommandQueue()\n";
\r
265 if ( ! $this->connected ) {
\r
266 echo "mpd->SendCommandQueue() / Error: Not connected\n";
\r
269 $this->command_queue .= MPD_CMD_END_BULK . "\n";
\r
270 if ( is_null($respStr = $this->SendCommand($this->command_queue)) ) {
\r
273 $this->command_queue = NULL;
\r
274 if ( $this->debugging ) echo "mpd->SendCommandQueue() / response: '".$respStr."'\n";
\r
282 * Adjusts the mixer volume on the MPD by <modifier>, which can be a positive (volume increase),
\r
283 * or negative (volume decrease) value.
\r
285 function AdjustVolume($modifier) {
\r
286 if ( $this->debugging ) echo "mpd->AdjustVolume()\n";
\r
287 if ( ! is_numeric($modifier) ) {
\r
288 $this->errStr = "AdjustVolume() : argument 1 must be a numeric value";
\r
292 $this->RefreshInfo();
\r
293 $newVol = $this->volume + $modifier;
\r
294 $ret = $this->SetVolume($newVol);
\r
296 if ( $this->debugging ) echo "mpd->AdjustVolume() / return\n";
\r
302 * Sets the mixer volume to <newVol>, which should be between 1 - 100.
\r
304 function SetVolume($newVol) {
\r
305 if ( $this->debugging ) echo "mpd->SetVolume()\n";
\r
306 if ( ! is_numeric($newVol) ) {
\r
307 $this->errStr = "SetVolume() : argument 1 must be a numeric value";
\r
311 // Forcibly prevent out of range errors
\r
312 if ( $newVol < 0 ) $newVol = 0;
\r
313 if ( $newVol > 100 ) $newVol = 100;
\r
315 // If we're not compatible with SETVOL, we'll try adjusting using VOLUME
\r
316 if ( $this->_checkCompatibility(MPD_CMD_SETVOL) ) {
\r
317 if ( ! is_null($ret = $this->SendCommand(MPD_CMD_SETVOL,$newVol))) $this->volume = $newVol;
\r
319 $this->RefreshInfo(); // Get the latest volume
\r
320 if ( is_null($this->volume) ) {
\r
323 $modifier = ( $newVol - $this->volume );
\r
324 if ( ! is_null($ret = $this->SendCommand(MPD_CMD_VOLUME,$modifier))) $this->volume = $newVol;
\r
328 if ( $this->debugging ) echo "mpd->SetVolume() / return\n";
\r
334 * Retrieves a database directory listing of the <dir> directory and places the results into
\r
335 * a multidimensional array. If no directory is specified, the directory listing is at the
\r
336 * base of the MPD music path.
\r
338 function GetDir($dir = "") {
\r
339 if ( $this->debugging ) echo "mpd->GetDir()\n";
\r
340 $resp = $this->SendCommand(MPD_CMD_LSDIR,$dir);
\r
341 $dirlist = $this->_parseFileListResponse($resp);
\r
342 if ( $this->debugging ) echo "mpd->GetDir() / return ".print_r($dirlist)."\n";
\r
348 * Adds each track listed in a single-dimensional <trackArray>, which contains filenames
\r
349 * of tracks to add, to the end of the playlist. This is used to add many, many tracks to
\r
350 * the playlist in one swoop.
\r
352 function PLAddBulk($trackArray) {
\r
353 if ( $this->debugging ) echo "mpd->PLAddBulk()\n";
\r
354 $num_files = count($trackArray);
\r
355 for ( $i = 0; $i < $num_files; $i++ ) {
\r
356 $this->QueueCommand(MPD_CMD_PLADD,$trackArray[$i]);
\r
358 $resp = $this->SendCommandQueue();
\r
359 $this->RefreshInfo();
\r
360 if ( $this->debugging ) echo "mpd->PLAddBulk() / return\n";
\r
366 * Adds the file <file> to the end of the playlist. <file> must be a track in the MPD database.
\r
368 function PLAdd($fileName) {
\r
369 if ( $this->debugging ) echo "mpd->PLAdd()\n";
\r
370 if ( ! is_null($resp = $this->SendCommand(MPD_CMD_PLADD,$fileName))) $this->RefreshInfo();
\r
371 if ( $this->debugging ) echo "mpd->PLAdd() / return\n";
\r
377 * Moves track number <origPos> to position <newPos> in the playlist. This is used to reorder
\r
378 * the songs in the playlist.
\r
380 function PLMoveTrack($origPos, $newPos) {
\r
381 if ( $this->debugging ) echo "mpd->PLMoveTrack()\n";
\r
382 if ( ! is_numeric($origPos) ) {
\r
383 $this->errStr = "PLMoveTrack(): argument 1 must be numeric";
\r
386 if ( $origPos < 0 or $origPos > $this->playlist_count ) {
\r
387 $this->errStr = "PLMoveTrack(): argument 1 out of range";
\r
390 if ( $newPos < 0 ) $newPos = 0;
\r
391 if ( $newPos > $this->playlist_count ) $newPos = $this->playlist_count;
\r
393 if ( ! is_null($resp = $this->SendCommand(MPD_CMD_PLMOVETRACK,$origPos,$newPos))) $this->RefreshInfo();
\r
394 if ( $this->debugging ) echo "mpd->PLMoveTrack() / return\n";
\r
400 * Randomly reorders the songs in the playlist.
\r
402 function PLShuffle() {
\r
403 if ( $this->debugging ) echo "mpd->PLShuffle()\n";
\r
404 if ( ! is_null($resp = $this->SendCommand(MPD_CMD_PLSHUFFLE))) $this->RefreshInfo();
\r
405 if ( $this->debugging ) echo "mpd->PLShuffle() / return\n";
\r
411 * Retrieves the playlist from <file>.m3u and loads it into the current playlist.
\r
413 function PLLoad($file) {
\r
414 if ( $this->debugging ) echo "mpd->PLLoad()\n";
\r
415 if ( ! is_null($resp = $this->SendCommand(MPD_CMD_PLLOAD,$file))) $this->RefreshInfo();
\r
416 if ( $this->debugging ) echo "mpd->PLLoad() / return\n";
\r
422 * Saves the playlist to <file>.m3u for later retrieval. The file is saved in the MPD playlist
\r
425 function PLSave($file) {
\r
426 if ( $this->debugging ) echo "mpd->PLSave()\n";
\r
427 $resp = $this->SendCommand(MPD_CMD_PLSAVE,$file);
\r
428 if ( $this->debugging ) echo "mpd->PLSave() / return\n";
\r
434 * Empties the playlist.
\r
436 function PLClear() {
\r
437 if ( $this->debugging ) echo "mpd->PLClear()\n";
\r
438 if ( ! is_null($resp = $this->SendCommand(MPD_CMD_PLCLEAR))) $this->RefreshInfo();
\r
439 if ( $this->debugging ) echo "mpd->PLClear() / return\n";
\r
446 * Move song from pos to the other
\r
448 function Move ($from,$to) {
\r
449 if ( ! is_null($resp = $this->SendCommand(MPD_CMD_PLMOVETRACK,$from,$to))) $this->RefreshInfo();
\r
450 //die(print_r($resp));
\r
457 * Removes track <id> from the playlist.
\r
459 function PLRemove($id) {
\r
460 if ( $this->debugging ) echo "mpd->PLRemove()\n";
\r
461 if ( ! is_numeric($id) ) {
\r
462 $this->errStr = "PLRemove() : argument 1 must be a numeric value";
\r
465 if ( ! is_null($resp = $this->SendCommand(MPD_CMD_PLREMOVE,$id))) $this->RefreshInfo();
\r
466 if ( $this->debugging ) echo "mpd->PLRemove() / return\n";
\r
472 * Enables 'loop' mode -- tells MPD continually loop the playlist. The <repVal> parameter
\r
473 * is either 1 (on) or 0 (off).
\r
475 function SetRepeat($repVal) {
\r
476 if ( $this->debugging ) echo "mpd->SetRepeat()\n";
\r
477 $rpt = $this->SendCommand(MPD_CMD_REPEAT,$repVal);
\r
478 $this->repeat = $repVal;
\r
479 if ( $this->debugging ) echo "mpd->SetRepeat() / return\n";
\r
485 * Enables 'randomize' mode -- tells MPD to play songs in the playlist in random order. The
\r
486 * <rndVal> parameter is either 1 (on) or 0 (off).
\r
488 function SetRandom($rndVal) {
\r
489 if ( $this->debugging ) echo "mpd->SetRandom()\n";
\r
490 $resp = $this->SendCommand(MPD_CMD_RANDOM,$rndVal);
\r
491 $this->random = $rndVal;
\r
492 if ( $this->debugging ) echo "mpd->SetRandom() / return\n";
\r
498 * Shuts down the MPD server (aka sends the KILL command). This closes the current connection,
\r
499 * and prevents future communication with the server.
\r
501 function Shutdown() {
\r
502 if ( $this->debugging ) echo "mpd->Shutdown()\n";
\r
503 $resp = $this->SendCommand(MPD_CMD_SHUTDOWN);
\r
505 $this->connected = FALSE;
\r
506 unset($this->mpd_version);
\r
507 unset($this->errStr);
\r
508 unset($this->mpd_sock);
\r
510 if ( $this->debugging ) echo "mpd->Shutdown() / return\n";
\r
516 * Tells MPD to rescan the music directory for new tracks, and to refresh the Database. Tracks
\r
517 * cannot be played unless they are in the MPD database.
\r
519 function DBRefresh() {
\r
520 if ( $this->debugging ) echo "mpd->DBRefresh()\n";
\r
521 $resp = $this->SendCommand(MPD_CMD_REFRESH);
\r
523 // Update local variables
\r
524 $this->RefreshInfo();
\r
526 if ( $this->debugging ) echo "mpd->DBRefresh() / return\n";
\r
532 * Begins playing the songs in the MPD playlist.
\r
535 if ( $this->debugging ) echo "mpd->Play()\n";
\r
536 if ( ! is_null($rpt = $this->SendCommand(MPD_CMD_PLAY) )) $this->RefreshInfo();
\r
537 if ( $this->debugging ) echo "mpd->Play() / return\n";
\r
543 * Stops playing the MPD.
\r
546 if ( $this->debugging ) echo "mpd->Stop()\n";
\r
547 if ( ! is_null($rpt = $this->SendCommand(MPD_CMD_STOP) )) $this->RefreshInfo();
\r
548 if ( $this->debugging ) echo "mpd->Stop() / return\n";
\r
554 * Toggles pausing on the MPD. Calling it once will pause the player, calling it again
\r
558 if ( $this->debugging ) echo "mpd->Pause()\n";
\r
559 if ( ! is_null($rpt = $this->SendCommand(MPD_CMD_PAUSE) )) $this->RefreshInfo();
\r
560 if ( $this->debugging ) echo "mpd->Pause() / return\n";
\r
566 * Skips directly to the <idx> song in the MPD playlist.
\r
568 function SkipTo($idx) {
\r
569 if ( $this->debugging ) echo "mpd->SkipTo()\n";
\r
570 if ( ! is_numeric($idx) ) {
\r
571 $this->errStr = "SkipTo() : argument 1 must be a numeric value";
\r
574 if ( ! is_null($rpt = $this->SendCommand(MPD_CMD_PLAY,$idx))) $this->RefreshInfo();
\r
575 if ( $this->debugging ) echo "mpd->SkipTo() / return\n";
\r
581 * Skips directly to a given position within a track in the MPD playlist. The <pos> argument,
\r
582 * given in seconds, is the track position to locate. The <track> argument, if supplied is
\r
583 * the track number in the playlist. If <track> is not specified, the current track is assumed.
\r
585 function SeekTo($pos, $track = -1) {
\r
586 if ( $this->debugging ) echo "mpd->SeekTo()\n";
\r
587 if ( ! is_numeric($pos) ) {
\r
588 $this->errStr = "SeekTo() : argument 1 must be a numeric value";
\r
591 if ( ! is_numeric($track) ) {
\r
592 $this->errStr = "SeekTo() : argument 2 must be a numeric value";
\r
595 if ( $track == -1 ) {
\r
596 $track = $this->current_track_id;
\r
599 if ( ! is_null($rpt = $this->SendCommand(MPD_CMD_SEEK,$track,$pos))) $this->RefreshInfo();
\r
600 if ( $this->debugging ) echo "mpd->SeekTo() / return\n";
\r
606 * Skips to the next song in the MPD playlist. If not playing, returns an error.
\r
609 if ( $this->debugging ) echo "mpd->Next()\n";
\r
610 if ( ! is_null($rpt = $this->SendCommand(MPD_CMD_NEXT))) $this->RefreshInfo();
\r
611 if ( $this->debugging ) echo "mpd->Next() / return\n";
\r
617 * Skips to the previous song in the MPD playlist. If not playing, returns an error.
\r
619 function Previous() {
\r
620 if ( $this->debugging ) echo "mpd->Previous()\n";
\r
621 if ( ! is_null($rpt = $this->SendCommand(MPD_CMD_PREV))) $this->RefreshInfo();
\r
622 if ( $this->debugging ) echo "mpd->Previous() / return\n";
\r
628 * Searches the MPD database. The search <type> should be one of the following:
\r
629 * MPD_SEARCH_ARTIST, MPD_SEARCH_TITLE, MPD_SEARCH_ALBUM
\r
630 * The search <string> is a case-insensitive locator string. Anything that contains
\r
631 * <string> will be returned in the results.
\r
633 function Search($type,$string) {
\r
634 if ( $this->debugging ) echo "mpd->Search()\n";
\r
635 if ( $type != MPD_SEARCH_ARTIST and
\r
636 $type != MPD_SEARCH_ALBUM and
\r
637 $type != MPD_SEARCH_TITLE ) {
\r
638 $this->errStr = "mpd->Search(): invalid search type";
\r
641 if ( is_null($resp = $this->SendCommand(MPD_CMD_SEARCH,$type,$string))) return NULL;
\r
642 $searchlist = $this->_parseFileListResponse($resp);
\r
644 if ( $this->debugging ) echo "mpd->Search() / return ".print_r($searchlist)."\n";
\r
645 return $searchlist;
\r
650 * Find() looks for exact matches in the MPD database. The find <type> should be one of
\r
652 * MPD_SEARCH_ARTIST, MPD_SEARCH_TITLE, MPD_SEARCH_ALBUM
\r
653 * The find <string> is a case-insensitive locator string. Anything that exactly matches
\r
654 * <string> will be returned in the results.
\r
656 function Find($type,$string) {
\r
657 if ( $this->debugging ) echo "mpd->Find()\n";
\r
658 if ( $type != MPD_SEARCH_ARTIST and
\r
659 $type != MPD_SEARCH_ALBUM and
\r
660 $type != MPD_SEARCH_TITLE ) {
\r
661 $this->errStr = "mpd->Find(): invalid find type";
\r
664 if ( is_null($resp = $this->SendCommand(MPD_CMD_FIND,$type,$string))) return NULL;
\r
665 $searchlist = $this->_parseFileListResponse($resp);
\r
667 if ( $this->debugging ) echo "mpd->Find() / return ".print_r($searchlist)."\n";
\r
668 return $searchlist;
\r
673 * Closes the connection to the MPD server.
\r
675 function Disconnect() {
\r
676 if ( $this->debugging ) echo "mpd->Disconnect()\n";
\r
677 fclose($this->mpd_sock);
\r
679 $this->connected = FALSE;
\r
680 unset($this->mpd_version);
\r
681 unset($this->errStr);
\r
682 unset($this->mpd_sock);
\r
687 * Returns the list of artists in the database in an associative array.
\r
689 function GetArtists() {
\r
690 if ( $this->debugging ) echo "mpd->GetArtists()\n";
\r
691 if ( is_null($resp = $this->SendCommand(MPD_CMD_TABLE, MPD_TBL_ARTIST))) return NULL;
\r
692 $arArray = array();
\r
694 $arLine = strtok($resp,"\n");
\r
697 while ( $arLine ) {
\r
698 list ( $element, $value ) = explode(": ",$arLine);
\r
699 if ( $element == "Artist" ) {
\r
702 $arArray[$arCounter] = $arName;
\r
705 $arLine = strtok("\n");
\r
707 if ( $this->debugging ) echo "mpd->GetArtists()\n";
\r
713 * Returns the list of albums in the database in an associative array. Optional parameter
\r
714 * is an artist Name which will list all albums by a particular artist.
\r
716 function GetAlbums( $ar = NULL) {
\r
717 if ( $this->debugging ) echo "mpd->GetAlbums()\n";
\r
718 if ( is_null($resp = $this->SendCommand(MPD_CMD_TABLE, MPD_TBL_ALBUM, $ar ))) return NULL;
\r
719 $alArray = array();
\r
721 $alLine = strtok($resp,"\n");
\r
724 while ( $alLine ) {
\r
725 list ( $element, $value ) = explode(": ",$alLine);
\r
726 if ( $element == "Album" ) {
\r
729 $alArray[$alCounter] = $alName;
\r
732 $alLine = strtok("\n");
\r
734 if ( $this->debugging ) echo "mpd->GetAlbums()\n";
\r
738 //*******************************************************************************//
\r
739 //***************************** INTERNAL FUNCTIONS ******************************//
\r
740 //*******************************************************************************//
\r
742 /* _computeVersionValue()
\r
744 * Computes a compatibility value from a version string
\r
747 function _computeVersionValue($verStr) {
\r
748 list ($ver_maj, $ver_min, $ver_rel ) = explode("\.",$verStr);
\r
749 return ( 100 * $ver_maj ) + ( 10 * $ver_min ) + ( $ver_rel );
\r
752 /* _checkCompatibility()
\r
754 * Check MPD command compatibility against our internal table. If there is no version
\r
755 * listed in the table, allow it by default.
\r
757 function _checkCompatibility($cmd) {
\r
758 // Check minimum compatibility
\r
759 $req_ver_low = $this->COMPATIBILITY_MIN_TBL[$cmd];
\r
760 $req_ver_hi = $this->COMPATIBILITY_MAX_TBL[$cmd];
\r
762 $mpd_ver = $this->_computeVersionValue($this->mpd_version);
\r
764 if ( $req_ver_low ) {
\r
765 $req_ver = $this->_computeVersionValue($req_ver_low);
\r
767 if ( $mpd_ver < $req_ver ) {
\r
768 $this->errStr = "Command '$cmd' is not compatible with this version of MPD, version ".$req_ver_low." required";
\r
773 // Check maxmum compatibility -- this will check for deprecations
\r
774 if ( $req_ver_hi ) {
\r
775 $req_ver = $this->_computeVersionValue($req_ver_hi);
\r
777 if ( $mpd_ver > $req_ver ) {
\r
778 $this->errStr = "Command '$cmd' has been deprecated in this version of MPD.";
\r
786 /* _parseFileListResponse()
\r
788 * Builds a multidimensional array with MPD response lists.
\r
790 * NOTE: This function is used internally within the class. It should not be used.
\r
792 function _parseFileListResponse($resp) {
\r
793 if ( is_null($resp) ) {
\r
796 $plistArray = array();
\r
797 $plistLine = strtok($resp,"\n");
\r
800 while ( $plistLine ) {
\r
801 list ( $element, $value ) = explode(": ",$plistLine);
\r
802 if($element == "file" || $element=="directory") {
\r
804 $plistArray[$plCounter]['name']=$value;
\r
805 $plistArray[$plCounter]['type']=$element;
\r
806 $plistArray[$plCounter]['title']=$value;
\r
808 if($element == "Name") {
\r
809 $plistArray[$plCounter]['title']=$value;
\r
811 $plistLine = strtok("\n");
\r
814 return $plistArray;
\r
819 * Updates all class properties with the values from the MPD server.
\r
821 * NOTE: This function is automatically called upon Connect() as of v1.1.
\r
823 function RefreshInfo() {
\r
824 // Get the Server Statistics
\r
825 $statStr = $this->SendCommand(MPD_CMD_STATISTICS);
\r
830 $statLine = strtok($statStr,"\n");
\r
831 while ( $statLine ) {
\r
832 list ( $element, $value ) = explode(": ",$statLine);
\r
833 $stats[$element] = $value;
\r
834 $statLine = strtok("\n");
\r
838 // Get the Server Status
\r
839 $statusStr = $this->SendCommand(MPD_CMD_STATUS);
\r
840 if ( ! $statusStr ) {
\r
844 $statusLine = strtok($statusStr,"\n");
\r
845 while ( $statusLine ) {
\r
846 list ( $element, $value ) = explode(": ",$statusLine);
\r
847 $status[$element] = $value;
\r
848 $statusLine = strtok("\n");
\r
852 // Get the Playlist
\r
853 $plStr = $this->SendCommand(MPD_CMD_PLLIST);
\r
854 $this->playlist = $this->_parseFileListResponse($plStr);
\r
855 $this->playlist_count = count($this->playlist);
\r
857 // Set Misc Other Variables
\r
858 $this->state = $status['state'];
\r
859 if ( ($this->state == MPD_STATE_PLAYING) || ($this->state == MPD_STATE_PAUSED) ) {
\r
860 $this->current_track_id = $status['song'];
\r
861 list ($this->current_track_position, $this->current_track_length ) = explode(":",$status['time']);
\r
863 $this->current_track_id = -1;
\r
864 $this->current_track_position = -1;
\r
865 $this->current_track_length = -1;
\r
868 $this->repeat = $status['repeat'];
\r
869 $this->random = $status['random'];
\r
871 $this->db_last_refreshed = $stats['db_update'];
\r
873 $this->volume = $status['volume'];
\r
874 $this->uptime = $stats['uptime'];
\r
875 $this->playtime = $stats['playtime'];
\r
876 $this->num_songs_played = $stats['songs_played'];
\r
877 $this->num_artists = $stats['num_artists'];
\r
878 $this->num_songs = $stats['num_songs'];
\r
879 $this->num_albums = $stats['num_albums'];
\r
883 /* ------------------ DEPRECATED METHODS -------------------*/
\r
884 /* GetStatistics()
\r
886 * Retrieves the 'statistics' variables from the server and tosses them into an array.
\r
888 * NOTE: This function really should not be used. Instead, use $this->[variable]. The function
\r
889 * will most likely be deprecated in future releases.
\r
891 function GetStatistics() {
\r
892 if ( $this->debugging ) echo "mpd->GetStatistics()\n";
\r
893 $stats = $this->SendCommand(MPD_CMD_STATISTICS);
\r
897 $statsArray = array();
\r
898 $statsLine = strtok($stats,"\n");
\r
899 while ( $statsLine ) {
\r
900 list ( $element, $value ) = explode(": ",$statsLine);
\r
901 $statsArray[$element] = $value;
\r
902 $statsLine = strtok("\n");
\r
905 if ( $this->debugging ) echo "mpd->GetStatistics() / return: " . print_r($statsArray) ."\n";
\r
906 return $statsArray;
\r
911 * Retrieves the 'status' variables from the server and tosses them into an array.
\r
913 * NOTE: This function really should not be used. Instead, use $this->[variable]. The function
\r
914 * will most likely be deprecated in future releases.
\r
916 function GetStatus() {
\r
917 if ( $this->debugging ) echo "mpd->GetStatus()\n";
\r
918 $status = $this->SendCommand(MPD_CMD_STATUS);
\r
922 $statusArray = array();
\r
923 $statusLine = strtok($status,"\n");
\r
924 while ( $statusLine ) {
\r
925 list ( $element, $value ) = explode(": ",$statusLine);
\r
926 $statusArray[$element] = $value;
\r
927 $statusLine = strtok("\n");
\r
930 if ( $this->debugging ) echo "mpd->GetStatus() / return: " . print_r($statusArray) ."\n";
\r
931 return $statusArray;
\r
936 * Retrieves the mixer volume from the server.
\r
938 * NOTE: This function really should not be used. Instead, use $this->volume. The function
\r
939 * will most likely be deprecated in future releases.
\r
941 function GetVolume() {
\r
942 if ( $this->debugging ) echo "mpd->GetVolume()\n";
\r
943 $volLine = $this->SendCommand(MPD_CMD_STATUS);
\r
944 if ( ! $volLine ) {
\r
947 list ($vol) = sscanf($volLine,"volume: %d");
\r
949 if ( $this->debugging ) echo "mpd->GetVolume() / return: $vol\n";
\r
955 * Retrieves the playlist from the server and tosses it into a multidimensional array.
\r
957 * NOTE: This function really should not be used. Instead, use $this->playlist. The function
\r
958 * will most likely be deprecated in future releases.
\r
960 function GetPlaylist() {
\r
961 if ( $this->debugging ) echo "mpd->GetPlaylist()\n";
\r
962 $resp = $this->SendCommand(MPD_CMD_PLLIST);
\r
963 $playlist = $this->_parseFileListResponse($resp);
\r
964 if ( $this->debugging ) echo "mpd->GetPlaylist() / return ".print_r($playlist)."\n";
\r
968 /* ----------------- Command compatibility tables --------------------- */
\r
969 var $COMPATIBILITY_MIN_TBL = array(
\r
972 var $COMPATIBILITY_MAX_TBL = array(
\r
975 } // ---------------------------- end of class ------------------------------
\r