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
-
<?PHP
-
class icestats {
-
// define connection variables
-
private $host = 'scriptsamurai.com';
-
private $port = 8000;
-
private $user = 'username';
-
private $pass = 'password';
-
private $mnt = '';
-
private $fp = ''; // class resource used to send/receive data
-
function __construct() {
-
$this->check_server();
-
}
-
-
function check_server() {
-
// check if the icecast server is even running
-
$this->fp = fsockopen($this->host, $this->port, &$errno, &$errstr, 10); // wait ten seconds
-
return is_resource($this->fp);
-
}
-
-
function check_station($mount='') {
-
if (empty($mount)) {
-
return false;
-
}
-
$this->mnt = $mount;
-
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");
-
$result = fgets($this->fp, 255);
-
fclose($this->fp);
-
return strstr($result, '200 OK');
-
}
-
-
function pull_stats(){
-
if (!$file = fopen('http://'.$this->user.':'.$this->pass.'@'.$this->host.':'.$this->port.'/admin/stats.xml', 'r')) {
-
return false;
-
}
-
// $file is a valid stream
-
$stats = stream_get_contents($file);
-
fclose($file);
-
// load raw XML stats into a SimpleXML object and then parse out just the mount-point we ask for, or return an error.
-
$parsed = new SimpleXMLElement($stats); unset($stats);
-
$key = null;
-
$mount_points = $parsed->xpath('//source');
-
foreach ($mount_points as $mount_index => &$mount_point) {
-
$mount = ($parsed->source[$mount_index]->attributes()); $mount = &$mount['mount'];
-
if ($mount == $this->mnt) {
-
$key = $mount_index; break;
-
}
-
}
-
// return correct array for this mount point.
-
return ($key !== null) ? $parsed->source[$mount_index] : false;
-
}
-
}
-
?>
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.
-
<?PHP
-
require_once('icestats.php');
-
$r = new icestats;
-
-
$stats = array();
-
if ($r) {
-
if ($r->check_station('/pirate-radio')) {
-
if ($stats = $r->pull_stats()) {
-
echo '<pre>'; print_r($stats);
-
} else {
-
echo 'There was a problem retrieving the station information.';
-
}
-
} else {
-
echo 'The requested station is currently unavailable.';
-
}
-
} else {
-
echo 'The radio server is currently unavailable.';
-
}
-
?>
A final note, when accessing $stats in anything other than print_r(), use $stats->property_name, because $stats is a SimpleXML object.
Add New Comment
Viewing 4 Comments
Thanks. Your comment is awaiting approval by a moderator.
Do you already have an account? Log in and claim this comment.
Do you already have an account? Log in and claim this comment.
it works fine, but we have 5 mountpoints in the stats
/48
/96
/128
/dump
/live
the listeners in the script comes from /live
how can i change to /128 ?
and can i list ips from
http://......../admin/listclients.xsl?mount=/128
mfg
huelgueuer
Do you already have an account? Log in and claim this comment.
I actually haven't tested this with multiple mount points - I just threw it together for a station I run in my personal time, so let me play with it a bit and see what I can come up with.
As to the IP address listings, if you do a print_r($stats) on the array returned back from the get_parsed_stats() function, you'll see what fields you have available for output - listener count and such are available, but I don't see a way off-hand to get the IP addresses of listeners. It would probably entail parsing another one of the XML files on the server, but like I said, this was just a quick thing I threw together, so I'm not sure.
I'll take a look and see what I can come up with for both issues, here, and post back.
- John
Do you already have an account? Log in and claim this comment.
it works very fine. now can i read all parameter in every mount point. thanks.
holger
Do you already have an account? Log in and claim this comment.
I am totally new to PHP and found that it wouldn't run at first on my hosting company's server (which is running PHP 5). I found that I needed to change the line
require_once('icestats.php');
in the example page to
include 'icestats.php';
Otherwise I got a 'class declared twice' error or something like that.
Also for those people like me who don't have a clue how to extract individual fields from the returned object, after a bit of trial and error (!) it turns out you can do it like this:
For example, to print the current artist:
echo $stats->artist[0];
Basically change 'artist' above for whatever other field your are interested in..
Thanks again for sharing your code -
Matt
Add New Comment
Trackbacks