Web Audio API onended事件未激发

Web Audio API onended event does not fire

本文关键字:事件 onended Audio API Web      更新时间:2023-09-26

我对节点流媒体的世界非常陌生,所以请原谅我缺乏信息。

我有一个简单的Node服务器,它接收文件流(使用BinaryJS),然后将其作为ArrayBuffer重新广播回客户端。本质上,假设我正在从服务器获取ArrayBuffer,并且我想回放它。我目前正在对它进行解码,创建一个新的源,并安排每次播放。这一切似乎都奏效了。

然而,我想在每次块结束时触发另一个函数。不过,"一体"活动似乎并没有启动。有人能帮忙吗?谢谢

client.on('open', function() {
    var stream = client.send(file)
    client.on('stream', function(stream) {
        var nextTime = 0.01
        stream.on('data', function(data) {
            console.log('Receiving data from server')
            context.decodeAudioData(data, function(audioBuffer) {
                var source = context.createBufferSource()
                source.buffer = song[song.length-1]
                source.connect(context.destination);
                source.onended = function() {
                    console.log('Buffer depleted')
                }
                source.start(nextTime)
                nextTime += audioBuffer.duration - 0.01
            })
        })
        stream.on('end', function() {
            console.log('End of stream, ' + current)
        });
    })
})

在挣扎了很长一段时间并在网上查看了很多答案后,我发现我的代码不起作用的原因是因为我一直在重写"源"变量。由于它只是一个实例(C++人员的指针),所以它只指向最新的源代码。从本质上讲,在事件触发之前,它已被覆盖。

我通过将所有源和缓冲区"缓存"到数组来解决这个问题。

client.on('open', function() {
    var stream = client.send(file)
    client.on('stream', function(stream) {
        stream.on('data', function(data) {
            console.log('Receiving data from server')
            context.decodeAudioData(data, function(audioBuffer) {
                sources.push(context.createBufferSource())
                song.push(audioBuffer)
                sources[sources.length-1].buffer = song[song.length-1]
                sources[sources.length-1].connect(context.destination);
                sources[sources.length-1].onended = function() {
                    console.log('Buffer depleted')
                    current += 1;
                }
                sources[sources.length-1].start(nextTime)
                nextTime += audioBuffer.duration - 0.01
            })
        })
        stream.on('end', function() {
            console.log('End of stream, ' + current)
        });
    })
})

这一次,我实际上是在将这些值推送到"sources"数组中,因此它没有被覆盖,事件也正确地触发了。

我不确定这是否是最有效的方法(我几乎不认为是),但它目前解决了我的问题。

如果有人有更好的解决方案,请告诉我:)