Веб-аудио событие “завершилось”, не будучи запущенным при воспроизведении части исходного буфера

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

  •  02-01-2020
  •  | 
  •  

Вопрос

У нас есть вспомогательная функция web audio, которая воспроизводит звуки из звуковой таблицы и сообщает нам, когда они закончатся.В прошлом мы использовали playbackState в цикле обновления, чтобы проверить, завершил ли узел свое воспроизведение, но поскольку Chrome 36 теперь использует текущую спецификацию, которая не поддерживает playbackState мы обновили код, чтобы использовать 'ended' событие.

Однако, похоже, что это не увольнение.

Ниже приведена наша функция 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];
}

В this._features.hasEvents переменная устанавливается путем проверки на node.onended !== null на аудиоузле, созданном во время загрузки.Буфер создается путем XHR'ing файла.Это может быть либо mp3, либо m4a, в зависимости от того, на чем мы играем.

В чем причина того, что _soundedEnded функция не вызывается?Я пробовал и то, и другое node.onended = function(){...} и node.addEventListener("ended", function(){..}) синтаксисы, но ни с тем, ни с другим не повезло.Похоже, у нас одинаковое поведение как в iOS 7 Safari, так и в Chrome для настольных компьютеров / Android.

Это было полезно?

Решение

Я только что решил эту проблему, поняв, что делаю что-то глупое.Ошибка связана не с WebAudio, а вместо этого с функцией обратного вызова, которая должна была удалить звуковой объект из _playingSounds массив.

Этот фрагмент кода:

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;

должно было быть больше похоже на это:

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;

Я пытался удалить объект по значению, а не по ключу, что, очевидно, не работает.Теперь код передает ключ функции, и все снова работает.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top