音頻可視化,顧名思義,就是經過獲取音頻的波形、頻率和其餘來自音頻的數據轉換成圖像,再到屏幕上顯示出來。經過它,咱們可以製做一些炫酷的前端音樂界面。javascript
下面,我將分析一個來自雲音樂技術團隊的音頻可視化開發案例,快速幫助小白,製做本身喜歡的炫酷的音頻可視化界面。html
先上圖前端
想開發這麼一個炫酷的音頻界面,咱們能夠先來聊聊 canvashtml5
canvas是HTML5中用於圖形繪製的容器元素,它一般經過JavaScript腳原本完成圖形繪製。要完成咱們下面的音頻可視化開發,咱們能夠借組結構canvas的幾個方法,下面將經過開發一個頁面倒計時的小案例來幫助初學者瞭解canvas的一些屬性和方法。java
先上代碼git
<canvas id="myCanvas">
</canvas>
<script>
const canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'red';
ctx.font = "50px Verdana";
let dis = 550;
let i = 10;
function animation(){
requestAnimationFrame(function(){
if(dis >= 0){
--dis;
if(dis%50 == 0 ){
ctx.clearRect(0,0,300,150);
ctx.fillText(i--,100,100);
}
animation();
}
});
}
animation();
</script>
複製代碼
咱們在html
頁面建立一個canvas
畫布元素並設置id爲myCanvas
,它的默認大小是300*150,建立好了這塊畫布,接下來咱們就能在JavaScript腳本中繪製圖形了。github
先經過getElementById()
找到這個元素,而後建立canvas對象ctx
並設置填充色爲紅色,字體爲Verdana,大小爲50px,設置dis
變量用於條件控制,再定義一個i
變量用於顯示倒計時數字,而後咱們就能夠開始在咱們的畫布裏繪製倒計時數字了。web
建立一個animation
函數,在這個函數裏面,咱們使用了一個html5專門用於請求動畫的APIrequestAnimationFrame
請求動畫幀,相比於定時器setTimeout
,它不會引發丟幀、丟幀,看起來更加流暢。canvas
在requestAnimationFrame
裏面,先設置刷幀條件dis>=0
,dis
每次減一,總共550次,再設置條件爲每50次執行一次繪製操做,在每次繪製以前,經過clearRect(x,y,width,height)
方法將畫布上給定矩形清空,它的4個參數分別表示要清除的矩形左上角的x,y座標,以及要清空矩形的寬度和高度,單位以像素計算。而後再經過fillText()
畫布指定位置繪製倒計時數字,該方法接收四個參數:text
輸出的文本,x
繪製文本的x座標,y
繪製文本的y座標,注意:這兩個值都是相對於畫布,最後一個參數maxWidth
表示容許文本的最大寬度,它是一個可選參數。數組
接着咱們經過遞歸的方式調用animation()
函數直到倒計時結束,最後在外部調用一下animation()
函數,至此,一個簡單的倒計時界面完成。咱們還能夠給canvas
經過innerWidth
和innerHeight
設置
畫布大小。
canvas
能夠繪製各類圖形,更多內容請自行參看canvas
內容
聊完了canvas
,接下來就是咱們的正題了。
在開始以前,咱們還須要瞭解什麼是Web Audio。
Web Audio 是 Web 端處理和分析音頻的一套 API 。它可使用戶在音頻上下文中進行音頻操做,具備模塊化路由的特色,它也使咱們可以控制音頻的空間化。
經過Web Audio,咱們可以實現取數據和映射數據兩個過程,下面咱們將實現這兩個過程。
咱們先在頁面建立一個canvas
元素和一個audio
標籤以及一個用於做播放按鈕的a
標籤。
而後在JavaScript裏面獲取audio
和a
這兩個元素,並給a
標籤設置單擊事件。
var btn = document.getElementById('play-btn');
var audio = document.getElementById('audio');
btn.addEventListener('click',function(){
btn.style.display = 'none';
audio.play();
onloadAudio();
})
複製代碼
在onLoadAudio()
函數裏面,咱們先獲取canvas
元素,設置它佔滿整個頁面,再建立canvas
的對象。
var canvas = document.getElementById('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
var ctx = canvas.getContext('2d');
複製代碼
建立 **AudioContext **對象,用來控制它所包含的節點的建立,以及音頻處理、解碼操做的執行。
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
複製代碼
經過 createAnalyser()
方法建立 **AnalyserNode **用來獲取音頻時間和頻率數據,實現音頻數據可視化。
var analyser = audioCtx.createAnalyser();
analyser.fftSize = 512;
複製代碼
fftSize 在 MDN 裏面介紹是快速傅里葉變換的一個參數,取值必須是從32到32768範圍內的2的非零冪,默認值爲2048,在這裏咱們取512。另外,fftSize 的值決定了 frequencyData 的長度。
將音頻節點關聯到 AudioContext上,做爲整個音頻分析的輸入。
咱們採用MediaElementAudioSourceNode 將<audio>
節點做爲輸入源,並將音頻關聯到分析器,再將分析器關聯到輸出設備。
var source = audioCtx.createMediaElementSource(audio);
source.connect(analyser);
analyser.connect(audioCtx.destination);
複製代碼
接下來獲取頻率數組。
var bufferLength = analyser.frequencyBinCount;
var dataArray = new Uint8Array(bufferLength);
複製代碼
frequencyBinCount()
的值是 fftSize 取值的一半,因此這裏的 Uint8Array() 數組的長度就是256。
而後設置音柱的寬度,而高度只定義變量而不賦值,留在後面經過dataArray[]
數組動態設置
var barWidth = WIDTH / bufferLength*1.5;
var barHeight;
複製代碼
定義一個 renderFrame()
函數用於繪製音柱,而且每次繪製以前都先將整個畫布清除,而後更新頻率數組。
ctx.clearRect(0,0,WIDTH,HEIGHT);
analyser.getByteFrequencyData(dataArray);
複製代碼
經過for
循環裏面設置每個矩形的高度,再根據高度設置一個背景色,而後繪製矩形,並填充背景顏色。而後經過遞歸的方式調用函數。
barHeight = dataArray[i];
var r = barHeight + 25 * (i / bufferLength);
var g = 250 * (i / bufferLength);
var b = 50;
ctx.fillStyle = "rgb(" + r + "," + g + "," + b + ")";
ctx.fillRect(x,HEIGHT-barHeight,barWidth,barHeight);
x += barWidth+2;
複製代碼
最後,運行代碼,體驗屬於你的可視化音樂吧。
本文簡單介紹了 canvas 的使用和如何經過 Web Audio 的相關 API 獲取音頻的頻率數據。
然而 canvas
和 Web Audio
的用處遠遠不止於此,讀者還能夠發揮想象力和創造力,開發出更多有意思的項目。
附上項目源碼:github.com/anpeier/les…