<!DOCTYPE html>
<html>
<head>
<title>audio</title>
</head>
<body>
<div>芒种</div>
<audio id="audio" controls muted>
<source src="1.mp3" type="audio/mpeg">
</audio>
<!-- <audio id="audio" src="./It‘s realme.mp3">芒种</audio> -->
<!-- <audio id="audio" src="./mangzhong.mp3">芒种</audio> -->
<canvas width="1200" height="700" id="canvas"></canvas>
</body>
<script type="text/javascript">
window.AudioContext = window.AudioContext || window.webkitAudioContext;
//音频上下文对象
let audioCtx = new AudioContext();
//创建音频资源文件
let source = audioCtx.createMediaElementSource(document.getElementById("audio"));
//创建音量
let gainNode = audioCtx.createGain();
//创建分析器
let analyser = audioCtx.createAnalyser();
//设置快速傅里叶频域值
analyser.fftSize = 128*4;
//初始化音量
gainNode.gain.setValueAtTime(1,audioCtx.currentTime);
//资源连接分析器
source.connect(analyser);
//分析器连接音量
analyser.connect(gainNode);
//音量连接目的对象
gainNode.connect(audioCtx.destination);
document.getElementById("audio").play();
//gainNode.gain.linearRampToValueAtTime(0,audioCtx.currentTime+12);
analysis()
//document.getElementById("audio").suspend();
function analysis(){
//实际得到频域数据个数
let length = analyser.frequencyBinCount
let audioDataArr = new Uint8Array(length);
function a(){
analyser.getByteFrequencyData(audioDataArr);
draw(audioDataArr);
requestAnimationFrame(a);
}
requestAnimationFrame(a);
}
/**
@type {HTMLCanvasElement}
**/
let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");
let devicePixelRatio = window.devicePixelRatio || 1;
let backingStoreRatio = ctx.webkitBackingStorePixelRatio ||
ctx.mozBackingStorePixelRatio ||
ctx.msBackingStorePixelRatio ||
ctx.oBackingStorePixelRatio ||
ctx.backingStorePixelRatio || 1;
let ratio = devicePixelRatio / backingStoreRatio;
canvas.style.width = canvas.width + ‘px‘;
canvas.style.height = canvas.height + ‘px‘;
canvas.width = canvas.width * ratio;
canvas.height = canvas.height * ratio;
ctx.scale(ratio, ratio);
ctx.translate(0.5, 0.5);
function draw(arr){
ctx.clearRect(0,0,canvas.width,canvas.height);
let w = canvas.width / 128;
for(let i = 0;i < arr.length;i++){
ctx.beginPath();
let graident = ctx.createLinearGradient(w*i,arr[i],canvas.width/ratio,canvas.height/ratio);
graident.addColorStop(1,"#1E90FF");
graident.addColorStop(0,"#00FF7F");
ctx.fillStyle = graident;
ctx.fillRect(w*i*2/ratio,(canvas.height - arr[i])/ratio,w*0.8/ratio,arr[i]/ratio);
}
let r = 100/ratio;
ctx.beginPath();
ctx.arc(canvas.width/2/ratio,canvas.height/2/ratio,r,0,2*Math.PI);
ctx.fillStyle = "#20212d";
ctx.fill();
ctx.closePath()
let offset = 2*Math.PI / 128;
let x0 = canvas.width/2/ratio;
let y0 = canvas.height/2/ratio;
let n = 0;
for(let i = -Math.PI/2;i < Math.PI/2;i += offset){
ctx.beginPath();
let x1 = x0 +r * Math.cos(i);
let y1 = y0 - r * Math.sin(i);
ctx.moveTo(x1,y1);
let x2 = x0 + (arr[n]*0.5 + r) * Math.cos(i);
let y2 = y0 - (arr[n]*0.5 + r) * Math.sin(i);
ctx.lineWidth = 3;
ctx.lineTo(x2,y2);
//console.log(x2,y2)
let g = ctx.createLinearGradient(x1,y1,x2,y2);
g.addColorStop(1,"#0077ff");
g.addColorStop(0.8,"#00aaff");
g.addColorStop(0,"#00ffff");
ctx.strokeStyle = g;
ctx.stroke();
n++;
ctx.closePath();
}
let m = 0;
for(let i = Math.PI*3/2;i > Math.PI/2;i -= offset){
ctx.beginPath();
let x1 = x0 +r * Math.cos(i);
let y1 = y0 - r * Math.sin(i);
ctx.moveTo(x1,y1);
let x2 = x0 + (arr[m]*0.5 + r) * Math.cos(i);
let y2 = y0 - (arr[m]*0.5 + r) * Math.sin(i);
ctx.lineWidth = 3;
ctx.lineTo(x2,y2);
//console.log(x2,y2)
let g = ctx.createLinearGradient(x1,y1,x2,y2);
g.addColorStop(1,"#0077ff");
g.addColorStop(0.8,"#00aaff");
g.addColorStop(0,"#00ffff");
ctx.strokeStyle = g;
ctx.stroke();
m++;
ctx.closePath();
}
//console.log(arr.length)
}
</script>
</html>
原文:https://www.cnblogs.com/dhjy123/p/12953671.html