HTML5 WebAudioAPI(三)--繪制頻譜圖


HTML

<style>
    #canvas {
        background: black;
    }
</style>
<div class="container">
    <button class="btn btn-primary" id="playBtn">
        <i class="glyphicon glyphicon-pause"></i>
    </button>
</div>
<canvas id="canvas" width="800" height="300"></canvas>

實例1,繪制頻譜圖:

var url='../content/audio/海闊天空.mp3';
if (!window.AudioContext) {
    alert('您的瀏覽器不支持AudioContext');
} else {
    //創建上下文
    var ctx = new AudioContext();
    var source = null;
    //使用Ajax獲取音頻文件

    var request = new XMLHttpRequest();
    request.open('GET', url, true);
    request.responseType = 'arraybuffer';//配置數據的返回類型
    //加載完成
    request.onload = function () {
        var arraybuffer = request.response;
        ctx.decodeAudioData(arraybuffer, function (buffer) {
            //創建分析器
            var analyser = ctx.createAnalyser();
            source = ctx.createBufferSource();
            //將source與分析器鏈接
            source.connect(analyser);
            //將分析器與destination鏈接,這樣才能形成到達揚聲器的通路
            analyser.connect(ctx.destination);
            //將解碼后的buffer數據復制給source
            source.buffer = buffer;
            //播放
            source.start(0);

            //開始繪制頻譜圖
            function drawSpectrum() {
                var canvas = document.getElementById('canvas'),
                    cwidth = canvas.width,
                    cheight = canvas.height - 2,
                    meterWidth = 10,//能量條的寬度
                    gap = 2,//能量條的間距
                    meterNum = 800 / (10 + 2),//計算當前畫布上能畫多少條
                    ctx = canvas.getContext('2d');
                var capHeight = 2;//
                var array = new Uint8Array(analyser.frequencyBinCount);
                analyser.getByteFrequencyData(array);
                console.info(array.length);
                var step = Math.round(array.length / meterNum);//計算從analyser中的采樣步長

                //清理畫布
                ctx.clearRect(0, 0, cwidth, cheight);
                //定義一個漸變樣式用於畫圖
                var gradient = ctx.createLinearGradient(0, 0, 0, 300);
                gradient.addColorStop(1, '#0f0');
                gradient.addColorStop(0.5, '#ff0');
                gradient.addColorStop(0, '#f00');
                ctx.fillStyle = gradient;
                //對信源數組進行抽樣遍歷,畫出每個頻譜條
                for (var i = 0; i < meterNum; i++) {
                    var value = array[i * step];
                    ctx.fillRect(i * 12/*頻譜條的寬度+條間距*/, cheight - value + capHeight,
                        meterWidth, cheight);
                }
                requestAnimationFrame(drawSpectrum)
            }
            requestAnimationFrame(drawSpectrum)
        }, function (e) {
            console.info('處理出錯');
        });
    }
    request.send();




    //綁定播放按鈕
    $('#playBtn').click(function () {
        var icon = $(this).find('i');;
        icon.toggleClass('glyphicon-play').toggleClass('glyphicon-pause');
        //停止播放
        source.stop();
    });
}

實例2,繪制緩慢下落的帽頭

var url='../content/audio/海闊天空.mp3';
if (!window.AudioContext) {
    alert('您的瀏覽器不支持AudioContext');
} else {
    //創建上下文
    var atx = new AudioContext();
    var source = null;
    //使用Ajax獲取音頻文件
    var request = new XMLHttpRequest();
    request.open('GET', url, true);
    request.responseType = 'arraybuffer';//配置數據的返回類型
    //加載完成
    request.onload = function () {
        var arraybuffer = request.response;
        atx.decodeAudioData(arraybuffer, function (buffer) {
            //創建分析器
            var analyser = atx.createAnalyser();
            source = atx.createBufferSource();
            //將source與分析器鏈接
            source.connect(analyser);
            //將分析器與destination鏈接,這樣才能形成到達揚聲器的通路
            analyser.connect(atx.destination);
            //將解碼后的buffer數據復制給source
            source.buffer = buffer;
            //播放
            source.start(0);


            //開始繪制頻譜圖
            var canvas = document.getElementById('canvas'),
                cwidth = canvas.width,
                cheight = canvas.height - 2,
                meterWidth = 10,//能量條的寬度
                gap = 2,//能量條的間距
                meterNum = 800 / (10 + 2);//計算當前畫布上能畫多少條
            var ctx = canvas.getContext('2d');
            var capHeight = 2,//冒頭的高度
                capStyle = '#fff',//冒頭的顏色
                capYPositionArray = [];//將上一面各個冒頭的位置保存到這個數組
            //定義一個漸變樣式用於畫圖
            var gradient = ctx.createLinearGradient(0, 0, 0, 300);
            gradient.addColorStop(1, '#0f0');
            gradient.addColorStop(0.5, '#ff0');
            gradient.addColorStop(0, '#f00');
            //繪制頻譜圖
            function drawSpectrum() {
                var array = new Uint8Array(analyser.frequencyBinCount);
                analyser.getByteFrequencyData(array);
                var step = Math.round(array.length / meterNum);//計算從analyser中的采樣步長
                //清理畫布
                ctx.clearRect(0, 0, cwidth, cheight);
                //對信源數組進行抽樣遍歷,畫出每個頻譜條
                for (var i = 0; i < meterNum; i++) {
                    var value = array[i * step]; //取樣作為y軸的值
                    //繪制緩慢降落的冒頭
                    if (capYPositionArray.length < Math.round(meterNum)) {
                        capYPositionArray.push(value);//初始化保存冒頭位置的數組,將第一個畫面位置保存
                    }
                    ctx.fillStyle = capStyle;
                    //1.開始繪制冒頭
                    if (value < capYPositionArray[i]) {
                        //使用前一次數據
                        ctx.fillRect(i * 12, cheight - (--capYPositionArray[i]), meterWidth, capHeight);
                    } else {
                        //否則,直接使用當前數據並記錄
                        ctx.fillRect(i * 12, cheight - value, meterWidth, capHeight);
                        capYPositionArray[i] = value;
                    }
                    //2.開始繪制頻譜條
                    ctx.fillStyle = gradient;
                    ctx.fillRect(i * 12/*頻譜條的寬度+條間距*/, cheight - value + capHeight,
                        meterWidth, cheight);
                }
                requestAnimationFrame(drawSpectrum);
            }
            requestAnimationFrame(drawSpectrum);
        }, function (e) {
            console.info('處理出錯');
        });

    }
    request.send();
    //綁定播放按鈕
    $('#playBtn').click(function () {
        var icon = $(this).find('i');;
        icon.toggleClass('glyphicon-play').toggleClass('glyphicon-pause');
        //停止播放
        source.stop();
    });
}

 

內容來源:http://www.cnblogs.com/Wayou/p/3543577.html

更多參考:

HTML5 WebAudioAPI簡介(一)

HTML5 WebAudioAPI-實例(二)


免責聲明!

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



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