前端q群 398913416 群里面有免费资料纯免费,大家一起学习,如果自己有什么好的学习资料也可以一起分享, 一个人的力量终究有限,共同进步。
一、基本思路
- 1.播放音频
- 2.在音频播放的时候拿到实时数据
- 3.在Canvas上按一定规则画出
二、代码实现
html
<canvas></canvas>
<audio src="./1.mp3" controls></audio>
<script src="./index.js">
css
canvas {
width: 100%;
height: 300px;
background: #000;
}
index.js
const audioEle = document.querySelector('audio');
const cvs = document.querySelector('canvas')
const ctx = cvs.getContext('2d');
function initCtx() {
cvs.width = window.innerWidth * devicePixelRatio;
cvs.height = (window.innerHeight / 2) * devicePixelRatio;
}
initCtx()
let isInit = false;
let dataArray, analyser;
audioEle.onplay = function () {
// console.log(11111);
if (isInit) return;
// 创建音频对象
const audCtx = new AudioContext(); //创建音视频上下文
// 创建一个音频源节点(音频处理的环节 比如修音 加入混响 音量调高调低) 来源来自于一个元素 音频元素
const source = audCtx.createMediaElementSource(audioEle);
// 创建AnalyserNode节点
analyser = audCtx.createAnalyser() // 分析器
analyser.fftSize = 512; // 变换的窗口大小越大越细腻 默认值2048 必须是2的N次幂;
// 创建一个数组 接收分析器节点的分析数据;
// console.log(analyser);
dataArray = new Uint8Array(analyser.frequencyBinCount) // 512 / 2
source.connect(analyser); // 连接
analyser.connect(audCtx.destination) // 输出
isInit = true
}
// 拿到实时数据在Canvas上按规则画出
function draw() {
requestAnimationFrame(draw);
const { width, height } = cvs
ctx.clearRect(0, 0, width, height);
// 让分析器节点分析数据到数组中;
if (!isInit) return;
analyser.getByteFrequencyData(dataArray);
const len = dataArray.length / 3;
const barWidth = width / len / 2;
ctx.fillStyle = '#78c5f7'
for (let i = 0; i < len; i++) {
let data = dataArray[i] // <= 256
const barHeight = data / 255 * height;
// 不会对称的
// const x = i * barWidth;
// 对称的
const x1 = i * barWidth + width / 2;
const x2 = width / 2 - (i + 1) * barWidth;
// 不会对称的
const y = height - barHeight;
// 对称的
ctx.fillRect(x1, y, barWidth - 2, barHeight)
ctx.fillRect(x2, y, barWidth - 2, barHeight)
// 不会对称的
// ctx.fillRect(x, y, barWidth, barHeight)
}
}
draw()