/ apps / web / src / hooks / useSimpleAudioRecorder.ts
useSimpleAudioRecorder.ts
 1  import { useState, useRef, useCallback } from 'react'
 2  
 3  export function useSimpleAudioRecorder() {
 4    const [isRecording, setIsRecording] = useState(false)
 5    const [audioBlob, setAudioBlob] = useState<Blob | null>(null)
 6    const mediaRecorderRef = useRef<MediaRecorder | null>(null)
 7    const audioChunksRef = useRef<Blob[]>([])
 8    const streamRef = useRef<MediaStream | null>(null)
 9  
10    const startRecording = useCallback(async () => {
11      try {
12        // Reset previous recording
13        setAudioBlob(null)
14        
15        const stream = await navigator.mediaDevices.getUserMedia({ 
16          audio: {
17            sampleRate: 16000,
18            channelCount: 1,
19            echoCancellation: true,
20            noiseSuppression: true,
21          } 
22        })
23        
24        streamRef.current = stream
25        
26        const mediaRecorder = new MediaRecorder(stream, {
27          mimeType: 'audio/webm'
28        })
29        
30        audioChunksRef.current = []
31        
32        mediaRecorder.ondataavailable = (event) => {
33          if (event.data.size > 0) {
34            audioChunksRef.current.push(event.data)
35          }
36        }
37        
38        mediaRecorder.onstop = () => {
39          const blob = new Blob(audioChunksRef.current, { type: 'audio/webm' })
40          setAudioBlob(blob)
41        }
42        
43        mediaRecorderRef.current = mediaRecorder
44        mediaRecorder.start()
45        setIsRecording(true)
46        
47      } catch (error) {
48        console.error('Failed to start recording:', error)
49        throw error
50      }
51    }, [])
52  
53    const stopRecording = useCallback(() => {
54      if (mediaRecorderRef.current && mediaRecorderRef.current.state !== 'inactive') {
55        mediaRecorderRef.current.stop()
56        setIsRecording(false)
57        
58        // Stop all tracks
59        if (streamRef.current) {
60          streamRef.current.getTracks().forEach(track => track.stop())
61          streamRef.current = null
62        }
63      }
64    }, [])
65  
66    const reset = useCallback(() => {
67      setAudioBlob(null)
68    }, [])
69  
70    return {
71      isRecording,
72      audioBlob,
73      startRecording,
74      stopRecording,
75      reset
76    }
77  }