HTML5音樂可視化


環境搭建

1,安裝nodejs和Git,配置環境變量
2,安裝express,npm install -g express-generator
3,創建項目,express -e music(項目名稱)
4,進入項目,npm install
5,安裝實時監聽工具,npm install -g supervisor
6,測試,supervisor bin/www,瀏覽器驗證127.0.0.1:3000

sublime運行js文件

1,打開build system -> new build system新建配置文件

{
    "cmd": ["node", "--use-strict", "--harmony", "$file"],
    "selector": "source.js"
}

保存文件Node.sublime-buildbuild system設置為Node

音樂的獲取與播放

構建應用的前后端

1,新建媒體數據文件夾,public/media,把音頻數據放入其中
2,搭建頁面CSS框架,/public/stylesheets/index.css
3,讀取頁面內容,views/index.ejs
4,后台路由控制,routes/index.js,獲取音樂列表並返回給前段

ajax請求服務端音頻數據

javascripts下新建文件index.js,在views/index.ejs引用創建的文件

<script type="text/javascript" src="/javascripts/index.js"></script>

編輯創建文件,實現點擊效果

<ul id="list">
        <% music.forEach(function(name){ %>
              <li title="<%= name %>"><%= name %></li>    #設置title屬性
        <% }) %>
</ul>

解碼並播放音頻

AudioContext

包含各個AudioNode對象以及它們的聯系的對象,即audio上下文對象。一個document中只有一個AudioContext創建:var ac = new window.AudioContext();

屬性:

destination,AudioDestinationNode對象,所有的音頻輸出聚集地,相當於音頻的硬件,所有的AudioNode都直接或間接連接到這里。

currentTime,AudioContext從創建開始到當前的時間(秒)。

方法:

decodeAudioData(arrayBuffer,succ(buffer),err),異步解碼包含在arrayBuffer中音頻數據

createBufferSource(),創建autioBufferSourceNode對象

createAnalyser(),創建AnalyserNode對象

createGain()/createGainNode(),創建GainNode對象

AudioBufferSourceNode

表示內存中的一段音頻資源,其音頻數據存儲在AudioBuffer中(其buffer屬性)
創建:var buffersource = ac.createBufferSource();

屬性:

buffer,AudioBuffer對象,表示要播放的音頻資源數據
——子屬性:duration,該音頻資源的時長(秒)

loop,是否循環播放,默認false

onended,可綁定音頻播放完畢時調用的時間處理程序

方法:

start/noteOn(when=ac.currentTime,offset=0,buration=buffer.duration-offset),開始播放音頻。
when:何時開始播放;
offset:從音頻的第幾秒開始播放;
duration:播放幾秒

stop/noteOff(when=ac.currentTime),結束播放音頻

添加音量控制

GainNode

改變音頻音量的對象,改變通過它的音頻數據所有的sampleframe的信號強度
創建:var gainNode = ac.createGain()/ac.createGainNode();

gain,AudioParam對象,通過改變其value值可以改變音頻信號的強弱,默認的value屬性值為1,通過最小值為0,最大值為1,其value值也可以大於1,小於0

播放bug修復

問題:播放第二首歌時,第一首歌依然在播放,主要原因是每次點擊音樂列表即調用load("/media/"+this.title),數據解碼並播放:

xhr.onload = function(){
    ac.decodeAudioData(xhr.response, function(buffer){
        var bufferSource = ac.createBufferSource();
        bufferSource.buffer = buffer;
        bufferSource.connect(gainNode);
        bufferSource[bufferSource.start?"start":"noteOn"](0);
    }, function(err){
                console.log(err);
    });
}

解決方法:
對音頻數據賦空值var source = null;,保存上一首歌的解碼數據source = bufferSource;,判斷執行停止播放source && source[source.stop ? "stop" : "noteoff"](0);

音樂數據可視化

AnalyserNode

音頻分析對象,它能實時的分析音頻資源的頻域和時域信息,但不會對音頻流做任何處理
創建:var analyser = ac.createAnalyser();

fftSize,設置FFT(FFT是離散傅里葉變換的快速算法,用於將一個信號變換到頻域)值得大小,用於分析得到頻域,為32 - 2048之間2的整數倍,默認為2048。實時得到的音頻頻域的數據個數為FFTSize的一半

frequencyBinCount,FFT值得一半,即實時得到的音頻頻域的數據個數

getByteFrequencyData(Uint8Array),復制音頻當前的頻域數據(數量是FrequencyBinCount)到Uint8Array(8位無符號整型類型化數組)中

創建Analyser對象:

var analyser = ac.createAnalyser();
analyser.fftSize = 512;
analyser.connect(gainNode);

連接到分析對象獲取數據:bufferSource.connect(analyser);

實現可視化功能函數:

function visualizer(){
    var arr = new Uint8Array(analyser.frequencyBinCount);
    analyser.getByteFrequencyData(arr);
    console.log(arr);
}

調用visualizer函數:

利用canvas將音樂數據可視化(柱狀圖)

views下加入id<div class="right" id="box"></div>

控制高度變化:

var box = $("#box")[0];
var height, width;
var canvas = document.createElement("canvas");
box.appendChild(canvas);

function resize(){
    height = box.clientHeight;
    width = box.clientWidth;
    canvas.height = height;
    canvas.width = width;
}
resize();    #調用觸發函數

window.onresize = resize;

利用canvas將音樂數據可視化(圓點圖)

應用優化

webAudio API

webAudio核心功能封裝為對象


Copyright ©  吳華錦
雅致寓於高閣漁舟唱晚,古典悠然
格調外發園林綠樹縈繞,馥郁清香


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM