mirror of
https://github.com/lucasrcsantana/story-generator.git
synced 2025-12-18 06:17:56 +00:00
100 lines
2.7 KiB
TypeScript
100 lines
2.7 KiB
TypeScript
import { useState, useEffect, useCallback } from 'react';
|
|
import { SpeechRecognition } from '../../../types/speech';
|
|
|
|
type RecognitionState = 'idle' | 'recording' | 'processing' | 'error';
|
|
|
|
interface UseSpeechRecognitionReturn {
|
|
transcript: string;
|
|
start: () => void;
|
|
stop: () => void;
|
|
reset: () => void;
|
|
status: RecognitionState;
|
|
error: string | null;
|
|
isSupported: boolean;
|
|
}
|
|
|
|
export function useSpeechRecognition(): UseSpeechRecognitionReturn {
|
|
const [status, setStatus] = useState<RecognitionState>('idle');
|
|
const [transcript, setTranscript] = useState('');
|
|
const [error, setError] = useState<string | null>(null);
|
|
const [recognition, setRecognition] = useState<SpeechRecognition | null>(null);
|
|
|
|
const isSupported = typeof window !== 'undefined' && ('SpeechRecognition' in window || 'webkitSpeechRecognition' in window);
|
|
|
|
useEffect(() => {
|
|
if (!isSupported) {
|
|
setError('Reconhecimento de voz não é suportado neste navegador');
|
|
return;
|
|
}
|
|
|
|
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
|
|
const recognition = new SpeechRecognition();
|
|
|
|
recognition.continuous = false;
|
|
recognition.lang = 'pt-BR';
|
|
recognition.interimResults = false;
|
|
recognition.maxAlternatives = 1;
|
|
|
|
recognition.onstart = () => setStatus('recording');
|
|
recognition.onend = () => setStatus('idle');
|
|
recognition.onerror = (event) => {
|
|
setStatus('error');
|
|
setError(`Erro na gravação: ${event.error}`);
|
|
};
|
|
|
|
recognition.onresult = (event) => {
|
|
const result = event.results[0][0].transcript;
|
|
setTranscript(prev => prev + ' ' + result);
|
|
setStatus('processing');
|
|
setTimeout(() => setStatus('idle'), 2000);
|
|
};
|
|
|
|
setRecognition(recognition);
|
|
}, [isSupported]);
|
|
|
|
const start = useCallback(() => {
|
|
if (!recognition || status === 'recording') return;
|
|
|
|
setTranscript('');
|
|
setError(null);
|
|
try {
|
|
recognition.start();
|
|
} catch (err) {
|
|
setError('Não foi possível iniciar a gravação');
|
|
setStatus('error');
|
|
}
|
|
}, [recognition, status]);
|
|
|
|
const stop = useCallback(() => {
|
|
if (recognition && status === 'recording') {
|
|
recognition.stop();
|
|
}
|
|
}, [recognition, status]);
|
|
|
|
const reset = useCallback(() => {
|
|
setTranscript('');
|
|
setError(null);
|
|
setStatus('idle');
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (status === 'recording') {
|
|
const timeout = setTimeout(() => {
|
|
stop();
|
|
setError('Tempo máximo de gravação atingido (2 minutos)');
|
|
}, 120_000);
|
|
|
|
return () => clearTimeout(timeout);
|
|
}
|
|
}, [status, stop]);
|
|
|
|
return {
|
|
transcript,
|
|
start,
|
|
stop,
|
|
reset,
|
|
status,
|
|
error,
|
|
isSupported
|
|
};
|
|
}
|