Architektura dźwięku w programie ActionScript 3.0 ma oferuje ogromne możliwości, lecz jest dość złożona. Aplikacje wymagające wyłącznie podstawowych funkcji, takich jak ładowanie i odtwarzanie dźwięku mogą korzystać z klasy ukrywającej niektóre złożone aspekty aplikacji przez udostępnienie uproszczonych zestawów wywołań metod i zdarzeń. W świecie konstruowania wzorców aplikacji klasa taka zwie się
fasadą
.
Klasa SoundFacade prezentuje pojedynczy interfejs umożliwiający realizację następujących zadań:
-
Ładowanie plików dźwiękowych za pomocą obiektu Sound, obiektu SoundLoaderContext oraz klasy SoundMixer
-
Odtwarzanie plików dźwiękowych za pomocą obiektu Sound oraz obiektu SoundChannel
-
Dysponowanie zdarzeń postępu odtwarzania
-
Wstrzymywanie i wznawianie odtwarzania dźwięków za pomocą obiektu Sound oraz obiektu SoundChannel
Klasa SoundFacade pomaga zaoferować większość funkcjonalności klas związanych z obsługą dźwięku w języku ActionScript w prosty sposób.
Poniższy kod przedstawia deklarację klasy, właściwości klasy oraz metodę konstruktora
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();
}
}
Klasa SoundFacade rozszerza klasę EventDispatcher tak, że może ona dysponować własne zdarzenia. Kod klasy deklaruje najpierw właściwości dla obiektu Sound oraz obiektu SoundChannel. Klasa zapisuje również wartość adresu URL pliku dźwiękowego oraz właściwość
bufferTime
używaną podczas przesyłania strumieniowego dźwięku. Ponadto przyjmuje ona niektóre wartości parametrów typu Boolean wpływające na zachowania podczas lądowania i odtwarzania:
-
Parametr
autoLoad
przekazuje do obiektu informację, że ładowanie dźwięku powinno rozpocząć się możliwie najszybciej po utworzeniu obiektu.
-
Parametr
autoPlay
wskazuje również, że odtwarzanie dźwięku powinno rozpocząć się możliwie szybko po załadowaniu wystarczającej ilości danych dźwiękowych. Jeśli jest to dźwięk przesyłany strumieniowo, odtwarzanie go rozpocznie się niezwłocznie po załadowaniu wystarczającej ilości danych, zgodnie z definicją we właściwości
bufferTime
.
-
Parametr
streaming
wskazuje ponadto, że ten plik dźwiękowy może zacząć być odtwarzany jeszcze przed ukończeniem ładowania.
Parametr
bufferTime
przyjmuje wartość domyślną -1. Jeśli metoda konstruktora wykryje wartość ujemną w parametrze
bufferTime
, ustawi ona właściwość
bufferTime
na wartość odpowiadającą
SoundMixer.bufferTime
. Umożliwia to aplikacji przejście na domyślną wartość globalną
SoundMixer.bufferTime
, gdy tylko będzie taka potrzeba.
W przypadku ustawienia parametru
autoLoad
na wartość
true
metoda konstruktora niezwłocznie wywoła następującą metodę
load()
w celu rozpoczęcia ładowania pliku dźwiękowego:
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);
}
Metoda
load()
tworzy nowy obiekt Sound, a następnie dodaje moduły wykrywania zdarzeń dla wszystkich ważniejszych zdarzeń związanych z dźwiękiem. Następnie przekazuje ona do obiektu Sound polecenie załadowania pliku dźwiękowego za pomocą obiektu SoundLoaderContext, umożliwiającego przekazanie wartości
bufferTime
.
Ponieważ istnieje możliwość zmiany właściwości
url
, instancja SoundFacade może być używana do odtwarzania kolejno różnych plików dźwiękowych: należy po prostu zmienić właściwość
url
i wywołać metodę
load()
, a zostanie załadowany nowy plik dźwiękowy.
Poniższe trzy metody modułu wykrywania zdarzeń ilustrują sposób śledzenia przez obiekt SoundFacade postępu ładowania oraz decydowanie, kiedy ma rozpocząć się odtwarzanie dźwięku:
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();
}
}
Metoda
onLoadOpen()
jest wykonywana po rozpoczęciu ładowania dźwięku. Jeśli dźwięk może być odtwarzany w trybie przesyłania strumieniowego, metoda
onLoadComplete()
niezwłocznie ustawia flagę
isReadyToPlay
na wartość
true
. Flaga
isReadyToPlay
określa, czy aplikacja może rozpocząć odtwarzanie dźwięku, być może w odpowiedzi na czynność wykonaną przez użytkownika, taką jak kliknięcie przycisku Odtwórz. Klasa SoundChannel zarządza buforowaniem danych dźwiękowych, dlatego nie ma potrzeby jawnego sprawdzani, czy załadowana została wystarczająca ilość danych, przed wywołaniem metody
play()
.
Metoda
onLoadProgress()
jest wykonywana okresowo w trakcie całego procesu ładowania. Po prostu dysponuje ona klon jej obiektu ProgressEvent do użycia przez kod korzystający z obiektu SoundFacade.
Po całkowitym załadowaniu danych dźwiękowych wykonywana jest metoda
onLoadComplete()
, wywołująca w razie potrzeby, dla dźwięków niepodlegających przesyłaniu strumieniowemu, metodę
play()
. Samą metodę
play(
) przedstawiono poniżej.
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();
}
}
}
Metoda
play()
wywołuje metodę
Sound.play()
, gdy dźwięk jest gotowy do odtworzenia. Wynikowy obiekt SoundChannel jest zapisywany we właściwości
sc
. Następnie metoda
play()
tworzy obiekt Timer, który będzie używany do dysponowania zdarzeń postępu odtwarzania w regularnych odstępach czasu.