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

Pasemos al método pause():

public function pause():void {
      // Comprobar si se ha cambiado de canción en la lista.
      // Si se ha cambiado, el pause se convertirá en un stop y la reproducción se reanudará al inicio de la nueva canción.
      // Si no ha habido cambio, se almacena la posición donde ha quedado la reproducción para reanudar ahí
      if (mismoTema(_playlist.lista[_list.selectedIndex].ruta)) {
          _posicion = _channel.position;
          _channel.stop();
          _playing = false;
          _timer.stop();
      } else {
          this.stop();
      }
}

Este método se comporta exactamente igual que stop() en el caso en el que durante la reproducción se haya seleccionado otro tema navegando por la lista. En cambio, si el tema que se estaba reproduciendo se trata del mismo que el que hay seleccionado en la lista porque no hemos tocado la lista durante la reproducción -el caso más habitual- entonces se almacena la posición actual de la reproducción para así poder reanudarla desde ahí, se detiene la reproducción -no confundir este stop() con nuestro stop() del reproductor, que abarca más funcionalidad- y finalmente paramos el temporizador de reproducción y el flag de estado de reproducción lo ponemos a false.

Vamos con previous(), o sea el método asignado al botón de atrás. Este método, y el método next(), tienen mayor complejidad ya que su funcionaliad depende de varios factores, que son los estados descritos por los botones de opción.

public function previous():void {
	var indice:int = _list.selectedIndex;

	if (_estadoRepeat == 1) {
	// Modo repetir una, se reproduce el principio de la misma

	} else if (_estadoRepeat == 0 && !_estadoRandom) {
		// Modo aleatorio en off, y en modo no repetir
		if (_list.selectedIndex == 0) {
			// Estaba reproduciendose primera cancion de playlist
			// Se sigue en la primera canción
			indice = 0;
		} else {
			// No estaba reproduciendose primera cancion de playlist
			indice = _list.selectedIndex - 1;
		}
		_list.selectedIndex = indice;

	} else if (_estadoRandom && _estadoRepeat != 1) {
		// Modo aleatorio ON, y modo reproduccion no es repetir solo una
		indice = Math.floor(Math.random()*(_list.length - 1));
		_list.selectedIndex = indice;
		trace("Reproducir aleatoriamente tema de indice " + indice);

	} else if (!_estadoRandom && _estadoRepeat == 2) {
		// Modo random OFF y modo repetir todas
		if (_list.selectedIndex > 0) {
			// No es principio de lista principal
			indice = _list.selectedIndex - 1;
		} else {
			// Es principio de lista principal
			indice = _list.length - 1;
		}
		_list.selectedIndex = indice;
	}

	if (this._playing) {
		this.stop();
		this.play();
	}
}

Como digo, este método depende del valor de dos propiedades que hacen de variables de estado o flags, _estadoRandom y _estadoRepeat. La primera acepta dos estados o valores y por eso es Booleana, o sea, la música va en orden aleatorio o no. La segunda acepta tres estados, 0, 1 y 2, que vienen a significar “no repetir”, “repetir actual”, “repetir todo”. Dicho esto, vamos con las condiciones:

  1. Si _estadoRepeat es 1, da igual el valor de _estadoRandom, se ha de repetir la misma canción y por lo tanto el botón atrás volverá a la misma canción. No cambiamos nada en la condición, pero luego más abajo llamando a los métodos stop() y play() del reproductor, reiniciaremos la misma canción.
  2. Si _estadoRepeat es 0 (no repetir, o modo normal por defecto) y no está activo el modo aleatorio, pasamos por una segunda condición: si se trataba de la primera canción de la lista, forzamos a que siga siendo esta la canción a reproducir, si no, seleccionamos la anterior.
  3. Si _estadoRepeat es distinto de 1, o sea, si estamos en modo “no repetir” o modo “repetir todas”, y el modo aleatorio está activado, seleccionamos una canción al azar.
  4. Por último si _estadoRepeat es 2 y el estado aleatorio está desactivado, en una segunda condición comprobamos si se trata de inicio de lista. Si es así, pasamos a la última canción de la lista. En caso contrario, pasamos a la anterior.

De esta forma se cubren todos los casos posibles. Luego con una simple llamada a los métodos del reproductor ya vistos stop() y play() se pone en marcha el reproductor de la forma que toca.

A continuación, el método next(), que no voy a comentar porque su funcionamiento es totalmente análogo a previous():

public function next():void {
	var indice:int = _list.selectedIndex;

	if (_estadoRepeat == 1) {
		// Modo repetir una, se reproduce el principio de la misma

	} else if (_estadoRepeat == 0 && !_estadoRandom) {
	        // Modo no repeat, secuencial no aleatorio (random OFF)
		if (_list.selectedIndex < _list.length - 1) {
			// No es final de lista principal
			indice = _list.selectedIndex + 1;
		} else {
			// Es final de lista principal
			// No hacer nada
		}
		_list.selectedIndex = indice;

	} else if (_estadoRandom && _estadoRepeat != 1) {
		// Modo random ON y no activo modo repetir una
		indice = Math.floor(Math.random()*(_list.length - 1));
		_list.selectedIndex = indice;

	} else if (!_estadoRandom && _estadoRepeat == 2) {
		// Modo random OFF y modo repetir todas
		if (_list.selectedIndex < _list.length - 1) {
			// No es final de lista principal
			indice = _list.selectedIndex + 1;
		} else {
			// Es final de lista principal
			indice = 0;
		}
		_list.selectedIndex = indice;

	}

	if (this._playing) {
		this.stop();
		this.play();
	}
}

Falta por ver el método que se ejecuta al cambiar el valor del componente Slider, que se ocupa del volumen del sonido. Este método se llama cambiarVolumen(). Lo único que hace es obtener el nuevo valor del Slider, al cual previamente le habíamos dado unos baremos en el Inspector de Componentes, y aplica ese valor al volumen del canal de sonido.

public function cambiarVolumen():void {
// Actualizar volumen del reproductor dependiendo del nuevo valor del slider
var volumen:Slider = this.getChildByName("barraVolumen") as Slider;
_volumen = volumen.value;
if (_channel != null) {
var soundTrans:SoundTransform = _channel.soundTransform;
soundTrans.volume = _volumen;
_channel.soundTransform = soundTrans;
}
}

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>