CoolFace
Apppublic

therickglenn/VoiceAnalyzer

sourceHugging Facemitupdated 2y agoView on Hugging Face
0likes
AudioVisualizer.js100 linesDownload Raw Back to root
1import React, { useEffect, useRef, useState } from "react";2 3const AudioVisualizer = () => {4    const audioContextRef = useRef(null);5    const analyserRef = useRef(null);6    const dataArrayRef = useRef(null);7    const sourceRef = useRef(null);8    const canvasRef = useRef(null);9    const [permissionGranted, setPermissionGranted] = useState(false);10    const [errorMessage, setErrorMessage] = useState(null);11 12    const initializeAudio = async () => {13        try {14            if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {15                throw new Error("getUserMedia is not supported in this browser.");16            }17 18            const stream = await navigator.mediaDevices.getUserMedia({ audio: true });19            setPermissionGranted(true);20            setErrorMessage(null);21            22            audioContextRef.current = new (window.AudioContext || window.webkitAudioContext)();23            analyserRef.current = audioContextRef.current.createAnalyser();24            25            sourceRef.current = audioContextRef.current.createMediaStreamSource(stream);26            sourceRef.current.connect(analyserRef.current);27            28            analyserRef.current.fftSize = 512;29            const bufferLength = analyserRef.current.frequencyBinCount;30            dataArrayRef.current = new Uint8Array(bufferLength);31            32            drawWaveform();33        } catch (err) {34            console.error('Error accessing microphone:', err);35            setErrorMessage(err.message);36        }37    };38 39    useEffect(() => {40        return () => {41            if (audioContextRef.current) {42                audioContextRef.current.close();43            }44        };45    }, []);46 47    const drawWaveform = () => {48        if (!canvasRef.current) return;49        50        const canvas = canvasRef.current;51        const ctx = canvas.getContext('2d');52        53        const renderFrame = () => {54            requestAnimationFrame(renderFrame);55            analyserRef.current.getByteTimeDomainData(dataArrayRef.current);56            57            ctx.fillStyle = '#000';58            ctx.fillRect(0, 0, canvas.width, canvas.height);59            60            ctx.lineWidth = 2;61            ctx.strokeStyle = '#00ffcc';62            ctx.beginPath();63            64            let sliceWidth = canvas.width / dataArrayRef.current.length;65            let x = 0;66            67            for (let i = 0; i < dataArrayRef.current.length; i++) {68                let v = dataArrayRef.current[i] / 128.0;69                let y = v * canvas.height / 2;70                71                if (i === 0) {72                    ctx.moveTo(x, y);73                } else {74                    ctx.lineTo(x, y);75                }76                77                x += sliceWidth;78            }79            80            ctx.lineTo(canvas.width, canvas.height / 2);81            ctx.stroke();82        };83        renderFrame();84    };85 86    return (87        <div className="container">88            <h1>Real-Time Audio Visualizer</h1>89            {!permissionGranted ? (90                <button className="start-button" onClick={initializeAudio}>Start Audio Analysis</button>91            ) : (92                <p>Analyzing audio...</p>93            )}94            {errorMessage && <p className="error-message">{errorMessage}</p>}95            <canvas ref={canvasRef} width={600} height={300} className="visualizer"></canvas>96        </div>97    );98};99 100export default AudioVisualizer;