Audio API - 隨音訊跳動的Cube

Dominic_Ming發表於2017-12-22

關於Audio API簡單介紹

閱讀時間:約2 - 3分鐘

一切源於一個簡單的需求,音樂播放器,一開始就只是寫個UI,呼叫媒體 API,然後加上了通過進度條對映到seek音訊進度到功能,再往上加需求的時候,就是音訊視覺化了。

記得十多年前的電腦上,Windows Media Player、千千靜聽等音訊軟體都會有音訊視覺化的介面,都是各種各樣隨著音訊的變化,繪製不同規律的圖案。可是在瀏覽器中,做音訊分析,對於我來說真的有點不可思議,直到我看到了AudioContext,它給音訊處理開啟了一扇門。

什麼是AudioContext

AudioContext 是 Audio API 中的音訊上下文,一切對於音訊的操作,都發生在 AudioContext。用大家熟悉的東西來說的話 AudioContext 和 Canvas 的上下文是類似的概念。

Audio API 在 W3C 標準中還是草案狀態(Web Audio API),但是不少PC現代主流瀏覽器已經實現了一部分的功能,所以我們還是可以先用Chrome來嘗試一番。

建立AudioContext 並且連線音訊

// 建立音訊上下文,這是一種相容的寫法
let actx = new (window.AudioContext || webkitAudioContext)();
// 我們從網頁的audio元素來連線音訊
let audio = document.getElementById("didit");
let source = actx.createMediaElementSource(audio);
複製程式碼

AudioContext 提供三種方式來提供音訊內容

  • AudioContext.createBufferSource()

    通過AudioContext.createBuffer建立或AudioContext.decodeAudioData解碼音軌來建立內容

  • AudioContext.createMediaElementSource()

    通過媒體元素來獲取

  • AudioContext.createMediaStreamSource()

    通過流媒體獲取(如麥克風)

利用Analyzer分析音訊內容

// 建立analyzer
let analyzer = actx.createAnalyser();
// 建立用來獲取音訊資料的緩衝buffer
let bufferLength = analyzer.fftSize;
let dataArray = new Uint8Array(bufferLength);

// 連線analyzer和音訊元
source.connect(analyzer)
analyzer.connect(actx.destination)
複製程式碼

在使用Analyser的時候,我遇到了一個問題,analyzer沒有辦法獲取到當前播放的內容。但是我注意到了在其他示例中,音訊上下文和他的工具集之間建立了連線。

這就引出了Audio API的工作方式,他的工具集和音訊上下文的目的地直接,是通過connect耦合的,在使用工具的時候,需要兩方互相連線。

我們在這裡使用analyzer.connect(actx.destination)連線音訊上下文目的地的原因是,音訊的播放資訊在AudioContext連線音訊元素的時候,就被AudioContext接管了,是它在傳輸現在播放音訊的資料,所以需要如此連線。

一個簡單的例子

function getNowText(some) {
  analyzer.getByteTimeDomainData(dataArray);

  let one = (findMax(dataArray) / 128);
  let delta = some - one;

  one = delta * 0.618 + one;

  c.rotate(0.5,0.5,0);
  c.scale(one , one , one );
  c.update();

  requestAnimationFrame(getNowText.bind(this,one))
}
複製程式碼

使用一個我之前寫的css3d庫(HakeCSS3D)來進行簡單的視覺效果,這裡我們取音訊最大值來作為控制變數,並實時更新。(請忽略我這個充滿副作用的寫法)

analyzer.getByteTimeDomainData(dataArray);是用來獲取當前時間的音訊分析資訊,它返回的資訊是128為基準值的整數。

實際效果參考:mcube.hustfe.com/ (請在PC現代瀏覽器下開啟)

瀏覽器支援情況

相關文章