Skip to content

Instantly share code, notes, and snippets.

@nickopris
Forked from njh/shoutcast.php
Created April 7, 2022 11:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nickopris/911ab1daf929b5a1ea25fc9ba4d2ed82 to your computer and use it in GitHub Desktop.
Save nickopris/911ab1daf929b5a1ea25fc9ba4d2ed82 to your computer and use it in GitHub Desktop.
PHP script to check the status of a Shoutcast stream
<?php
$PLAYLIST_URL = 'http://www.bbc.co.uk/radio/listen/live/r1.pls';
set_time_limit(5);
// Fetch and parse a .pls playlist file
// @returns an array of URLs in the playlist
function readPlaylist($url)
{
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$body = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
if ($info['http_code'] != '200') {
throw new Exception("Response was not success.");
} elseif ($info['content_type'] != 'audio/x-scpls') {
throw new Exception("Content Type is incorrect.");
} else {
$lines = preg_split("/[\r\n]+/", $body);
$first = array_shift($lines);
if ($first != '[playlist]') {
throw new Exception("First line of playlist is not [playlist]");
}
$kv = array();
foreach($lines as $num => $line) {
if (preg_match('/^(\w+)=(.+)$/', $line, $matches)) {
$kv[$matches[1]] = $matches[2];
} elseif ($line) {
throw new Exception("Failed to parse line ".($num+1)." of playlist.");
}
}
$result = array();
for($i=1; $i<=intval($kv['NumberOfEntries']); $i++) {
array_push($result, $kv["File$i"]);
}
return $result;
}
}
// Try and connect to an HTTP stream
// @return an array of information about the stream
function checkStream($urlstr)
{
$url = parse_url($urlstr);
$host = $url['host'];
$port = isset($uri['port']) ? $uri['port'] : 80;
$timeout = 10;
// Open socket to remote HTTP server
$socket = fsockopen($host, $port, $errno, $errstr, $timeout);
if (!$socket) {
throw new Exception("Unable to connect to $host:$port ($errstr)");
}
// Write the HTTP request to the socket
$path = $url['path'];
if (isset($url['query'])) $path .= '?' . $url['query'];
fwrite($socket, "GET $path HTTP/1.1\r\n");
fwrite($socket, "Host: $host\r\n");
fwrite($socket, "\r\n");
// Parse the first line of the response
$headers = array();
$status = fgets($socket);
if (preg_match("/^HTTP\/(\d\.\d)\s+(\d+)\s+(.+?)\s*$/", $status, $matches)) {
$headers['http_version'] = $matches[1];
$headers['http_status'] = $matches[2];
$headers['http_message'] = $matches[3];
} else {
throw new Exception("Failed to parse HTTP response status line");
}
if ($headers['http_status'] != 200) {
throw new Exception("Response was not 200 success");
}
// Read in the rest of the response
$body = '';
$headersEnded = FALSE;
while (!feof($socket)) {
$line = fgets($socket);
if ($headersEnded) {
// Read until we have 1024 bytes of body
$body .= $line;
if (strlen($body) > 1024)
break;
} else {
// Parse the HTTP header
if (preg_match("/^([\w\-]+)\s*:\s*(.+?)\s*$/", $line, $matches)) {
list(, $key, $value) = $matches;
$headers[$key] = $value;
} else {
$headersEnded = TRUE;
}
}
}
fclose($socket);
// Try and detect the mime type of the body of the response
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime = $finfo->buffer($body);
return array(
'headers' => $headers,
'mime' => $mime
);
}
print "<h1>Loading playlist</h1>\n";
$items = readPlaylist($PLAYLIST_URL);
print "<ol>\n";
foreach ($items as $item) {
print "<li>$item</li>\n";
}
print "</ol>\n";
foreach ($items as $num => $item) {
print "<h1>Checking stream ".($num+1)."</h1>\n";
$response = checkStream($item);
print "<pre>";
var_dump($response);
print "</pre>";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment