Flash MX 2004 MP3 Player Pg.8

source: http://www.thegoldenmean.com/

8 — Secondary Functions

Scripting the MP3 player Phase Two: the Secondary Functions

Although I refer to these as “secondary”, they are no less crucial to the workings of the Player. Several of these functions will look familiar from previous tutorials in this series. First we write the three functions that animate the streaming and position progress bars and the infoTxt text field. Recall that these three functions are invoked by setIntervals within the doPlay() function. The two functions that animate the progress bars are very similar. We will look first at the download (or “streaming”) progress bar.

displayStreaming()

The function first checks to see if the MP3 file has completely downloaded. If yes the setInterval is terminated, the dBar_mc is moved to its end position and a brief text message is written. (This little text field was something I made during development. I sort of liked so I kept it. It is entirely optional. You can feel free to eliminate it if you find it annoying or superfluous.)

function displayStreaming (theSource:Object) {
      //check to see if track has finished downloading:
   if (trackLoaded) {
      clearInterval (streamingID);
      output_txt.text="loaded";
      dBar._x = dBar._width;
   } else {

If the data is still downloading, that status is noted in the little text field and the progress bar is moved by an amount that is calculated from the percent loaded and progBarFactor which was defined on page six. This is one of the ways we make the Player adjust to different sized graphics. We don’t care what the pixel dimensions of the progress bar graphic is, we just move it by a relative unit.

   output_txt.text="streaming";
   var percentLoaded:Number = Math.floor((theSource.getBytesLoaded()/
      theSource.getBytesTotal())*100);
         dBar._x = percentLoaded*progBarFactor;
   }
}

doneStreaming()

This tiny function is invoked by the Sound Object’s onLoad method. When the onLoad event occurs this function simply modifies the value of the trackLoaded variable. Every time the displayStreaming() function runs it first checks the value of this variable. As soon as the variable is seen to be “true” displayStreaming() terminates.

function doneStreaming():Void {
   trackLoaded = true;
}

displayPosition()

This is the function which animates the pBar clip, indicating amount of the track that has been played so far. Called by a setInterval in the doPlay() function, this is very similar to the one above with some notable exceptions. One thing you have to watch out for is the possibility that on a slower connection the Player may “catch up” to itself. That is, it might play faster than it downloads. In that case, position does briefly equal duration even though you are not at the end of the song. That can fool the Player into thinking it has finished playing when in fact it obviously hasn’t, making for a certain amount of havoc with the progress bar code. The solution is to see if position equals duration AND bytes loaded equals bytes total. If both conditions aren’t met the Player knows the song hasn’t ended yet.

function displayPosition (theSource:Object) {
   var trackTime:Number = times[ct].nodeValue;
   if (theSource.position > 0) {
         //what to do when the playhead gets to the end of the song
      if (theSource.position == theSource.duration && theSource.getBytesLoaded ()
         == theSource.getBytesTotal ()) {
         clearInterval (playingID);
         pBar._x = pBar._width;
      } else {
         //what to do while the song is still playing
   var playProgress:Number = Math.floor((theSource.position/trackTime)*100);
      pBar._x  = playProgress*progBarFactor;
      }
   }
}

textCrawl()

In contrast to the last two functions, the one that animates the infoTxt text field is relatively simple. Its job is to evaluate whether the text has extended beyond the visible area and, if it has, to scroll the text while the track plays. This allows you to keep a small text field but still pack in a good amount of information. Note that I slide the text field 5 pixels per tick of the setInterval. You can modify this speed of course. Using a larger number speeds up the scroll; a smaller number slows down the scroll.

function textCrawl():Void {
  if(infoTxt.textWidth > infoW) {
    infoTxt._x -= 5;
      //redraw screen
    updateAfterEvent();
  /*--------------------
  check text field position; if it has moved its entire
  length, jump back to beginning. Note we use the myPoint
  Object to use coordinates relative to info_mc, NOT the Stage
  ----------------------*/

    if(infoTxt._x < (myPoint.x - infoTxt.textWidth)) {
      infoTxt._x = myPoint.x + infoW;
    }
  }
}

Next comes a flurry of small functions that are called by buttons and doPlay().

pauseTrack()

If a track is paused instead of stopped we need store its position so it can resume playing where it had been. Remember that the position property is in milliseconds but the offset argument in a Sound Object’s start() method is in seconds so divide position by 1000 to get the offset value

function pauseTrack():Void {
   stopped = false;
   pauseTime = myTunes.position/1000;
   myTunes.stop();
   clearInterval(crawlerID);
   clearInterval(playingID);

}

We stop the infoTxt and pBar animation, but since the file can continue to download while the Player is paused it makes sense to keep the streaming animation running.

stopTrack()

Stopping is different from pausing. Stopping forgets where the track had been which in effect resets the current track to the beginning. The function also must reset the progress bars and infoTxt text field to their starting points

function stopTrack():Void {
   myTunes.stop();
   stopped = true;
   displayInit();

}

nextTrack()

This small function first checks to see if the player is set to shuffle.checks to see if the current track is the last track in the array and if so resets it to the first in the list. Otherwise it increments the current track variable by one. Then it invokes the doPlay() function and passes that function the URL of the new current track. Remember to put in the “.nodeValue” to eliminate the quotation marks stored in the array.

function nextTrack():Void {
    if (shuffle) {
      ct = random(titles.length);
      doPlay(urls[ct].nodeValue);
      } else {
        if (ct == mt) {
          ct = 0;
          doPlay(urls[ct].nodeValue);
          } else {
            ct++;
            doPlay(urls[ct].nodeValue);
          }
        }
      }

prevTrack()

Nearly identical to the previous function, prevTrack() checks to see if the current track is the first track in the array and if so resets it to the last in the list. Otherwise it decrements the current track variable by one.

function prevTrack():Void {
    if (shuffle) {
      ct = random(titles.length);
      doPlay(urls[ct].nodeValue);
      } else {
        if (ct == 0) {
          ct = mt;
          doPlay(urls[ct].nodeValue);
          } else {
            ct--;
            doPlay(urls[ct].nodeValue);
          }
        }
      }

playTrack()

When clicked, the play button has to be smart enough to discern whether the Sound Object has been stopped or paused. The playTrack() function checks the state of the movie. If it is stopped, it calls doPlay on the current track, starting it from the beginning. If the movie is paused (if the value of the "stopped" variable is “false”), it first clears any existing setIntervals, then starts the track using pauseTime as the offset value and finally resumes the setIntervals that animate the displays.

function playTrack():Void {
   if (stopped) {
      doPlay(urls[ct].nodeValue);
   } else {
      clearInterval (streamingID);
      clearInterval (playingID);
      clearInterval (crawlerID);
      myTunes.start(pauseTime);
      playingID = setInterval (displayPosition, 100, myTunes);
      crawlerID = setInterval(textCrawl, 200);

The function checks the download status of the MP3 file. If the track hasn’t finished downloading, the function restarts the streamingID setInterval.

      if(!trackLoaded){
         streamingID = setInterval (displayStreaming, 100, myTunes);
      }
   }
}

displayInit()

When the Sound Object is stopped (not paused), this all the display elements (infoTxt, pBar and dBar) back to their zero points and terminates any running setIntervals. This function is also invoked as part of the initialization routine that doPlay() begins with.

function displayInit():Void {
  clearInterval (streamingID);
  clearInterval (playingID);
  clearInterval (crawlerID);
  //use myPoint to set position relative
  //to info_mc, NOT the Stage
  infoTxt._x = myPoint.x+4;
  pBar._x = 0;
  dBar._x = 0;
}

extinguish()

When you click the pause, stop or play buttons, you want that button to switch to its active state. But you also want any other buttons that might have been active to switch to their inactive state. For instance, when you click “pause” you want that button to light up, but you also want the “play” button to turn off. extinguish() is a quick, easy way to turn “off” all the button clips in the control_mc. This little function uses a for-in loop to breeze through every Object in the controls_mc clip and make sure that any movieclips it finds are sent to their “unlit” frame. We can get away with this because the only movieclip instances in controls_mc are buttons. The stop, pause and play buttons are each individually responsible for setting themselves to the “on” state.

function extinguish(src:MovieClip) {
   var context:MovieClip = src._parent;
   for (var item:String in context) {
      if (typeof context[item] == "movieclip") {
         context[item].gotoAndStop("unlit");
      }
   }
}

We have certainly come a long way. The end is in sight. Page nine discusses the code utilized by the User Interface elements.

go to page: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14
divider ornament

--top--