source: plugins_spip/spip2liquidsoap/classes/savonet.php @ 3934

Last change on this file since 3934 was 3934, checked in by kent1, 10 years ago

Si on a une "queue" dans les streams on le met de coté pour que cela nous serve plus tard

File size: 10.1 KB
Line 
1<?php
2
3/**
4 * ----------------------------------------------------------------------------
5 * "THE BEER-WARE LICENSE" (Revision 42):
6 * <franksp@internl.net> wrote this file. As long as you retain this notice you
7 * can do whatever you want with this stuff. If we meet some day, and you think
8 * this stuff is worth it, you can buy me a beer in return Frank Spijkerman
9 * ----------------------------------------------------------------------------
10 *
11 * @package savonet
12 * @copyright 2008, Frank Spijkerman
13 *  for the Savonet Project
14 */
15
16class savonet {
17        /**
18         * The hostname of the liquidsoap
19         * server
20         * @var string
21         */
22        private $hostname;
23
24        /**
25         * The post of the liquidsoap server
26         * @var integer
27         */
28        private $port;
29
30        /**
31         * Array for storage of the stream list,
32         * this is used for caching.
33         * @var array
34         */
35        private $streams = array();
36
37        /**
38         * Constructor
39         *
40         * Prepares some settings
41         *
42         * @param string $hostname
43         *   The hostname of liquidsoap
44         * @param integer $port
45         *   The port of liquidsoap, usualy 1234
46         */
47        function __construct($hostname = 'localhost', $port = 1234)
48        {
49                $this->hostname = $hostname;
50                $this->port = $port;
51        }
52
53        /**
54         * Destructor
55         *
56         * Disconnects the connection if there is any.
57         */
58        function __destruct()
59        {
60                // disconnect
61                $this->disconnect();
62        }
63
64        /**
65         * This function makes the connection to savonet
66         */
67        public function connect()
68        {
69                // Make this socket
70                $this->sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
71                if ($this->sock == FALSE)
72                        return false;
73
74                // Connect
75                if (!socket_connect($this->sock, $this->hostname, $this->port))
76                        return false;
77
78                $this->stream_list();
79        }
80
81        /**
82         * Disconnect from liquidsoap ;(
83         */
84        public function disconnect()
85        {
86                // say good bye politely, then close the socket.
87                if ($this->sock) {
88                        $this->write("quit");
89                        socket_close($this->sock);
90                }
91        }
92
93        /**
94         * queue_list
95         *
96         * Returns a list with the current items in the queue
97         *
98         * @param string $name
99         *   The name of the queue
100         * @return array
101         */
102        public function queue_list($name)
103        {
104                // check for the name
105                if (empty($name))
106                        return;
107
108                // Check if the stream is available
109                if (($stream = $this->checkStreamType($name, "editable")) === FALSE)
110                        throw new Exception("No such stream $name, or of the wrong type");
111
112                $data = $this->write($name . ".queue");
113
114                // Return an empty array when nothing in the queue
115                if (empty($data[0]))
116                        return array();
117
118                // Enrich the data with metadata
119                $rv = array();
120                foreach(explode(" ", $data[0]) as $i)
121                        $rv[] = $this->get_metadata($i);
122
123                return $rv;
124        }
125
126        /**
127         * queue_push
128         *
129         * Adds an URI to the queue
130         * @param string $name
131         * @param string $uri
132         */
133        public function queue_push($name, $uri)
134        {
135                // gimme some input
136                if (empty($name) && empty($uri))
137                        return;
138
139                // Check if the stream is available
140                if (($stream = $this->checkStreamType($name, "editable")) === FALSE)
141                        throw new Exception("No such stream $name, or of the wrong type");
142
143                $data = $this->write($name . ".push " . $uri);
144
145                // Check if valid uri
146                if (empty($data[0]))
147                        return array();
148
149                // Return the metadata aswel.
150                return $this->get_metadata($data[0]);
151        }
152
153        /**
154         * queue_move
155         *
156         * Moves a rid in the queue to a new position.
157         *
158         * @param string $name
159         *   Name of the queue
160         * @param string $rid
161         *   Record id
162         * @param string $pos
163         *   New position
164         */
165        public function queue_move($name, $rid, $pos)
166        {
167                // Gimme
168                if (empty($name) && !is_numeric($rid) &&
169                                !is_numeric($pos))
170                        return;
171
172                // Check if the stream is available
173                if (($stream = $this->checkStreamType($name, "editable")) === FALSE)
174                        throw new Exception("No such stream $name, or of the wrong type");
175
176                return $this->write($name . ".move $rid $pos");
177        }
178
179        /**
180         * queue_insert
181         *
182         * Inserts a rid at a specific pos.
183         *
184         * @param string $name
185         *   The name of the queue
186         * @param string $pos
187         *   The position
188         * @param string $uri
189         *   The uri
190         */
191        public function queue_insert($name, $pos, $uri)
192        {
193                // Check input
194                if (empty($name) && !is_numeric($pos) && empty($uri))
195                        return;
196
197                // Check if the stream is available
198                if (($stream = $this->checkStreamType($name, "editable")) === FALSE)
199                        throw new Exception("No such stream $name, or of the wrong type");
200
201                return $this->write($name . ".insert $pos $uri");
202        }
203
204        /**
205         * queue_remove
206         *
207         * Removes a rid from the queue
208         *
209         * @param string $name
210         * @param integer $rid
211         * @return array
212         */
213        public function queue_remove($name, $rid)
214        {
215                if (empty($name) && !is_numeric($rid))
216                        return;
217
218                // Check if the stream is available
219                if (($stream = $this->checkStreamType($name, "editable")) === FALSE)
220                        throw new Exception("No such stream $name, or of the wrong type");
221
222                return $this->write($name . ".remove " . $rid);
223        }
224
225        /**
226         * stream_list
227         *
228         * Fetches the list of available streams
229         * and formats it in a nice array and returns that.
230         *
231         * @return array
232         */
233        public function stream_list()
234        {
235                $retval = $this->write("list");
236
237                $list = array();
238                if(is_array($retval)){
239                        foreach ($retval as $rv){
240                                $rv = explode(" : ", $rv);
241                                $list_add['name'] = $rv[0];
242                                $list_add['type'] = $rv[1];
243                                unset($list_add['uri']);
244                                if($rv[1] == 'playlist'){
245                                        $url = $this->write($list_add['name'].".uri");
246                                        $list_add['uri'] = $url[0];
247                                }
248                                $list[] = $list_add;
249                        }
250                }
251                // save it for caching
252                $this->streams = $list;
253
254                return $list;
255        }
256
257        /**
258         * now_playing
259         *
260         * returns a formated string with the current
261         * thats playing.
262         *
263         * @return string $song
264         */
265        public function now_playing($retour='string')
266        {
267                $retval = $this->write("list");
268                if(is_array($retval)){
269                        foreach ($retval as $rv){
270                                $list = explode(" : ", $rv);
271                                if(preg_match('/output/',$rv)){
272                                        $output = $list[0];
273                                        break;
274                                }
275                        }
276                }
277                $metadatas_output = $this->write($output.'.metadata');
278
279                while (list(, $val) = each($metadatas_output)) {
280                    if ($val == '--- 1 ---') {
281                        break;
282                    }
283                   array_shift($metadatas_output);
284                }
285                foreach ($metadatas_output as $rv)
286                {
287                        list($key, $value) = split('=', $rv, 2);
288                        // Remove the quotes
289                        $value = trim($value, '"');
290                        $md[$key] = $value;
291                }
292
293                if($retour== 'array'){
294                        return $md;
295                }
296               
297                $retour = $md['artist'] ? $md['artist']. " - ":'';
298                $retour .= $md['title'];
299                return $retour;
300        }
301
302        /**
303         * on_air
304         *
305         * @return int $current_song
306         *   return the 'rid' of the current song
307         */
308        public function on_air()
309        {
310                return $this->write("request.on_air");
311        }
312
313        /**
314         * checkStreamType
315         *
316         * Checks if the stream if of the correct type
317         *
318         * @param string $name
319         *   The name of the stream
320         * @param string $type
321         *   The type of the stream, like output. or editable.
322         */
323        private function checkStreamType($name, $type)
324        {
325                // Get the cache if empty
326                if (empty($this->streams))
327                        $this->stream_list();
328
329                foreach ($this->streams as $stream)
330                {
331                        // search for the name and check the type
332                        if ($stream['name'] == $name && strstr($stream['type'], $type))
333                                return $stream;
334                }
335
336                return FALSE;
337        }
338
339        /**
340         * Skip
341         *
342         * Skip is only available on a few stream types.
343         * so it has to check first it its allowed.
344         *
345         * @param string $name
346         *   The name of the stream
347         */
348        public function skip($name)
349        {
350                // Check the stream
351                if (($stream = $this->checkStreamType($name, "output.")) === FALSE)
352                        throw new Exception("No such stream $name, or of the wrong type");
353
354                $this->write($name . ".skip");
355        }
356
357        /**
358         * get_full_metadata
359         *
360         * @param string $name
361         *   The name of the stream
362         * @return Object
363         *   An object filled with all the infos.
364         */
365        public function get_full_metadata($name)
366        {
367                if (empty($name))
368                        return;
369
370                if (($stream = $this->checkStreamType($name, "output") === FALSE) && ($stream = $this->checkStreamType($name, "store_metadata") === FALSE))
371                        return false;
372
373                if($this->checkStreamType($name, "output") != FALSE){
374                        $retval = $this->write($name.".metadata");
375                }else{
376                        $retval = $this->write($name.".get");
377                }
378
379                // Lets parse it
380                $md = array();
381                $i = 0;
382                foreach ($retval as $rv)
383                {
384                        if(preg_match('/--- ([1-9].*) ---/',$rv)){
385                                $i = $i+1;
386                        }else{
387                                list($key, $value) = split('=', $rv, 2);
388                                // Remove the quotes
389                                $value = trim($value, '"');
390                                $md[$i][$key] = $value;
391                        }
392                }
393                return $md;
394        }
395
396        /**
397         * get_metadata
398         *
399         * @param string $rid
400         *   This id of the song.
401         * @return Object
402         *   An object filled with all the info.
403         */
404        public function get_metadata($rid)
405        {
406                if (empty($rid) OR !intval($rid))
407                        return;
408
409                $retval = $this->write("request.metadata " . $rid);
410
411                // No such request
412                if ($retval[0] == 'No such request.')
413                        return;
414                // Lets parse it
415                $md = array();
416                foreach ($retval as $rv)
417                {
418                        list($key, $value) = split('=', $rv, 2);
419                        // Remove the quotes
420                        $value = trim($value, '"');
421                        $md[$key] = $value;
422                }
423                return $md;
424        }
425
426        /**
427         * is_alive
428         *
429         * Connects to the savonet server and returns alive
430         *
431         * @return string
432         * Active Queue, 0 = none.
433         */
434        public function is_alive()
435        {
436                $test = $this->write("request.alive");
437                return $test;
438        }
439
440        /**
441         * write
442         *
443         * Writes and reads stuff from savo
444         * Because we are lazy.
445         *
446         * @param string $what
447         *   The msg thats getting passed to savonet.
448         */
449        function write($what)
450        {
451                if($this->is_connected()){
452
453                // Write to socket
454                if (socket_write($this->sock, $what . "\n") == FALSE)
455                        throw Exception("Unable to write to socket: " .
456                                socket_strerror(socket_last_error())
457                        );
458                // Loop on each line and push it to an array
459                while ($buffer = socket_read($this->sock, 512, PHP_NORMAL_READ))
460                {
461                        if(trim($buffer) != ''){
462                                $buf[] = trim($buffer);
463                        }
464                        if (preg_match('/END/',$buffer)){
465                                array_pop($buf);
466                                break;
467                        }
468                }
469                return $buf;
470                }else{
471                        return false;
472                }
473
474        }
475
476        /**
477         * is_connected
478         *
479         * Check if the connection is connected otherwise
480         * throws an exception if $throw is true.
481         *
482         * @params $throw bool
483         *   throws an exception or not. default true.
484         * @return bool
485         *   returns 1 if connected. 0 if not.
486         *   only returns 0 when $throw is false
487         */
488        public function is_connected($throw = false)
489        {
490                if ($this->sock == FALSE)
491                        if ($throw)
492                                throw new Exception("Socket is not connected.");
493                        else
494                                return false;
495
496                return 1;
497        }
498}
Note: See TracBrowser for help on using the repository browser.