El método start()

facebook-svg gplus-svg twitter-svg

Utilizamos el método start() de una fuente de reproducción para programar cuando empieza a reproducirse el sonido.

Por ejemplo si queremos que la música empiece ya podemos escribir:

fuenteDeReproduccion.start();

o podemos utilizar la propiedad currentTime del AudioContext, que representa el momento actual.

fuenteDeReproduccion.start(audioCtx.currentTime);

Si queremos que la reproducción empiece con 2 segundos de retraso podemos escribir:

fuenteDeReproduccion.start(audioCtx.currentTime + 2);

Pero hay más: El método start() puede tomar otros dos argumentos: el desplazamiento ( offset ) y la duración.
Si queremos que el archivo de sonido empiece no desde el principio sino en un punto concreto ( digamos en el segundo 10 ) tenemos que utilizar el desplazamiento de esta manera:

fuenteDeReproduccion.start(audioCtx.currentTime, 10);

Asimismo si queremos que la reproducción pare 15 segundos antes, podemos utilizar el tercer atributo de start(): la duración.

fuenteDeReproduccion.start(audioCtx.currentTime, 0, audioBuffer.duration - 15);

donde audioBuffer.duration representa la duración del archivo audio.

Un caso práctico

Hemos visto como reproducir un archivo de sonido. Sin embargo, cada vez que reiniciamos el audio, este vuelve a empezar desde 0. En muchos casos no es lo que el usuario quiere. Sería mucho mejor poder reiniciar el audio en el punto en el cual lo hemos dejado. Para esto vamos a necesitar el segundo argumento del método start(): el offset.

En el HTML añadimos un control deslizante que vamos a utilizar como representación visual del avance de la reproducción.

<p>
<button id="boton">&#9655;</button>
<input id="progresoInput" type="range" value="0" />
</p>

En el JavaScript para monitorizar el progreso del audio hace falta otra variable global:

var progreso = 0;

También en el bloque de código del setInterval tenemos que hacer algunos cambios: Si el audio se está reproduciendo, hay que calcular el progreso en segundos, transformarlo en porcientos y actualizar la representación visual del avance.
Si el audio ha llegado al final, tenemos que restablecer el valor de  la variable progreso: progreso = 0;

window.setInterval( function(){ 
   // si el audio se está reproduciendo
   if(stop == false){
    // calcula el progreso del audio en segundos
    progreso = audioCtx.currentTime - tiempo;
    // calcula el progreso del audio en porcientos
    var porcien = progreso * 100 / audioBuffer.duration;
    // visualiza el progreso del audio
    progresoInput.value = porcien;
   } 
    
   if(audioBuffer && audioCtx.currentTime - tiempo >= audioBuffer.duration){
      stop = true;
      boton.innerHTML = "&#9655;"//reproducir
      progreso = 0;
   }
  },1000/30);

Por fin, en la función audio utilizada como función de retrollamada ( callback ), en cada clic actualizamos el valor del tiempo:

function audio(){  
    if (stop) { // si el audio está parado
      tiempo = audioCtx.currentTime - progreso;
      stop = false;
      boton.innerHTML = "||"; //detener
      reproducirAudio(progreso);
    }else{ // de lo contrario
      stop = true;
      boton.innerHTML = "&#9655;"; //reproducir
      detenerAudio();
    }
  }

Vea este ejemplo en codepen.
Pare el audio y vuelva a reiniciarlo. La reproducción continua desde el punto en el cual fue parado.

See the Pen Reproducir archivos de sonido #3* by Gabi (@enxaneta) on CodePen.

Mejorar el ejemplo anterior

Sería interesante poder controlar la reproducción del sonido arrasrando el botón del slider a la posición que queramos. Si el audio está parado ( if(stop == true) ) la única cosa que necesitamos hacer es utilizar el método addEventListener de esta manera:

progresoInput.addEventListener(
    "input",
    function() {
      if(stop == true) {progreso = this.value * audioBuffer.duration / 100;}
    },false
  );

Vea este ejemplo en codepen.
Pruebe arrastrar el botón del slider cuando el audio esté parado.

See the Pen El método start() #3 by Gabi (@enxaneta) on CodePen.

Si el audio se está reproduciendo la cosa es un poco más complicada. Básicamente necesitamos tres eventos:

1. En el evento mousedown, si el audio se está reproduciendo tenemos que pararlo. También tenemos que parar la animación y para esto utilizamos el método clearInterval().
La variable global inputStop que aparece en el código nos deja saber si el audio estaba parado o no cuando hemos presionado el botón del ratón ( mousedown ).

progresoInput.addEventListener(
    "mousedown",
    function() {
      if (!stop) {
        stop = true;
        inputStop = true; // una variable global
        detenerAudio();
      }
      if (sid) {
        window.clearInterval(sid);
      }
    },
    false
  );

2. Cuando el usuario desplaza el botón del slider (el evento input ) recalculamos el progreso y el tiempo:

progresoInput.addEventListener(
    "input",
    function() {
      progreso = this.value * audioBuffer.duration / 100;
      tiempo = audioCtx.currentTime - progreso;
    },
    false
  );

3. Finalmente al soltar el botón del ratón ( mouseup ), si en el mousedown tuvimos que parrar el audio, lo reiniciamos con reproducirAudio() y activamos de nuevo el setInterval

progresoInput.addEventListener(
    "mouseup",
    function() {
      if (inputStop) { //si en el mousedown tuvimos que parrar el audio
        stop = false;
        inputStop = false;
        reproducirAudio(progreso);
      }
      sid = activarSetInterval();
    },
    false
  );

Vea este ejemplo en codepen.
Pruebe arrastrar el botón del slider cuando el audio esté parado, y también cuando se esté reproduciendo.

See the Pen El método start #4 by Gabi (@enxaneta) on CodePen.