JSFiddle - React, Tailwind, and code Playground
by atesgoral
HTML
<canvas id="c1" width="512" height="255"></canvas><canvas id="c2" width="255" height="255"></canvas>
CSS
#c1 { background: white }
#c2 { background: blue }
JavaScript
const url = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/9473/new_year_dubstep_minimix.ogg';
const context = new AudioContext();
const sourceNode = context.createBufferSource();
const processor = context.createScriptProcessor(2048, 1, 1);
const analyser = context.createAnalyser();
analyser.smoothingTimeConstant = 0.3;
analyser.fftSize = 1024;
sourceNode.connect(analyser);
analyser.connect(processor);
const bins = new Uint8Array(analyser.frequencyBinCount);
const ctx1 = c1.getContext('2d');
const ctx2 = c2.getContext('2d');
let beat = 0;
function render() {
requestAnimationFrame(render);
//ctx1.clearRect(0, 0, c1.width, c1.height);
ctx1.fillStyle = '#ffffff';
ctx1.globalAlpha = 0.333;
ctx1.fillRect(0, 0, c1.width, c1.height);
ctx1.globalAlpha = 1;
ctx1.fillStyle = '#000000';
for (let i = 0; i < bins.length; i++) {
ctx1.fillRect(i, 255 - bins[i], 1, bins[i]);
//ctx1.fillRect(i, 255 - bins[i], 1, 5);
}
ctx2.clearRect(0, 0, c2.width, c2.height);
ctx2.fillStyle = '#ffffff';
ctx2.beginPath();
ctx2.arc(c2.width / 2, c2.height / 2, beat * c2.width / 2, 0, 2 * Math.PI);
ctx2.fill();
}
render();
let prevAvg = 0;
processor.onaudioprocess = function () {
analyser.getByteFrequencyData(bins);
let sum = 0;
for (let i = 0; i < bins.length; i++) {
sum += bins[i];
}
const avg = sum / bins.length;
if (avg - prevAvg > 20) {
beat = 1;
} else {
beat *= 0.5;
//beat = 0;
}
prevAvg = avg;
//beat = avg;
};
processor.connect(context.destination);
sourceNode.connect(context.destination);
const request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
request.onload = function () {
//console.log('Loaded');
context.decodeAudioData(request.response, function (buffer) {
//console.log('Decoded');
sourceNode.buffer = buffer;
sourceNode.start(0);
}, function (error) {
console.error(error);
});
}
request.send();