L'événement Web Audio « terminé » n'est pas déclenché lors de la lecture d'une partie d'un tampon source

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

  •  02-01-2020
  •  | 
  •  

Question

Nous disposons d'une fonction d'assistance audio Web qui lit les sons d'une feuille de son et nous permet de savoir quand ils sont terminés.Dans le passé, nous avons utilisé playbackState sur une boucle de mise à jour pour vérifier qu'un nœud a terminé sa lecture, mais depuis Chrome 36 utilise désormais la spécification actuelle, qui ne prend pas en charge playbackState nous avons mis à jour le code pour utiliser le 'ended' événement.

Cela ne semble cependant pas être renvoyé.

Voici notre fonction 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];
}

Le this._features.hasEvents la variable est définie en vérifiant node.onended !== null sur un nœud audio créé lors du chargement.Le tampon est créé en effectuant un XHR sur un fichier.Cela peut être un mp3 ou un m4a, selon ce sur quoi nous jouons.

Quelle est la raison pour laquelle _soundedEnded la fonction n'est pas appelée ?J'ai essayé les deux node.onended = function(){...} et node.addEventListener("ended", function(){..}) syntaxes, sans chance ni de l'un ni de l'autre.Nous semblons avoir le même comportement dans iOS 7 Safari et dans Chrome pour ordinateur de bureau/Android.

Était-ce utile?

La solution

Je viens de résoudre ce problème, après avoir réalisé que je faisais quelque chose de stupide.Le bug ne vient pas de WebAudio, mais plutôt de la fonction de rappel qui était censée supprimer l'objet sonore du _playingSounds tableau.

Ce bout de code :

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;

ça aurait dû être plutôt comme ça :

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;

J'essayais de supprimer l'objet par la valeur plutôt que par la clé, ce qui ne fonctionne évidemment pas.Le code transmet maintenant la clé à la fonction et tout fonctionne à nouveau.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top