Javascript Web Audio API

音樂視覺化 - 音量頻譜

賴羿閎 Ian Lai 2020/12/12 23:45:16
468

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`
  }
}

 

賴羿閎 Ian Lai