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
.