-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathuseSpeechRecognition.ts
85 lines (69 loc) · 2.21 KB
/
useSpeechRecognition.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import { logger } from '@/app/log/logger';
import { useState, useRef, useEffect } from 'react';
interface SpeechRecognitionOptions {
interimResults?: boolean;
lang?: string;
continuous?: boolean;
}
const useSpeechToText = (options: SpeechRecognitionOptions = {}) => {
const [isListening, setIsListening] = useState(false);
const [transcript, setTranscript] = useState('');
const recognitionRef = useRef<SpeechRecognition | null>(null);
useEffect(() => {
if (!('webkitSpeechRecognition' in window)) {
logger.error('Web Speech API is not supported');
return;
}
const recognition = new window.webkitSpeechRecognition();
recognitionRef.current = recognition;
recognition.interimResults = options.interimResults || true;
recognition.lang = options.lang || 'en-US';
recognition.continuous = options.continuous || false;
if ('webkitSpeechGrammarList' in window) {
const grammar =
'#JSGF V1.0; grammar punctuation; public <punc> = . | , | ! | ; | : ;';
const speechRecognitionList = new window.webkitSpeechGrammarList();
speechRecognitionList.addFromString(grammar, 1);
recognition.grammars = speechRecognitionList;
}
recognition.onresult = (event: SpeechRecognitionEvent) => {
let text = '';
for (let i = 0; i < event.results.length; i++) {
text += event.results[i][0].transcript;
}
// Always capitalize the first letter
setTranscript(text.charAt(0).toUpperCase() + text.slice(1));
};
recognition.onerror = (event) => {
logger.error(event.error);
};
recognition.onend = () => {
setIsListening(false);
setTranscript('');
};
return () => {
if (recognitionRef.current) {
recognitionRef.current.stop();
}
};
}, []);
const startListening = () => {
if (recognitionRef.current && !isListening) {
recognitionRef.current.start();
setIsListening(true);
}
};
const stopListening = () => {
if (recognitionRef.current && isListening) {
recognitionRef.current.stop();
setIsListening(false);
}
};
return {
isListening,
transcript,
startListening,
stopListening,
};
};
export default useSpeechToText;