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.
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"
}
}
Since Icecast 2.4 the preferred way to get machine readable meta-data about the streams running through a server is status-json.xsl. This JSON API is default enabled on all installations. Since 2.4.1 it is by default an open API and sending an ACAO header of "*".
In case of old Icecast installations (2.3.x): they can be retrofitted with the JSON API (it would be enough for the administrator to copy status-json.xsl and xml2json.xslt from the 2.4.1 release to the web directory).