0

How do I extract "current track / now playing" info from a shoutcast/icecast radio stream? I tried following solutions:

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));
Jenever
  • 500
  • 5
  • 17
  • What players for `http://icecast-qmusic.cdp.triple-it.nl/Qmusic_be_live_64.aac` are able to show stream data? I'm listening to it now and I don't see any metadata on this stream. – Brad Mar 19 '19 at 15:52
  • Also, stop setting your user agent to `Mozilla`. That will break compatibility on older versions of SHOUTcast. Your user-agent string specifically needs to *not* contain `Mozilla` for SHOUTcast v1 servers. Alternatively, the URL needs to have a semicolon `;` appended for those servers. (But, do not use this hack unless you have to! It isn't compatible with most other servers.) – Brad Mar 19 '19 at 15:53
  • Thank you for your feedback Brad (I actually read some of your valuable posts here on Stack Overflow before asking this). Good to know about the user agent, I removed the header property. Regarding players that show the stream data, there is https://radiobelgium.be/, which is in fact an app, not a website/service. And there is of course always the homepage of the radio station, although they can probably use completely different methods of showing the stream data... – Jenever Mar 19 '19 at 16:43
  • Yeah, not all stations embed the metadata into the stream, but most do. ICY-style metadata is most common, and is what you see for most MP3 and ADTS (which is what AAC is generally wrapped with) streams. Ogg streams (far less common) have their own metadata that you have to read by parsing the Ogg stream itself. – Brad Mar 19 '19 at 17:01

0 Answers0