Spaces:
Running
on
A100
Running
on
A100
| import { useRef, useEffect, useState } from 'react'; | |
| interface UseAudioAnalyzerReturn { | |
| audioData: Uint8Array; | |
| analyser: AnalyserNode | null; | |
| connectToStream: (stream: MediaStream) => void; | |
| disconnect: () => void; | |
| } | |
| export const useAudioAnalyzer = (fftSize: number = 256): UseAudioAnalyzerReturn => { | |
| const [audioData, setAudioData] = useState<Uint8Array>(new Uint8Array(fftSize / 2)); | |
| const [analyser, setAnalyser] = useState<AnalyserNode | null>(null); | |
| const audioContextRef = useRef<AudioContext | null>(null); | |
| const sourceRef = useRef<MediaStreamAudioSourceNode | null>(null); | |
| const animationFrameRef = useRef<number | null>(null); | |
| const connectToStream = (stream: MediaStream) => { | |
| try { | |
| // Clean up existing connections | |
| disconnect(); | |
| // Create new audio context and analyser | |
| const audioContext = new (window.AudioContext || (window as any).webkitAudioContext)(); | |
| const analyserNode = audioContext.createAnalyser(); | |
| analyserNode.fftSize = fftSize; | |
| analyserNode.smoothingTimeConstant = 0.8; | |
| // Connect stream to analyser | |
| const source = audioContext.createMediaStreamSource(stream); | |
| source.connect(analyserNode); | |
| // Store references | |
| audioContextRef.current = audioContext; | |
| sourceRef.current = source; | |
| setAnalyser(analyserNode); | |
| // Start updating audio data | |
| const bufferLength = analyserNode.frequencyBinCount; | |
| const dataArray = new Uint8Array(bufferLength); | |
| const updateAudioData = () => { | |
| if (analyserNode) { | |
| analyserNode.getByteFrequencyData(dataArray); | |
| setAudioData(new Uint8Array(dataArray)); | |
| animationFrameRef.current = requestAnimationFrame(updateAudioData); | |
| } | |
| }; | |
| updateAudioData(); | |
| } catch (error) { | |
| console.error('Error setting up audio analyzer:', error); | |
| } | |
| }; | |
| const disconnect = () => { | |
| // Cancel animation frame | |
| if (animationFrameRef.current) { | |
| cancelAnimationFrame(animationFrameRef.current); | |
| animationFrameRef.current = null; | |
| } | |
| // Disconnect audio nodes | |
| if (sourceRef.current) { | |
| sourceRef.current.disconnect(); | |
| sourceRef.current = null; | |
| } | |
| // Close audio context | |
| if (audioContextRef.current) { | |
| audioContextRef.current.close(); | |
| audioContextRef.current = null; | |
| } | |
| setAnalyser(null); | |
| setAudioData(new Uint8Array(fftSize / 2)); | |
| }; | |
| // Cleanup on unmount | |
| useEffect(() => { | |
| return () => { | |
| disconnect(); | |
| }; | |
| }, []); | |
| return { | |
| audioData, | |
| analyser, | |
| connectToStream, | |
| disconnect, | |
| }; | |
| }; | |