前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WebAudio API

WebAudio API

作者头像
jinghong
发布2020-05-09 15:26:57
1.2K0
发布2020-05-09 15:26:57
举报
文章被收录于专栏:前端开发0202前端开发0202

webAudio API

webAudio API接口可以用来实现音乐可视化、音频剪辑、修声、语音、去声等等强大的操作

webAudioAPI接口关系图:

AudioContext

AudioContext是所有音频操作的前提,一个类似Canvas的ctx的上下文对象

代码语言:javascript
复制
var ac = new (window.AudioContext ||  window.webkitAudioContext || window.mozAudioContext || window.msAudioContext) 
//由于API兼容性问题,需要在创建时加上后缀

AudioBufferSourceNode

创建音频源 方法(1) 这种方式是通过请求方式播放音乐

代码语言:javascript
复制
 var ac = new (window.AudioContext ||  window.webkitAudioContext || window.mozAudioContext || window.msAudioContext)();
        let url = './Kalimba.mp3';
//通过 fetch请求本地文件,返回样式设置为arraybuffer
        fetch(url,{
            responseType:'arraybuffer'
        })
        .then(res => {
          //将返回的数据转成arrayBuffer数据,并返回
          return res.arrayBuffer();
        })
        .then(res =>{
            //使用ac.decodeAudioData(arrayBuffer, succ(buffer), err)方法音频解码,获取成功后调用第一个回调并返回buffer解码数据,失败则调用最后个回调
            ac.decodeAudioData(res,(buffer)=>{
                //创建bufferSource
                let BufferSource = ac.createBufferSource();
                //将返回的数据给它
                BufferSource.buffer = buffer;
                //直接连接音频聚集地
                BufferSource.connect(ac.destination);
                //开始播放
                BufferSource[BufferSource.start ? 'start' : 'noteOn'](0);
            },(err)=>{console.log(err);})
        })

MediaElementAudioSourceNode

创建音频源 方法(2) 这种方式是通过 DOM元素 播放音乐

代码语言:javascript
复制
    <input type="button" value="播放" onclick='music.play()'>  //点击播放音乐   
    <input type="button" value="停止" onclick="music.pause()"> //点击停止音乐
    <script>
        var ac = new (window.AudioContext ||  window.webkitAudioContext || window.mozAudioContext || window.msAudioContext);
        //创建音乐DOM元素
        let music = new Audio('./Kalimba.mp3');
        //通过 DOM元素创建音频源
        let source = ac.createMediaElementSource(music);
        //直接连接音频聚集地
        source.connect(ac.destination);
    </script>

使用input[type=file]创建 (可以本地获取)

代码语言:javascript
复制
 var audioCtx = new window.AudioContext();
      var audioInput = document.getElementById("uploader"); //HTML语句:<input type="file" id="uploader" />
      audioInput.onchange = function() {
        //文件长度不为0则真的选中了文件,因为用户点击取消也会触发onchange事件。
        if (audioInput.files.length !== 0) {
          files = audioInput.files[0]; //得到用户选取的文件 //文件选定之后,马上用FileReader进行读入
          fr = new FileReader();
          fr.onload = function(e) {
            var fileResult = e.target.result; //文件读入完成,进行解码
            audioCtx.decodeAudioData(
              fileResult,
              function(buffer) {
                let source = audioCtx.createBufferSource();
                source.buffer = buffer; //将解码出来的数据放入source中 //转到播放和分析环节
                source.connect(audioCtx.destination);
                source.start(0);
              },
              function(err) {
                alert("!Fail to decode the file"); //解码出错
              }
            );
          };
          fr.onerror = function(err) {
            alert("!Fail to read the file"); //文件读入出错
          };
          fr.readAsArrayBuffer(files); //同样的,ArrayBuffer方式读取
        }
      };

GainNode

gain是在音乐播放之前处理声音大小的中间件

这里使用DOM元素方式来演示 , 请求方式的设置也和它一样

代码语言:javascript
复制
<input type="button" value="播放" onclick='music.play()'>  //点击播放音乐   
<input type="button" value="停止" onclick="music.pause()"> //点击停止音乐
<input type="range" max="100" min="0" value="60" oninput="setGain(this)"> //控制音乐播放声音
    <script>
        var ac = new (window.AudioContext ||  window.webkitAudioContext || window.mozAudioContext || window.msAudioContext);
        //创建音乐DOM元素
        let music = new Audio('./Kalimba.mp3');
        //通过 DOM元素创建音频源
        let source = ac.createMediaElementSource(music);
        //Gain连接destination
        let gain = ac.createGain();
        gain.connect(ac.destination);
        //必须连接Gain , 不再是连接destination了,否则音频没有经过gain处理,效果不会生效
        source.connect(gain);
        //设置gain.gain.value 的值,跟随input的value改变,实现改变声音大小
        function setGain(that)
        {   
            gain.gain.value = that.value/that.max;
        }
    </script>

analyserNode

这个节点可以实现音频的可视化,是一个可视化中必不可少的重要步骤

代码语言:javascript
复制
//创建Analyser
var analyser = ac.createAnalyser();
//设置fftSize大小
analyser.fftSize = 512;
//链接destination Gain节点,随之Gain节点到终点去
analyser.connect(gain);
//创建Uint8Array数据,并运用frequencyBinCount 来获取fft的一半
var arr = new Uint8Array(analyser.frequencyBinCount);
//然后使用getByFrequencyData来获取范围频域
analyser.getByteFrequencyData(arr);
//最后配合Canvas和requestAnimationFrame(callback)动画函数来实现可视化;
代码语言:javascript
复制
 var ctx = document.querySelector("canvas").getContext("2d");
      ctx.canvas.width = document.body.clientWidth;
      var width = ctx.canvas.width,
        height = ctx.canvas.height;
      window.onresize = function() {
        ctx.canvas.width = document.body.clientWidth;
        width = document.body.clientWidth;
        let line = ctx.createLinearGradient(0, 0, 0, height);
        line.addColorStop(1, "red");
        line.addColorStop(0.5, "yellow");
        line.addColorStop(0, "green");
        ctx.fillStyle = line;
      };
      let line = ctx.createLinearGradient(0, 0, 0, height);
      line.addColorStop(1, "red");
      line.addColorStop(0.5, "yellow");
      line.addColorStop(0, "green");
      ctx.fillStyle = line;
      function draw(Data) {
        ctx.clearRect(0, 0, width, height);
        var w = width / 128;
        for (let i = 0; i < Data.length; i++) {
          ctx.fillRect(
            w * i,
            height - (Data[i] / 256) * height,
            (width / Data.length) * 1.5,
            Data[i]
          );
        }
      }
      var ac = new (window.AudioContext ||
        window.webkitAudioContext ||
        window.mozAudioContext ||
        window.msAudioContext)();
      //创建gain 来控制声音大小
      let gain = ac.createGain();
      //链接音频终点
      gain.connect(ac.destination);
      //创建analyser 来实现可视化
      let analyser = ac.createAnalyser();
      analyser.fftSize = 512;
      //链接gain
      analyser.connect(gain);
      //获取音乐数据
      fetch("./music/Kalimba.mp3", {
        responseType: "arraybuffer"
      })
        .then(res => res.arrayBuffer())
        .then(res => {
          ac.decodeAudioData(res, buffer => {
            let bufferSource = ac.createBufferSource();
            bufferSource.buffer = buffer;
            bufferSource.connect(analyser);
            bufferSource[bufferSource.start ? "start" : "noteOn"](0);
          });
        });
      (function() {
        //创建数据
        var arr = new Uint8Array(analyser.frequencyBinCount);
        //解决各浏览器的兼容性问题
        requestAnimationFrame =
          window.requestAnimationFrame ||
          window.webkitRequestAnimationFrame ||
          window.mozRequestAnimationFrame;
        //创建动画函数
        function animate() {
          //获取频域
          analyser.getByteFrequencyData(arr);
          draw(arr);
          //循环
          requestAnimationFrame(animate);
        }
        //启动动画函数
        requestAnimationFrame(animate);
      })();

      function setGain(that) {
        gain.gain.value = +that.value / +that.max;
      }
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-09-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • webAudio API
    • AudioContext
      • AudioBufferSourceNode
        • MediaElementAudioSourceNode
        • 使用input[type=file]创建 (可以本地获取)
      • GainNode
        • analyserNode
        相关产品与服务
        消息队列 TDMQ
        消息队列 TDMQ (Tencent Distributed Message Queue)是腾讯基于 Apache Pulsar 自研的一个云原生消息中间件系列,其中包含兼容Pulsar、RabbitMQ、RocketMQ 等协议的消息队列子产品,得益于其底层计算与存储分离的架构,TDMQ 具备良好的弹性伸缩以及故障恢复能力。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档