Reproducción de sonidos

Flash Player 9 y posterior, Adobe AIR 1.0 y posterior

Para reproducir un sonido cargado solo hay que llamar al método Sound.play() de un objeto Sound:

var snd:Sound = new Sound(new URLRequest("smallSound.mp3")); 
snd.play();

Al reproducir sonidos con ActionScript 3.0, se pueden realizar las operaciones siguientes:

  • Reproducir un sonido desde una posición de inicio específica

  • Pausar un sonido y reanudar la reproducción desde la misma posición posteriormente

  • Saber exactamente cuándo termina de reproducirse un sonido

  • Hacer un seguimiento del progreso de la reproducción de un sonido

  • Cambiar el volumen o el desplazamiento cuando se reproduce un sonido

Para realizar estas operaciones durante la reproducción deben utilizarse las clases SoundChannel, SoundMixer y SoundTransform.

La clase SoundChannel controla la reproducción de un solo sonido. La propiedad SoundChannel.position puede considerarse como una cabeza lectora, que indica el punto actual en los datos de sonido que se están reproduciendo.

Cuando una aplicación llama al método Sound.play(), se crea una nueva instancia de la clase SoundChannel para controlar la reproducción.

La aplicación puede reproducir un sonido desde una posición de inicio específica, pasando dicha posición en milisegundos como el parámetro startTime del método Sound.play(). También puede especificar un número fijo de veces que se repetirá el sonido en una sucesión rápida pasando un valor numérico en el parámetro loops del método Sound.play().

Cuando se llama al método Sound.play() con los parámetros startTime y loops, el sonido se reproduce de forma repetida desde el mismo punto de inicio cada vez, tal como se muestra en el código siguiente:

var snd:Sound = new Sound(new URLRequest("repeatingSound.mp3")); 
snd.play(1000, 3);

En este ejemplo, el sonido se reproduce desde un punto un segundo después del inicio del sonido, tres veces seguidas.

Pausa y reanudación de un sonido

Si la aplicación reproduce sonidos largos, como canciones o emisiones podcast, es recomendable dejar que los usuarios pausen y reanuden la reproducción de dichos sonidos. Durante la reproducción en ActionScript un sonido no se puede pausar; solo se puede detener. Sin embargo, un sonido puede reproducirse desde cualquier punto. Se puede registrar la posición del sonido en el momento en que se detuvo y volver a reproducir el sonido desde dicha posición posteriormente.

Por ejemplo, supongamos que el código carga y reproduce un archivo de sonido como este:

var snd:Sound = new Sound(new URLRequest("bigSound.mp3")); 
var channel:SoundChannel = snd.play();

Mientras se reproduce el sonido, la propiedad SoundChannel.position indica el punto del archivo de sonido que se está reproduciendo en ese momento. La aplicación puede almacenar el valor de posición antes de detener la reproducción del sonido, como se indica a continuación:

var pausePosition:int = channel.position; 
channel.stop();

Para reanudar la reproducción del sonido desde el mismo punto en que se detuvo, hay que pasar el valor de la posición almacenado anteriormente.

channel = snd.play(pausePosition);

Control de la reproducción

Es posible que la aplicación desee saber cuándo se deja de reproducir un sonido para poder iniciar la reproducción de otro o para limpiar algunos recursos utilizados durante la reproducción anterior. La clase SoundChannel distribuye un evento Event.SOUND_COMPLETE cuando finaliza la reproducción de un sonido. La aplicación puede detectar este evento y adoptar las medidas oportunas como se muestra a continuación:

import flash.events.Event; 
import flash.media.Sound; 
import flash.net.URLRequest; 
 
var snd:Sound = new Sound(); 
var req:URLRequest = new URLRequest("smallSound.mp3"); 
snd.load(req); 
 
var channel:SoundChannel = snd.play(); 
channel.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete); 
 
public function onPlaybackComplete(event:Event) 
{ 
    trace("The sound has finished playing."); 
}

La clase SoundChannel no distribuye eventos de progreso durante la reproducción. Para informar sobre el progreso de la reproducción, la aplicación puede configurar su propio mecanismo de sincronización y hacer un seguimiento de la posición de la cabeza lectora del sonido.

Para calcular el porcentaje de sonido que se ha reproducido, se puede dividir el valor de la propiedad SoundChannel.position entre la duración de los datos del sonido que se está reproduciendo:

var playbackPercent:uint = 100 * (channel.position / snd.length);

Sin embargo, este código solo indica porcentajes de reproducción precisos si los datos de sonido se han cargado completamente antes del inicio de la reproducción. La propiedad Sound.length muestra el tamaño de los datos de sonido que se cargan actualmente, no el tamaño definitivo de todo el archivo de sonido. Para hacer un seguimiento del progreso de reproducción de un flujo de sonido, la aplicación debe estimar el tamaño final de todo el archivo de sonido y utilizar dicho valor en sus cálculos. Se puede estimar la duración final de los datos de sonido mediante las propiedades bytesLoaded y bytesTotal del objeto Sound, de la manera siguiente:

var estimatedLength:int =  
    Math.ceil(snd.length / (snd.bytesLoaded / snd.bytesTotal)); 
var playbackPercent:uint = 100 * (channel.position / estimatedLength);

El código siguiente carga un archivo de sonido más grande y utiliza el evento Event.ENTER_FRAME como mecanismo de sincronización para mostrar el progreso de la reproducción. Notifica periódicamente el porcentaje de reproducción, que se calcula como el valor de la posición actual dividido entre la duración total de los datos de sonido:

import flash.events.Event; 
import flash.media.Sound; 
import flash.net.URLRequest; 
 
var snd:Sound = new Sound(); 
var req:URLRequest = new  
    URLRequest("http://av.adobe.com/podcast/csbu_dev_podcast_epi_2.mp3"); 
snd.load(req); 
 
var channel:SoundChannel; 
channel = snd.play(); 
addEventListener(Event.ENTER_FRAME, onEnterFrame); 
channel.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete); 
 
function onEnterFrame(event:Event):void 
{ 
    var estimatedLength:int =  
        Math.ceil(snd.length / (snd.bytesLoaded / snd.bytesTotal)); 
    var playbackPercent:uint =  
        Math.round(100 * (channel.position / estimatedLength)); 
    trace("Sound playback is " + playbackPercent + "% complete."); 
} 
 
function onPlaybackComplete(event:Event) 
{ 
    trace("The sound has finished playing."); 
    removeEventListener(Event.ENTER_FRAME, onEnterFrame); 
}

Una vez iniciada la carga de los datos de sonido, este código llama al método snd.play() y almacena el objeto SoundChannel resultante en la variable channel. A continuación, añade un detector de eventos a la aplicación principal para el evento Event.ENTER_FRAME y otro detector de eventos al objeto SoundChannel para el evento Event.SOUND_COMPLETE que se produce cuando finaliza la reproducción.

Cada vez que la aplicación alcanza un nuevo fotograma en su animación, se llama al método onEnterFrame(). El método onEnterFrame() estima la duración total del archivo de sonido según la cantidad de datos que ya se han cargado, y luego calcula y muestra el porcentaje de reproducción actual.

Cuando se ha reproducido todo el sonido, se ejecuta el método onPlaybackComplete() y se elimina el detector de eventos para el evento Event.ENTER_FRAME, de manera que no intente mostrar actualizaciones de progreso tras el fin de la reproducción.

El evento Event.ENTER_FRAME puede distribuirse muchas veces por segundo. En algunos casos no será necesario mostrar el progreso de la reproducción con tanta frecuencia. De ser así, la aplicación puede configurar su propio mecanismo de sincronización con la clase flash.util.Timer; véase Trabajo con fechas y horas.

Detener flujos de sonido

Existe una anomalía en el proceso de reproducción para los sonidos que se están transmitiendo, es decir, para los sonidos que todavía se están cargando mientras se reproducen. Cuando la aplicación llama al método SoundChannel.stop() en una instancia de SoundChannel que reproduce un flujo de sonido, la reproducción se detiene en un fotograma y en el siguiente se reinicia desde el principio del sonido. Esto sucede porque el proceso de carga del sonido todavía está en curso. Para detener la carga y la reproducción de un flujo de sonido, llame al método Sound.close().