Voorbeeld van geluid: Podcast-spelerFlash Player 9 of hoger, Adobe AIR 1.0 of hoger Een podcast is een geluidsbestand dat via internet wordt gedistribueerd, op aanvraag of in het kader van een abonnement. Podcasts worden meestal gepubliceerd als onderdeel van een reeks, ook wel podcast-kanaal genoemd. Aangezien podcast-afleveringen één minuut, maar ook meerdere uren kunnen duren, worden deze meestal gestreamd tijdens het afspelen. Podcast-afleveringen, ook wel items genoemd, worden meestal aangeleverd in MP3-indeling. Video-podcasts zijn ook populair, maar in deze voorbeeldtoepassing worden alleen audio-podcasts afgespeeld waarvoor MP3-bestanden worden gebruikt. Dit voorbeeld is geen aggregatortoepassing met volledige podcast-functionaliteit. De voorbeeldtoepassing voorziet bijvoorbeeld niet in het beheer van abonnementen op specifieke podcasts en houdt niet bij welke podcasts de gebruiker al heeft beluisterd, zodat deze informatie niet beschikbaar is als de gebruiker de toepassing opnieuw uitvoert. De voorbeeldtoepassing is een goed uitgangspunt voor een aggregator met volledige podcast-functionaliteit. In het voorbeeld van de podcast-speler worden de volgende ActionScript-programmeringstechnieken geïllustreerd:
Zie www.adobe.com/go/learn_programmingAS3samples_flash_nl als u de toepassingsbestanden voor dit voorbeeld wilt downloaden. De bestanden voor de toepassing Podcast Player zijn te vinden in de map Samples/PodcastPlayer. De toepassing bestaat uit de volgende bestanden:
RSS-gegevens voor een podcast-kanaal lezenDe toepassing Podcast Player begint met het lezen van informatie over een aantal podcast-kanalen en corresponderende afleveringen: 1. Eerst leest de toepassing een XML-configuratiebestand met een lijst van podcast-kanalen en geeft een lijst met kanalen voor de gebruiker weer. 2. Wanneer de gebruiker een van de podcast-kanalen selecteert, wordt de RSS-feed voor het kanaal gelezen en wordt een lijst met kanaalafleveringen weergegeven. In dit voorbeeld wordt de hulpprogrammaklasse URLLoader gebruikt om tekstgegevens van een externe locatie of uit een lokaal bestand op te halen. De Podcast Player maakt eerst een object URLLoader om een lijst met RSS-feeds in XML-indeling uit het bestand playerconfig.xml op te halen. Wanneer de gebruiker vervolgens een specifieke feed in de lijst selecteert, wordt een nieuw object URLLoader gemaakt om de RSS-gegevens uit de URL van die feed te lezen. Het laden en afspelen van geluid vereenvoudigen met behulp van de klasse SoundFacadeDe 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:
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:
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. De voortgang van het afspelen weergevenHet maken van een object Timer ter controle van het afspelen is een complexe aangelegenheid, waarvoor u slechts één keer code zou moeten schrijven. Door deze Timer-logica onder te brengen in een herbruikbare klasse zoals de klasse SoundFacade stelt u toepassingen in staat naar dezelfde soorten voortgangsgebeurtenissen te luisteren wanneer een geluid wordt geladen als wanneer het wordt afgespeeld. Het object Timer dat door de methode SoundFacade.play() wordt gemaakt, verzendt elke seconde een instantie TimerEvent. De volgende methode onPlayTimer() wordt uitgevoerd zodra er een nieuwe TimerEvent arriveert: 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); } De methode onPlayTimer() implementeert de techniek voor het schatten van grootte die wordt beschreven in de sectie De status van het afspelen volgen. Vervolgens wordt er een nieuwe instantie ProgressEvent met het gebeurtenistype SoundFacade.PLAY_PROGRESS gemaakt, waarbij de eigenschap bytesLoaded is ingesteld op de huidige positie van het object SoundChannel en de eigenschap bytesTotal is ingesteld op de geschatte lengte van de geluidsgegevens. Afspelen onderbreken en hervattenDe eerder weergegeven methode SoundFacade.play() accepteert de parameter pos, die correspondeert met een startpositie in de geluidsgegevens. Als de waarde van pos nul is, wordt het afspelen van het geluid vanaf het begin gestart. De methode SoundFacade.stop() accepteert ook de parameter pos zoals deze hier wordt weergegeven: public function stop(pos:int = 0):void { if (this.isPlaying) { this.pausePosition = pos; this.sc.stop(); this.playTimer.stop(); this.isPlaying = false; } } Steeds wanneer de methode SoundFacade.stop() wordt aangeroepen, wordt de eigenschap pausePosition zodanig ingesteld dat de toepassing weet waar de afspeelkop moet worden geplaatst als de gebruiker het afspelen van datzelfde geluid wil hervatten. De hieronder weergegeven methoden SoundFacade.pause() en SoundFacade.resume() roepen respectievelijk de methode SoundFacade.stop() en SoundFacade.play() aan, waarbij steeds een waarde voor de parameter pos wordt doorgegeven. public function pause():void { stop(this.sc.position); } public function resume():void { play(this.pausePosition); } De methode pause() geeft de huidige waarde van SoundChannel.position door aan de methode play(), die deze waarde in de eigenschap pausePosition opslaat. De methode resume() begint opnieuw met het afspelen van hetzelfde geluid, waarbij de waarde van pausePosition als startpunt wordt gebruikt. Het Podcast Player-voorbeeld uitbreidenIn dit voorbeeld wordt een elementaire podcast-speler gepresenteerd, waarmee het gebruik van de herbruikbare klasse SoundFacade wordt geïllustreerd. U kunt andere functies toevoegen om het nut van deze toepassing verder uit te breiden, zoals:
|
|