JS音频图像化

本文介绍了如何利用JavaScript和HTML5的WebAudioAPI获取音频数据,通过AnalyserNode获取频谱信息,并将这些数据转化为canvas上的动态点状图形,展示音频的频率分布。
摘要由CSDN通过智能技术生成

JS音频图像化

话不多说先上实现结果
在这里插入图片描述

构建一个由点构成的圆形canvas

html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="./index.css" />
  </head>
  <body>
    <canvas></canvas>
    <audio src="" controls></audio>
    <script src="./index.js"></script>
  </body>
</html>

js



const audioEle = document.querySelector('audio');

audioEle.crossOrigin = "anonymous";
audioEle.src = 'https://images.project1.team/DDDD.mp3';

const cvs = document.querySelector('canvas');
const ctx = cvs.getContext('2d');

// 初始化canvas的尺寸
function initCvs() {
  const size = 800;
  cvs.width = size * devicePixelRatio;
  cvs.height = size * devicePixelRatio;
  cvs.style.width = cvs.style.height = size + 'px';
}
initCvs();
// datas 数组点,maxValue 每个点延长线最大长度
function draw(datas, maxValue) {
  const r = cvs.width / 4 + 20 * devicePixelRatio;
  const center = cvs.width / 2;
  ctx.clearRect(0, 0, cvs.width, cvs.height);

  const hslStep = 360 / (datas.length - 1);
  const maxLen = cvs.width / 2 - r;
  const minLen = 2 * devicePixelRatio;
  for (let i = 0; i < datas.length; i++) {
    ctx.beginPath();
    const len = Math.max((datas[i] / maxValue) * maxLen, minLen);
    const rotate = hslStep * i;
    ctx.strokeStyle = `hsl(${rotate}deg, 65%, 65%)`;
    ctx.lineWidth = minLen;
    const rad = (rotate * Math.PI) / 180;
    const beginX = center + Math.cos(rad) * r;
    const beginY = center + Math.sin(rad) * r;
    const endX = center + Math.cos(rad) * (r + len);
    const endY = center + Math.sin(rad) * (r + len);
    ctx.moveTo(beginX, beginY);
    ctx.lineTo(endX, endY);
    ctx.stroke();
  }
}
// const arr = new Array(100).fill(0).map(() => Math.random() * 255);
draw(new Array(256).fill(0), 255);

在这里插入图片描述
音频处理

let isInit = false;
let analyser, buffer;
// 音频
audioEle.onplay = () => {
  if (isInit) {
    return;
  }
 
  const audioCtx = new AudioContext();
  const source = audioCtx.createMediaElementSource(audioEle);
 

  // 创建一个分析器
  analyser = audioCtx.createAnalyser();
  analyser.fftSize = 512;
  // analyser.maxDecibels = 100;
  buffer = new Uint8Array(analyser.frequencyBinCount);
  source.connect(analyser);

  analyser.connect(audioCtx.destination);
  isInit = true;
};

// 麦克风
// navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
//   if (isInit) {
//     return;
//   }
//   isInit = true;
//   const audioCtx = new AudioContext();
//   const source = audioCtx.createMediaStreamSource(stream);
//   analyser = audioCtx.createAnalyser();
//   analyser.fftSize = 512;
//   buffer = new Uint8Array(analyser.frequencyBinCount);

//   source.connect(analyser);
//   analyser.connect(audioCtx.destination);
// });

function update() {
  requestAnimationFrame(update);
  if (!isInit) {
    return;
  }
  analyser.getByteFrequencyData(buffer);
  const offset = Math.floor((buffer.length * 2) / 3);
  const data = new Array(offset * 2);
  for (let i = 0; i < offset; i++) {
    data[i] = data[data.length - i - 1] = buffer[i];
  }
  
  draw(data, 255);
}

update();

源码

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值