Search code examples
audiostreamingshoutcasticecastinternet-radio

Fetch Icecast song title without buffering audio


I want to write a small JavaScript library that can fetch "now playing" data for Icecast streams. From what I understand, I can do this by sending a HTTP request to a radio stream as follows:

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

The server will then answer with some reponse headers. One of them is the icy-metaint field that indicates the interval at which the metadata is inserted into the stream. The metadata will look something like this:

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

Although this gets me the information I need, it isn't very efficient if you don't need the audio itself. (This can be the case when the stream isn't playing.) Is there a way to fetch the stream title without buffering the audio? I know I can scrape HTML to get it, but that method has significant limitations.


Solution

  • SHOUTcast/Icecast metadata always comes after the first audio chunk. There is no way to get in-stream metadata without having an audio chunk before it.

    The good news is that this isn't as inefficient as you might think. Most stations use 8KB metadata intervals. Many use 16KB intervals. I don't think I have ever seen a metadata interval greater than 32KB. The server side will buffer the audio stream and flush this buffer as soon as you connect. You will often receive metadata within the first or second response packet.

    If it's helpful to you, I have a free API available for fetching metadata from streams that does exactly what you propose. It connects to a stream, skips through the audio data, parses the metadata, and returns JSON. It is accessible from within the browser.

    Request

    $.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);
    });
    

    Response

    {
      "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"
      }
    }