Skip to content

Instantly share code, notes, and snippets.

@dimitris-c
Last active October 4, 2023 17:10
Show Gist options
  • Save dimitris-c/3e2af7ab451c965d126c02ab580f1eb8 to your computer and use it in GitHub Desktop.
Save dimitris-c/3e2af7ab451c965d126c02ab580f1eb8 to your computer and use it in GitHub Desktop.
Taken from : https://www.smackfu.com/stuff/programming/shoutcast.html
Webarchive: https://web.archive.org/web/20190521203350/https://www.smackfu.com/stuff/programming/shoutcast.html
Shoutcast Metadata Protocol
How To Parse Titles from MP3 Streams
I wanted to add the ability to show titles from Shoutcast streams on the SliMP3, like Winamp does. The protocol isn't documented anywhere officially (of course). So I ended up cobbling together info from google caches, xmms source code, and mailing lists. Hopefully, this document will save others from the same fate.
## Step 0: Overview picture
-----------------------------------------------------------------------
[ audio data ][metadata.length][metadata][ audio data ]
-----------------------------------------------------------------------
##Step 1: Request metadata
This is as simple as adding a new field to your HTTP request:
Icy-MetaData:1
So the entire request might look like this:
GET path HTTP/1.0 <CRLF>
Icy-MetaData:1 <CRLF>
<CRLF>
If you request the metadata, you must parse it, or else you'll get blips in your mp3's every second or so. On the other hand, that's a pretty good way to see whether you're getting the metadata at all.
##Step 2: Get the metadata interval
One of the headers that comes back from your request will tell you how often the metadata is sent in the stream. Specifically, how many MP3 data bytes there are between metadata blocks. The header looks like this:
icy-metaint: number
You probably want to store that number.
Step 3: Get the metadata
This is the important part.
Read the data stream as you normally would, keeping a byte count as you go. When the number of bytes equals the metadata interval, you will get a metadata block. The first part of the block is a length specifier, which is the next byte in the stream. This byte will equal the metadata length / 16. Multiply by 16 to get the actual metadata length. (Max byte size = 255 so metadata max length = 4080.) Now read that many bytes and you will have a string containing the metadata. Restart your byte count, and repeat. Success!
Note that the metadata length is set to 0 most of the time, meaning there is no metadata. The metadata is normally sent at two particular places: immediately after connecting and when the song changes. It seems as if some servers aren't real diligent about the former, so it might take a while to get your first block.
Also, be sure you don't count the bytes in the metadata length field or the metadata when you're figuring out whether you've hit the interval. Only the MP3 data counts. So you can't be lazy and just keep a total byte count and mod it.
##Step 4: Interpret the metadata
Part of the metadata string should look like this:
StreamTitle='title of the song';
Extract the title, and you're golden.
Simple, eh?
(Thanks to Michael Meador for digging into the WinAmp binary and correcting me on the format of the metadata.)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment