Jwrockon's picture
Upload 232 files (#1)
5e1b738 verified
raw
history blame
1.7 kB
import { useRef, useCallback, useEffect } from "react";
export function AudioVisualizer({ stream, ...props }) {
const canvasRef = useRef(null);
const visualize = useCallback((stream) => {
const audioContext = new (window.AudioContext ||
window.webkitAudioContext)();
const source = audioContext.createMediaStreamSource(stream);
const analyser = audioContext.createAnalyser();
analyser.fftSize = 2048;
source.connect(analyser);
const canvas = canvasRef.current;
const canvasCtx = canvas.getContext("2d");
const bufferLength = analyser.frequencyBinCount;
const dataArray = new Uint8Array(bufferLength);
const drawVisual = () => {
requestAnimationFrame(drawVisual);
analyser.getByteTimeDomainData(dataArray);
canvasCtx.fillStyle = "rgb(255, 255, 255)";
canvasCtx.fillRect(0, 0, canvas.width, canvas.height);
canvasCtx.lineWidth = 2;
canvasCtx.strokeStyle = "rgb(0, 0, 0)";
canvasCtx.beginPath();
const sliceWidth = (canvas.width * 1.0) / bufferLength;
let x = 0;
for (let i = 0; i < bufferLength; ++i) {
const v = dataArray[i] / 128.0;
const y = (v * canvas.height) / 2;
if (i === 0) {
canvasCtx.moveTo(x, y);
} else {
canvasCtx.lineTo(x, y);
}
x += sliceWidth;
}
canvasCtx.lineTo(canvas.width, canvas.height / 2);
canvasCtx.stroke();
};
drawVisual();
}, []);
useEffect(() => {
stream && visualize(stream);
}, [visualize, stream]);
return <canvas {...props} width={720} height={240} ref={canvasRef}></canvas>;
}