简体   繁体   English

Web Audio API onended事件不会触发

[英]Web Audio API onended event does not fire

I'm extremely new to the world of Node streaming, so pardon my lack of information. 我对Node流技术非常陌生,请原谅我缺乏信息。

I've got a simple Node server that receives a file stream (using BinaryJS), and then re-broadcasts it back to the client as an ArrayBuffer. 我有一个简单的Node服务器,该服务器接收文件流(使用BinaryJS),然后将其作为ArrayBuffer重新广播回客户端。 In essence, assume that I'm getting an ArrayBuffer from the server, and I want to play it back. 本质上,假设我从服务器获取了ArrayBuffer,并且想播放它。 I'm currently decoding it as it comes in, creating a new source and scheduling playback every time. 我目前正在对其进行解码,创建一个新的源并安排每次播放。 It all seems to work. 一切似乎都有效。

However, I want to trigger another function every time a chunk ends. 但是,我想每次块结束时触发另一个功能。 The 'onended' event does not seem to be firing though. “ onended”事件似乎并未触发。 Can someone help? 有人可以帮忙吗? Thanks. 谢谢。

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)
        });
    })
})

After struggling for quite some time and looking at a lot of answers online, I figured that the reason my code didn't work was because I was constantly re-writing the 'source' variable. 经过一段时间的努力并在线查看了许多答案之后,我发现我的代码无法正常工作的原因是因为我不断地重写'source'变量。 Since it was just an instance (a pointer for C++ folks), it pointed only to the latest source. 由于它只是一个实例(C ++专家的指针),因此仅指向最新资源。 Essentially, it was being overwritten before the event could fire. 从本质上讲,在事件触发之前 ,它已被覆盖。

I solved it by 'caching' all sources and buffers to arrays. 我通过将所有源和缓冲区“缓存”到数组中来解决它。

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)
        });
    })
})

This time, I was actually pushing those values into the 'sources' array, and hence it wasn't overwritten and the event fired properly. 这次,我实际上是将这些值放入“源”数组中,因此不会被覆盖,并且事件会正确触发。

I'm not sure if this is the most efficient way (I hardly think it is), but it solves my problem for now. 我不确定这是否是最有效的方法(我几乎认为不是),但是目前它可以解决我的问题。

If anyone has a better solution, do let me know :) 如果有人有更好的解决方案,请告诉我:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM