-
Notifications
You must be signed in to change notification settings - Fork 284
/
Copy pathuseSpeechRecognition.ts
85 lines (69 loc) · 2.22 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 { 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);
const optionsRef = useRef(options);
useEffect(() => {
if (!("webkitSpeechRecognition" in window)) {
console.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) => {
console.error(event.error);
};
recognition.onend = () => {
setIsListening(false);
setTranscript("");
};
return () => {
if (recognitionRef.current) {
recognitionRef.current.stop();
}
};
}, [options]);
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;