Recipe 15.9. Tracking the Progress of a Playing Sound


Problem

You want to know where the playhead is in the current song so you can see how much of the song has played, in relation to the full song.

Solution

Use Sound.length to determine how long a song is, and SoundChannel.position to determine how much of it has played.

Discussion

Recipe 15.6discussed how to add a progress bar that not only shows the playing position of a sound file, but also how much of that file has been loaded into the player. That recipe created the part of the bar that showed how much of the song has loaded.

This recipe covers the other part, showing you how to track a sound's progress as it plays. To do this, you'll need to know two things: the length of the sound and its current playing position. Although it may seem counterintuitive, these two properties are found in two different classes. The length of the sound is a property of the Sound object, and the playing position is part of the SoundChannel. Similar to how the buffering progress bar was created, these two values can be compared against each other to get the percentage of the sound that has played.

Unfortunately, it gets just a bit more complex than the buffering bar. The problem is that the length property isn't accurate until the sound file is fully loaded. It actually just shows the length of the loaded data. So, for example, if 10 percent of a 10-minute audio file has loaded so far, then length would report that the file was 1 minute long. (Actually, both length and position report the time in milliseconds, but you can convert that to minutes and seconds if you needed to display the numbers.)

Fortunately, you can do some simple math to get an estimate of the sound file's actual length. Since length reports a fraction of the actual length, if you divide it by that fraction, the result is very close to the true time of the sound. Taking the example just mentioned, length shows a time of one minute. However, that's based on just 1/10th of the file being loaded. If you divide 1 by 1/10 (the same as multiplying by 10), you get 10 minutes as the length of the sound.

The fraction in this case is bytesLoaded/bytesTotal, which has already been calculated and stored in a variable to draw the buffering bar. So all it really takes is one more line of code to correct the length:

length /= percentBuffered;

As in Recipe 15.2, you'll get a more accurate picture of how this works if you access the MP3 file over the web and clear your browser's cache each time.


The following example shows both progress bars together:

package {     import flash.display.Sprite;     import flash.media.Sound;     import flash.media.SoundChannel;     import flash.net.URLRequest;     import flash.events.Event;     public class ProgressBar2 extends Sprite {         private var _sound:Sound;         private var _channel:SoundChannel;                  public function ProgressBar2(  ) {             addEventListener(Event.ENTER_FRAME, onEnterFrame);             _sound = new Sound(new URLRequest("song.mp3"));             _channel = _sound.play(  );         }                  public function onEnterFrame(event:Event):void         {             var barWidth:int = 200;             var barHeight:int = 5;                          var loaded:int = _sound.bytesLoaded;             var total:int = _sound.bytesTotal;                          var length:int = _sound.length;             var position:int = _channel.position;                          // Draw a background bar             graphics.clear(  );             graphics.beginFill(0xFFFFFF);             graphics.drawRect(10, 10, barWidth, barHeight);             graphics.endFill(  );             if(total > 0) {                 // The percent of the sound that has loaded                 var percentBuffered:Number = loaded / total;                 // Draw a bar that represents the percent of                  // the sound that has loaded                 graphics.beginFill(0xCCCCCC);                 graphics.drawRect(10, 10,                                    barWidth * percentBuffered,                                   barHeight);                 graphics.endFill(  );                                  // Correct the sound length calculation                 length /= percentBuffered;                                    // The percent of the sound that has played                   var percentPlayed:Number = position / length;                 // Draw a bar that represents the percent of                  // the sound that has played                 graphics.beginFill(0x666666);                 graphics.drawRect(10, 10,                                    barWidth * percentPlayed,                                   barHeight);                 graphics.endFill(  );             }         }     }     }

See Also

Recipe 15.1 for information on how to load external sound files and Recipe 15.2.




ActionScript 3. 0 Cookbook
ActionScript 3.0 Cookbook: Solutions for Flash Platform and Flex Application Developers
ISBN: 0596526954
EAN: 2147483647
Year: 2007
Pages: 351

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net