import React, { useState, useRef } from 'react'; const VoiceRecorder = ({ onTranscriptionComplete }) => { const [isRecording, setIsRecording] = useState(false); const [isProcessing, setIsProcessing] = useState(false); const mediaRecorderRef = useRef(null); const audioChunksRef = useRef([]); const startRecording = async () => { try { const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); // Use webm, it compresses nicely and is widely supported by modern browsers mediaRecorderRef.current = new MediaRecorder(stream, { mimeType: 'audio/webm' }); mediaRecorderRef.current.ondataavailable = (event) => { if (event.data.size > 0) { audioChunksRef.current.push(event.data); } }; mediaRecorderRef.current.onstop = async () => { setIsProcessing(true); const audioBlob = new Blob(audioChunksRef.current, { type: 'audio/webm' }); audioChunksRef.current = []; // Reset chunks const formData = new FormData(); formData.append('audio', audioBlob, 'recording.webm'); try { const response = await fetch('/api/voice/transcribe', { method: 'POST', body: formData, }); if (!response.ok) throw new Error('Transcription failed'); const data = await response.json(); if (data.transcribed_text && onTranscriptionComplete) { onTranscriptionComplete(data.transcribed_text); } } catch (error) { console.error("Voice processing error:", error); alert("Failed to transcribe audio."); } finally { setIsProcessing(false); } }; audioChunksRef.current = []; mediaRecorderRef.current.start(); setIsRecording(true); } catch (err) { console.error("Microphone access denied:", err); alert("Microphone access is required for voice input."); } }; const stopRecording = () => { if (mediaRecorderRef.current && isRecording) { mediaRecorderRef.current.stop(); // Release the microphone lock mediaRecorderRef.current.stream.getTracks().forEach(track => track.stop()); setIsRecording(false); } }; return (
{isRecording ? "🔴" : "🎤"} {isRecording ? "Recording... Click stop to transcribe" : "Click to describe your issue with voice"}
); }; export default VoiceRecorder;