HTML5 ——web audio API 音樂可視化(二)

上一篇 web audio API 音樂可視化(一)介紹了一些基本的API,以及如何簡單的播放一個音頻,本篇介紹一下怎麼對獲取到的音頻進行分析,並將分析後的數據繪製成圖像。javascript

最終效果請戳這裏;html

完整版代碼請戳這裏,若是還看得過眼,請給一個start⭐java

1、API介紹

分析音頻要用到一個音頻分析對象AnalyserNode,它能實時分析音頻資源的頻域和時域信息,但不會對音頻流作任何處理。建立方法:git

var analyser = ac.createAnalyser();github

要用到的屬性和方法:web

  • fftSize:設置FFT(FFT是離散傅里葉變換的快速算法,用於將一個信號變換到頻域)值得大小,用於分析獲得的頻域,爲32-2048之間的2的整數次倍,默認爲2048。實時獲得的音頻頻域的數據個數爲fftSize的一半;
  • frequencyBinCount:FFT值的一半,即實時獲得的音頻頻域的數據個數;
  • getByteFrequencyData(Uint8Array):複製音頻當前的頻域數據(數量是frequencyBinCount)到Uint8Array中。

要實時的分析音頻數據並繪製成圖形,就要用到一個requestAnimationFrame動畫函數,實時得去分析數據進行圖像渲染,此動畫函數默認的是每秒調用60次。算法

2、實例代碼

var size = 128;
var xhr = new XMLHttpRequest();
var ac = new window.AudioContext();
var analyser = ac.createAnalyser();
var gainNode = ac[ac.createGain ? "createGain" :"createGainNode"]();

gainNode.connect(ac.destination);
analyser.fftSize = size * 2;
analyser.connect(gainNode);

function getMusic(name){
    xhr.abort();
    xhr.open("get","media/"+name);
    xhr.responseType = "arraybuffer";
    xhr.onload = function(){
      ac.decodeAudioData(xhr.response,function(buffer){
        var bufferSource = ac.createBufferSource();
        bufferSource.buffer = buffer;
        bufferSource.connect(analyser);
        bufferSource[bufferSource.start ? "start" : "noteOn"](0);
      },function(err){
        console.log(err)
      })
      };
      xhr.send();
}

//實時分析音頻函數
function analysis(){
    var arr = new Uint8Array(analyser.frequencyBinCount);
    requestAnimationFrame = window.requestAnimationFrame;
    function a(){
        analyser.getByteFrequencyData(arr);
         draw(arr);  //調用繪圖函數
        console.log(arr);  //在控制檯能夠看到輸出的音頻數據
        requestAnimationFrame(a);
    }
    requestAnimationFrame(a);
}

analysis();

接下來就是畫圖函數了。canvas

對於canvas不熟悉的童鞋,請參照canvas基礎知識api

//建立canvas 並添加到文檔中
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
$(".content").html(canvas); //.content是須要展現圖形的位置

var height = $(".content").height();
var width = $(".content").width();
canvas.width = width;
canvas.height = height;

function resize(){  //若是窗口的大小改變了,繪圖跟着改變
    canvas.height = height;  //設置繪圖相關的參數和屬性
    canvas.width = width;
    var line = ctx.createLinearGradient(0,0,0,height); 
    line.addColorStop(0,"#CD96CD");
    line.addColorStop(0.5,"#C6E2FF");
    line.addColorStop(1,"#00BFFF");

    ctx.fillStyle = line;
}

resize();

function draw(arr){   //參數arr就是上面分析函數裏獲得的arr
    ctx.clearRect(0,0,width,height);  //每次畫圖以前先清空畫布
    var w = width / size;        //平均每一個柱的寬度  size 要畫的柱子的個數
    for(var i=0;i<size;i++){   //柱子的個數
        var h = arr[i] / 256 * height;              //每一個柱的高度      
        ctx.fillRect(w*i,height - h,w *0.6, h);     //w*i 表示第i個柱子的起始點的x座標,height - h表示第i個柱子的起始點的y座標,w*0.6表示柱子的寬度,h是高度
    }
}

draw函數在 analysis分析函數中調用。函數

最終效果請戳這裏;

完整版代碼,請戳這裏吧;

相關文章
相關標籤/搜索