How do I extract "current track / now playing" info from a shoutcast/icecast radio stream? I tried following solutions:
- https://github.com/ghaiklor/icecast-parser
- https://code.google.com/archive/p/streamscraper/
- Parsing the .xspf file Can't extract metdata from some icecast streams
- Analyzing the audio stream in PHP/native Android (get info from streaming radio, Pulling Track Info From an Audio Stream Using PHP, http://www.smackfu.com/stuff/programming/shoutcast.html
All of the methods above work for some radiostations, such as http://icecast.vrtcdn.be/stubru-high.mp3
However, for a number of icecast/shoutcast streams, all of them fail. Example: http://icecast-qmusic.cdp.triple-it.nl/Qmusic_be_live_64.aac. When analyzing the audio stream itself, the streamTitle is always empty. The xspf file always has an empty title tag. However, I notice other apps and websites do succeed in gathering current track info for this radio station. The homepage of the radio station also contains the current track/playlist info: https://qmusic.be/playlist/qmusic.
I know I could go and write an html scraper that extracts this data, but I only want to use this as a last resort. Besides, I have multiple streams with similar problems and this would not be a generic solution that can be applied to all of them.
So, am I missing something? Is there another general way in which metadata can be extracted from an icecast/shoutcast server? I also tried using the 7.html file or the /stats?sid=1 files, but did not have a lot of luck with these approaches (as in: files not present/invalid urls). Below a php script from one of the hyperlinks that works in some cases. Any help or feedback would be greatly appreciated!
PS: Sorry for the mixup of tools/frameworks/languages. Tried lots of stuff here. Extra thanks for answers that are React-Native compatible!
<?php
function getMp3StreamTitle($streamingUrl, $interval, $offset = 0, $headers = true)
{
$needle = 'StreamTitle=';
$ua = 'Mozilla';
$opts = [
'http' => [
'header' => 'Icy-MetaData: 1',
'user_agent' => $ua
]
];
if (($headers = get_headers($streamingUrl))) {
foreach ($headers as $h) {
if (strpos(strtolower($h), 'icy-metaint') !== false && ($interval = explode(':', $h)[1])) {
break;
}
}
}
$context = stream_context_create($opts);
if ($stream = fopen($streamingUrl, 'r', false, $context)) {
$buffer = stream_get_contents($stream, $interval, $offset);
fclose($stream);
if (strpos($buffer, $needle) !== false) {
$title = explode($needle, $buffer)[1];
return substr($title, 1, strpos($title, ';') - 2);
} else {
return getMp3StreamTitle($streamingUrl, $interval, $offset + $interval, false);
}
} else {
throw new Exception("Unable to open stream [{$streamingUrl}]");
}
}
var_dump(getMp3StreamTitle('http://icecast.vrtcdn.be/stubru-high.mp3', 16000));