【问题标题】:Fetch Icecast song title without buffering audio在不缓冲音频的情况下获取 Icecast 歌曲标题
【发布时间】:2015-01-05 04:29:59
【问题描述】:

我想编写一个小型 JavaScript 库,它可以为 Icecast 流获取“正在播放”的数据。根据我的understand,我可以通过向无线电流发送 HTTP 请求来做到这一点,如下所示:

GET /radiotunes_bebop HTTP/1.1
Host: pub2.radiotunes.com
Icy-MetaData:1

然后服务器将回答一些响应头。其中之一是icy-metaint 字段,它指示元数据插入到流中的时间间隔。元数据将如下所示:

StreamTitle='Dexter Gordon - Jodi';StreamUrl='';

虽然这为我提供了我需要的信息,但如果您不需要音频本身,它的效率就不是很高。 (当流没有播放时可能会出现这种情况。)有没有办法在不缓冲音频的情况下获取流标题?我知道我可以抓取 HTML 来获取它,但是这种方法有很大的局限性。

【问题讨论】:

    标签: audio streaming shoutcast icecast internet-radio


    【解决方案1】:

    从 Icecast 2.4 开始,获取有关通过服务器运行的流的机器可读元数据的首选方法是 status-json.xsl。此 JSON API 在所有安装中默认启用。从 2.4.1 开始,它默认是一个开放的 API,并发送一个“*”的 ACAO 标头。

    如果是旧的 Icecast 安装 (2.3.x):它们可以使用 JSON API 进行改造(管理员从 2.4.1 复制 status-json.xsl 和 xml2json.xslt 就足够了 发布到网络目录)。

    【讨论】:

    • 一个主要警告:这并不普遍。一些最大的仅限互联网的无线电网络甚至还不支持它(例如Digitally ImportedSomaFM)。希望这种情况在未来会有所改善。与此同时,恐怕我将不得不坚持使用更糟糕但更可靠的解决方案。
    • 当然,这适用于您为特定流创建网页时。如果您必须使用随机流,那您就完蛋了。如果流是 Vorbis 或 OPUS,则 ICY 抓取将不起作用,因为元数据位于 Ogg 容器中。 Firefox 有一个 JS 元数据 API,但这是特定于供应商的。
    【解决方案2】:

    SHOUTcast/Icecast 元数据总是出现在第一个音频块之后。如果没有音频块,就无法获取流内元数据。

    好消息是,这并不像您想象的那么低效。大多数电台使用 8KB 元数据间隔。许多使用 16KB 间隔。我认为我从未见过大于 32KB 的元数据间隔。服务器端将缓冲音频流并在您连接后立即刷新此缓冲区。您通常会在第一个或第二个响应包中收到元数据。

    如果它对您有帮助,我有一个 free API available for fetching metadata from streams 可以完全按照您的建议进行。它连接到一个流,跳过音频数据,解析元数据,然后返回 JSON。它可以从浏览器中访问。

    请求

    $.getJSON('http://api.audiopump.co/metadata/getStreamMetadata', {
      url: 'http://cdn.audiopump.co/radioreddit/main_mp3_128k',
      apiKey: 'YOUR_API_KEY'
    }).done(function (data) {
      console.log(data);
    });
    

    响应

    {
      "streamInfo": {
        "contentType": "audio/mpeg",
        "name": "Radio Reddit - Main",
        "genres": [
          "Indie",
          "Rock",
          "Talk"
        ],
        "websiteUrl": "http://radioreddit.com",
        "isPublic": true
      },
      "current": {
        "filename": "the_Nothingdoers_(evanowe)_Things_We_Should_Forget.mp3",
        "StreamTitle": "the Nothingdoers (/u/evanowe) - Things We Should Forget"
      }
    }
    

    【讨论】:

    • 恐怕我在 API 的响应中遇到了一些非 ASCII 字符的问题:i.imgur.com/nfcpgIH.pngi.imgur.com/TA46n36.png 尽管存在 Content-Type,但 é 字符未正确解码标头表示 UTF-8 编码。
    • @Pieter 感谢您的错误报告。站名编码问题是一个错误,我认为这是我的 API 服务器运行的 Node.js 的核心。 github.com/joyent/node/issues/8699 我正在努力确认这一点,并希望有一个解决方法。流元数据本身虽然......元数据预计已经在 UTF-8 中。然而,许多编码器不这样做。我正在考虑添加一个选项,您可以在其中指定您的编码。这会有帮助吗?你知道你使用的是什么编码吗?而且,你有我可以重现这个的流吗?
    • 在按照this recommendation 发出请求之前,我会执行$.ajaxSetup({ scriptCharset: "utf-8" , contentType: "application/json; charset=utf-8"});,但我在请求标头中看不到任何关于UTF-8 的内容。您可以使用此流重现错误:pub6.radiotunes.com/radiotunes_cafedeparis
    • @Pieter API 将始终返回 UTF-8。问题是源流本身被假定为 UTF-8,因为这是大多数编码器使用的。 (不幸的是,在 SHOUTcast 中并没有真正为元数据定义字符编码,因此并非所有编码器都使用 UTF-8。)这是我正在测试的流,但自从我测试以来我没有看到任何重音字符.我将在今天晚些时候再试一次,并将为流的元数据编码添加一个参数。我会尽快回复您。您能否也发送电子邮件至 brad@audiopump.co,以便我可以通过电子邮件联系?谢谢。
    • 供将来参考:此方法不再有效。当我尝试访问 API 时,我从 nginx 服务器收到 504 网关超时。啊,好吧,这是一项免费服务......它持续的时间很有趣。
    猜你喜欢
    • 2013-01-10
    • 1970-01-01
    • 2011-06-13
    • 1970-01-01
    • 2011-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多