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:
And a bit of JavaScript:
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]
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]
Nice work, Jacob.
August 19, 2008 at 10:26 AM EliPity 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. :(
Songbird implements things like that too in it's JavaScript API.
August 19, 2008 at 12:04 PM AnonymousHi Jacob,
August 19, 2008 at 4:34 PM AnonymousI 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.
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?
August 20, 2008 at 1:03 AM Jacob SeidelinIf 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
@blueberry: You're absolutely right and I should look into that.
August 20, 2008 at 3:31 AM Anonymous@james, johnny: Yea, hopefully there will be some way to get binary data in Opera in the future.
I think i am gonna blog about this. This is a nice topic to blog about
August 20, 2008 at 4:20 AM Andrea GiammarchiJacob, 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 ).
August 20, 2008 at 5:51 AM Andrea GiammarchiUnfortunately, 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 ;)
Jacob, something like that:
August 20, 2008 at 6:02 AM Jacob Seidelinvar 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);
}
};
@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.
August 20, 2008 at 1:17 PM AnonymousAnyway, 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.
yeah that id3v2 is teh real evils =O
August 20, 2008 at 4:42 PM Andrea GiammarchiJacob, you are right. I though they were at the beginning, so blueberry suggestion seems to be the best one for me as well.
August 21, 2008 at 1:35 AM AnonymousAnyway, as last optimization, have you tried to set the range in this way?
bytes=-128
Regards
Can anyone tell me one reason why to do such a thing in AJAX ? Thank you.
August 21, 2008 at 12:57 PM Andrea Giammarchianonymous, 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.
August 21, 2008 at 3:29 PM Jacob SeidelinNow, 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
As Andrea points out, this is about experimenting and making JavaScript do unusual things.
August 22, 2008 at 10:11 AM AnonymousIf your demand for usefulness and reason should be met, this blog would be a sad and empty place.
And timesize? have a request method?
November 5, 2008 at 3:43 AM cephe kaplamaThanks a lot.
June 9, 2009 at 8:08 AM dis cepheThe example page has been updated with the new code.
July 17, 2009 at 3:44 AM Anonymousdoesn't work in internet explorer 6 btw.. which is still unfortunately 25% of the market.
October 30, 2009 at 9:25 AM Vinny Bensonhow do we get the length of the media?
November 11, 2009 at 1:05 AM Anonymousmuito loko
November 17, 2009 at 2:09 PM Anonymousi am necessited of the help, 1 site exemply for the ID3, peoples me help.
November 18, 2009 at 11:01 AM Anonymousdo when used the id3 is necessary more what?
thank you very much
I'm in need of help, 1 sample site to use ID3, please help me
November 18, 2009 at 11:04 AM Beben KobenI can not make it work. what does the id3 on one site? more than I need to use the id3?
thank you very much
i think this owner smart ... ugh!!!
January 19, 2010 at 8:40 AM ThomasSo 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 antimatter15I 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:)
July 9, 2010 at 5:46 PM Jacob Seidelinhttp://github.com/antimatter15/js-id3v2
@antimatter15: Nice work! Hopefully that will help the people requesting v2 support.
July 12, 2010 at 11:58 PM rogermarI 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.
September 29, 2010 at 8:11 AM fumpHow can I do it using your library?
How about m4a and ogg ?
April 9, 2012 at 12:40 PM UnknownOpera will work now that they are cozying up to Google now... :-/
May 20, 2013 at 1:07 AM UnknownOpera will work now that they are cozying up to Google now... :-/
May 20, 2013 at 1:07 AM Johnson DadaThis is great thanks
July 31, 2013 at 3:59 AM UnknownHey men, really thanx for that lib, but there is so many syntax errors =_=
February 21, 2014 at 6:42 PM இரா. வசந்த குமார்.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.
Hi...
June 17, 2014 at 3:38 AM இரா. வசந்த குமார்.Thanks for the code. It is really helpful.
Is it possible to extract the album cover pic from mp3 file using your script?
-Vasanth
Hi...
June 17, 2014 at 3:38 AMThanks for the code. It is really helpful.
Is it possible to extract the album cover pic from mp3 file using your script?
-Vasanth