此文介紹HTML5音頻API的主要框架和工作流程,因為音頻處理模塊很多,因此只簡單介紹幾種音頻處理模塊,並通過例子來展示效果。後續會介紹利用HTML5音頻API實現的項目,歡迎大家關注,敬請期待。
HTML5音頻API的主要框架和工作流程如下圖,在 AudioContext 音頻上下文中,把音頻文件轉成 buffer格式,從音頻源 source 開始,經過 AuidoNode 處理音頻,最後到達 destination 輸出音樂。這裡形成了一個音頻通道,每個模塊通過 connect 方法連結並傳送音頻。
AudioContextAudioContext 是一個音頻上下文,像一個大工廠,所有的音頻在這個音頻上下文中處理。
let audioContext = new(window.AudioContext || window.webkitAudioContext)();
AudioContext 音頻上下文提供了很多屬性和方法,用於創建各種音頻源和音頻處理模塊等,這裡只介紹一部分,更多屬性和方法可到MDN(https://developer.mozilla.org/zh-CN/docs/Web/API/AudioContext)查閱文檔。
屬性AudioContext.destination
返回 AudioDestinationNode 對象,表示當前 AudioContext 中所有節點的最終節點,一般表示音頻渲染設備。
方法AudioContext.createBufferSource()
創建一個 AudioBufferSourceNode 對象, 他可以通過 AudioBuffer 對象來播放和處理包含在內的音頻數據。
AudioContext.createGain()
創建一個 GainNode,它可以控制音頻的總音量。
AudioContext.createBiquadFilter()
創建一個 BiquadFilterNode,它代表代表一個雙二階濾波器,可以設置幾種不同且常見濾波器類型:高通、低通、帶通等。
createOscillator()
創建一個 OscillatorNode, 它表示一個周期性波形,基本上來說創造了一個音調。
音頻轉換成Buffer格式使用 decodeAudioData() 方法把音頻文件編譯成buffer格式。
function decodeAudioData(audioContext, url) {
return new Promise((resolve) => {
let request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
request.onload = () => {
audioContext.decodeAudioData(request.response, (buffer) => {
if (!buffer) {
alert('error decoding file data: ' + url);
return;
} else {
resolve(buffer);
}
})
}
request.onerror = function() {
alert('BufferLoader: XHR error');
}
request.send();
})
}
let buffer = decodeAudioData(audioContext, './sounds/music.mp3');
AudioNode音頻節點接口是一個音頻處理模塊。包括音頻源,音頻輸出,中間處理模塊。
方法AudioNode.connect()
連結兩個 AudioNode 節點,把音頻從一個 AudioNode 節點輸出到另一個 AudioNode 節點,形成一個音頻通道。
AudioNode.disconnect()
把 AudioNode 節點與其他節點斷開連結。
AudioBufferSourceNode音頻源有多種,這裡只介紹 buffer 的音頻源, buffer 的音頻源通過 AudioContext 接口的 createBufferSource 方法來創建。音頻源節點繼承 AudioNode 音頻節點。
let bufferSource = audioContext.createBufferSource();
創建了 AudioBufferSourceNode 對象後,把 buffer 格式的音頻數據賦值給 AudioBufferSourceNode 對象的 buffer 屬性,此時音頻已經傳遞到音頻源,可以對音頻進行處理或輸出。
bufferSource.buffer = buffer;
方法AudioBufferSourceNode.start([when][, offset][, duration])
開始播放。
AudioBufferSourceNode.stop([when])
停止播放,注意調用該方法後,無法再次調用 AudioBufferSourceNode.start 播放。
AudioDestinationNode音頻終點是通過 AudioContext 接口的 destination 屬性訪問的。音頻終點繼承 AudioNode 音頻節點,
AudioDestinationNode 節點無法再把音頻信息傳遞給下一個音頻節點,即無法再連結其他音頻節點,因為他已經是終點,沒有輸出,也可以理解為他自己就是輸出。
let audioDestinationNode = audioContext.destination;
此時我們有音頻起點 AudioBufferSourceNode 和音頻終點 AudioDestinationNode ,使用 AudioNode.connect() 方法把起點和終點連結起來,就形成了一條有輸入輸出的音頻通道,可以把音頻直接播放出來。
bufferSource.connect(audioDestinationNode);
戳我看慄子
GainNode用於音量變化。它是一個 AudioNode 類型的音頻處理模塊。
let gainNode = audioContext.createGain();
把音頻源、音頻輸出和音頻處理模塊連結一起,形成可控制音量大小的音頻。
bufferSource.connect(gainNode);
gainNode.connect(audioDestinationNode);
let controlVolume = value => {
gainNode.gain.value = value);
}
// 兩倍音量播放
controlVolume(2);
戳我看慄子
BiquadFilterNode表示一個簡單的低頻濾波器,可控制聲調。它是一個 AudioNode 類型的音頻處理模塊。
let filterNode = audioContext.createBiquadFilter();
輸出一個變調的音頻:
bufferSource.connect(filterNode);
filterNode.connect(audioDestinationNode);
let controlFrequency = function(value) {
filterNode.frequency.value = value;
}
// 音頻為1000變調
controlFrequency(1000);
多個音頻源在一個音頻上下文中,可以有多個音頻處理通道,即多個音頻源同時輸出。各個音頻處理通道內的操作是獨立的,不影響其他音頻通道。
戳我看慄子
多個音頻處理模塊一個音頻源可以經過多個音頻處理模塊處理,音頻處理模塊疊加效果後輸出。
戳我看慄子:
https://codepen.io/leechikit/pen/Nvpwrq
歡迎關注:
Leechikit (https://segmentfault.com/u/leechikit/articles)
原文連結:
https://segmentfault.com/a/1190000010561222
到此本文結束,歡迎提問和指正。寫原創文章不易,若本文對你有幫助,請點讚、推薦和關注作者支持。
相關文章推薦
HTML5拖放API Drag and Drop
mui初級入門教程(一)— 小白入手mui的學習路線 html5+ App開發工程化實踐之路
相關講堂推薦
html5+ App開發工程化實踐之路
html5+ App開發之 Android 平臺離線集成 5+ SDK