Web Audio API- onended事件范围

时间:2015-06-11 18:41:00

标签: javascript event-handling web-audio

我对Web Audio API AudioSourceBufferNode及其引发的事件有一个棘手的问题。

基本上我想要做的是拥有两个AudioSourceBufferNodes,每个AudioSourceBufferNodes在另一个完成并继续来回播放时被触发。我知道一旦你调用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;
}

这可能看起来很麻烦,但是我有非常具体的理由来做整个来回播放的事情,所以我真的很想弄明白。无论如何,问题似乎是当我在source2.start()回调中呼叫source1.onended时,source2.onended似乎没有听到它何时结束并且从未被调用。因此,如果我设法进入source2.onended回调,source1.onended也不会听到新重新分配的source1

所以我想我想知道的是,这个活动的范围是什么,是否有更好的方法来完成我想要做的事情?

1 个答案:

答案 0 :(得分:0)

这不是范围问题。您将在第5行(在getSound()内部)创建一个新的source2对象,并设置其onended属性。但是,当调用source1.onended时,它会将source2设置为由getSound创建的NEW对象 - 这将不会有onended set。你需要在你的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”链接缓冲区并不能很好地工作,如果它们是真正相互邻接的 - 会有一个显着的差距,因为音频完成在音频线程中播放,然后排队主线程上的消息,该消息通过事件队列。如果应该有间隙(比如,两首淡入/淡出的歌曲),那就没关系了。