網路音訊常見問題

Boris Smus

過去幾個月來,WebKit Web Audio API 已成為網頁遊戲和音訊應用程式的強大平台。隨著開發人員熟悉這項功能,我發現他們經常會問到類似的問題。這次快速更新旨在解答一些常見問題,讓您在使用 Web Audio API 時獲得更愉快的體驗。

問:我無法發出聲響,請幫幫忙!

答:如果您不熟悉 Web Audio API,請參閱入門教學課程,或參考 Eric 的根據使用者互動播放音訊的做法。

問:我應該有幾個音訊內容?

答:一般來說,每個頁面應包含一個 AudioContext,單一音訊內容可支援許多連結至該內容的節點。雖然您可以在單一頁面中加入多個 AudioContext,但這可能會導致效能降低。

問:我有一個 AudioBufferSourceNode,我剛剛使用 noteOn() 播放了這個節點,現在想再次播放,但 noteOn() 沒有任何動作!該怎麼辦?

答:來源節點播放完畢後,就無法再播放。如要再次播放底層緩衝區,請建立新的 AudioBufferSourceNode 並呼叫 noteOn()

雖然重新建立來源節點可能效率不彰,但來源節點已針對這種模式進行大量最佳化。此外,如果您保留 AudioBuffer 的句柄,就不需要向素材資源提出其他要求,即可再次播放相同的聲音。如果您需要重複這個模式,請使用 playSound(buffer)簡單的輔助函式封裝播放功能。

問:為什麼播放音訊時,每次都需要建立新的來源節點?

答:這個架構的概念是將音訊資產與播放狀態分離。以唱片機為例,緩衝區可視為唱片和來源,而播放頭則是唱片機。由於許多應用程式都會同時播放相同緩衝區的多個版本,因此這個模式非常重要。

問:如何處理 audiovideo 標記的音訊?

答:MediaElementAudioSourceNode 正在開發中!在可用時,大致會如下所示 (在透過音訊標記播放的樣本中加入濾鏡效果):

<audio src="sounds/sample.wav" controls>
var audioElement = document.querySelector('audio');
var mediaSourceNode = context.createMediaElementSource(audioElement);
mediaSourceNode.connect(filter);
filter.connect(context.destination);

這項功能的追蹤資訊請見 這個 crbug。請注意,在這個設定中,您不需要呼叫 mediaSourceNode.noteOn(),音訊標記會控制播放作業。

問:何時可以從麥克風聽到聲音?

答:這項功能的音訊輸入部分會使用 getUserMedia 實作WebRTC 的一部分,並做為 Web Audio API 中的特殊來源節點提供。可與 createMediaElementSource 搭配使用。

問:如何檢查 AudioSourceNode 播放完畢的時間?

答:目前您必須使用 JavaScript 計時器,因為 Web Audio API 不支援這項功能。以下是 Web Audio API 教學課程的範例程式碼片段,說明如何執行這項操作:

// Assume source and buffer are previously defined.
source.noteOn(0);
var timer = setTimeout(function() {
    console.log('playback finished');
}, buffer.duration * 1000);

我們有一個未關閉的錯誤,可讓 Web Audio API 實作更精確的回呼。

問:載入音效會導致整個 UI 執行緒鎖定,導致 UI 無法回應。救命!**

答:請使用 decodeAudioData API 進行非同步載入,避免阻斷主執行緒。請參閱這個範例

問:Web Audio API 是否可用於以比即時更快的速度處理聲音?

答:是的,我們正在研究解決方案。敬請密切關注!

問題:我製作了一個很棒的 Web Audio API 應用程式,但當執行該應用程式的分頁進入背景時,聲音就會變得怪怪的!

答:這可能是因為您使用 setTimeouts,如果網頁處於背景狀態,則會產生不同的行為。日後,Web Audio API 將可使用網路音訊的內部計時器 (context.currentTime 屬性),在特定時間回呼。詳情請參閱這項功能要求

一般來說,建議您在應用程式進入背景時停止播放。您可以使用 Page Visibility API 偵測網頁進入背景時機。

問:如何使用 Web Audio API 變更音訊的音調?

答:變更來源節點的 playbackRate

問:我可以變更音調而不變更速度嗎?

答:Web Audio API 可以在音訊內容中加入 PitchNode,但這很難實作。這是因為音訊社群中沒有簡單的音高轉移演算法。已知的技術會產生雜訊,尤其是在音高轉移幅度較大時。解決這個問題的方法有兩種:

  • 時間域演算法,會導致重複的區段回音構件。
  • 頻域技術,會造成混響音效的人工產物。

雖然沒有原生節點可用於執行這些技巧,但您可以使用 JavaScriptAudioNode 執行這些技巧。這個程式碼片段可做為起點。

問:如何以所選取的取樣率建立 AudioContext?

回答:目前不支援這項功能,但我們正在研究相關問題。請參閱這項功能要求

如有其他問題,歡迎使用 web-audio 標記在 Stack Overflow 提問。