La arquitectura de sonido ActionScript 3.0 es eficaz, pero compleja. Las aplicaciones que solo necesitan funciones básicas de carga y reproducción de sonido pueden utilizar una clase que oculta parte de la complejidad; dicha clase proporciona un conjunto más sencillo de llamadas de método y eventos. En el mundo de los patrones de diseño de software, esta clase se denomina
facade
.
La clase SoundFacade presenta una interfaz única para realizar las tareas siguientes:
-
Cargar archivos de sonido con un objeto Sound, un objeto SoundLoaderContext y la clase SoundMixer
-
Reproducir archivos de sonido con los objetos Sound y SoundChannel
-
Distribuir eventos de progreso de reproducción
-
Pausar y reanudar la reproducción del sonido mediante los objetos Sound y SoundChannel
La clase SoundFacade intenta ofrecer la mayor parte de las funciones de las clase de sonido ActionScript, pero con una menor complejidad.
En el código siguiente se muestra la declaración de clase, las propiedades de clase y el método constructor
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 clase SoundFacade amplía la clase EventDispatcher para que pueda distribuir sus propios eventos. El código de clase declara primero las propiedades de un objeto Sound y un objeto SoundChannel. La clase también almacena el valor del URL del archivo de sonido y una propiedad
bufferTime
que se utilizará al transmitir el sonido. Asimismo, acepta algunos valores de parámetro booleanos que afectan al comportamiento de carga y reproducción.
-
El parámetro
autoLoad
indica al objeto que la carga de sonido debe empezar en cuanto se cree este objeto.
-
El parámetro
autoPlay
indica que la reproducción de sonido debe empezar en cuanto se hayan cargado suficientes datos de sonido. Si se trata de un flujo de sonido, la reproducción empezará tan pronto como se hayan cargado suficientes datos, según especifica la propiedad
bufferTime
.
-
El parámetro
streaming
indica que este archivo de sonido puede empezar a reproducirse antes de que haya finalizado la carga.
El parámetro
bufferTime
se establece de forma predeterminada en un valor de -1. Si el método constructor detecta un valor negativo en el parámetro
bufferTime
, establece la propiedad
bufferTime
en el valor de
SoundMixer.bufferTime
. Esto permite que la aplicación se establezca de forma predeterminada en el valor
SoundMixer.bufferTime
global, según se desee.
Si el parámetro
autoLoad
se establece en
true
, el método constructor llama inmediatamente al siguiente método
load()
para iniciar la carga del archivo de sonido:
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);
}
El método
load()
crea un nuevo objeto Sound y añade detectores para todos los eventos de sonido importantes. A continuación, indica al objeto Sound que cargue el archivo de sonido, mediante un objeto SoundLoaderContext para pasar el valor
bufferTime
.
Puesto que se puede cambiar la propiedad
url
, se puede usar una instancia SoundFacade para reproducir distintos archivos de sonido en secuencia: solo hay que cambiar la propiedad
url
y llamar al método
load()
para que se cargue el nuevo archivo de sonido.
Los tres siguientes métodos de detección de eventos muestran la forma en que el objeto SoundFacade hace un seguimiento del progreso de carga y decide el momento en que se inicia la reproducción del sonido:
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();
}
}
El método
onLoadOpen()
se ejecuta cuando se inicia la carga de sonido. Si se puede reproducir el sonido en el modo de transmisión, el método
onLoadComplete()
establece el indicador
isReadyToPlay
en
true
inmediatamente. El indicador
isReadyToPlay
determina si la aplicación puede empezar a reproducir el sonido, tal vez como respuesta a una acción de usuario, como hacer clic en un botón Reproducir. La clase SoundChannel administra el búfer de los datos de sonido, de modo que no es necesario comprobar explícitamente si se han cargado suficientes datos antes de llamar al método
play()
.
El método
onLoadProgress()
se ejecuta periódicamente durante el proceso de carga. Distribuye un clon de su objeto ProgressEvent que utilizará el código que usa este objeto SoundFacade.
Cuando los datos de sonido se han cargado completamente, se ejecuta el método
onLoadComplete()
y se llama al método
play()
para sonidos que no sean de una transmisión de flujo si es necesario. El método
play()
se muestra a continuación.
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();
}
}
}
El método
play()
llama al método
Sound.play()
si el sonido está listo para reproducirse. El objeto SoundChannel resultante se almacena en la propiedad
sc
. El método
play()
crea un objeto Timer que se utilizará para distribuir eventos de progreso de reproducción a intervalos regulares.