Web Áudio do evento "acabou" não ser demitido quando a reprodução de parte de uma memória intermédia de origem
-
02-01-2020 - |
Pergunta
Temos uma web de áudio, função auxiliar que reproduz sons a partir de uma folha de som, e permite-nos saber quando eles estão acabados.No passado, temos usado playbackState
em um loop update para verificar se há um nó de ter terminado a sua reprodução, mas desde que o google Chrome 36 agora usa a atual especificação, que não suporta playbackState
nós atualizamos o código para usar o 'ended'
do evento.
Isso não parece estar a ser demitido, no entanto.
O seguinte é o nosso playAudio função:-
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];
}
O this._features.hasEvents
variável é definida pela verificação para node.onended !== null
em um nó de áudio criado durante a carga.O buffer é criado por XHR ing um arquivo.Este pode ser um mp3 ou m4a, dependendo do que estamos a jogar.
Qual é a razão que o _soundedEnded
função não está sendo chamado?Eu tentei tanto node.onended = function(){...}
e node.addEventListener("ended", function(){..})
sintaxes, com nenhuma sorte de ambos.Parece que temos o mesmo comportamento em ambas iOS 7 Safari, e a área de trabalho do Android do google Chrome.
Solução
Acabei de resolvido isso, depois de perceber que eu estava fazendo algo estúpido.O erro não é com WebAudio, mas em vez disso, com a função de retorno de chamada que era suposta para remover o objeto de som do _playingSounds
matriz.
Essa parte do 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;
deve ter sido mais ou menos esta:
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;
Eu estava a tentar remover o objeto pelo valor, em vez de chave, que obviamente não funciona.O código agora passa a tecla para a função, e tudo funciona de novo.