Sound-Beispiel: Podcast-PlayerFlash Player 9 und höher, Adobe AIR 1.0 und höher Ein Podcast ist eine über das Internet verteilte Sounddatei, die entweder speziell angefordert oder abonniert wurde. Podcasts werden in der Regel als Serie veröffentlicht, die auch als ein Podcast-Kanal bezeichnet wird. Da Podcast-Episoden zwischen einer Minute und mehreren Stunden umfassen können, werden sie im Allgemeinen während der Wiedergabe gestreamt. Podcast-Episoden, die auch als Objekte bezeichnet werden, liegen in der Regel im MP3-Format vor. Auch Video-Podcasts sind sehr populär. Diese Beispielanwendung gibt jedoch nur Audio-Podcasts wieder, die MP3-Dateien verwenden. Dieses Beispiel ist keine Podcast Aggregator-Anwendung mit vollständigem Funktionsumfang. Beispielsweise verwaltet sie keine Abonnements von bestimmten Podcasts oder speichert Aufzeichnungen darüber, welche Podcasts der Benutzer bereits gehört hat. Sie kann jedoch als Startpunkt für einen Podcast-Aggregator mit einem größeren Funktionsumfang dienen. Das Beispiel „Podcast Player“ veranschaulicht die folgenden ActionScript-Programmiertechniken:
Die Anwendungsdateien für dieses Beispiel finden Sie auf www.adobe.com/go/learn_programmingAS3samples_flash_de. Die Dateien der Anwendung „Podcast Player“ befinden sich im Ordner „Samples/PodcastPlayer“. Die Anwendung umfasst die folgenden Dateien:
Lesen von RSS-Daten eines Podcast-KanalsZunächst liest die Anwendung „Podcast Player“ Informationen über die Anzahl an Podcast-Kanälen und deren Episoden: 1. Als Erstes liest die Anwendung eine XML-Konfigurationsdatei mit einer Liste der Podcast-Kanäle ein und zeigt diese Kanalliste dem Benutzer an. 2. Nachdem der Benutzer einen der Podcast-Kanäle ausgewählt hat, liest das Programm den RSS-Feed des Kanals ein und zeigt eine Liste der Kanalepisoden an. In diesem Beispiel wird die URLLoader utility-Klasse dazu verwendet, um textbasierte Daten von einem remoten Speicherort oder aus einer lokalen Datei zu empfangen. Zunächst erstellt der Podcast Player ein URLLoader-Objekt, um eine Liste der RSS-Feeds im XML-Format aus der Datei „playerconfig.xml“ abzurufen. Dann, wenn der Benutzer einen bestimmten Feed in der Liste markiert, wird ein neues URLLoader-Objekte erstellt, um die RSS-Daten von der URL dieses Feeds zu lesen. Vereinfachen des Ladens und der Soundwiedergabe mithilfe der SoundFacade-KlasseDie ActionScript 3.0-Soundarchitektur ist leistungsfähig, aber komplex. Anwendungen, die nur einfache Funktionen zum Laden und zur Wiedergabe von Sounds umfassen müssen, können mithilfe einer Klasse erstellt werden, die einige der komplexen Funktionen ausblendet, und nur einen einfachen Satz von Methoden aufruft und Ereignissen bereitstellt. In der Welt des Softwaredesigns wird eine solche Klasse als facade (Fassade) bezeichnet. Die SoundFacade-Klasse stellt eine einfache Schnittstelle für die folgenden Aufgaben bereit:
Die SoundFacade-Klasse versucht, den wichtigsten Teil der Funktionsmerkmale der ActionScript-Soundklassen bei geringerer Komplexität bereitzustellen. Im folgenden Code wird die Deklaration der Klasse, der Klasseneigenschaften und der SoundFacade()-Konstruktormethode gezeigt: 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();
}
}
Die SoundFacade-Klasse erweitert die EventDispatcher-Klasse, sodass sie eigene Ereignisse auslösen kann. Zunächst deklariert der Klassencode Eigenschaften für ein Sound- und ein SoundChannel-Objekt. Außerdem speichert die Klasse den URL-Wert der Sounddatei und eine bufferTime-Eigenschaft, die beim Streamen des Sounds verwendet werden. Weiterhin akzeptiert sie einige boolesche Parameterwerte, die sich auf das Verhalten beim Laden und bei der Wiedergabe auswirken:
Der bufferTime-Parameter hat einen Standardwert von -1. Wenn die Konstruktormethode einen negativen Wert im bufferTime-Parameter erfasst, stellt sie die bufferTime-Eigenschaft auf den Wert SoundMixer.bufferTime ein. Damit kann die Anwendung den globalen SoundMixer.bufferTime-Wert als Standardwert annehmen. Wenn der autoLoad-Parameter auf true gesetzt ist, ruft die Konstruktormethode unmittelbar die folgende load()-Methode auf, um das Laden der Sounddatei zu starten: 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);
}
Die load()-Methode erstellt ein neues Sound-Objekt und fügt Listener für alle wichtigen Soundereignisse hinzu. Dann weist sie das Sound-Objekt an, die Sounddatei zu laden. Dabei verwendet sie ein SoundLoaderContext-Objekt, um den bufferTime-Wert zu übergeben. Da die url-Eigenschaft geändert werden kann, können mit einer SoundFacade-Instanz verschiedene Sounddateien nacheinander wiedergegeben werden: Ändern Sie einfach die url-Eigenschaft und rufen Sie die load()-Methode auf – die neue Sounddatei wird geladen. Die folgenden drei Ereignis-Listener-Methoden zeigen, wie das SoundFacade-Objekt den Ladefortschritt verfolgt und dann entscheidet, wann der Sound wiedergegeben wird: 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();
}
}
Die onLoadOpen()-Methode wird ausgeführt, wenn das Laden des Sounds beginnt. Wenn der Sound im Streaming-Modus wiedergegeben werden kann, stellt die onLoadComplete()-Methode das isReadyToPlay-Flag direkt auf true ein. Das isReadyToPlay-Flag legt fest, ob die Anwendung die Soundwiedergabe starten kann, eventuell als Reaktion auf eine Benutzeraktion wie das Klicken auf die Wiedergabe-Schaltfläche. Die SoundChannel-Klasse verwaltet die Pufferung der Sounddaten, es ist also nicht erforderlich, explizit zu überprüfen, ob ausreichend Daten geladen wurden, bevor die play()-Methode aufgerufen wird. Die onLoadProgress()-Methode wird während des Ladeprozesses in regelmäßigen Abständen ausgeführt. Sie sendet einfach einen Klon ihres ProgressEvent-Objekts für den Code, der dieses SoundFacade-Objekt verwendet. Nachdem die Sounddaten vollständig geladen wurden, wird die onLoadComplete()-Methode ausgeführt, die bei Bedarf die play()-Methode für nicht gestreamte Sounds aufruft. Die play()-Methode wird im Folgenden gezeigt. 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();
}
}
}
Die play()-Methode ruft die Sound.play()-Methode auf, wenn der Sound bereit zur Wiedergabe ist. Das resultierende SoundChannel-Objekt wird in der sc-Eigenschaft gespeichert. Dann erstellt die play()-Methode ein Timer-Objekt, das in regelmäßigen Abständen Wiedergabefortschrittsereignisse auslöst. Anzeigen des WiedergabefortschrittsDas Erstellen eines Timer-Objekts zur Steuerung der Wiedergabeüberwachung ist ein komplexer Vorgang, den Sie jedoch nur einmal ausführen müssen. Durch die Kapselung dieser Timer-Logik in eine wiederverwendbare Klasse wie die SoundFacade-Klasse können Anwendungen auf die gleichen Fortschrittsereignisse überwachen, wenn ein Sound geladen und wenn er wiedergegeben wird. Das Timer-Objekt wird von der SoundFacade.play()-Methode erstellt, die jede Sekunde eine TimerEvent-Instanz auslöst. Die folgende onPlayTimer()-Methode wird immer dann ausgeführt, wenn ein neues TimerEvent-Ereignis eintrifft: 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);
}
Die onPlayTimer()-Methode implementiert die Technik zur Einschätzung der Größe, die im Abschnitt Überwachen der Wiedergabe beschrieben wurde. Dann erstellt sie eine neue ProgressEvent-Instanz mit dem Ereignistyp SoundFacade.PLAY_PROGRESS; die bytesLoaded-Eigenschaft ist auf die aktuelle Position des SoundChannel-Objekts eingestellt und die bytesTotal-Eigenschaft auf die geschätzte Länge der Sounddaten. Unterbrechen und Fortsetzen der WiedergabeDie im vorangegangenen Abschnitt vorgestellte SoundFacade.play()-Methode akzeptiert einen pos-Parameter, der einer Startposition in den Sounddaten entspricht. Wenn der pos-Wert Null beträgt, startet der Sound am Anfang der Datei. Darüber hinaus akzeptiert die SoundFacade.stop()-Methode einen pos-Parameter. Dies wird im Folgenden gezeigt: public function stop(pos:int = 0):void
{
if (this.isPlaying)
{
this.pausePosition = pos;
this.sc.stop();
this.playTimer.stop();
this.isPlaying = false;
}
}
Immer, wenn die SoundFacade.stop()-Methode aufgerufen wird, stellt sie die pausePosition-Eigenschaft so ein, dass die Anwendung weiß, wo sie den Abspielkopf positionieren soll, wenn der Benutzer die Wiedergabe des gleichen Sounds fortsetzen möchte. Die im Folgenden gezeigten Methoden SoundFacade.pause() und SoundFacade.resume() rufen die Methoden SoundFacade.stop() und SoundFacade.play() auf und übergeben jedes Mal einen pos-Parameterwert. public function pause():void
{
stop(this.sc.position);
}
public function resume():void
{
play(this.pausePosition);
}
Die pause()-Methode übergibt den aktuellen SoundChannel.position-Wert an die play()-Methode, die diesen Wert in der pausePosition-Eigenschaft speichert. Die resume()-Methode startet die Wiedergabe des gleichen Sounds mit dem pausePosition-Wert als Startpunkt neu. Aufwerten der Beispielanwendung „Podcast Player“Dieses Beispiel stellt einen Podcast-Player mit Grundfunktionen dar und illustriert die Verwendung der wiederverwendbaren SoundFacade-Klasse. Sie können weitere Funktionen hinzufügen, um diese Anwendung aufzuwerten. Dazu gehören unter anderem folgende Funktionen:
|
|