Spaces:
Sleeping
Sleeping
File size: 1,695 Bytes
5e1b738 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
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>;
}
|