Flash CS3 Documentation |
|||
| Programming ActionScript 3.0 > Working with sound > Playing sounds > Monitoring playback | |||
Your application might want to know when a sound stops playing so it can start playing another sound, or clean up some resources used during the previous playback. The SoundChannel class dispatches an Event.SOUND_COMPLETE event when its sound finishes playing. Your application can listen for this event and take appropriate action, as shown below [corrected example to load a URLRequest, also to attach event listener to the SoundChannel object: 10/15/07]:
import flash.events.Event;
import flash.media.Sound;
import flash.net.URLRequest;
var snd:Sound = new Sound();
var req:URLRequest = new URLRequest("smallSound.mp3");
snd.load(req);
var channel:SoundChannel = snd.play();
channel.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);
public function onPlaybackComplete(event:Event)
{
trace("The sound has finished playing.");
}
The SoundChannel class does not dispatch progress events during playback. To report on playback progress, your application can set up its own timing mechanism and track the position of the sound playhead.
To calculate what percentage of a sound has been played, you can divide the value of the SoundChannel.position property by the length of the sound data that's being played:
var playbackPercent:uint = 100 * (channel.position / snd.length);
However, this code only reports accurate playback percentages if the sound data was fully loaded before playback began. The Sound.length property shows the size of the sound data that is currently loaded, not the eventual size of the entire sound file. To track the playback progress of a streaming sound that is still loading, your application should estimate the eventual size of the full sound file and use that value in its calculations. You can estimate the eventual length of the sound data using the bytesLoaded and bytesTotal properties of the Sound object, as follows:
var estimatedLength:int =
Math.ceil(snd.length / (snd.bytesLoaded / snd.bytesTotal));
var playbackPercent:uint = 100 * (channel.position / estimatedLength);
The following code loads a larger sound file and uses the Event.ENTER_FRAME event as its timing mechanism for showing playback progress. It periodically reports on the playback percentage, which is calculated as the current position value divided by the total length of the sound data [corrected example so the event listener for SOUND_COMPLETE is attached to the SoundChannel object: 10/15/07]:
import flash.events.Event;
import flash.media.Sound;
import flash.net.URLRequest;
var snd:Sound = new Sound();
var req:URLRequest = new
URLRequest("http://av.adobe.com/podcast/csbu_dev_podcast_epi_2.mp3");
snd.load(req);
var channel:SoundChannel;
channel = snd.play();
addEventListener(Event.ENTER_FRAME, onEnterFrame);
channel.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete);
function onEnterFrame(event:Event):void
{
var estimatedLength:int =
Math.ceil(snd.length / (snd.bytesLoaded / snd.bytesTotal));
var playbackPercent:uint =
Math.round(100 * (channel.position / estimatedLength));
trace("Sound playback is " + playbackPercent + "% complete.");
}
function onPlaybackComplete(event:Event)
{
trace("The sound has finished playing.");
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}
After the sound data starts loading, this code calls the snd.play() method and stores the resulting SoundChannel object in the channel variable. Then it adds an event listener to the main application for the Event.ENTER_FRAME event and another event listener to the SoundChannel object for the Event.SOUND_COMPLETE event that occurs when playback is complete.
Each time the application reaches a new frame in its animation, the onEnterFrame() method is called. The onEnterFrame() method estimates the total length of the sound file based on the amount of data that has already been loaded, and then it calculates and displays the current playback percentage.
When the entire sound has been played, the onPlaybackComplete() method executes, removing the event listener for the Event.ENTER_FRAME event so that it doesn't try to display progress updates after playback is done.
The Event.ENTER_FRAME event can be dispatched many times per second. In some cases, you won't want to display playback progress that frequently. In those cases, your application can set up its own timing mechanism using the flash.util.Timer class; see Working with dates and times.
Flash CS3