Icecast / Shoutcast广播流:提取正在播放的信息

时间:2019-03-18 15:52:23

标签: metadata icecast shoutcast

如何从广播/冰广播的广播流中提取“当前曲目/正在播放”信息?我尝试了以下解决方案:

以上所有方法对某些无线电台均适用,例如 http://icecast.vrtcdn.be/stubru-high.mp3

但是,对于许多Icecast / Shoutcast流,它们都失败了。示例:http://icecast-qmusic.cdp.triple-it.nl/Qmusic_be_live_64.aac。分析音频流本身时,streamTitle始终为空。 xspf文件始终具有一个空的标题标签。但是,我注意到其他应用程序和网站确实可以成功收集该广播电台的当前曲目信息。广播电台的主页上还包含当前的曲目/播放列表信息:https://qmusic.be/playlist/qmusic

我知道我可以去编写一个HTML抓取器来提取这些数据,但是我只想将其用作最后的手段。此外,我有多个存在类似问题的流,并且这不是适用于所有流的通用解决方案。

那么,我想念什么吗?是否有另一种通用方法可以从Icecast / Shoutcast服务器提取元数据?我也尝试使用7.html文件或/ stats?sid = 1文件,但是这些方法没有很多运气(例如:文件不存在/无效的url)。在某些情况下,可以从超链接之一获得的PHP脚本下方。任何帮助或反馈将不胜感激!

PS:很抱歉工具/框架/语言的混合。在这里尝试了很多东西。特别感谢您提供与React-Native兼容的答案!

<?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));

0 个答案:

没有答案