Reproduciendo Sonidos Secuencialmente en Silverlight

Ya hace poco les mencioné un proyecto OpenSource en el que trabajo; pronto postearé al respecto.

Bien; en ese proyecto Silverlight es protagonista. De hecho el proyecto se llama SilverTeacher.

Dado que es un proyecto altamente cargado de multimedia, obviamente se necesita reproducir sonido.

Cómo se reproducen sonidos en Siverlight?

Rocket Science!!! Observen:

    1:  private void ReproduceSound(string name)
    2:  {
    3:      melSounds.Source = new Uri(
    4:          String.Concat("/sounds/", name, ".wma", UriKind.Relative));
    5:      melSounds.Stop();
    6:      melSounds.Play();
    7:  }

Bueno… aquí el único sujeto desconocido es el tal melSounds

Se los presento:

 internal System.Windows.Controls.MediaElement melSounds;

Es un sujeto de tipo MediaElement. MediaElement es un control que uno arrastra del toolbox. No tiene representación visual en el editor. Queda a un ladito invisible, casi como los DialogBox de la programación Windows tradicional.

Observen entonces que lo único que hay que hacerle, es proporcionarle la Uri del elemento a reproducir y luego darle “Play”.

Observen también que primero doy la instrucción “Stop”. Por qué?

Esto lo hago, porque cuando por primera vez se reproduce un sonido, el “cursor” de la reproducción queda al final del mismo. Así que si luego de reproducirse le damos “Play” no se ejecutará nada, porque el cursor está al final.

La forma de reposicionar el cursor, es mediante la instrucción “Stop”. Súper fácil no?

Hasta ahí todo bien. Pero que tal si quisiéramos reproducir dos o más sonidos consecutivamente?

Usando el método anterior, uno pensaría: “Muy fácil, ejecuto este código:”

    1:  ReproduceSound(nombrePrimerArchivo);
    2:  ReproduceSound(nombreSegundoArchivo);

Desafortunadamente la cosa no funciona bien así

Dado el carácter asincrónico de la reproducción de los sonidos, lo que pasaría es que sólo el último sonido se reproduciría.

La solución no es muy directa. Es más bien “tricky”.

Luego de probar y probar, descubrí que el MediaElement tiene un evento llamado MediaEnded. Entonces lo único que habría que hacer, es controlar ese evento, para que se comience a reproducir el siguiente archivo.

De hecho, ya una aplicación real de esta teoría, se aprecia en el siguiente método:

    1:  private void melSounds_MediaEnded(object sender, System.Windows.RoutedEventArgs e)
    2:  {
    3:      switch (melSounds.Source.OriginalString)
    4:      {
    5:          case "/sounds/success.wma":
    6:              if (goals == GOALS_TO_WIN)
    7:              {
    8:                  //ShowStars();
    9:                  ReproduceSound("cheer");
   10:              }
   11:              break;
   12:          case "/sounds/error.wma":
   13:              SayColor();
   14:              break;
   15:          default:
   16:              break;
   17:      }
   18:  }

Observen allí cómo de acuerdo al sonido que haya acabado de reproducirse (lo sé a través de su “source” o fuente) escojo cuál debería ser el siguiente archivo y lo reproduzco.

Tal cual, es la solución!!!