SoundJS y AudioSprites

26/03/2016 CreateJS

SoundJS

Dejemos los gráficos por un momento y presentemos a SoundJS, la librería encargada de los sonidos de nuestra aplicación. SoundJS ofrece una API multiplataforma para gestionar de forma sencilla recursos de audio sin preocuparnos del navegador ni la compatibilidad con dispositivos.

SoundJS es una clase abstracta, al igual que Ticker, no se inicializa, si no que accedemos a ella directamente. Para usarlo deberemos 'registrar' los sonidos que deseemos, de este modo podremos reproducirlos, loopearlos, pausarlos, etc, cuando deseemos.

Para registrar un sonido basta con usar la función registerSound(path, id), donde 'path' será la ruta del fichero de audio, y 'id' será un String identificador del sonido.

                createjs.Sound.registerSound("sounds/sound.mp3", "sound"); // registramos un sonido sound.mp3 al que llamamos 'sound'
            

Esto 'registrará' el sonido, pero sólo podremos usarlo cuando esté completamente cargado en memoria. Por esta razón es útil usar un Event Handler, es decir, crearemos una función que escuchará al Evento 'fileload', el cual es lanzado por SoundJS cuando el archivo ha sido cargado.

                createjs.Sound.on("fileload", onLoad, this); // onLoad será la función a la que llamaremos cuando el fichero se haya terminado de cargar
            

Entonces, para reproducirlo, podemos hacer algo así:

                 var onLoad = function (e) {
                    createjs.Sound.play("sound");  // Lo reproducimos gracias a su id 'sound'
                }
            

Entre las propiedades interesantes que podemos tocar esta la de volume, que nos permitirá modificar el volumen de cada sonido individualmente.

                createjs.Sound.play("sound").volume = 0.5; // se reproducirá con un volumen al 50%
            

Otra propiedad es la de mute, que silencia de forma global todo el sistema de SoundJS

                createjs.Sound.muted = true; // no se escuchará ningún Sonido
            

También podremos registrar varios sonidos a la vez con registerSounds(sounds, basePath), donde 'sounds' es un Array de objetos. Cada objeto deberá tener las propiedades 'src' y 'id'.

                
                    var basePath = "sounds/";
                    var sounds = [
                        {src:"sound_1.mp3", id:"robot"},
                        {src:"sound_2.mp3", id:"sound"},
                        {src:"sound_3.mp3", id:"shot", data: 5} //data es opcional, indica el número de sonidos concurrentes permitidos
                    ];
                    createjs.Sound.registerSounds(sounds, basePath);
                
            

Y otra propiedad muy interesante es alternateExtensions, un array de strings donde indicaremos 'extensiones' alternativas. Es decir, si cargamos puros sonidos .mp3 y SoundJS detecta que en un determinado navegador el formato .mp3 no está soportado, buscará otro fichero igual probando con una extensión alternativa (consultando este array)

Es buena práctica incluir también los mismos sonidos en formato .ogg y seguidamente añadir esta extensión a SoundJS con:

                createjs.Sound.alternateExtensions = ["ogg"]; // si sound_1.mp3 no se puede reproducir, buscará un archivo llamado sound_1.ogg
            

AudioSprites

CreateJS

SoundJS no se queda ahí, desde la versión 0.6 añade soporte para los AudioSprites. Registrar múltiples sonidos supone leer de disco múltiples archivos y, si son muchos sonidos, tendrá como consecuencia un coste considerable de recursos.

Por esta razón, puede ser más conveniente unificar todos los archivos de sonido en un único archivo, y suministrar información sobre dónde empieza cada sonido, cuánto dura y cómo identificarlo. De esto se trata AudioSprite.

Para usarlo, simplemente cambiaremos el array de sonidos, por un array un poco más complejo:

                
                    var basePath = "sounds/";
                    var sounds = [{
                        src:"MyAudioSprite.ogg", // ubicación del AudioSprite, archivo con todos los sonidos
                        data: {
                            audioSprite: [ // array con todos los sonidos
                                {id:"sound_1", startTime:0, duration:500},
                                {id:"sound_2", startTime:1000, duration:400},
                                {id:"sound_3", startTime:1900, duration: 1000}
                            ]}
                        }
                    ];
                    createjs.Sound.registerSounds(sounds, basePath); // registramos el archivo, que contiene todos los sonidos
                
            

Es importante dejar un tiempo de unos 500 milisegundos entre cada sonido.

Ahora, si queremos reproducir uno, lo haremos de la misma manera, llamándolo por su id:

                createjs.Sound.play("sound_2");
            

Lograr sacar la información de startTime y duration, teniendo en cuenta esos milisegundos que debemos dejar entre los sonidos, puede ser una tarea muy tediosa y molesta. Por suerte, la comunidad de CreateJS ha creado una pequeña herramienta para ayudarnos con esta tarea. La podemos visitar aquí.

Generando un AudioSprite

Primero deberemos instalarlo, mediante consola de comandos, en nuestro sistema de forma global usando NPM:

                npm install -g audiosprite
            

Ahora podremos usar el comando audiosprite. Este comando recibirá los siguientes parámetros:

                audiosprite [options] file1.mp3 file2.mp3 *.wav
            

Donde en 'options' indicaremos algunas opciones o configuraciones opcionales. Seguidamente indicamos todos los archivos que queremos que 'unifique' para generar el audiosprite, en este caso son 'file1.mp3', 'file2.mp3' y todos los archivos .wav que encuentre.

Por ejemplo podemos hacer lo siguiente:

                audiosprite --format createjs --output sounds *.mp3 *.wav
            
  • --format createjs: Audiosprite puede generar salidas en distintos formatos, aquí indicamos que queremos que sea en el formato de CreateJS.
  • --output sounds: Indicamos a dónde queremos que genere el archivo, en este caso, creará un directorio llamado 'sounds' y ahí meterá todos los audiosprites (si, generará varios, en distintos formatos, por defecto [ogg,m4a,mp3,ac3])
  • *.mp3 *.wav: Finalmente los archivos que buscará. En este caso indicamos todos los .mp3 y .wav que encuentre.

Ejecutamos el comando y voila! ya tendremos un audiosprite en varios formatos, con toda la información en un .json

                
                    {
                        "src": "sounds/sounds.ogg",
                        "data": {
                        "audioSprite": [
                            {
                            "id": "sound_1",
                            "startTime": 0,
                            "duration": 2142.0408163265306
                            },
                            {
                            "id": "sound_2",
                            "startTime": 4000,
                            "duration": 3108.5714285714284
                            }]
                        }
                    }
                
            

Y esa será la información que le pasaremos a SoundJS cuando llamemos a registerSounds(). Mucho más cómodo.

Si tienes alguna duda o sugerencia, no dudes en participar!