關於Audio API簡單介紹javascript
閱讀時間:約2 - 3分鐘css
一切源於一個簡單的需求,音樂播放器,一開始就只是寫個UI,調用媒體 API,而後加上了經過進度條映射到seek音頻進度到功能,再往上加需求的時候,就是音頻可視化了。java
記得十多年前的電腦上,Windows Media Player、千千靜聽等音頻軟件都會有音頻可視化的界面,都是各類各樣隨着音頻的變化,繪製不一樣規律的圖案。但是在瀏覽器中,作音頻分析,對於我來講真的有點難以想象,直到我看到了AudioContext,它給音頻處理打開了一扇門。css3
AudioContext 是 Audio API 中的音頻上下文,一切對於音頻的操做,都發生在 AudioContext。用你們熟悉的東西來講的話 AudioContext 和 Canvas 的上下文是相似的概念。git
Audio API 在 W3C 標準中仍是草案狀態(Web Audio API),可是很多PC現代主流瀏覽器已經實現了一部分的功能,因此咱們仍是能夠先用Chrome來嘗試一番。github
// 建立音頻上下文,這是一種兼容的寫法
let actx = new (window.AudioContext || webkitAudioContext)();
// 咱們從網頁的audio元素來鏈接音頻
let audio = document.getElementById("didit");
let source = actx.createMediaElementSource(audio);
複製代碼
AudioContext 提供三種方式來提供音頻內容web
AudioContext.createBufferSource()
api
經過AudioContext.createBuffer建立或AudioContext.decodeAudioData解碼音軌來建立內容瀏覽器
AudioContext.createMediaElementSource()
工具
經過媒體元素來獲取
AudioContext.createMediaStreamSource()
經過流媒體獲取(如麥克風)
// 建立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現代瀏覽器下打開)