Creating an XML Music Player in Flash Using AS3

By Blue_Chi | Flash CS3 | ActionScript 3.0 | Intermediate | Page 1, 2, 3, 4, 5, 6

In the final section of our tutorial we add one final feature and will fix any bugs that might pop up if you decide to make some small variations to the player, we will also polish the code and optimize it. Here is the outline of this section:

  1. Adding a feature for continuous playback.
  2. Fixing possible bugs.
  3. Optimizing the code.

Continuous Playback

Currently our gallery will stop playing once a song finishes, we need to add the feature to make it automatically move to the next song once a track finishes playing. We already written the code used in the onNext function to play the next song. We can make use of this to achieve our goal by registering this function with the Event.SOUND_COMPLETE event. This event is to be registered to the SoundChannel instance. This event is triggered one a sound being played inside a SoundChannel finishes playing. We are going to implement this code inside our playSong() method. Simply update it with the following line:

function playSong(mySong:Number):void{
var myTitle = my_songs[mySong].@TITLE;
var myArtist = my_songs[mySong].@ARTIST;
var myURL = my_songs[mySong].@URL;

title_txt.text = myTitle;
artist_txt.text = myArtist;

if (my_channel){
my_channel.stop();
}

my_sound = new Sound();
my_sound.load(new URLRequest(myURL));
my_channel = my_sound.play();
my_channel.addEventListener(Event.SOUND_COMPLETE, onNext);
}

We are registering our event listener with the same function we used for our next_btn. However, in our previous definition of the onNext listener we explicitly stated that it will be used with a MouseEvent and that no longer is the case as it will be used with a generic event operated by the SoundChannel Class. To make our event listener with any event instead of being restricted for use by a MouseEvent we simply need to change the datatype of it this way:

next_btn.addEventListener(MouseEvent.CLICK, onNext);
function onNext(e:Event):void{ //This used to have MouseEvent, change it to Event.
current_song++;
if (current_song>=my_total){
current_song=0;
}
playSong(current_song);
}

That should do it. The player now will automatically start playing the next song when it finishes playing any song.

Fixing Bugs

You might decide not to have the music player start playing the first song automatically, doing this can be simply done by removing the .playSong() method from within the processXML() event listener.

function processXML(e:Event):void {
var myXML:XML = new XML(e.target.data);

my_songs = myXML.SONG;
my_total = my_songs.length();

playSong(0); // Simply remove this line to stop automatic playback.
}

However, this could generate an errors if you now attempt to press the pause button will generate an error because it is attempting to stop a song when no song is actually playing. To avoid this we can use a conditional to ensure that the pause button code is not executed except when something is actually in the channel, look for the onPause() event listener and update it this way:

pause_btn.addEventListener(MouseEvent.CLICK, onPause);
function onPause(e:MouseEvent):void{
if (my_channel){
song_position = my_channel.position;
my_channel.stop();
song_paused=true;
}
}

We also need to make our play button play the first song instead of attempting to resume a song. To do this we will add another level to our conditional to call the playSong() function. Look for the onPlay() event listener and update it this way:

play_btn.addEventListener(MouseEvent.CLICK, onPlay);
function onPlay(e:MouseEvent):void{
if (song_paused){
my_channel = my_sound.play(song_position);
song_paused=false;
} else if (!my_channel){
playSong(current_song);
}
}

That should do it. Test your movie now to manually start playback.

Optimizing The Code

Good practice urges us to clear all unnecessary variables and unregister all event listeners which are no longer needed. This will help minimize the chances of memory errors and will improve the performance of our Flash movie. In our code here this will require updating the XML loading part of the code as we no longer need some of these assets after we load the XML assets. We will clear our instance of the URLLoader and will unregister the processXML listener as soon as the XML data successfully loads. To do this look for the processXML() event listener and update your code this way:

function processXML(e:Event):void {
var myXML:XML = new XML(e.target.data);

my_songs = myXML.SONG;
my_total = my_songs.length();

playSong(0); // Simply remove this line to stop automatic playback.

myXMLLoader.removeEventListener(Event.COMPLETE, processXML);
myXMLLoader = null;

}

The second place at which we can optimize our code is the playSong() method. We can manually the unregister the event listener registered by the previous instance of the SoundChannel before we attach new content to it as we will register a new event listener for that object again. You can do that by updating the playSong() method this way:

function playSong(mySong:Number):void{
var myTitle = my_songs[mySong].@TITLE;
var myArtist = my_songs[mySong].@ARTIST;
var myURL = my_songs[mySong].@URL;

title_txt.text = myTitle;
artist_txt.text = myArtist;

if (my_channel){
my_channel.stop();
my_channel.removeEventListener(Event.SOUND_COMPLETE, onNext);
}

my_sound = new Sound();
my_sound.load(new URLRequest(myURL));
my_channel = my_sound.play();
my_channel.addEventListener(Event.SOUND_COMPLETE, onNext);
}

These are the only parts of our code which we can easily optimize. Your music player is now ready for deployment! Enjoy.

This concludes our tutorial. I hope that you learnt something new from it. You can download the source file from here. Please feel free to post any questions you have at the Oman3D Forum.

- End of Tutorial