Pulling Track Info from an Audio Stream Using PHP

Pulling Track Info From an Audio Stream Using PHP

This is a SHOUTcast stream, and yes it is possible. It has absolutely nothing to do with ID3 tags. I wrote a script awhile ago to do this, but can't find it anymore. Just last week I helped another guy who had a fairly complete script to do the same thing, but I can't just post the source to it, as it isn't mine. I will however get you in touch with him, if you e-mail me at brad@musatcha.com.

Anyway, here's how to do it yourself:

The first thing you need to do is connect to the server directly. Don't use HTTP. Well, you could probably use cURL, but it will likely be much more hassle than its worth. You connect to it with fsockopen() (doc). Make sure to use the correct port. Also note that many web hosts will block a lot of ports, but you can usually use port 80. Fortunately, all of the AOL-hosted SHOUTcast streams use port 80.

Now, make your request just like your client would.

GET /whatever HTTP/1.0

But, before sending <CrLf><CrLf>, include this next header!

Icy-MetaData:1

That tells the server that you want metadata. Now, send your pair of <CrLf>.

Ok, the server will respond with a bunch of headers and then start sending you data. In those headers will be an icy-metaint:8192 or similar. That 8192 is the meta interval. This is important, and really the only value you need. It is usually 8192, but not always, so make sure to actually read this value!

Basically it means, you will get 8192 bytes of MP3 data and then a chunk of meta, followed by 8192 bytes of MP3 data, followed by a chunk of meta.

Read 8192 bytes of data (make sure you are not including the header in this count), discard them, and then read the next byte. This byte is the first byte of meta data, and indicates how long the meta data is. Take the value of this byte (the actual byte with ord() (doc)), and multiply it by 16. The result is the number of bytes to read for metadata. Read those number of bytes into a string variable for you to work with.

Next, trim the value of this variable. Why? Because the string is padded with 0x0 at the end (to make it fit evenly into a multiple of 16 bytes), and trim() (doc) takes care of that for us.

You will be left with something like this:

StreamTitle='Awesome Trance Mix - DI.fm';StreamUrl=''

I'll let you pick your method of choice for parsing this. Personally I'd probably just split with a limit of 2 on ;, but beware of titles that contain ;. I'm not sure what the escape character method is. A little experimentation should help you.

Don't forget to disconnect from the server when you're done with it!

There are lots of SHOUTcast MetaData references out there. This is a good one: http://www.smackfu.com/stuff/programming/shoutcast.html

Retrieving the name of an audio track from a stream

I've came across this library by Eshaz showing that is possible to retrieve meta data directly from the browser. But unfortunately CORS policies must be properly set to work.

Like Brad pointed out, the best option is retrieve the information from the server side.

Here hoping the AudioTrack feature turn mainstream in the near future. Thank you @Brad for all the help.

Is it possible to get Icecast metadata from HTML5 audio element?

No, your HTML5 elements are only aware of the stream data, and aren't even making the appropriate request to fetch the metadata.

See these posts:

  • Developing the client for the icecast server

  • Pulling Track Info From an Audio Stream Using PHP

  • http://www.smackfu.com/stuff/programming/shoutcast.html

Now, this isn't impossible by any means. You just have to do it server-side. (See that second link in particular.)

I should also point out that on a full-blown SHOUTcast Server (haven't tested with Icecast, but its worth a try) generates "7.html" which contains data on the number of listeners, max listeners, peak listeners, stereo/mono, bitrate, and current track name as comma-separated values. Like this:

2,1,33,625,2,128,J Mascis - Not Enough

If you can fetch http://yourstreamingserver:port/7.html, then you can get this data very easily.

How to extract StreamTitle from network audio stream using Wireshark?

What you're looking at is a stream with SHOUTcast-style (commonly referred to as ICY) metadata muxed in. As far as I know, there are no Wireshark filters for demuxing this. However, the problem is even simpler than that.

The metadata is inserted at regular intervals. You don't even need VLC to strip it out. If you look at the response headers, you will see one called Icy-MetaInt. This is the interval, in bytes, of the metadata chunks. The first byte in the metadata chunk is the length of the metadata block divided by 16. The metadata block is then padded by null bytes.

For example, suppose the meta interval is 8192 bytes...

[8192 bytes of audio][1 byte meta length][meta block][8192 bytes of audio][etc...]

Just read the first byte after the audio, multiply by 16, and then read that many bytes from the stream for your metadata block. Chop off the null bytes at the end of it, and you have your data.

Even simpler, StreamRipper outputs the metadata on its STDERR stream. You could pipe that into a script.

See my answer here for more details: https://stackoverflow.com/a/4914538/362536

MP3 meta data over http response

Just to clarify, you are effectively proxying an MP3 file from SoundCloud, and you want to embed metadata into it?

Winamp will pick up ID3 tags in an HTTP-served MP3 file. However, if you are using ID3v1, those tags don't exist until the very end of the file. If you want the file to be identified without having to download the whole file, you must use ID3v2 which are typically located at the beginning of the file. (I actually recommend using both ID3v1 and ID3v2 for broader player compatibility, but almost everything supports ID3v2, so it is your choice.)

Now, there is another method but if you use this method the metadata won't be saved in the file when downloaded. You can use SHOUTcast-style metadata. Basically, Winamp and other clients (like VLC) send a request header, Icy-MetaData: 1. This tells the server that it supports SHOUTcast-style metadata. In your server response, you would insert metadata every 8KB or so. Basically, you want the reverse of what I have detailed here: https://stackoverflow.com/a/4914538/362536

In the end, simply adding ID3v2 tags will solve your problem in the best way, but I wanted to mention the alternative option in case you needed it for something else.



Related Topics



Leave a reply



Submit