音樂視覺化 - 音量頻譜
Web Audio Api 是由 W3C 規範的可控制音訊 API,我們可以應用在網站音樂的播放、處理、編輯,使音樂視覺化等。
Web Audio Api 是根據模組化路由 (Modular routing) 的概念所設計,音源以「音訊節點 (AudioNode)」執行基本的音訊處理,各節點間可以互相連接而構成「音訊路由圖 (Audio routing graphs)」。在同一個環境 ( AudioContext ) 內,可支援多個音源與多樣化音效配置。此模組化設計可提供更高的靈活度,並能建立複雜的音訊函式與動態效果。
Web Audio Api 容器
AudioContext 是一個聲音的容器,在 AudioContext 裡,我們可以針對輸入的音源進行處理,將音訊轉換成節點的方式 ( AudioNode ) 存在,每個節點都有輸入和輸出,節點間透過 connect() 方式互相連接,讓開發者可以先設計好各種音效處理節點,再依不同情境套用,做到模組化音效處理。
const AudioContext = window.AudioContext || window.webkitAudioContext // 跨瀏覽器
const audioCtx = new AudioContext()
載入音源 MediaElementSource
音訊有多種來源,可由特定的音訊節點 (如震盪器、自訂函式,或簡易的資料陣列) 直接在 JavaScript 中產生。音源可連至 HTML 媒體元素 (如 <video> 或 <audio>),也可來自於 WebRTC 的 MediaStream (本端裝置的相機或遠方電腦)。
這邊使用 HTML 的 <audio>
tag,將音源載至瀏覽器內,並透過 createMediaElementSource 把 <audio> 內的音訊轉成「聲音節點」( AudioNode ),之後就可以和其他節點互相連接 。
<audio controls src="music.mp3"></audio>
const source = audioCtx.createMediaElementSource(myAudio)
AnalyserNode 分析節點
AnalyserNode 可以取得音源的頻率數據( FrequencyData )和時域數據( TimeDomainData ),快速傅立葉變換 (Fast Fourier Transform (FFT) ) 來捕獲音訊資料,來實現音頻的可視化。
先建立 AnalyserNode 實例
const analyser = audioCtx.createAnalyser()
我們需要先給定 AnalyserNode 的 fftSize。fftSize 數字越大,代表頻域的數據被切分得越細
analyser.fftSize = 2048
將音源與 AnalyserNode 透過 connect() 連結,再透過 analyser 輸出音訊
source.connect(analyser)
analyser.connect(audioCtx.destination)
當播放音樂時,宣告一組 Uint8Array,並反覆呼叫 analyser.getByteFrequencyData 取得音訊資料
// 播放音樂
function play() {
isPlaying = true
requestAnimationFrame(getFFTData)
}
// 取得 FFT
function getFFTData() {
const fftArray = new Uint8Array(analyser.frequencyBinCount)
analyser.getByteFrequencyData(fftArray)
// TODO 繪製頻譜
if (isPlaying) {
requestAnimationFrame(getFFTData)
}
}
繪製音頻圖
這邊以 div 來呈現音頻,從 fftArray 陣列中取得數值,並設定 div 的高度,來呈現頻率的高低起伏
function draw(fftArray) {
for (var i = 0; i < 512; i++) {
elements[i].style.height = `${fftArray[i] + 2}px`
}
}