UNPKG

@lakshmiprasanth/react-voice-to-text

Version:

A modern React package for voice-to-text conversion with real-time speech recognition and file upload support

202 lines (197 loc) 7.32 kB
'use strict'; var react = require('react'); /** * Check browser support for speech recognition and related APIs */ function getBrowserSupport() { if (typeof window === 'undefined') { return { webSpeechAPI: false, mediaRecorder: false, getUserMedia: false, browser: { name: 'unknown', version: 'unknown' } }; } const browserInfo = getBrowserInfo(); return { webSpeechAPI: 'SpeechRecognition' in window || 'webkitSpeechRecognition' in window, mediaRecorder: 'MediaRecorder' in window, getUserMedia: 'mediaDevices' in navigator && 'getUserMedia' in navigator.mediaDevices, browser: browserInfo }; } /** * Get browser name and version */ function getBrowserInfo() { if (typeof navigator === 'undefined') { return { name: 'unknown', version: 'unknown' }; } const userAgent = navigator.userAgent; let name = 'unknown'; let version = 'unknown'; // Chrome if (userAgent.includes('Chrome') && !userAgent.includes('Edg')) { name = 'Chrome'; const match = userAgent.match(/Chrome\/(\d+)/); if (match) version = match[1]; } // Safari else if (userAgent.includes('Safari') && !userAgent.includes('Chrome')) { name = 'Safari'; const match = userAgent.match(/Version\/(\d+)/); if (match) version = match[1]; } // Firefox else if (userAgent.includes('Firefox')) { name = 'Firefox'; const match = userAgent.match(/Firefox\/(\d+)/); if (match) version = match[1]; } // Edge else if (userAgent.includes('Edg')) { name = 'Edge'; const match = userAgent.match(/Edg\/(\d+)/); if (match) version = match[1]; } return { name, version }; } const useSpeechRecognition = (options = {}) => { const { language = 'en-US', continuous = true, interimResults = true, maxAlternatives = 1, onResult, onError, onStart, onEnd, onAudioStart, onAudioEnd, onSoundStart, onSoundEnd, onSpeechStart, onSpeechEnd, onNoMatch, onNomatch } = options; const [isSupported, setIsSupported] = react.useState(false); const [isListening, setIsListening] = react.useState(false); const [transcript, setTranscript] = react.useState(''); const [finalTranscript, setFinalTranscript] = react.useState(''); const [interimTranscript, setInterimTranscript] = react.useState(''); const [error, setError] = react.useState(null); const recognitionRef = react.useRef(null); const finalTranscriptRef = react.useRef(''); // Check browser support and initialize react.useEffect(() => { const support = getBrowserSupport(); setIsSupported(support.webSpeechAPI); if (support.webSpeechAPI) { const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition; recognitionRef.current = new SpeechRecognition(); const recognition = recognitionRef.current; // Configure recognition recognition.continuous = continuous; recognition.interimResults = interimResults; recognition.lang = language; recognition.maxAlternatives = maxAlternatives; // Set up event listeners recognition.onresult = (event) => { let interimTranscript = ''; let finalTranscript = ''; for (let i = event.resultIndex; i < event.results.length; i++) { const transcript = event.results[i][0].transcript; if (event.results[i].isFinal) { finalTranscript += transcript; } else { interimTranscript += transcript; } } finalTranscriptRef.current = finalTranscript; setFinalTranscript(finalTranscript); setInterimTranscript(interimTranscript); setTranscript(finalTranscript + interimTranscript); onResult?.(event); }; recognition.onerror = (event) => { setError(event.error); setIsListening(false); onError?.(event); }; recognition.onstart = () => { setIsListening(true); setError(null); onStart?.(); }; recognition.onend = () => { setIsListening(false); onEnd?.(); }; recognition.onaudiostart = onAudioStart; recognition.onaudioend = onAudioEnd; recognition.onsoundstart = onSoundStart; recognition.onsoundend = onSoundEnd; recognition.onspeechstart = onSpeechStart; recognition.onspeechend = onSpeechEnd; recognition.onnomatch = onNomatch || onNoMatch; } // Cleanup return () => { if (recognitionRef.current) { recognitionRef.current.abort(); } }; }, [continuous, interimResults, language, maxAlternatives, onResult, onError, onStart, onEnd, onAudioStart, onAudioEnd, onSoundStart, onSoundEnd, onSpeechStart, onSpeechEnd, onNoMatch, onNomatch]); const start = react.useCallback(() => { if (!isSupported || !recognitionRef.current) { setError('Speech recognition is not supported'); return; } try { recognitionRef.current.start(); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to start recognition'); } }, [isSupported]); const stop = react.useCallback(() => { if (recognitionRef.current) { recognitionRef.current.stop(); } }, []); const abort = react.useCallback(() => { if (recognitionRef.current) { recognitionRef.current.abort(); } }, []); const reset = react.useCallback(() => { setTranscript(''); setFinalTranscript(''); setInterimTranscript(''); setError(null); finalTranscriptRef.current = ''; }, []); const updateConfig = react.useCallback((config) => { if (recognitionRef.current) { if (config.language !== undefined) { recognitionRef.current.lang = config.language; } if (config.continuous !== undefined) { recognitionRef.current.continuous = config.continuous; } if (config.interimResults !== undefined) { recognitionRef.current.interimResults = config.interimResults; } if (config.maxAlternatives !== undefined) { recognitionRef.current.maxAlternatives = config.maxAlternatives; } } }, []); return { isSupported, isListening, transcript, finalTranscript, interimTranscript, error, start, stop, abort, reset, updateConfig }; }; exports.useSpeechRecognition = useSpeechRecognition; //# sourceMappingURL=useSpeechRecognition.js.map