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

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

On rétabli l'enregistrement de la programmation

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                                if($rv[1] == 'playlist'){
244                                        $url = $this->write($list_add['name'].".uri");
245                                        $list_add['uri'] = $url[0];
246                                }
247                                $list[] = $list_add;
248                        }
249                }
250                // save it for caching
251                $this->streams = $list;
252
253                return $list;
254        }
255
256        /**
257         * now_playing
258         *
259         * returns a formated string with the current
260         * thats playing.
261         *
262         * @return string $song
263         */
264        public function now_playing($retour='string')
265        {
266                $retval = $this->write("list");
267                if(is_array($retval)){
268                        foreach ($retval as $rv){
269                                $list = explode(" : ", $rv);
270                                if(preg_match('/output/',$rv)){
271                                        $output = $list[0];
272                                        break;
273                                }
274                        }
275                }
276                $metadatas_output = $this->write($output.'.metadata');
277
278                while (list(, $val) = each($metadatas_output)) {
279                    if ($val == '--- 1 ---') {
280                        break;
281                    }
282                   array_shift($metadatas_output);
283                }
284                foreach ($metadatas_output as $rv)
285                {
286                        list($key, $value) = split('=', $rv, 2);
287                        // Remove the quotes
288                        $value = trim($value, '"');
289                        $md[$key] = $value;
290                }
291
292                if($retour== 'array'){
293                        return $md;
294                }
295               
296                $retour = $md['artist'] ? $md['artist']. " - ":'';
297                $retour .= $md['title'];
298                return $retour;
299        }
300
301        /**
302         * on_air
303         *
304         * @return int $current_song
305         *   return the 'rid' of the current song
306         */
307        public function on_air()
308        {
309                return $this->write("request.on_air");
310        }
311
312        /**
313         * checkStreamType
314         *
315         * Checks if the stream if of the correct type
316         *
317         * @param string $name
318         *   The name of the stream
319         * @param string $type
320         *   The type of the stream, like output. or editable.
321         */
322        private function checkStreamType($name, $type)
323        {
324                // Get the cache if empty
325                if (empty($this->streams))
326                        $this->stream_list();
327
328                foreach ($this->streams as $stream)
329                {
330                        // search for the name and check the type
331                        if ($stream['name'] == $name && strstr($stream['type'], $type))
332                                return $stream;
333                }
334
335                return FALSE;
336        }
337
338        /**
339         * Skip
340         *
341         * Skip is only available on a few stream types.
342         * so it has to check first it its allowed.
343         *
344         * @param string $name
345         *   The name of the stream
346         */
347        public function skip($name)
348        {
349                // Check the stream
350                if (($stream = $this->checkStreamType($name, "output.")) === FALSE)
351                        throw new Exception("No such stream $name, or of the wrong type");
352
353                $this->write($name . ".skip");
354        }
355
356        /**
357         * get_full_metadata
358         *
359         * @param string $name
360         *   The name of the stream
361         * @return Object
362         *   An object filled with all the infos.
363         */
364        public function get_full_metadata($name)
365        {
366                if (empty($name))
367                        return;
368
369                if (($stream = $this->checkStreamType($name, "output") === FALSE) && ($stream = $this->checkStreamType($name, "store_metadata") === FALSE))
370                        return false;
371
372                if($this->checkStreamType($name, "output") != FALSE){
373                        $retval = $this->write($name.".metadata");
374                }else{
375                        $retval = $this->write($name.".get");
376                }
377
378                // Lets parse it
379                $md = array();
380                $i = 0;
381                foreach ($retval as $rv)
382                {
383                        if(preg_match('/--- ([1-9].*) ---/',$rv)){
384                                $i = $i+1;
385                        }else{
386                                list($key, $value) = split('=', $rv, 2);
387                                // Remove the quotes
388                                $value = trim($value, '"');
389                                $md[$i][$key] = $value;
390                        }
391                }
392                return $md;
393        }
394
395        /**
396         * get_metadata
397         *
398         * @param string $rid
399         *   This id of the song.
400         * @return Object
401         *   An object filled with all the info.
402         */
403        public function get_metadata($rid)
404        {
405                if (empty($rid) OR !intval($rid))
406                        return;
407
408                $retval = $this->write("request.metadata " . $rid);
409
410                // No such request
411                if ($retval[0] == 'No such request.')
412                        return;
413                // Lets parse it
414                $md = array();
415                foreach ($retval as $rv)
416                {
417                        list($key, $value) = split('=', $rv, 2);
418                        // Remove the quotes
419                        $value = trim($value, '"');
420                        $md[$key] = $value;
421                }
422                return $md;
423        }
424
425        /**
426         * is_alive
427         *
428         * Connects to the savonet server and returns alive
429         *
430         * @return string
431         * Active Queue, 0 = none.
432         */
433        public function is_alive()
434        {
435                $test = $this->write("request.alive");
436                return $test;
437        }
438
439        /**
440         * write
441         *
442         * Writes and reads stuff from savo
443         * Because we are lazy.
444         *
445         * @param string $what
446         *   The msg thats getting passed to savonet.
447         */
448        function write($what)
449        {
450                if($this->is_connected()){
451
452                // Write to socket
453                if (socket_write($this->sock, $what . "\n") == FALSE)
454                        throw Exception("Unable to write to socket: " .
455                                socket_strerror(socket_last_error())
456                        );
457                // Loop on each line and push it to an array
458                while ($buffer = socket_read($this->sock, 512, PHP_NORMAL_READ))
459                {
460                        if(trim($buffer) != ''){
461                                $buf[] = trim($buffer);
462                        }
463                        if (preg_match('/END/',$buffer)){
464                                array_pop($buf);
465                                break;
466                        }
467                }
468                return $buf;
469                }else{
470                        return false;
471                }
472
473        }
474
475        /**
476         * is_connected
477         *
478         * Check if the connection is connected otherwise
479         * throws an exception if $throw is true.
480         *
481         * @params $throw bool
482         *   throws an exception or not. default true.
483         * @return bool
484         *   returns 1 if connected. 0 if not.
485         *   only returns 0 when $throw is false
486         */
487        public function is_connected($throw = false)
488        {
489                if ($this->sock == FALSE)
490                        if ($throw)
491                                throw new Exception("Socket is not connected.");
492                        else
493                                return false;
494
495                return 1;
496        }
497}
Note: See TracBrowser for help on using the repository browser.