Flash MX 2004 MP3 Player Pg.7
source: http://www.thegoldenmean.com/
7 — Major Functions
This paragraph should be replaced by a Flash movie if you have at least version 7 of the Flash Player and your browser has Javascript enabled.
Scripting the Player: the Major Functions
The next few pages are just going to be long tedious blocks of code. Try to stay with me! This page presents the two core functions: doPlay() which should look very familiar to you from previous Player tutorials, and songListLoaded() which is the callback function that executes when the XML playlist has loaded.
All this code resides on frame 14 of the scripts layer. The doPlay() function is the central “engine” of the Player. It clears any previous Sound Object, initializes a new one, starts the info display animations and determines what to do when one song ends.
the doPlay() function
Start by initializing the Player environment:
function doPlay(url:String):Void { //we always want to start with a fresh Sound object, if (typeof myTunes == "object") { myTunes.stop (); delete myTunes; } displayInit(); stopped = false; trackLoaded = false;
Note that doPlay() accepts one argument: the url of the new track to play. The variable stopped is set to false because the Player isn’t stopped at this point, and trackLoaded is set to false because the new track hasn’t yet loaded! The final step in initializing the Player is to reset all buttons and then move the play button to its active state. We do this in case the user had previously paused the Player and then clicked the next or previous button. We don’t want the pause button to still be in it’s active state when the Player is playing.
extinguish(play_mc); controls_mc.play_mc.gotoAndStop("lit");
The extinguish() and displayInit() functions will be covered in more depth on the next page. Briefly, displayInit() clears any setIntervals that might be running and moves the progress bars and infoTxt back to their zero positions; extinguish() makes sure all the buttons are set to their “unlit” states.
The doPlay() function now moves on to play a new song:
myTunes = new Sound (this); myTunes.onLoad = Delegate.create(this, doneStreaming); myTunes.loadSound (url, true); myTunes.setVolume (volume);
In the block of code above, the Sound Object’s onLoad method is used as a convenient and effective device to terminate the streaming progress bar’s animation. Previous tutorials in this series used an awkward “if (getBytesLoaded() == getBytesTotal())” comparison with every tick of the setInterval. It is much cleaner to let the Sound Object itself announce when it has arrived. When the MP3 file has completely downloaded, the Sound Object’s onLoad event fires. Now all the displayStreaming function has to do is check the value of a variable. More on that on the following page. The Delegate Class used here is a very helpful tool for managing scope issues in functions. It is a deeper topic than I can go into here but suggestions for further reding includ articles by Senocular, Daron Schall and Mike Chambers (this last one is quite technical).
Next we create the setIntervals. The first two are responsible for animating the download and position progress bars. The third causes the infoTxt text field to scroll if its content exceeds the width of the text field.
streamingID = setInterval (displayStreaming, 100, myTunes); playingID = setInterval (displayPosition, 100, myTunes); crawlerID = setInterval(textCrawl, 200);
If you are not familiar with setInterval, I’ll take a brief detour to examine one of them. The setInterval function will repeatedly call another function at an interval you determine. In order to move the streaming progress bar, the first setInterval above calls the displayStreaming() function every 100 milliseconds, using the myTunes Sound Object as the argument displayStreaming() requires. Note you do not use the parentheses when you make reference to a function inside of a setInterval. For example the following code would fail:
setInterval (displayStreaming(), 100, myTunes).
Now let’s create the content that gets displayed in the infoTxt text field. We combine data that is stored in three of the arrays, using “ct” (“current track”) as the numeric identifier to get the matching content from each array:
infoTxt.text = titles[ct].nodeValue+ "/"+artists[ct].nodeValue+ "/"+albums[ct].nodeValue;
Finally, tell the Player what to do when the current track ends:
If the play mode is “shuffle”, set the current track (“ct”) to a random number between zero and the maximum (“mt”). Otherwise just invoke nextTrack().
myTunes.onSoundComplete = function () { if (shuffle) { ct = random(mt+1); doPlay(urls[ct].nodeValue); } else { nextTrack (); } }; }
the songListLoaded() callback function
If you downloaded the demo files prior to December 2005 and have upgraded to Flash 8, please download the demo files again. The XPathDocument Object was deprecated in a revision of the XFactorStudio XPath classes. I have updated the ActionScript to work with the current (as of December 2005) version of the XPath Classes, and this update appears to compile successfully with both Flash MX 2004 and Flash 8.) My deep appreciation to axons for pointing out that Flash 8 broke the original demos, and patiently working with me to fix it.
Although we don’t actually load the XML playlist until the very last frame (frame 15), the callback function that is invoked when the data does load is of such critical importance to the Project that I have it here, one of the two major functions. This function first populates the arrays that hold all the track information using the XPath methods. (I really hope you took the time to read the w3schools XPath tutorial or the material at Tankslye’s site xfactorstudio.com.) It then makes the initial call to doPlay() to get the Player started. Pay close attention to the XPath syntax. It is interesting that when XPath selects an attribute it stores the entire string including the quote marks, not the value of the attribute minus the quote signs. To get just the value without the quotes we have to tack “.nodeValue” to every reference to the array content. Recall that the Arrays themselves were declared on the previous page of this tutorial, so they exist already and are waiting to be populated. Also previously declared was plXML (the name I came up with to stand for “playlist XML”), the XML Object which stores the playlist data.
function songListLoaded(success:Boolean):Void { if(success){ //fill arrays using XPath artists = XPath.selectNodes(plXML, "/songs/song/@artist"); titles = XPath.selectNodes(plXML, "/songs/song/@title"); albums = XPath.selectNodes(plXML, "/songs/song/@album"); times = XPath.selectNodes(plXML, "/songs/song/@playtime"); sizes = XPath.selectNodes(plXML, "/songs/song/@filesize"); urls = XPath.selectNodes(plXML, "/songs/song/@url");
Next, attach a value to “mt”, the maximum track variable which was declared previously. Remember to subtract one from the total so as to conform to zero-based Array counting.
mt = titles.length-1;
Finally, check the value of the boolean shuffle variable and invoke the doPlay() function to start the Player going:
if (shuffle){ ct = random(titles.length); doPlay(urls[ct].nodeValue); } else { ct = 0; doPlay(urls[ct].nodeValue); } } }
We are now finished with the biggest two functions, but the Player still needs lots more functionality. Page eight covers what I call the “secondary” functions.
--top--