How to pull statistics from Icecast with PHP

Update: I’ve refactored a good deal of the code here to support radio servers with multiple mount points. It now uses the SimpleXML functions in PHP5, so make sure you’ve got those enabled.

icestats.php

  1. <?PHP
  2. class icestats {
  3.     // define connection variables
  4.     private $host = 'scriptsamurai.com';
  5.     private $port = 8000;
  6.     private $user = 'username';
  7.     private $pass = 'password';
  8.     private $mnt  = '';
  9.     private $fp   = ''; // class resource used to send/receive data
  10.     function __construct() {
  11.         $this->check_server();
  12.     }
  13.  
  14.     function check_server() {
  15.         // check if the icecast server is even running
  16.         $this->fp = fsockopen($this->host, $this->port, &$errno, &$errstr, 10); // wait ten seconds
  17.         return is_resource($this->fp);
  18.     }
  19.  
  20.     function check_station($mount='') {
  21.         if (empty($mount)) {
  22.             return false;
  23.         }
  24.         $this->mnt = $mount;
  25.         fputs($this->fp, "GET $mount HTTP/1.0\r\nUser-Agent: PHP5/Icecast2 Checker (PHP5/scriptsamurai.com)\r\nHost: ".$this->host."\r\n\r\n");
  26.             $result = fgets($this->fp, 255);
  27.         fclose($this->fp);
  28.         return strstr($result, '200 OK');
  29.     }
  30.  
  31.     function pull_stats(){
  32.         if (!$file = fopen('http://'.$this->user.':'.$this->pass.'@'.$this->host.':'.$this->port.'/admin/stats.xml', 'r')) {
  33.             return false;
  34.         }
  35.         // $file is a valid stream
  36.         $stats = stream_get_contents($file);
  37.         fclose($file);
  38.         // load raw XML stats into a SimpleXML object and then parse out just the mount-point we ask for, or return an error.
  39.         $parsed = new SimpleXMLElement($stats); unset($stats);
  40.         $key = null;
  41.         $mount_points = $parsed->xpath('//source');
  42.         foreach ($mount_points as $mount_index => &$mount_point) {
  43.             $mount = ($parsed->source[$mount_index]->attributes()); $mount = &$mount['mount'];
  44.             if ($mount == $this->mnt) {
  45.                 $key = $mount_index; break;
  46.             }
  47.         }
  48.         // return correct array for this mount point.
  49.         return ($key !== null) ? $parsed->source[$mount_index] : false;
  50.     }
  51. }
  52. ?>

this next script is just a demo of how to access the above - you’ll want to take a look at the print_r($stats) and see which fields you want returned for that mount point, then style them accordingly.

  1. <?PHP
  2. require_once('icestats.php');
  3. $r = new icestats;
  4.  
  5. $stats = array();
  6. if ($r) {
  7.     if ($r->check_station('/pirate-radio')) {
  8.         if ($stats = $r->pull_stats()) {
  9.             echo '<pre>'; print_r($stats);
  10.         } else {
  11.             echo 'There was a problem retrieving the station information.';
  12.         }
  13.     } else {
  14.         echo 'The requested station is currently unavailable.';
  15.     }
  16. } else {
  17.     echo 'The radio server is currently unavailable.';
  18. }
  19. ?>

A final note, when accessing $stats in anything other than print_r(), use $stats->property_name, because $stats is a SimpleXML object.

comments

Viewing 4 Comments

Trackbacks

blog comments powered by Disqus