El evento de audio web "finalizó" no se activa al reproducir parte de un búfer de origen

StackOverflow https://stackoverflow.com//questions/25077703

  •  02-01-2020
  •  | 
  •  

Pregunta

Contamos con una función auxiliar de audio web que reproduce sonidos de una partitura sonora y nos avisa cuando están terminados.En el pasado, hemos usado playbackState en un ciclo de actualización para verificar si un nodo ha terminado su reproducción, pero como Chrome 36 ahora usa la especificación actual, que no admite playbackState Hemos actualizado el código para usar el 'ended' evento.

Sin embargo, esto no parece ser despedido.

La siguiente es nuestra función playAudio:-

playAudio: function(trackName){
    var node = this._atx.createBufferSource();
    node.buffer = this._buffer;

    var gain = this._atx.createGain();

    node.connect(gain);
    gain.connect(this._atx.destination);

    var start = this._tracks[trackName][0];
    var length = this._tracks[trackName][1] - start;

    node.start(0, start, length);

    var sound = {name: trackName, srcNode: node, gainNode: gain, startTime: this._atx.currentTime, duration: length, loop: false, playHeadStart: start};

    if (this._features.hasEvents) {
        //node.addEventListener("ended", function () {
        //   this._soundEnded(sound)
        //}.bind(this));
        node.onended = function(){
            this._soundEnded(sound);
        }.bind(this);
    }

    this._playingSounds[++this._soundId] = sound;
    return this._soundId;
},
_soundEnded: function (sound) {
    this._playingSounds[sound] = null;
    delete this._playingSounds[sound];
}

El this._features.hasEvents La variable se establece comprobando si node.onended !== null en un nodo de audio creado durante la carga.El búfer se crea haciendo XHR en un archivo.Puede ser un mp3 o un m4a, dependiendo de en qué estemos jugando.

¿Cuál es la razón por la que el _soundedEnded ¿No se llama a la función?he probado ambos node.onended = function(){...} y node.addEventListener("ended", function(){..}) sintaxis, sin suerte de ninguno de los dos.Parece que tenemos el mismo comportamiento tanto en iOS 7 Safari como en escritorio/Android Chrome.

¿Fue útil?

Solución

Acabo de resolver esto, después de darme cuenta de que estaba haciendo algo estúpido.El error no está en WebAudio, sino en la función de devolución de llamada que se suponía eliminaría el objeto de sonido del _playingSounds formación.

Este fragmento de código:

var sound = {name: trackName, srcNode: node, gainNode: gain, startTime:     this._atx.currentTime, duration: length, loop: false, playHeadStart: start};

if (this._features.hasEvents) {
    //node.addEventListener("ended", function () {
    //   this._soundEnded(sound)
    //}.bind(this));
    node.onended = function(){
        this._soundEnded(sound);
    }.bind(this);
}

this._playingSounds[++this._soundId] = sound;
return this._soundId;

debería haber sido más así:

var sound = {name: trackName, srcNode: node, gainNode: gain, startTime: this._atx.currentTime, duration: length, loop: false, playHeadStart: start};
var soundId = ++this._soundId;
if (this._features.hasEvents) {

    node.onended = function(){
        this._soundEnded(soundId);
    }.bind(this);
}

this._playingSounds[soundId] = sound;
return soundId;

Estaba intentando eliminar el objeto por el valor, en lugar de por la clave, lo que obviamente no funciona.El código ahora pasa la clave a la función y todo vuelve a funcionar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top