De ActionScript 3.0-geluidsarchitectuur is krachtig, maar complex. In toepassingen waarvoor alleen elementaire functies voor het laden en afspelen en geluiden nodig zijn, kan een klasse worden gebruikt waarmee de complexiteit deels wordt verborgen door een vereenvoudigde set methodeaanroepen en gebeurtenissen te bieden. In de wereld van softwareontwerppatronen wordt een dergelijke klasse een
facade
genoemd.
De klasse SoundFacade biedt één enkele interface voor het uitvoeren van de volgende taken:
-
Geluidsbestanden laden met behulp van een object Sound, een object SoundLoaderContext en de klasse SoundMixer
-
Geluidsbestanden afspelen met behulp van het object Sound en het object SoundChannel
-
Gebeurtenissen over de voortgang van het afspelen verzenden
-
Het afspelen van het geluid onderbreken en hervatten met behulp van het object Sound en het object SoundChannel
De klasse SoundFacade probeert het merendeel van de functionaliteit van de ActionScript-geluidsklassen te bieden en daarbij de complexiteit beperkt te houden.
In de volgende code worden de klassendeclaratie, de klasseneigenschappen en de constructormethode
SoundFacade()
weergegeven:
public class SoundFacade extends EventDispatcher
{
public var s:Sound;
public var sc:SoundChannel;
public var url:String;
public var bufferTime:int = 1000;
public var isLoaded:Boolean = false;
public var isReadyToPlay:Boolean = false;
public var isPlaying:Boolean = false;
public var isStreaming:Boolean = true;
public var autoLoad:Boolean = true;
public var autoPlay:Boolean = true;
public var pausePosition:int = 0;
public static const PLAY_PROGRESS:String = "playProgress";
public var progressInterval:int = 1000;
public var playTimer:Timer;
public function 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), 30000);
if (autoLoad)
{
load();
}
}
De klasse SoundFacade vormt een uitbreiding van de klasse EventDispatcher, zodat deze eigen gebeurtenissen kan verzenden. In de klassencode worden eerst eigenschappen voor een object Sound en een object SoundChannel gedeclareerd. In de klasse wordt ook de waarde van de URL van het geluidsbestand opgeslagen, evenals de eigenschap
bufferTime
voor gebruik bij streaming van het geluid. Bovendien worden er bepaalde Booleaanse parameterwaarden geaccepteerd, die invloed hebben op het laad- en afspeelgedrag:
-
Via de parameter
autoLoad
krijgt het object de opdracht om met het laden van het geluid te beginnen zodra dit object is gemaakt.
-
Met de parameter
autoPlay
wordt aangegeven dat het afspelen van het geluid moet starten zodra er voldoende geluidsgegevens zijn geladen. Als dit streaming geluid betreft, wordt het afspelen gestart zodra er voldoende gegevens, zoals opgegeven door de eigenschap
bufferTime
, zijn geladen.
-
Met de parameter
streaming
wordt aangegeven dat er met het afspelen van dit geluidsbestand kan worden begonnen voordat het laden is voltooid.
De parameter
bufferTime
is standaard ingesteld op -1. Als de constructormethode een negatieve waarde in de parameter
bufferTime
detecteert, wordt de eigenschap
bufferTime
ingesteld op de waarde van
SoundMixer.bufferTime
. Zo kan de toepassing desgewenst standaard worden ingesteld op de algemene waarde van
SoundMixer.bufferTime
.
Als de parameter
autoLoad
op
true
is ingesteld, roept de constructormethode onmiddellijk de volgende methode
load()
aan om te beginnen met het laden van het geluidsbestand:
public function load():void
{
if (this.isPlaying)
{
this.stop();
this.s.close();
}
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);
}
Met de methode
load()
wordt een nieuw object Sound gemaakt, waarna listeners voor alle belangrijke geluidsgebeurtenissen worden toegevoegd. Vervolgens krijgt het object Sound de opdracht het geluidsbestand te laden, waarbij een object SoundLoaderContext wordt gebruikt om de waarde voor
bufferTime
door te geven.
Aangezien de eigenschap
url
kan worden gewijzigd, kan er een instantie SoundFacade worden gebruikt om verschillende geluidsbestanden na elkaar af te spelen: wijzig eenvoudig de eigenschap
url
en roep de methode
load()
aan; het nieuwe geluidsbestand wordt geladen.
De volgende drie methoden voor gebeurtenislisteners laten zien hoe het object SoundFacade de voortgang van het laden traceert en bepaalt wanneer er wordt gestart met het afspelen van het geluid:
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(evt.clone());
if (autoPlay && !isPlaying)
{
play();
}
}
De methode
onLoadOpen()
wordt uitgevoerd zodra het laden van het geluid wordt gestart. Als het geluid in streaming modus kan worden afgespeeld, stelt de methode
onLoadComplete()
de markering
isReadyToPlay
direct in op
true
. De markering
isReadyToPlay
bepaalt of de toepassing met het afspelen van het geluid kan beginnen, bijvoorbeeld na een bepaalde gebruikershandeling, zoals het klikken op een afspeelknop. De klasse SoundChannel beheert de buffering van geluidsgegevens, wat betekent dat het niet nodig is om expliciet te controleren of er voldoende gegevens zijn geladen voordat de methode
play()
wordt aangeroepen.
De methode
onLoadProgress()
wordt periodiek aangeroepen tijdens het laadproces. Er wordt een kloon van het object ProgressEvent verzonden, die kan worden gebruikt door code die gebruikmaakt van dit object SoundFacade.
Wanneer de geluidsgegevens volledig zijn geladen, wordt de methode
onLoadComplete()
uitgevoerd en wordt zo nodig de methode
play()
voor niet-streaming geluiden aangeroepen. De methode
play(
) zelf wordt hieronder weergegeven.
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();
}
}
}
De methode
play()
roept de methode
Sound.play()
aan als het geluid gereed is om te worden afgespeeld. Het resulterende object SoundChannel wordt opgeslagen in de eigenschap
sc
. De methode
play()
maakt vervolgens een object Timer dat wordt gebruikt om gebeurtenissen over de voortgang van het afspelen met een regelmatig interval te verzenden.