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.6 discussed 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.
|