topical media & game development
actionscript-book-PodcastPlayer-com-example-programmingas3-podcastplayer-SoundFacade.ax
actionscript-book-PodcastPlayer-com-example-programmingas3-podcastplayer-SoundFacade.ax
[swf]
flex
package
{
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.events.SecurityErrorEvent;
import flash.events.TimerEvent;
import flash.media.ID3Info;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundLoaderContext;
import flash.media.SoundMixer;
import flash.net.URLRequest;
import flash.utils.Timer;
Provides a slightly simpler interface to the sound-related classes in the
flash.media package. Dispatches "playProgress" ProgressEvents and adds
pause and resume functionality.
public class @ax-actionscript-book-PodcastPlayer-com-example-programmingas3-podcastplayer-SoundFacade extends EventDispatcher
{
The Sound object used to load the sound file.
public var s:Sound;
The SoundChannel object used to play and track playback progess
of the sound.
public var sc:SoundChannel;
The URL of the sound file to load.
public var url:String;
The buffer time to use when loading this object's sound file.
public var bufferTime:int = 1000;
Identifies when the sound file has been fully loaded.
public var isLoaded:Boolean = false;
Identifies when the sound file has been fully loaded.
public var isReadyToPlay:Boolean = false;
Identifies when the sound file is being played.
public var isPlaying:Boolean = false;
Specifies that the sound file can be played while it is being loaded.
public var isStreaming:Boolean = true;
Indicates that sound loading should start as soon as this object is created.
public var autoLoad:Boolean = true;
Indicates that sound playing should start as soon as enough sound data has been loaded.
If this is a streaming sound, playback will begin as soon as enough data, as specified
by the bufferTime property, has been loaded.
public var autoPlay:Boolean = true;
The position of the playhead in the sound data when the playback was last paused.
public var pausePosition:int = 0;
Defines how often to dispatch the playback progress event.
public var progressInterval:int = 1000;
Defines the "playProgress" event type.
public static const PLAY_PROGRESS:String = "playProgress";
The Timer that's used to update the progress display.
public var playTimer:Timer;
Constructor.
public function @ax-actionscript-book-PodcastPlayer-com-example-programmingas3-podcastplayer-SoundFacade(soundUrl:String, autoLoad:Boolean = true, autoPlay:Boolean = true, streaming:Boolean = true, bufferTime:int = -1):void
{
this.url = soundUrl;
// sets boolean values that determine the behavior of this object
this.autoLoad = autoLoad;
this.autoPlay = autoPlay;
this.isStreaming = streaming;
// defaults to the global bufferTime value
if (bufferTime < 0)
{
bufferTime = SoundMixer.bufferTime;
}
// keeps buffer time reasonable, between 0 and 30 seconds
this.bufferTime = Math.min(Math.max(0, bufferTime), 30);
if (autoLoad)
{
load();
}
}
public function load():void
{
if (this.isPlaying)
{
this.stop();
this.s.close();
this.pausePosition = 0;
}
this.isLoaded = false;
this.s = new Sound();
this.s.addEventListener(ProgressEvent.PROGRESS, onLoadProgress);
this.s.addEventListener(Event.OPEN, onLoadOpen);
this.s.addEventListener(Event.COMPLETE, onLoadComplete);
this.s.addEventListener(Event.ID3, onID3);
this.s.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
this.s.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onIOError);
var req:URLRequest = new URLRequest(this.url);
var context:SoundLoaderContext = new SoundLoaderContext(this.bufferTime, true);
this.s.load(req, context);
}
public function onLoadOpen(event:Event):void
{
if (this.isStreaming)
{
this.isReadyToPlay = true;
if (autoPlay)
{
this.play();
}
}
this.dispatchEvent(event.clone());
}
public function onLoadProgress(event:ProgressEvent):void
{
this.dispatchEvent(event.clone());
}
public function onLoadComplete(event:Event):void
{
this.isReadyToPlay = true;
this.isLoaded = true;
this.dispatchEvent(event.clone());
// if the sound hasn't started playing yet, start it now
if (autoPlay && !isPlaying)
{
play();
}
}
public function play(pos:int = 0):void
{
if (!this.isPlaying)
{
if (this.isReadyToPlay)
{
this.sc = this.s.play(pos);
this.sc.addEventListener(Event.SOUND_COMPLETE, onPlayComplete);
this.isPlaying = true;
this.playTimer = new Timer(this.progressInterval);
this.playTimer.addEventListener(TimerEvent.TIMER, onPlayTimer);
this.playTimer.start();
}
else if (this.isStreaming && !this.isLoaded)
{
// start loading again and play when ready
// it appears to resume loading from the spot where it left off...cool
this.load();
return;
}
}
}
public function stop(pos:int = 0):void
{
if (this.isPlaying)
{
this.pausePosition = pos;
this.sc.stop();
this.playTimer.stop();
this.isPlaying = false;
}
if (this.isStreaming && !this.isLoaded)
{
// stop streaming
this.s.close();
this.isReadyToPlay = false;
}
}
public function pause():void
{
stop(this.sc.position);
}
public function resume():void
{
play(this.pausePosition);
}
public function get isPaused():Boolean
{
return (this.pausePosition > 0)
}
public function onPlayComplete(event:Event):void
{
this.pausePosition = 0;
this.playTimer.stop();
this.isPlaying = false;
this.dispatchEvent(event.clone());
}
public function onID3(event:Event):void
{
try
{
var id3:ID3Info = event.target.id3;
for (var propName:String in id3)
{
trace(propName + " = " + id3[propName]);
}
}
catch (err:SecurityError)
{
trace("Could not retrieve ID3 data.");
}
}
public function get id3():ID3Info
{
return this.s.id3;
}
public function onIOError(event:IOErrorEvent):void
{
trace("@ax-actionscript-book-PodcastPlayer-com-example-programmingas3-podcastplayer-SoundFacade.onIOError: " + event.text);
this.dispatchEvent(event.clone());
}
public function onPlayTimer(event:TimerEvent):void
{
var estimatedLength:int =
Math.ceil(this.s.length / (this.s.bytesLoaded / this.s.bytesTotal));
var progEvent:ProgressEvent =
new ProgressEvent(PLAY_PROGRESS, false, false, this.sc.position, estimatedLength);
this.dispatchEvent(progEvent);
}
}
}
(C) Æliens
27/08/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.