网络音频 API- onended 事件范围
Web Audio API- onended event scope
我在使用网络音频 API AudioSourceBufferNode 及其 onended 事件时遇到了一个棘手的问题。
基本上我想做的是有两个 AudioSourceBufferNode,当另一个完成并继续来回播放时,每个 AudioSourceBufferNode 都会被触发。我知道一旦您调用 start() ,AudioSourceBufferNodes 就几乎完成了,并且它们被设计为在此之后进行垃圾收集。所以我试着像这样解决这个问题:
var source1;
var source2;
source1 = getSound(buffer1);
source2 = getSound(buffer2);
source1.start();
source1.onended = function(){
source2 = getSound(buffer2);
source2.start();
}
source2.onended = function(){
source1 = getSound(buffer1);
source1.start();
}
function getSound(buffer){
var src = context.createBufferSource();
src.buffer = buffer;
src.connect(context.destination);
return src;
}
这可能看起来很麻烦,但我有非常具体的理由来做整个来回播放的事情,所以我真的很想弄清楚。无论如何,问题似乎是当我在 source1.onended
回调中调用 source2.start()
时,source2.onended
似乎没有听到它何时结束并且永远不会被调用。所以也有理由认为,如果我设法进入 source2.onended
回调,source1.onended
也不会听到新分配的 source1
。
所以我想我想知道的是,onended 事件的范围是什么,是否有更好的方法来完成我想做的事情?
这不是范围问题。您在第 5 行(在 getSound() 内部)创建了一个新的 source2 对象,并设置了它的 onended 属性。但是,当 source1.onended 被调用时,它会将 source2 设置为由 getSound 创建的新对象 - 不会设置 onended 。实际上,您需要在 onended 方法中设置 onended。
var source1=null;
var source2=null;
function onendedSource1() {
source2 = getSound(buffer2);
source2.onended = onendedSource2;
source2.start();
}
function onendedSource2() {
source1 = getSound(buffer1);
source1.onended = onendedSource1;
source1.start();
}
function getSound(buffer){
var src = context.createBufferSource();
src.buffer = buffer;
src.connect(context.destination);
return src;
}
// kick it all off.
source1 = getSound(buffer1);
source1.onended = onendedSource1;
source1.start();
// note you could just replace the three lines above with one call to onendedSource2();
请注意,使用 "onended" 将缓冲区链接在一起不会很好地工作,如果它们打算真正彼此邻接 - 将会有很大的差距,因为音频在音频线程中完成播放,然后在主线程上排队消息,该消息通过事件队列。如果应该有间隙(比如,两首歌逐渐消失 in/out),没关系。
我在使用网络音频 API AudioSourceBufferNode 及其 onended 事件时遇到了一个棘手的问题。
基本上我想做的是有两个 AudioSourceBufferNode,当另一个完成并继续来回播放时,每个 AudioSourceBufferNode 都会被触发。我知道一旦您调用 start() ,AudioSourceBufferNodes 就几乎完成了,并且它们被设计为在此之后进行垃圾收集。所以我试着像这样解决这个问题:
var source1;
var source2;
source1 = getSound(buffer1);
source2 = getSound(buffer2);
source1.start();
source1.onended = function(){
source2 = getSound(buffer2);
source2.start();
}
source2.onended = function(){
source1 = getSound(buffer1);
source1.start();
}
function getSound(buffer){
var src = context.createBufferSource();
src.buffer = buffer;
src.connect(context.destination);
return src;
}
这可能看起来很麻烦,但我有非常具体的理由来做整个来回播放的事情,所以我真的很想弄清楚。无论如何,问题似乎是当我在 source1.onended
回调中调用 source2.start()
时,source2.onended
似乎没有听到它何时结束并且永远不会被调用。所以也有理由认为,如果我设法进入 source2.onended
回调,source1.onended
也不会听到新分配的 source1
。
所以我想我想知道的是,onended 事件的范围是什么,是否有更好的方法来完成我想做的事情?
这不是范围问题。您在第 5 行(在 getSound() 内部)创建了一个新的 source2 对象,并设置了它的 onended 属性。但是,当 source1.onended 被调用时,它会将 source2 设置为由 getSound 创建的新对象 - 不会设置 onended 。实际上,您需要在 onended 方法中设置 onended。
var source1=null;
var source2=null;
function onendedSource1() {
source2 = getSound(buffer2);
source2.onended = onendedSource2;
source2.start();
}
function onendedSource2() {
source1 = getSound(buffer1);
source1.onended = onendedSource1;
source1.start();
}
function getSound(buffer){
var src = context.createBufferSource();
src.buffer = buffer;
src.connect(context.destination);
return src;
}
// kick it all off.
source1 = getSound(buffer1);
source1.onended = onendedSource1;
source1.start();
// note you could just replace the three lines above with one call to onendedSource2();
请注意,使用 "onended" 将缓冲区链接在一起不会很好地工作,如果它们打算真正彼此邻接 - 将会有很大的差距,因为音频在音频线程中完成播放,然后在主线程上排队消息,该消息通过事件队列。如果应该有间隙(比如,两首歌逐渐消失 in/out),没关系。