美文网首页前端杂货铺
手把手教你用Js实现音频可视化

手把手教你用Js实现音频可视化

作者: loosenRogers | 来源:发表于2018-05-06 19:19 被阅读31次

    HTML5中提供了Web Audio API,开发者可以通过这个API为音频添加特效,实现音频可视化效果。下面我们就来一步步实现一个音频可视化webapp,文中描述如有错误或不足,欢迎斧正。

    创建AudioContext

    var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    

    AudioContext接口表示有音频模块链接而成的音频处理图,每个模块对应一个AudioNode。AudioContext可以控制它所包含的节点的创建,以及音频处理、解码操作的执行。做任何事情之前都要先创建AudioContext对象,因为一切都发生在这个环境之中。

    创建AudioBufferSourceNode

    var AudioBufferSourceNode = audioCtx.createBufferSource();
    

    AudioBufferSourceNode接口可以通过AudioBuffer对象来播放音频数据。下面我们需要获得音频数据,转换成AudioBuffer对象,赋值到AudioBufferSourceNode的buffer属性。

    获取音频数据

    这边所获得的音频数据最终是要转换成AudioBuffer对象,供AudioBufferSourceNode使用。AudioBuffer对象可以通过AudioContext.createBuffer来创建或者通过AudioContext.decodeAudioData解码音轨后返回。这边,我们decodeAudioData()方法解码来获得。decodeAudioData()方法可用于异步解码音频文件中的ArrayBuffer。ArrayBuffer数据可以通过XMLHttpRequest或者FileReader来获取。

    FileReader获取本地音频ArrayBuffer

    页面中添加input标签来获取本地音频

    <input id="loadfile" type="file">
    

    FileReader获取ArrayBuffer类型音频数据

    document.getElementById('loadfile').onchange = function(){
        var file = this.files[0];
        var fr = new FileReader();
    
        fr.onload = function(e){
            audioCtx.decodeAudioData(e.target.result,function(buffer){
                playFun(buffer);  // 解码后返回的AudioBuffer对象作为播放函数的参数传入
            },function(err){
                console.log(err);
            })
        }
        fr.readAsArrayBuffer(file);
    }
    
    Ajax获取音频数据

    这边把ajax获取音频数据封装到一个函数中

    function getData() {
      var request = new XMLHttpRequest();
      request.open('GET', url, true);
      request.responseType = 'arraybuffer'; // 设置数据类型为arraybuffer
      request.onload = function() {
        var audioData = request.response;
        audioCtx.decodeAudioData(audioData, function(buffer) {
            playFun(buffer); 
          },
          function(e){"Error with decoding audio data" + e.err});
      }
      request.send();
    }
    

    播放音频数据

    现在我们已经获得音频数据并将其转换成AudioBuffer对象,下面就是音频数据的播放

    function playFun(buffer){
      AudioBufferSourceNode.buffer = buffer; // AudioBuffer数据赋值给buffer属性
      //AudioBufferSourceNode.connect(audioCtx.destination); // 如果只是播放音频,这边就直接将AudioBufferSourceNode连接到AudioDestinationNode
      AudioBufferSourceNode.connect(AnalyserNode);  // 实现播放后,需要将bufferSourceNode连接到AnalyserNode,才能通过AnalyserNode获取后面可视化所需的数据
      AudioBufferSourceNode.loop = true;  // 循环播放,默认为false
      AudioBufferSourceNode.start(0); // 开始播放音频
    }
    

    音频数据可视化

    创建AnalyserNode
    var AnalyserNode = audioCtx.createAnalyser();
    

    AnalyserNode节点可以提供实时的频率及时间域分析的信息。

    获取音频频域数据
    var arr = new Uint8Array(AnalyserNode.frequencyBinCount);//用于存放音频数据的数组,其长度是fftsize的一半
    requestAnimationFrame = window.requestAnimationFrame ||
                window.webkitrequestAnimationFrame ||
                window.mozrequestAnimationFrame;//兼容
    function fn(){
      AnalyserNode.getByteFrequencyData(arr);// 将音频频域数据复制到传入的Uint8Array数组
      draw(arr); // 频域数据作为参数传入绘制函数draw
      requestAnimationFrame(fn);
    }
    requestAnimationFrame(fn);
    

    AnalyserNode.getByteTimeDomainData()方法用于获取音频时域数据,AnalyserNode.getByteFrequencyData()方法用于获取音频频域数据。当获取频域数据时,我们需要通过设置AnalyserNode.fftSize来控制频域数据转换长度;fftSize越大,其频域转换计算时间越长,其默认值为2048。同时,AnalyserNode.frequenceBinCount属性值与fftSize相关,其为fftSize值的一半,其决定音频可视化时有多少数值点。

    音频音量控制

    创建GainNode
    GainNode = Musicvisualizer.ac[audioCtx.createGain?"createGain":"createGainNode"]();
    AnalyserNode.connect(GainNode);  // AnalyserNode连接到GainNode
    GainNode.connect(audioCtx.destination);  // GainNode连接到AudioDestinationNode
    

    GainNode 接口表示音量变更,我们一般把这个节点放到倒数第二个进行连接,最后再将GainNode连接到AudioDestinationNode
    至此,依赖Web Audio API实现音频可视化的整个过程就完成了。下面这幅图展示了整个流程。

    Web Audio API音频可视化示例流程图

    效果展示

    最后,通过绘制,我们实现的效果图如下。数据实现了柱状和点状的可视化效果(项目github地址)。

    MusicVisualizer.gif

    参考

    Web Audio API
    Web Audio API的运用
    基于Web Audio API实现音频可视化效果

    相关文章

      网友评论

      本文标题:手把手教你用Js实现音频可视化

      本文链接:https://www.haomeiwen.com/subject/hiqkrftx.html