Reproductor de música en Actionscript 3, usando POO y patrón MVC

Sólo nos queda comentar el resto de métodos de la clase Reproductor no vistos aún. Aquí es donde se manejan las clases ligadas al sonido: Sound, SoundChannel y SoundTransform. Empecemos con el el método play() y otros dos métodos de apoyo, mismoTema() y crearSonido():

public function play():void {
        if (_playlist != null) {
                _list.scrollToSelected();
                var indice:uint = _list.selectedIndex;
                var ruta:String = _playlist.lista[indice].ruta;
                if (_channel != null && mismoTema(ruta)) {
                        _channel = _sonido.play(_posicion);
                } else {
                        crearSonido(ruta);
                        var display_txt:TextField = this.getChildByName("temaActual_txt") as TextField;
                        display_txt.text = _list.getItemAt(_list.selectedIndex).label;
                }
                _channel.addEventListener(Event.SOUND_COMPLETE, finCancion);
                var soundTrans:SoundTransform = _channel.soundTransform;
                soundTrans.volume = _volumen;
                _channel.soundTransform = soundTrans;
                _playing = true;
                _timer.start();
       }
}

// Comprueba si el sonido actual y el seleccionado en la lista coinciden, o se ha cambiado
// la selección.
private function mismoTema(ruta:String):Boolean {
	if (_sonido.url.indexOf(ruta) != -1) {
		// El sonido a reproducir o reproduciéndose coincide con el seleccionado en la lista
		        return true
	} else {
		// Se ha cambiado el sonido seleccionado en la lista
		return false;
	}
}

private function crearSonido(ruta:String):void {
	if (_sonido != null) {
		_sonido.removeEventListener(ProgressEvent.PROGRESS, datosRecibidos);
		_sonido = null;
	}
	_sonido = new Sound(new URLRequest(ruta));
	_sonido.addEventListener(ProgressEvent.PROGRESS, datosRecibidos);
	trace("Reproduciendo sonido " + _sonido + " desde " + _posicion);
	_channel = _sonido.play(_posicion);
}

Lo primero es comprobar que ya está creada la instancia de Playlist. Si es así, se ordena a la lista que dirija su scroll a la canción seleccionada actualmente, se obtiene su índice, y a partir de este, se obtiene la ruta al archivo de esa canción desde la instancia de Playlist. Si ya hay creado un canal de sonido, y el tema actual es el tema que ya había seleccionado -esto se comprueba en el método mismoTema()- se vuelve a reproducir desde la posición almacenada. Si no, se llama a crearSonido(), y actualiza el display de texto con el nombre del nuevo tema. En este método, se comprueba si ya existía una referencia a una instancia de Sound. En caso afirmativo, se elimina. Posteriormente se crea una nueva instancia de Sound, asignándole un detector de carga del sonido que gestionará el método datosRecibidos(), y se ejecuta la reproducción de dicho sonido en el canal (instancia de SoundChannel) al que tenemos referencia. Las últimas líneas de play(), añaden un detector de fin de canción al canal de sonido, asignan el volumen almacenado al objeto SoundTransform de dicho canal, pone una propiedad de estado (o flag) llamada _playing a true . Esta propiedad establece si hay una reproducción en marcha o no. En este caso, la hay. Por último, inicia el temporizador de reproducción.

Los dos siguientes métodos ya aparecen referenciados en el código anterior, así que es buen momento para introducirlos. Se trata de finCancion() que es asignado al detector de fin de sonido del canal en el método play(), y de datosRecibidos(), que es otro manejador de eventos, en este caso del progreso de carga de los datos de sonido, y es asignado en el método crearSonido(). Vamos pues a ver dichos métodos:

private function datosRecibidos(e:ProgressEvent):void {
        _tiempoCargado = e.bytesLoaded / e.bytesTotal;
        _barraTiempo.actualizarBuffer(escala);
}

private function finCancion(e:Event):void {
        next();
}

El método datosRecibidos() calcula un ratio a partir de los datos obtenidos actualmente, y los datos totales. Esto nos ayudará a actualizar la barra de carga, cosa que viene a continuación, y a aplicar una estimación de la duración total de la canción mientras se esté cargando, con el fin de colocar correctamente el cabezal de reproducción durante el proceso de carga. Esto ya lo he explicado en profundidad al describir los métodos onTimer() de Reproductor, y en actualizar() de BarraTiempo. La segunda línea de datosRecibidos() llama al método actualizarBuffer() de BarraTiempo para que aplique dicho ratio a la escala de la barra de carga, como ya se vio al revisar esa clase.

Vamos ahora con el método stop() de Reproductor:

public function stop():void {
       if (_channel != null) {
               _channel.stop();
               _posicion = 0;
               _playing = false;
               _timer.stop();
       }
       // Actualizar display de tiempo a 0
       var timer_txt:TextField = this.getChildByName("time_txt") as TextField;
       timer_txt.text = "00:00";
       // Resetear barra de tiempo_barraTiempo.reset();
}

Primero comprueba que ya existe un sonido asignado a un canal, o sea, que se ha reproducido. En este caso, se para el sonido. Puede estar ya parado pero así nos aseguramos. Lo mismo con la posición y el temporizador de reproducción. El flag _playing se deja en false. Lo siguiente es actualizar el display de tiempo a “00:00″, y resetear la barra de tiempo, es decir, que el cabezal de reproducción vuelva al principio.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>