過去幾個月來,WebKit Web Audio API 已成為網頁遊戲和音訊應用程式的熱門平台。開發人員熟悉這項功能後,我發現他們會反覆提出類似問題。我們希望透過這項快速更新,解決一些常見問題,讓您享有更愉快的 Web Audio API 使用體驗。
問:幫幫我,我無法發出聲音!
答:如果您是 Web Audio API 的新手,請參閱入門教學課程,或是 Eric 的根據使用者互動播放音訊食譜。
問:我應該要有幾個音訊內容?
答:一般來說,每個網頁應包含一個 AudioContext,單一音訊環境可支援多個連結至該環境的節點。雖然您可以在單一頁面中加入多個 AudioContext,但這可能會導致效能下降。
問:我有一個 AudioBufferSourceNode,剛才用 noteOn() 播放過,現在想再次播放,但 noteOn() 卻沒有任何作用!該怎麼辦?
答:來源節點播放完畢後,就無法繼續播放。如要再次播放基礎緩衝區,請建立新的 AudioBufferSourceNode 並呼叫 noteOn()。
雖然重新建立來源節點可能感覺效率不彰,但來源節點已針對這種模式進行大量最佳化。此外,如果保留 AudioBuffer 的控制代碼,就不需要再次要求資產播放相同音效。如果發現自己需要重複這個模式,請使用 簡單的輔助函式 (例如 playSound(buffer)) 封裝播放作業。
問:播放音效時,為什麼每次都需要建立新的來源節點?
答:這個架構的概念是將音訊資產與播放狀態分離。以唱片播放器為例,緩衝區相當於唱片,來源則相當於唱針。由於許多應用程式會同時播放同一緩衝區的多個版本,因此這個模式至關重要。
問:如何處理 audio 和 video 標記的聲音?
答: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(),音訊標記會控制播放。
問:何時可以透過麥克風收音?
答:這項功能的音訊輸入部分將透過 WebRTC 使用 getUserMedia 實作,並以 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 將能使用 Web Audio 的內部計時器 (context.currentTime 屬性),在特定時間回呼。詳情請參閱這項功能要求。
一般來說,應用程式進入背景時,建議停止播放。您可以使用 Page Visibility API 偵測網頁何時進入背景。
問:如何使用 Web Audio API 變更聲音的音調?
答:變更來源節點上的 playbackRate。
問:我可以變更音調,但不變更速度嗎?
答:Web Audio API 可能會在音訊環境中加入 PitchNode,但這項功能難以實作。這是因為音訊社群沒有直接的音高轉移演算法。已知技術會產生失真,尤其是在音高變化幅度較大的情況下。解決這個問題的方法有兩種:
- 時域演算法,導致重複的區隔回音構件。
- 頻域技術,會導致迴響音訊失真。
雖然沒有執行這些技術的原生節點,但您可以使用 JavaScriptAudioNode 執行。這個程式碼片段可做為起點。
問:如何以我選擇的取樣率建立 AudioContext?
答:目前不支援這項功能,但我們正在研究中。請參閱這項功能要求。
如有其他問題,歡迎前往 StackOverflow 提問並加上 web-audio 標記。