L'architettura audio di ActionScript 3.0 è potente ma complessa. Le applicazioni che richiedono solo funzioni di base di caricamento e riproduzione audio possono utilizzare una classe che nasconde alcune caratteristiche particolarmente complesse fornendo un set semplificato di chiamate a metodi ed eventi. Nel mondo della progettazione software, una classe di questo tipo viene definita
facade
(o “di facciata”).
La classe SoundFacade presenta un'unica interfaccia per eseguire le operazioni seguenti:
-
caricamento dei file audio mediante un oggetto Sound, un oggetto SoundLoaderContext e la classe SoundMixer;
-
riproduzione dei file audio mediante l'oggetto Sound e l'oggetto SoundChannel;
-
invio di eventi progress per la riproduzione;
-
sospensione e ripresa della riproduzione dell'audio mediante l'oggetto Sound e l'oggetto SoundChannel.
La classe SoundFacade ha lo scopo di offrire la maggior parte delle funzionalità delle classi audio di ActionScript ma con un livello inferiore di complessità.
Il codice seguente illustra la dichiarazione della classe, le proprietà della classe e il metodo di costruzione
SoundFacade()
:
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();
}
}
La classe SoundFacade estende la classe EventDispatcher in modo da poter inviare degli eventi propri. Innanzi tutto, il codice della classe dichiara le proprietà di un oggetto Sound e di un oggetto SoundChannel. La classe memorizza anche il valore dell'URL del file audio e una proprietà
bufferTime
da utilizzare quando si utilizza audio in streaming. Inoltre, accetta alcuni valori di parametro booleani che influiscono sul comportamento del caricamento e della riproduzione:
-
Il parametro
autoLoad
indica all'oggetto che il caricamento dell'audio deve iniziare non appena l'oggetto viene creato.
-
Il parametro
autoPlay
indica che la riproduzione dell'audio deve iniziare non appena è stata caricata una quantità sufficiente di dati audio. Se si tratta di audio in streaming, la riproduzione ha inizio non appena è stata caricata la quantità di dati audio specificata dalla proprietà
bufferTime
.
-
Il parametro
streaming
indica che la riproduzione di questo file audio può iniziare prima che ne sia stato completato il caricamento.
Il valore predefinito del parametro
bufferTime
è -1. Se il metodo di costruzione rileva un valore negativo nel parametro
bufferTime
, imposta la proprietà
bufferTime
sul valore di
SoundMixer.bufferTime
. In questo modo, l'applicazione può essere impostata in modo predefinito sul valore
SoundMixer.bufferTime
globale come desiderato.
Se il parametro
autoLoad
è impostato su
true
, il metodo di costruzione chiama immediatamente il metodo
load()
seguente per avviare il caricamento del file audio:
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);
}
Il metodo
load()
crea un nuovo oggetto Sound e successivamente aggiunge i listener per tutti gli eventi audio importanti. Quindi, specifica all'oggetto Sound di caricare il file audio, utilizzando un oggetto SoundLoaderContext per passare il valore
bufferTime
.
Dal momento che la proprietà
url
può essere modificata, è possibile utilizzare un’istanza SoundFacade per riprodurre diversi file audio in successione: per caricare il nuovo file audio, è sufficiente modificare la proprietà
url
e chiamare il metodo
load()
.
I tre eventi del listener di eventi seguenti mostrano il modo in cui l'oggetto SoundFacade tiene traccia dell'avanzamento del caricamento e decide quando iniziare la riproduzione del suono:
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();
}
}
Il metodo
onLoadOpen()
viene eseguito quando inizia il caricamento dell'audio. Se l'audio può essere riprodotto in streaming, il metodo
onLoadComplete()
imposta immediatamente il flag
isReadyToPlay
su
true
. Il flag
isReadyToPlay
determina se l'applicazione può avviare la riproduzione dell'audio, ad esempio in risposta a un'azione dell'utente (come la selezione di un pulsante Riproduci). La classe SoundChannel gestisce la bufferizzazione dei dati audio, pertanto non è necessario verificare se sono stati caricati dati a sufficienza prima di chiamare il metodo
play()
.
Il metodo
onLoadProgress()
viene eseguito periodicamente durante il processo di caricamento. Si limita a inviare un clone del proprio oggetto ProgressEvent per essere utilizzato dal codice che utilizza l'oggetto SoundFacade.
Quando i dati audio sono stati completamente caricati, viene eseguito il metodo
onLoadComplete()
e, se necessario, viene chiamato il metodo
play()
per l'audio non in streaming. Di seguito viene mostrato il metodo
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();
}
}
}
Il metodo
play()
chiama il metodo
Sound.play()
se l'audio è pronto per essere riprodotto. L'oggetto SoundChannel risultante viene memorizzato nella proprietà
sc
. Il metodo
play()
crea quindi un oggetto Timer da utilizzare per inviare eventi progress per la riproduzione a intervalli regolari.