2015-06-11 86 views
0

我對Web Audio API AudioSourceBufferNode及其冒犯事件有一個棘手的問題。Web Audio API-onended事件範圍

基本上我想要做的是有兩個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; 
} 

這可能看起來很麻煩,但我做的整個背部和來回打的事情非常具體的原因,所以我真的很喜歡的數字,出。無論如何,這個問題似乎是,當我在source1.onended回調中呼叫source2.start()時,source2.onended似乎沒有聽到它何時結束並且永遠不會被調用。所以也有理由說,如果我設法進入source2.onended回調,source1.onended也不會聽到最近重新分配的source1

所以我想我想知道的是,這個冒險事件的範圍是什麼,還有更好的方法來完成我想要做的事情嗎?

回答

0

這不是範圍問題。您正在第5行(在getSound()內部)創建一個新的source2對象,並設置其onended屬性。但是,當調用source1.onended時,它會將source2設置爲由getSound創建的NEW對象 - 它不會觸發設置。你需要在你的冒險的方法中設置這個冒險,實際上。

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」到鏈緩衝區在一起是不會正常工作,如果他們的目的是真正彼此緊靠 - 將有顯著的差距,作爲音頻完成音頻線玩,然後在主線程上排隊消息,並且該消息在事件隊列中完成。如果應該有差距(比如說兩首淡入淡出的歌曲),那很好。

+0

ahhh,太棒了。這就像一個魅力,謝謝你,並感謝解釋。對於它的價值,只要我使用相對安全的緩衝區大小(4096或更高),音頻似乎可以無縫播放。然而出於好奇,是否有更傳統的方式將緩衝區鏈接在一起? – user2871915

+0

這個怎麼樣,因爲你知道每個緩衝區的持續時間?啓動source1並安排source2在source1結束時啓動(您知道)。 source1已觸發的事件在source2的末尾安排新的source1,並在source1的末尾添加source2已觸發的事件安排source2。我認爲這隻會在源文件足夠長的時候才起作用,以便在當前正在播放的源文件結束之前處理已觸發的事件。 –