katzuma has asked for the wisdom of the Perl Monks concerning the following question:

I was trying to add (without success) this feature to the mp3 server code that can be found in the Tutorial section
As you can see the discussion hung on the last post about how to introduce meta data in the stream.
This is what i discovered after a short research:
First, the server sends metadata only if the client ask for it. There are two main formats of "streaming metadata" : icy and audiocast.
The client can send a "icy-metadata:1" in the request to tell the server that it can read such infos. The server responds with a "icy-metaint:8129" where the number is the interval in bytes where the client should expect metadata in the stream. So the infos are embedded inside the audio. The other formats relies on a different udp connection to send text informations. (The client sends a "x-audiocast-udpport:49229" where the number is the preferred but not mandatory port).

Focusing on the "icy" method:
As we has seen the server tells the client something like:" Every x (usually 8129) bytes of audio stream you will find some metadata".
The first byte will equal the metadata length / 16. Then we have something like "StreamTitle=' title'; StreamUrl='myradio'". Thats it. Most of the times the whole packet will be "\0" meaning there's no metadata (the title hasnt changed).This is why the interval isn't important as long as the server takes care not to resend the stuff if it has not changed.
Coming to the code:
The simplest approach didn't work for me: read 8129 of song, append the metadata (could be "\0") and so on.
$readbuf = read (SONG , $slice ,8129); <br> my $metainfo= "StreamTitle='my title';";<br> my $metahead = pack 'C', int(length($metainfo) / 16); <br> my $metadata = $metahead.$metainfo;<br> # my $metadata = "\0"; This should work !!!!! aaargh!!! $slice.=$metadata;<br>
What i got from that code was that the info arrived to my client with lots of bleeps and out-of-sync drops.
Assuming im not encoding properly the metadata it should work at least when i only send a "\0"....(im surely missing something here) Also trying with more complicated approaches (tracking a $bytes_to_next_metadata assuming the bytes written where not exactly the same as the ones read) didn't give better results.
Anyone can put the final words (lines of codes) to solve this?
Thanks.

Replies are listed 'Best First'.
Re: Adding metadata support to the Mp3 streaming server
by skx (Parson) on Oct 15, 2003 at 12:59 UTC

     There's a little bit of detail you're missing - which I think is enough to throw you off.

     When you serve the response back instead of sending "HTTP 200 OK", you must instead send "ICY 200 OK".

     I wrote GNUMP3d - just about to move to the GNU servers, where CVS is already located - and I got this working fairly easily by reading this document.

     You can see my code here, the important function being "getHTTPHeader".

    Steve
    ---
    steve.org.uk
      Changing the HTTP 200 OK to ICY 200 OK didn't solve my problem.
      Anyway it seems to me that your code doesn't support metadata ( it doesn't send a icy-metaint value in its header)..im i wrong?
        I am looking for a solution to this problem too. gnumpd doesn't actually 'stream' files, it just creates a playlist and then winamp will play the files one by one! It will be really appreciated if someone post the code for sending the metadata to the client while streaming.