Merge branch 'master' of ssh://karora@repo.or.cz/srv/git/adorno
[adorno.git] / inc / xmms2Player.php
blobf79aa2add752cd6aacd09d35110ce3277059f624
1 <?php
3 putenv('COLUMNS=500');
5 error_log( "Using XMMS backend: ". $c->daemon_type );
6 class xmms2Connection {
7 var $active; // Once it actually is...
8 var $xmms2;
9 var $status;
11 /**
12 * Create a minimally initialised connection object
14 function xmms2Connection() {
15 $this->active = false;
16 $this->xmms2 = false;
17 $this->status = array();
20 /**
21 * Connect to the remote xmms2
22 * - a complete fake.
24 function Connect() {
25 global $c;
27 $this->xmms2 = true;
28 $this->active = true;
31 /**
32 * Do a question/response pair with the daemon
34 function Daemon( $say ) {
35 if ( ! $this->active ) $this->Connect();
37 $command = 'xmms2 ' . $say . ' 2>&1';
38 $output = array();
39 $retval = 0;
40 error_log("adorno: DBG: XMMS2CMD: >>>$command<<<");
41 exec( $command, &$output, &$retval );
43 if ( preg_match( '#Could not connect to xmms2d#i', $output[0] ) ) {
44 exec( 'xmms2-launcher', &$output, &$retval );
45 error_log("adorno: DBG: Launching XMMS2 daemon: ($retval) - " . $output[0]);
46 exec( 'xmms2 playlist type Default queue', &$output, &$retval );
47 error_log("adorno: DBG: Launching XMMS2 daemon: ($retval) - " . $output[0]);
48 $output = array();
49 $retval = 0;
50 exec( $command, &$output, &$retval );
52 return $output;
55 /**
56 * Query the xmms2 about it's current status
58 function UpdateStatus() {
59 $status = $this->Daemon( "state" );
60 $this->status['state'] = $status[0];
61 $status = $this->Daemon( "info" );
62 foreach( $status AS $k => $v ) {
63 list( $key, $value ) = preg_split( '/ = /', $v, 2);
64 $this->status[$key] = $value;
69 /**
70 * Encode a filename to escape spaces & stuff.
72 function EncodeFileName( $track ) {
73 if ( preg_match( '#[a-z]{3,7}://#', $track ) ) {
74 return $track;
76 $encoded = str_replace( chr(92), '\\\\', $track);
77 $encoded = str_replace( '"', '\\"', $track);
78 // $encoded = str_replace( "'", "\\'", $track);
79 // $encoded = preg_replace( '/([\\\'"#&;`|*?~<>^\(\)[]{}$ ])/', '\\\\\1', $encoded);
80 # $encoded = escapeshellarg($track);
81 $encoded = '"file://' . $encoded . '"';
82 error_log( "Trying to play: $encoded" );
83 return $encoded;
87 /**
88 * Play a track. Xmms2 is OK if we tell it to play when it is already.
90 function Play( $track ) {
91 global $c;
93 $this->UpdateStatus();
95 // Replace ' with '' so escapeshellcmd reliably ignores it, then with \' afterwards
96 $this->Daemon("add ". $this->EncodeFileName($track));
97 if ( $this->status['state'] == 'Stopped' ) {
98 $this->Daemon("next");
99 $this->Daemon("play");
101 else
102 $this->Daemon("play");
107 * Move a track in the playlist
109 function MoveTrack( $index, $offset ) {
110 if ( $index < 1 || ($index + $offset) < 1 ) return; // Can't move playing track
112 $this->Daemon( sprintf("move %d %d", $index, $index + $offset ) );
117 * Query the xmms2 about it's current playlist and position
119 function GetCurrent() {
120 global $c;
122 $this->UpdateStatus();
123 $songnow = (object) array();
124 $songnow->started = date( 'Y-m-d H:i:s', $this->status['[server] laststarted'] );
125 $songnow->track = str_replace( 'file://', '', $this->status['[server] url'] );
127 return $songnow;
131 * Query the xmms2 about it's current playlist and position
133 function GetQueue() {
134 global $c;
136 $this->UpdateStatus();
137 $next = $this->status['song'] + 1;
138 $this->queue = array();
140 $filename = "";
141 $pos = -1;
143 $playlist = $this->Daemon( "list" );
144 foreach( $playlist AS $k => $v ) {
146 if ( $pos >= 0 ) {
147 $filename = preg_replace( '#^( |->)\[\d+/\d+\] #', '', $v );
148 if ( substr($filename,0,7) == 'file://' ) {
149 $filename = substr( $filename, 7 );
150 $filename = urldecode( $filename );
151 $this->queue[$pos++] = $filename;
154 else if ( $pos < 0 && substr( $v, 0, 2) == '->' ) {
155 $pos = 0;
159 return $this->queue;
164 $GLOBALS["xmms2"] = new xmms2Connection();
170 /******************************************************************
171 * The actual API the web interface calls is then very simple...
172 ******************************************************************/
175 * Queue a file for playing
177 function daemon_play_track( $path ) {
178 global $xmms2;
179 error_log("adorno: DBG: Trying to play '$path'");
180 $xmms2->Play( $path );
185 * Get a list of the files currently queued for the future
187 function daemon_get_queue() {
188 global $xmms2;
189 $q = $xmms2->GetQueue();
190 return $q;
195 * Get the currently playing track and it's starting time
197 function daemon_current_track() {
198 global $xmms2;
199 return $xmms2->GetCurrent();
204 * Get the currently playing track and it's starting time
206 function daemon_other_command( $action, $track ) {
207 global $xmms2;
208 switch( $action ) {
209 case 'resume':
210 $xmms2->Daemon('play');
211 break;
212 case 'pause':
213 $xmms2->Daemon($action);
214 break;
215 case 'next':
216 $xmms2->Daemon($action);
217 break;
218 default:
219 error_log("adorno: ERROR: Unsupported command '$action'" );
222 return true;
226 * Get the currently playing track and it's starting time
228 function daemon_move( $index, $offset ) {
229 global $xmms2;
230 return $xmms2->MoveTrack($index,$offset);