This article describes a class for receiving Shoutcast streams. For some background information, look at this short protocol description, or visit the Shoutcast website.
In my last project, I had to receive, capture, and play Shoutcast streams. I looked for some ready to use implementations, but didn't find any, so I decided to write my own.
Using the Code
Because it's a relatively simple protocol, the code is also quite simple, but it does what it should. :)
For the best interoperability to other classes (e.g., for DirectSound playing it), I derived from the abstract
Stream, so other classes that can handle streams can handle my stream too.
public ShoutcastStream(string url)
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.KeepAlive = false;
request.UserAgent = "VLC media player";
response = (HttpWebResponse)request.GetResponse();
metaInt = int.Parse(response.Headers["Icy-MetaInt"]);
receivedBytes = 0;
netStream = response.GetResponseStream();
connected = true;
In the constructor, the connection is established. Therefore, we have to put a new field into the HTTP request,
Icy-MetaData:1. We also set the
UserAgent to "VLC Media Player" (we can also use WinAmp etc.) because some Shoutcast servers behave different with different
After we get the response, we read out the
Icy-MetaInt value. This is the value that shows how many data bytes we receive before the server will send a metainfo block.
public override int Read(byte buffer, int offset, int count)
if (receivedBytes == metaInt)
int metaLen = netStream.ReadByte();
if (metaLen > 0)
byte metaInfo = new byte[metaLen * 16];
int len = 0;
while ((len += netStream.Read(metaInfo, len,
metaInfo.Length - len)) < metaInfo.Length) ;
receivedBytes = 0;
int bytesLeft = ((metaInt - receivedBytes) > count) ?
count : (metaInt - receivedBytes);
int result = netStream.Read(buffer, offset, bytesLeft);
receivedBytes += result;
catch (Exception e)
connected = false;
If the requested count of bytes is less than the remaining bytes before the next metainfo block, we will read as much bytes as requested. But if there are less bytes before the next metainfo block as the user has requested, we will only read the remaining bytes and return. When the user calls
Read the next time, we fill first receive the metainfo block and then continue reading the media data from the stream.
Every time a metainfo block is received, the current stream title is extracted. If the stream title changes, the corresponding event is fired.
Before using this in your application, you have to extend your App.config by the following:
<httpWebRequest useUnsafeHeaderParsing ="true"/>
Points of Interest
If someone is interested in playing a Shoutcast stream using Managed DirectSound (pure .NET), ask for it. Perhaps, I'm going to write an article about that.
- 1.0 - Initial revision (10 June 2007)