過去幾個月來,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()
,音訊標記會控制播放作業。
問:何時可以從麥克風聽到聲音?
答:這項功能的音訊輸入部分會使用 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 提問。