Displaying a dynamically loaded MP3 file’s ID3 information in ActionScript 2.0 and ActionScript 3.0

by Peter deHaan on March 1, 2008

in Sound, migration

The following examples show how you can dynamically load an external MP3 file and display it’s ID3 information in ActionScript 2.0 and ActionScript 3.0 using the Sound class and id3 property.

Full code after the jump.

The following example shows how you can display an MP3 file’s ID3 information using the onID3 event handler and the Sound object’s id3 property in ActionScript 2.0:

// ActionScript 2.0
/**
 * Requires:
 *  - A TextArea component on the Stage with an instance name of "textArea".
 */
var url:String = "http://www.helpexamples.com/flash/sound/song2.mp3";
var sound:Sound = new Sound();
sound.onID3 = function():Void {
    textArea.text += "album" + ":\t" + sound.id3.album + "\n";
    textArea.text += "artist" + ":\t" + sound.id3.artist + "\n";
    textArea.text += "comment" + ":\t" + sound.id3.comment + "\n";
    textArea.text += "genre" + ":\t" + sound.id3.genre + "\n";
    textArea.text += "songname" + ":\t" + sound.id3.songname + "\n";
    textArea.text += "track" + ":\t" + sound.id3.track + "\n";
    textArea.text += "year" + ":\t" + sound.id3.year + "\n";
    textArea.text += "-------------------";
}
sound.loadSound(url, true);

The following example shows how you can display an MP3 file’s ID3 information using the ID3 event and the Sound object’s id3 property in ActionScript 3.0:

// ActionScript 3.0
/**
 * Requires:
 *  - A TextArea component on the Stage with an instance name of "textArea".
 */
var url:String = "http://www.helpexamples.com/flash/sound/song2.mp3";
var urlRequest:URLRequest = new URLRequest(url);
var sound:Sound = new Sound();
sound.addEventListener(Event.ID3, sound_id3);
sound.load(urlRequest);
sound.play();
 
function sound_id3(evt:Event):void {
    textArea.text += "album" + ":\t" + sound.id3.album + "\n";
    textArea.text += "artist" + ":\t" + sound.id3.artist + "\n";
    textArea.text += "comment" + ":\t" + sound.id3.comment + "\n";
    textArea.text += "genre" + ":\t" + sound.id3.genre + "\n";
    textArea.text += "songName" + ":\t" + sound.id3.songName + "\n";
    textArea.text += "track" + ":\t" + sound.id3.track + "\n";
    textArea.text += "year" + ":\t" + sound.id3.year + "\n";
    textArea.text += "-------------------";
}

(flash.media::ID3Info)#0
  album = “Tragic Sounds”
  artist = “Macromedia”
  comment = ” 0000005C 00000132 000006C4″
  genre = “136″
  songName = “Song Two”
  track = “2″
  year = “2004″

{ 21 comments… read them below or add one }

1 Andrew Koop 12.10.08 at 1:13 pm

If I wanted to pull an mp3 from an xml file and know I need to replace

var url:String = "http://www.helpexamples.com/flash/sound/song2.mp3";

I’ve been trying to use the following code (item_url is in my xml file)

// ActionScript 2.0
var item_url:Sound = new Sound();
item_url.loadSound(url,true);

Any advice will be appreciated. :)

2 Andrew Koop 12.10.08 at 1:16 pm

Ack, sorry for the nonsensical first sentence. I meant to say that I want to pull a dynamic mp3 from an xml file. I’m working on a slideshow and have audio that corresponds to each photo.

3 Peter deHaan 12.10.08 at 1:47 pm

Andrew Koop,

What does the XML file look like?

Peter

4 Andrew Koop 12.11.08 at 6:17 am

Thanks for your reply. XML is as follows:

<item filename="slide1.jpg"
    title="Indiana University Michael Maurer School of Law"
    description="Dean Lauren Robel, IU Foundation President Gene Tempel, Janie Maurer, Michael S. “Mickey” Maurer, and IU President Michael McRobbie sign the gift agreement."
    name=""
    url="a_new_name.mp3">

There are 15 items laid out in this same way. Does that help give an idea?

5 Peter deHaan 12.11.08 at 7:05 am

Andrew Koop,

OK, well, the url and filename are XML attributes, so you’d need to prefix the attribute name with a “@”. For example, the following code will loop over the item nodes in the XML and trace the @filename, @title, and @url attributes:

// ActionScript 3.0
var itemsXML:XML = <items>
            <item filename="slide1.jpg"
                    title="Title 1"
                    description="Description 1"
                    name=""
                    url="audio1.mp3" />
            <item filename="slide2.jpg"
                    title="Title 2"
                    description="Description 2"
                    name=""
                    url="audio2.mp3" />
            <item filename="slide3.jpg"
                    title="Title 3"
                    description="Description 3"
                    name=""
                    url="audio3.mp3" />
        </items>;
 
var idx:uint;
var len:uint = itemsXML.item.length();
var node:XML;
 
for (idx = 0; idx < len; idx++) {
    node = itemsXML.item[idx];
    trace(node.@title, "|", node.@filename, "|", node.@url);
}

Which displays the following output:

Title 1 | slide1.jpg | audio1.mp3
Title 2 | slide2.jpg | audio2.mp3
Title 3 | slide3.jpg | audio3.mp3

So depending on how you’re loading the XML and looping over the nodes, your code may look something like the following:

var mp3_url:String = node.@url;
 
var item_url:Sound = new Sound();
item_url.loadSound(mp3_url, true);

Peter

6 Andrew Koop 12.11.08 at 7:18 am

Thanks so much! I’ll give it a try. :)

7 Andrew Koop 12.11.08 at 7:39 am

I’ve replaced the old with this

// ActionScript 2.0
item.fm_button.onRelease = function() {
    var mp3_url:String = node.@url;
    var item_url:Sound = new Sound();
    item_url.loadSound(mp3_url, true);
}

and I’m getting fieldname and unexpected } encountered errors. I’ve added the XML that you posted to the end of the file.

Any ideas?

Thanks :)

8 Andrew Koop 12.11.08 at 7:51 am

Would it be easiest if I posted my whole actionscript layer?

9 Peter deHaan 12.11.08 at 8:06 am

Sorry,

For some reason I assumed we were all using ActionScript 3.0 (although that loadSound() should have tipped me off).

Let me see if I can figure out how to do this easily in ActionScript 2.0… [dramatic pause]

OK, this should work. I copied the XML into an external file, items.xml, and saved the .FLA and .XML files in the same directory.

// ActionScript 2.0
var itemsXML:XML = new XML();
itemsXML.ignoreWhite = true;
itemsXML.onLoad = itemsXML_onLoad;
itemsXML.load("items.xml");
 
function itemsXML_onLoad(success:Boolean):Void {
    if (!success) {
        trace("Unable to load/parse XML. Aborting.");
        return;
    }
 
    var idx:Number;
    var len:Number = itemsXML.firstChild.childNodes.length;
    var node:XML;
 
    for (idx = 0; idx < len; idx++) {
        node = itemsXML.firstChild.childNodes[idx];
        trace(node.attributes.title + " | " + node.attributes.filename + " | " + node.attributes.url);
    }
}

Running that should output the same results as our ActionScript 3.0 example;

Title 1 | slide1.jpg | audio1.mp3
Title 2 | slide2.jpg | audio2.mp3
Title 3 | slide3.jpg | audio3.mp3

So now if you wanted to get to a certain node’s url attribute, you could probably do something like the following:

// ActionScript 2.0
item.fm_button.onRelease = function() {
    var mp3_url:String = itemsXML.firstChild.childNodes[idx].attributes.url;
    var item_url:Sound = new Sound();
    item_url.loadSound(mp3_url, true);
}

The only real “gotcha” is that you’d need to have some “idx” variable somewhere tracking which child node index you wanted in the XML file.

Hope that helps,
Peter

10 Andrew Koop 12.11.08 at 8:11 am

Hey, sorry. I should have mentioned that I am using 2 for this file. I’ll give this a whirl. Thanks again. I really appreciate your help.

11 Andrew Koop 12.11.08 at 8:30 am

My apologies for the super amount of code here, but I think this might help explain what I have going on in the file. I’ve inserted your actionscript, but I’m thinking I only need a portion of it. Would you mind taking a looking and letting me know what you think?

// ActionScript 2.0
stop();
 
import mx.transitions.Tween;
import mx.transitions.easing.*;
 
flashmo_item._visible = false;
item_number_group.item_number._visible = false;
 
var xml_file:String = "items.xml";
var folder:String = "thumbnails/";
var auto_duration:Number = 5000;// where 1 second equals 1000
var auto_play:Boolean = false;// true = ON | false = OFF
var tween_duration:Number = 0.6;// in seconds
 
var item_filename:Array = new Array();
var item_url:Array = new Array();
var item_url_target:Array = new Array();
var item_title:Array = new Array();
var item_description:Array = new Array();
var item_name:Array = new Array();
var item_sound:Array = new Array();
var total:Number;
var i:Number;
var interval_id:Number;
var current:Number = 0;
var xml:XML = new XML();
 
xml.onLoad = function() {
    item_list.fm_item._visible = false;
    var nodes = this.firstChild.childNodes;
    total = nodes.length;
 
    for (i=0; i < total; i++) {
        item_filename[i] = nodes[i].attributes.filename;
        item_url[i] = nodes[i].attributes.url;
        item_url_target[i] = nodes[i].attributes.target;
        item_title[i] = nodes[i].attributes.title;
        item_description[i] = nodes[i].attributes.description;
        item_name[i] = nodes[i].attributes.name;
 
    }
    create_item_list();
};
xml.load(xml_file);
xml.ignoreWhite = true;
 
function create_item_list():Void {
    for (i=0; i0) {
            item._visible = false;
        }
 
        item.fm_button.onRelease = function() {
 
var itemsXML:XML = new XML();
itemsXML.ignoreWhite = true;
itemsXML.onLoad = itemsXML_onLoad;
itemsXML.load("items.xml");
 
function itemsXML_onLoad(success:Boolean):Void {
    if (!success) {
        trace("Unable to load/parse XML. Aborting.");
        return;
    }
 
    var idx:Number;
    var len:Number = itemsXML.firstChild.childNodes.length;
    var node:XML;
 
    for (idx = 0; idx < len; idx++) {
        node = itemsXML.firstChild.childNodes[idx];
        trace(node.attributes.url);
    }
}
 
        var mi = item_number_group.item_number.duplicateMovieClip("item_number"+i, i);
        mi.over = true;
        mi.item_label = i+1;
        mi.item_no = i;
        mi._x = i*30;
    }
    if (auto_play == true) {
        interval_id = setInterval(this, "change_item", auto_duration, "next");
    }
    change_menu_item(0);// the default item on load
}
function change_item(command) {
    fm_previous.enabled = fm_next.enabled=false;
 
    for (i=0; i < total; i++) {
        item_number_group["item_number"+i].flashmo_button.enabled = false;
    }
    old_number = current;
 
    if (command == "previous") {
        current--;
    } else if (command == "next") {
        current++;
    } else {
        current = command;
 
    }
    if (current=total) {
        current = 0;
    }
 
    change_menu_item(current);
 
    old_item = this["fm_item"+old_number];
    old_item.fm_button.enabled = false;
    new_item = this["fm_item"+current];
    new_item.fm_button.enabled = true;
    new_item._visible = true;
 
 
    var fm_tween = new Tween(old_item, "_alpha", Regular.easeInOut, 100, 0, tween_duration, true);
    new Tween(new_item, "_alpha", Regular.easeInOut, 0, 100, tween_duration, true);
    fm_tween.onMotionFinished = function() {
        fm_previous.enabled = fm_next.enabled=true;
        for (i=0; i < total; i++) {
            item_number_group["item_number"+i].flashmo_button.enabled = true;
        }
        old_item._visible = false;
    };
}
 
function fm_interval() {
    if (fm_auto._currentframe == 2) {
        interval_id = setInterval(this, "change_item", auto_duration, "next");
    } else {
        clearInterval(interval_id);
    }
    fm_auto.play();
}
 
fm_previous.onRelease = function() {
    change_item("previous");
};
fm_next.onRelease = function() {
    change_item("next");
};
fm_auto.onRelease = function() {
    this._parent.fm_interval();
};
if (auto_play == true) {
    fm_auto.gotoAndStop(1);
} else {
    fm_auto.gotoAndStop(2);
 
}
function change_menu_item(no):Void {
    for (i=0; i < total; i++) {
        var mi = item_number_group["item_number"+i];
        mi.flashmo_button._visible = true;
        mi.over = true;
        mi.flashmo_button.onRollOver = function() {
            this._parent.over = false;
        };
        mi.flashmo_button.onRollOut = mi.flashmo_button.onDragOut=function () {
            this._parent.over = true;
        };
        mi.flashmo_button.onRelease = function() {
            change_item(this._parent.item_no);
        };
        mi.onEnterFrame = function() {
            if (this.over == true) {
                this.prevFrame();
            } else {
                this.nextFrame();
            }
        };
    }
    delete item_number_group["item_number"+no].flashmo_button.onRollOut;
    item_number_group["item_number"+no].flashmo_button._visible = false;
    item_number_group["item_number"+no].over = false;
}
12 Peter deHaan 12.11.08 at 8:52 am

Andrew Koop,

I actually have to run to work, but I can take a look when/if I get home tonight.

Peter

13 Andrew Koop 12.11.08 at 10:02 am

Awesome. Thanks so much. :)

14 joe bloggs 12.19.08 at 10:17 pm

sound.id3.songName should be sound.id3.songname

15 ProstoVasya 02.06.09 at 1:50 am

Thanks for sharing your knowledge. This is very useful.

16 Phreakizoid 05.31.09 at 7:25 pm

Ok I am making mp3 players. http://www.nukethemes.info as you can see they work ok using an xml file. What i am wondering is there a way to code it to where I can set it to automatically pull the names of the files from a folder sitting on the site and just display the info with out using an xml file or php and sql. I basically want to be able to just upload a file to the music folder and the flash to know to read the file name and display it.

17 Phreakizoid 07.02.09 at 3:30 pm

Ok nevermind i figured this out on my own, and now have it working thanks anyway.

18 shemBadui 07.08.09 at 7:25 am

hi there!
i’m working on building a music player and i’m trying to retrieve the id3 tags for displaying the artwork of the album cover … i’m having a hard time doing that…
any help would be appreciated

19 shemBadui 07.08.09 at 7:28 am

by the way i’m using flashlite 2.0 with actionscript 2.0

20 crsnt 09.19.09 at 5:23 am

Hi,

I’m getting No policy files granted access error (firefox) and tags are not showing (IE and Firefox).
I’ve tried putting crossdomain.xml on the same place as swf file (root).
still not working.

I even used soundcontext with CheckPolicy attribute set to True.

Have you experienced this problem??

Thanks

21 Thi 01.14.10 at 3:43 pm

same problem as above :(

My music are hosted on a free domain, webs.com
So, when I upload an crossdomain.xml, it is substitued by their own crossdomain.xml

Leave a Comment

You can use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

Previous post:

Next post: