Streaming...

Ogg streaming is easier to work with than mp3 streaming... :)
-----------------------------------------------------------

Ogg:

Winamp requests the file with a header like so:
GET /test.ogg HTTP/1.1\r\n
Host:localhost\r\n
User-Agent:Winamp\r\n
Accept:*/*\r\n
\r\n
[Notice how there isn't a space between "Host:" and "localhost" or "User-Agent:" and "Winamp" or "Accept:" and "*/*"...
The HTTP standard says that there should be a space here... So look for it... (incase Winamp fixes this...)]

The streaming server then sends back the following header:
HTTP/1.1 200 OK\r\n
Content-Type: application/ogg\r\n
Content-Length: %d\r\n // Where %d is the filesize in bytes, this line can be omitted...
Accept-Ranges: bytes\r\n // You can omit this line...
ice-audio-info: ice-samplerate=44100\r\n
ice-bitrate: Quality 0\r\n"
ice-description: This is my server desription\r\n
ice-genre: Rock\r\n
ice-name: This is my server desription\r\n
ice-private: 0\r\n
ice-public: 1\r\n
ice-url: http://localhost:8000/\r\n
Server: Icecast 2.0.2\r\n
\r\n
The server then sends the ogg file itself.
-----------------------------------------------------------

Ogg chains (a list of ogg files followed one after the other seemingly as just one file...)

Ogg chains work exactly the same as normal ogg streaming, but the ogg file itself is a list of ogg files...
1. Client requests ogg chain "test.ogg"
2. Server responds with the above header (probably without the Content-Length field)
3. while more files to send
4.     send more files...
-----------------------------------------------------------

mp3:

Winamp requests the file like so:
GET /test.mp3 HTTP/1.0\r\n
Host: localhost\r\n
User-Agent: WinampMPEG/5.0\r\n
Accept: */*\r\n
Icy-MetaData:1\r\n
Connection: close\r\n
\r\n
[Notice how there isn't a space between "Icy-MetaData:" and "1"...
The HTTP standard says that there should be a space here... So look for it... (incase Winamp fixes this...)]

The streaming server then sends back the following header:
HTTP/1.1 200 OK\r\n
Content-Type: audio/mpeg\r\n
Content-Length: %d\r\n // Where %d is the filesize in bytes, this line can be omitted...
Accept-Ranges: bytes\r\n // You can omit this line...
\r\n
The server then sends the mp3 file itself.
Since Winamp requested MetaData, the streaming server can also respond sending MetaData aswell.
HTTP/1.1 200 OK\r\n
Content-Type: audio/mpeg\r\n
Content-Length: %d\r\n // Where %d is the filesize in bytes, this line can be omitted...
Accept-Ranges: bytes\r\n // You can omit this line...
icy-metaint: %d\r\n // Where %d is the interval in which you will send metadata
\r\n
The streaming server then responds by sending the mp3 file with metadata every metaint bytes.
The first byte of the metadata is a length indicator, divided by 16 that tells you the size of the rest of the metadata.
The metadata is at max 4080 bytes long, not including the 1 byte length indicator, so 4081 bytes.
while ( file has data ) {
  read (metaint) bytes from file
  send (metaint) bytes to client

  char metadata[(255 * 16) + 1] = " StreamTitle='title of the song';";
  int size = ((int)((strlen(metadata) - 1) / 16) * 16);
  metadata[0] = size / 16;

  send metadata (size + 1) bytes to client
}
-----------------------------------------------------------

Links: