你是不是已经厌倦了增删改查,来尝尝用WebAPI写一个音频可视化

通俗地讲首先我们要拿到数据====>>然后我们就能够对数据进行处理===>>播放===>>然后画画

在html5标签中有一个audio可以播放音频但是不能直接用作可视化这里就需要用一些api(audioContext  音频上下文对象 里面提供了很多用于处理音频的对象和方法)来完成,可以参照一下api文档

 javascriptAPI文档https://developer.mozilla.org/zh-CN/docs/Web/API/BaseAudioContext首先

        我们要获取数据  ,我们有3常用的获取数据的方式:本地文件、ajax请求、audio标签

先说简单的audio标签的方式

<!-- 音乐播放器  crossOrigin="anonymous"  loop="loop" -->
        <audio id="musicFile" controls="controls" preload="metadata" crossorigin="anonymous" >
        <source src="http://dl.stream.qqmusic.qq.com/C4000041Jedy2YybNI.m4a?guid=2844145630&vkey=89D3419BFFF0BA86917726B51C930F974FD2E44B1B6EF5A5E39B7C5B6BBAB44B50C2CEB4A5D69A8A09380571A7BA9C756CC489C340A913D7&uin=2655251652&fromtag=66" />
        </audio>

 在这里有个需要注意的点是 必须加上crossorigin=“anonymous”属性 跨域                                         剩下的我用代码+注释来完成   下面的代码可以直接运行但是注意音频的地址需要从新换一下         大家可以去qq音乐官网去扒一个 切记不要使用本地音频

QQ音乐官网

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <!-- 音乐播放器  crossOrigin="anonymous"  loop="loop" -->
  <audio id="musicFile" controls="controls" preload="metadata" crossorigin="anonymous">
<!-- 要是播放不了就把下面的地址换了就行了 不要使用本地地址 file协议没法跨域 -->
    <source
      src="http://dl.stream.qqmusic.qq.com/C4000041Jedy2YybNI.m4a?guid=2844145630&vkey=89D3419BFFF0BA86917726B51C930F974FD2E44B1B6EF5A5E39B7C5B6BBAB44B50C2CEB4A5D69A8A09380571A7BA9C756CC489C340A913D7&uin=2655251652&fromtag=66" />
  </audio>
  <!-- 画布用来做可视化的载体  -->
  <!-- 此处不了解的同学没关系 想了解的话可以去看看jsAPI的canvas对象 -->
  <canvas id="canvas">
    你的浏览器不支持canvas标签
  </canvas>
  <script>
    //获取audio标签 实际上我们可以直接使用id 来操作
    var audio = document.getElementById("musicFile")
    //获取canvas表现 我们要在上面画画
    var canvas = document.getElementById("canvas")
    //调用我们写好的方法
    onLoadAudio()
    function onLoadAudio() {
      //上下文创建 考虑一下webkit的兼容性问题 
      const context = new (window.AudioContext || window.webkitAudioContext)()
      /**
       *  ?createMediaElementSource(element) 这个是用来获取数据的方法创建数据源
       *  !element就是指的标签<audio>(音频)的对象或者<video>(视屏)的对象 使用getElementById或者直接用id
       *  !数据源创建后audio的数据就会被数据源对象给接管 但是不包括播放暂停也就是audio对象里面的属性方法都还可以使用
       *  !这个对象直接能够解码不需要额外的操作
       **/
      var source = context.createMediaElementSource(audio)
      /**
       * ?createAnalyser() 这个方法是用来创建一个用于处理数据的对象 就叫他处理机吧
       * !前面我们说过 我们要先获得数据 然后在对数据进行处理 现在就是使用这个对象来处理 但是现在这个对象没有拿到数据
       * !这个对象的功能我们不用细说 我们只说音频可视化要使用的 方法就行了
       * */
      var analyser = context.createAnalyser();
      analyser.fftSize = 1024;
      //傅里叶变换 这个值越大 采集的数据越精细 默认是2048 这个不用

      /**
       * ?我们之前说过数据已交给createMediaElementSource创建的对象来接管了但是作为数据源的它还没有把数据给流出去
       * !我们使用  对象.connect(对象)  方法来链接数据的去向 前面一个对象是数据现在待的地方 后面一个事数据要去的地方
       * !所以我们现在应当吧数据源 里面的数据 给到 createAnalyser创建的对象 也就是我们的处理机 source.connect(analyser)这样链接一下
       * */
      source.connect(analyser)

      /**
       * ?我们现在的数据已经交由处理机接管了 我们接管过后的数据还需要给到扬声器 context.destination 这样才能有声音
       * */
      analyser.connect(context.destination);

      /**
       * ? console.log(bufferLength);
       * !(⊙﹏⊙)这值是傅里叶变换那里设置的一半 也就是512
       * !我们会对音频数据进行帧采样使用8位2进制的数组存放
       * !这个数组中的数据也是我们用来做可视化重要的依据 
       * !觉得有点抽象的话建议先把整个代码复制后直接运行 看看可视化的样子
       * !然后在去csdn看看声音是怎么以数据方式存放的 后面我会单独出一个来讲 可能就好理解一些了
      **/
      var bufferLength = analyser.frequencyBinCount;
      var dataArray = new Uint8Array(bufferLength);

      /**
       * *我们连接好数据的流向之后我们 就播放音乐吧
       * */
      audio.play();

      // //下面是画布
      
      canvas.width = '512'  //定义画布的宽度
      canvas.height = '100' //定义画布的高度
      var ctx = canvas.getContext("2d")
      var WIDTH = canvas.width
      var HEIGHT = canvas.height
      // 条子的宽度 和高度
      var barWidth = WIDTH / bufferLength //* 1.5 //这里本身是不用*1.5的 但是建议*1.5 具体原因私信问我吧
      var barHeight

      // 那么开始happy
      // var dataArray = new Uint8Array(analyser.frequencyBinCount);
      function draw() {
        analyser.getByteFrequencyData(dataArray)
        ctx.clearRect(0, 0, WIDTH, HEIGHT)
          r = 0, //红色
          g = 224, //绿色  本人比较喜欢绿色
          b = 0; //蓝色
        for (var i = 0, x = 0; i < bufferLength; i++) {
          barHeight = dataArray[i]
          var canvasH = barHeight / 2.5
          r = barHeight + 25 * (i / bufferLength);
          b = 250 * (i / bufferLength)
          //比较喜欢蓝色 所以绿色多一点
          //画 颜色变换 酷就可以了
          ctx.fillStyle = "rgb(" + r + "," + g + "," + b + ")"
          ctx.fillRect(x, HEIGHT - canvasH, barWidth, canvasH)
          x += barWidth + 0 //0这里是条子的间隔根据喜好来吧
        }
        requestAnimationFrame(draw);
      }
      draw();
    }
  </script>
</body>

</html>

剩下的两种我下次再讲吧 先会一种 剩下两种只在数据源上有区别了

有不懂得 或者我有什么地方错的 欢迎大家在评论区留言 或者私信我 嘿嘿

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梵颜夕不会发疯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值