Ejemplo de sonido: Podcast PlayerFlash Player 9 y posterior, Adobe AIR 1.0 y posterior Una emisión podcast es un archivo de sonido que se distribuye por Internet, bajo demanda o por suscripción. Las emisiones podcast suelen publicarse como parte de una serie (denominada "canal podcast"). Puesto que los episodios de emisiones podcast pueden durar entre un minuto y muchas horas, normalmente se transmiten mientras se reproducen. Los episodios de emisiones podcast, también denominados "elementos", se suelen transmitir en formato MP3. Las emisiones podcast de vídeo gozan de una gran popularidad, pero esta aplicación de ejemplo sólo reproduce emisiones podcast de audio que utilizan archivos MP3. Este ejemplo no constituye un agregador de emisiones podcast completo. Por ejemplo, no gestiona suscripciones a emisiones podcast específicas ni recuerda las emisiones podcast que ha escuchado el usuario la próxima vez que se ejecuta la aplicación. Podría servir de punto de partida para un agregador de emisiones podcast más completo. El ejemplo de Podcast Player ilustra las siguientes técnicas de programación con ActionScript:
Para obtener los archivos de la aplicación para esta muestra, consulte www.adobe.com/go/learn_programmingAS3samples_flash_es. Los archivos de la aplicación Podcast Player se encuentran en la carpeta Samples/PodcastPlayer. La aplicación consta de los siguientes archivos:
Lectura de datos RSS para un canal podcastLa aplicación Podcast Player empieza leyendo información sobre varios canales podcast y sus episodios: 1. En primer lugar, la aplicación lee un archivo de configuración XML que contiene una lista de canales podcast y muestra dicha lista al usuario. 2. Cuando el usuario selecciona uno de los canales podcast, lee la fuente RSS del canal y muestra una lista de los episodios del canal. Este ejemplo utiliza la clase de utilidad URLLoader para recuperar datos basados en texto desde una ubicación remota o un archivo local. Podcast Player crea primero un objeto URLLoader para obtener una lista de fuentes RSS en formato XML del archivo playerconfig.xml. A continuación, cuando el usuario selecciona una fuente específica de la lista, se crea un nuevo objeto URLLoader para leer datos RSS del URL de dicha fuente. Simplificación de la carga y la reproducción de sonido mediante la clase SoundFacadeLa arquitectura de sonido ActionScript 3.0 es eficaz, pero compleja. Las aplicaciones que sólo 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:
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 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: sólo 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. Visualización del progreso de reproducciónCrear un objeto Timer para controlar la reproducción es una operación compleja que sólo se debería tener que programar una sola vez. La encapsulación de esta lógica Timer en una clase reutilizable (como la clase SoundFacade) permite que las aplicaciones detecten las mismas clases de eventos de progreso cuando se carga y se reproduce un sonido. El objeto Timer que crea el método SoundFacade.play() distribuye una instancia de TimerEvent cada segundo. El siguiente método onPlayTimer() se ejecuta cuando llega una nueva clase TimerEvent. 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);
}
El método onPlayTimer() implementa la técnica de estimación de tamaño descrita en la secciónControl de la reproducción. Luego crea una nueva instancia de ProgressEvent con un tipo de evento de SoundFacade.PLAY_PROGRESS, con la propiedad bytesLoaded establecida en la posición actual del objeto SoundChannel y la propiedad bytesTotal establecida en la duración estimada de los datos de sonido. Pausa y reanudación de la reproducciónEl método SoundFacade.play() mostrado anteriormente acepta un parámetro pos correspondiente a un punto inicial de los datos de sonido. Si el valor pos es cero, el sonido empieza a reproducirse desde el principio. El método SoundFacade.stop() también acepta un parámetro pos, tal como se muestra aquí: public function stop(pos:int = 0):void
{
if (this.isPlaying)
{
this.pausePosition = pos;
this.sc.stop();
this.playTimer.stop();
this.isPlaying = false;
}
}
Cuando se llama al método SoundFacade.stop(), éste establece la propiedad pausePosition para que la aplicación sepa dónde colocar la cabeza lectora si el usuario desea reanudar la reproducción del mismo sonido. Los métodos SoundFacade.pause() y SoundFacade.resume() que se muestran a continuación invocan los métodos SoundFacade.stop() y SoundFacade.play() respectivamente y pasan un valor de parámetro pos cada vez. public function pause():void
{
stop(this.sc.position);
}
public function resume():void
{
play(this.pausePosition);
}
El método pause() pasa el valor SoundChannel.position al método play(), que almacena dicho valor en la propiedad pausePosition. El método resume() empieza a reproducir de nuevo el mismo sonido con el valor pausePosition como punto inicial. Ampliación del ejemplo de Podcast PlayerEn este ejemplo se presenta un Podcast Player básico que aborda la utilización de la clase SoundFacade reutilizable. También se podrían añadir otras funciones para ampliar la utilidad de esta aplicación, entre las que se incluyen:
|
|