canvas和AudioContext实现音频柱状图

在这里插入图片描述
需要一个audio标签和canvas标签

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      canvas {
        display: block;
        background: #c6d2c9;
      }
    </style>
  </head>
  <body>
    <div id="box">
      <!--<audio src="http://www.ttistt.com/music/2.mp3"></audio>-->
      <audio src="kda.mp3"></audio>
    </div>
    <canvas></canvas>
  </body>
</html>

先搞一下一些基本的前置条件

let c = document.querySelector("canvas");
c.width = window.innerWidth;
c.height = window.innerHeight;
window.onresize = function () {
    c.width = window.innerWidth;
    c.height = window.innerHeight;
};
let cxt = c.getContext("2d");
// 定义线性渐变位置和颜色
let color = cxt.createLinearGradient(
    c.width / 2,
    c.height / 2 - 100,
    c.width / 2,
    c.height / 2 + 100
);
color.addColorStop(0, "#32edf9");
color.addColorStop(0.5, "#e38cf5");
color.addColorStop(1, "#a2f591");
 
// 获取audio元素
let audio = document.querySelector("audio");
 
// 设置音量大小 循环
audio.volume = 1;
audio.loop = "loop";
 
// 搞一个开关控制音乐播放
let off = false;
 
// 音频数据
let voiceL = null;
 
// 定义显示的数量
let count = 200;
 
// 点击文档控制播放停止
document.addEventListener("click", function () {
    off ? audio.pause() : audio.play();
    off = !off;
    create(); //需要完成的方法
});

定义create方法

function create(params) {
  let actx = new AudioContext();
 
  // 创建一个AnalyserNode,用来获取音频时间和频率数据
  let ayser = actx.createAnalyser();
 
  // 搞到所需要的音频资源
  let aSrc = actx.createMediaElementSource(audio);
}

让音频资源和分析者进行关联

// 关联分析
aSrc.connect(ayser);
// 关联最终的目标点
aSrc.connect(actx.destination);

创建一个无符号8位数组,用于存放音频数据,长度取frequencyBinCount

voiceL = new Uint8Array(ayser.frequencyBinCount);

构造一个draw方法用于绘制音频图

function draw() {
  cxt.clearRect(0, 0, c.width, c.height);
 
  // getByteFrequencyData()方法将当前频率数据复制到传入的Uint8Array(无符号字节数组)中
  ayser.getByteFrequencyData(voiceL);
  
  // 因为只显示200个所以要搞一下显示的间隔
  let step = Math.round(voiceL.length / count);
 
  for (let i = 0; i < count; i++) {
    let j = voiceL[i * step];
    // 设置填充色
    cxt.fillStyle = color;
    // 从中间向两边填充
    cxt.fillRect(c.width / 2 + i * 10, c.height / 2, 5, j);
    cxt.fillRect(c.width / 2 - i * 10, c.height / 2, 5, j);
    cxt.fillRect(c.width / 2 + i * 10, c.height / 2, 5, -j);
    cxt.fillRect(c.width / 2 - i * 10, c.height / 2, 5, -j);
  }
  requestAnimationFrame(draw);
}

完整代码

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      * {
        margin: 0;
        padding: 0;
      }
      canvas {
        display: block;
        background: #c6d2c9;
      }
    </style>
  </head>
  <body>
    <div id="box">
      <!--<audio src="http://www.ttistt.com/music/2.mp3"></audio>-->
      <audio src="kda.mp3"></audio>
    </div>
    <canvas></canvas>
    <script>
      let c = document.querySelector("canvas");
      c.width = window.innerWidth;
      c.height = window.innerHeight;
      window.onresize = function () {
        c.width = window.innerWidth;
        c.height = window.innerHeight;
      };
      let cxt = c.getContext("2d");
      // 定义线性渐变位置和颜色
      let color = cxt.createLinearGradient(
        c.width / 2,
        c.height / 2 - 100,
        c.width / 2,
        c.height / 2 + 100
      );
      color.addColorStop(0, "#32edf9");
      color.addColorStop(0.5, "#e38cf5");
      color.addColorStop(1, "#a2f591");
 
      // 获取audio元素
      let audio = document.querySelector("audio");
      // 设置音量大小
      audio.volume = 1;
      audio.loop = "loop";
      // 搞一个开关控制音乐播放
      let off = false;
      // 音频数据
      let voiceL = null;
      // 定义显示的数量
      let count = 200;
      // 点击文档控制播放停止
      document.addEventListener("click", function () {
        off ? audio.pause() : audio.play();
        off = !off;
        create();
      });
 
      function create(params) {
        let actx = new AudioContext();
        // 创建一个AnalyserNode,用来获取音频时间和频率数据
        let ayser = actx.createAnalyser();
        // 搞到所需要的音频资源
        let aSrc = actx.createMediaElementSource(audio);
 
        // 关联分析
        aSrc.connect(ayser);
        // 关联最终的目标点
        aSrc.connect(actx.destination);
 
        // 获取一个可视化的数量 frequencyBinCount 的值固定为 AnalyserNode 接口中fftSize值的一半
        voiceL = new Uint8Array(ayser.frequencyBinCount);
        draw();
        function draw() {
          cxt.clearRect(0, 0, c.width, c.height);
          // getByteFrequencyData()方法将当前频率数据复制到传入的Uint8Array(无符号字节数组)中
          ayser.getByteFrequencyData(voiceL);
          // 因为只显示200个所以要搞一下显示的间隔
          let step = Math.round(voiceL.length / count);
          for (let i = 0; i < count; i++) {
            let j = voiceL[i * step];
            // 设置填充色
            cxt.fillStyle = color;
            // 从中间向两边填充
            cxt.fillRect(c.width / 2 + i * 10, c.height / 2, 5, j);
            cxt.fillRect(c.width / 2 - i * 10, c.height / 2, 5, j);
            cxt.fillRect(c.width / 2 + i * 10, c.height / 2, 5, -j);
            cxt.fillRect(c.width / 2 - i * 10, c.height / 2, 5, -j);
          }
          requestAnimationFrame(draw);
        }
      }
    </script>
  </body>
</html>
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值