Check out my
new book!
HTML5 Games book
Read ID3 tags with JavaScript A small JavaScript library capable of reading ID3 (v1) tags from MP3 files.

I figured I'd try to put the binary Ajax code to some other use than the EXIF data library, and a simple project seemed to be the ID3 tags used to store artist, title, etc. in MP3's. For now, it's only capable of reading (the rather lacking) ID3v1 tags since these are very simple compared to the more fleshed out and robust ID3v2 tags. Maybe I'll try to add support for the v2 tags later.

The script tries to only requesting partial data by using the Range request header if ranges are supported. This means we only have to download the actual tag data but also that we have to make a HEAD request first to get the file size and to ensure ranges are actually supported.

It's rather simple to use:

Two JS files are needed:
<script type="text/javascript" src="../binaryajax/binaryajax.js" ></script>
<script type="text/javascript" src="id3.js" ></script>

And a bit of JavaScript:
// URL of the mp3 file (must be on the same domain!)
var file = "mymusicfile.mp3";

// define your own callback function
function mycallback() {
 // either call the ID3.getAllTags([file]) function which returns an object holding all the tags
 alert(
  "All tags in this file: " + ID3.getAllTags(file).toSource()
 );

 // or call ID3.getTag([file], [tag]) to get a specific tag
 alert(
  "Title: " + ID3.getTag(file, "title") + " by artist: " + ID3.getTag(file, "artist")
 );
}

ID3.loadTags(file, mycallback);


Tags available are: artist, title, album, year, album, comment, genre

As with the EXIF reader, it does not work with Opera since I still haven't found a way to access binary data with that browser.

Check out a demo here: http://www.nihilogic.dk/labs/id3/

Download the source code here: id3.zip [3.17 KB]
⇓ 34 comments Anonymous

Nice work, Jacob.

Pity about Opera though. I bumped into the same can't-read-binary-data issue when i was writing my SCUMM interpreter. The only solution was to decompose the file into a JavaScript array of bytes. Annoying to say the least. :(

August 19, 2008 at 10:26 AM
Eli

Songbird implements things like that too in it's JavaScript API.

August 19, 2008 at 12:04 PM
Anonymous

Hi Jacob,

I think you will have your share of luck with Opera just because Opera is pushing towards web 3.0 This means that they filed a proposal for browser content to access file system data this means also binary data.

August 19, 2008 at 4:34 PM
Anonymous

I don't think you do need to download the whole file. Don't ID3v1 tags always start a set amount of bytes in to the end of the file? Can't we do a HEAD request on the file to get it's size, then a 'Range' request to download just the ID3 part of it?

If my understanding of ID3v1 is up to scratch, we shouldn't really have to download more than a couple kilobytes per file.

It might even be possible to do a 'Range' request with a negative number

August 20, 2008 at 1:03 AM
Jacob Seidelin

@blueberry: You're absolutely right and I should look into that.

@james, johnny: Yea, hopefully there will be some way to get binary data in Opera in the future.

August 20, 2008 at 3:31 AM
Anonymous

I think i am gonna blog about this. This is a nice topic to blog about

August 20, 2008 at 4:20 AM
Andrea Giammarchi

Jacob, as blueberry said, the biggest limit I can spot is that you need to load an entire MP3 to get a maximum amount of 227 bytes ( ID3V1 with fixed length ).

Unfortunately, I could not find a way to get received length with IE, using both JS and/or VBScript, always an error when you try to access into responseBody, or responseStream, during interation and state 3.

On the other hand, with FireFox you could simply start a timer when ready state is 3 and timer has not been started before.

Accordingly, when the binary length will be equal or more than 227 bytes you can save the value, abort the operation, and parse saved value with your methods (why did you choose privileged?)

IE? ... as usual, who still prefer that browser, will wait the entire file, while when we will be able to get downloaded data with IE too, things will change a lot, making Ajax more close to AS than before in every platform ;)

August 20, 2008 at 5:51 AM
Andrea Giammarchi

Jacob, something like that:


var timer = 0;
oHTTP.onreadystatechange = function() {
if(oHTTP.readyState == 3 && timer == 0){
var self = this;
timer = setInterval(function(){
if(227 < oHTTP.responseBody.length){
clearInterval(timer);
self.binaryResponse = new BinaryFile(oHTTP.responseBody);
oHTTP.abort();
oHTTP = null;
fncCallback(self);
}
}, 20);
}
};

August 20, 2008 at 6:02 AM
Jacob Seidelin

@andrea: Thanks for the feedback, but I'm not quite sure what you're suggesting. The way I read you're code snippet, that would only work if the data you need is at the beginning of the file, no? And the ID3 tags are at the end.

Anyway, I've tried out the approach blueberry suggested and it seems to work fine in both FF, IE and Safari. I'm not a big HTTP or web server nerd and I'm not sure how well supported Range requests are, but since I'm already doing a HEAD request to get the file size, the server also tells us if it supports ranges, so I think it's all good.

The example page has been updated with the new code.

August 20, 2008 at 1:17 PM
Anonymous

yeah that id3v2 is teh real evils =O

August 20, 2008 at 4:42 PM
Andrea Giammarchi

Jacob, you are right. I though they were at the beginning, so blueberry suggestion seems to be the best one for me as well.
Anyway, as last optimization, have you tried to set the range in this way?

bytes=-128

Regards

August 21, 2008 at 1:35 AM
Anonymous

Can anyone tell me one reason why to do such a thing in AJAX ? Thank you.

August 21, 2008 at 12:57 PM
Andrea Giammarchi

anonymous, you are right, basically, the simplest way is to let server reply with a json object populated with every information, and in a simple / fast way.

Now, try to think that this blog is about experiments, and that read binary files via javascript is one of them, and that using the server, without a server side language, is another good experiment as well :D

August 21, 2008 at 3:29 PM
Jacob Seidelin

As Andrea points out, this is about experimenting and making JavaScript do unusual things.

If your demand for usefulness and reason should be met, this blog would be a sad and empty place.

August 22, 2008 at 10:11 AM
Anonymous

And timesize? have a request method?

November 5, 2008 at 3:43 AM
cephe kaplama

Thanks a lot.

June 9, 2009 at 8:08 AM
dis cephe

The example page has been updated with the new code.

July 17, 2009 at 3:44 AM
Anonymous

doesn't work in internet explorer 6 btw.. which is still unfortunately 25% of the market.

October 30, 2009 at 9:25 AM
Vinny Benson

how do we get the length of the media?

November 11, 2009 at 1:05 AM
Anonymous

muito loko

November 17, 2009 at 2:09 PM
Anonymous

i am necessited of the help, 1 site exemply for the ID3, peoples me help.
do when used the id3 is necessary more what?
thank you very much

November 18, 2009 at 11:01 AM
Anonymous

I'm in need of help, 1 sample site to use ID3, please help me
I can not make it work. what does the id3 on one site? more than I need to use the id3?
thank you very much

November 18, 2009 at 11:04 AM
Beben Koben

i think this owner smart ... ugh!!!

January 19, 2010 at 8:40 AM
Thomas

So how hard is it to get it to work for ID3v2? Gona look into this myself as I need it.

February 12, 2010 at 7:02 PM
antimatter15

I wrote a JS ID3v2 parser, it's not the prettiest thing, but it seems to work. I haven't tested it in anything other than the Chromium nightlies, but hopefully it'll work:)

http://github.com/antimatter15/js-id3v2

July 9, 2010 at 5:46 PM
Jacob Seidelin

@antimatter15: Nice work! Hopefully that will help the people requesting v2 support.

July 12, 2010 at 11:58 PM
rogermar

I want to get music file details like 'file name', 'song name', 'size', 'artist', 'length','ratings' etc. This is required for my website. The user should click a button on the site and a popup should come, where he can select which folder contains the mp3 files. Then the popup program should create the necessary data and upload it to the server.

How can I do it using your library?

September 29, 2010 at 8:11 AM
fump

How about m4a and ogg ?

April 9, 2012 at 12:40 PM
Unknown

Opera will work now that they are cozying up to Google now... :-/

May 20, 2013 at 1:07 AM
Unknown

Opera will work now that they are cozying up to Google now... :-/

May 20, 2013 at 1:07 AM
Johnson Dada

This is great thanks

July 31, 2013 at 3:59 AM
Unknown

Hey men, really thanx for that lib, but there is so many syntax errors =_=

i.e., if you declare a function through "var", then you have to end statement with semicolon ";".

Firefox swallows that code, but Chrome didn't till I fixed all syntax errors.
"use strict" is not an option.
Anyway, thanks.

February 21, 2014 at 6:42 PM
இரா. வசந்த குமார்.

Hi...
Thanks for the code. It is really helpful.

Is it possible to extract the album cover pic from mp3 file using your script?

-Vasanth

June 17, 2014 at 3:38 AM
இரா. வசந்த குமார்.

Hi...
Thanks for the code. It is really helpful.

Is it possible to extract the album cover pic from mp3 file using your script?

-Vasanth

June 17, 2014 at 3:38 AM
Post a Comment