zoukankan      html  css  js  c++  java
  • 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-实例(二)

  • 相关阅读:
    CentOS6+nginx+uwsgi+mysql+django1.6.6+python2.6.6
    CentOS 6.5下安装Python+Django+Nginx+uWSGI
    python学习之旅
    Gitlab安装操作说明书
    快速上手git gitlab协同合作
    在centos6.3用yum安装redis
    CentOS 6.5 下安装 Redis 2.8.7
    Ruby Gems更换淘宝源方法
    Apache 日志分析(一)
    Apache 日志分析(二)
  • 原文地址:https://www.cnblogs.com/tianma3798/p/6033643.html
Copyright © 2011-2022 走看看