Basically, I am trying to mimick exactly what Google offers with their Webspeech Api however, I keep running into the issue where as soon as I stop talking the transcribed message from earlier disappears and then also when i click stop recording it just reverts to record for a split second and then stop recording again. Please help me fix this. Here is acess to my index and main files.
Main.tsx:
import React, {useState} from 'react'
import useSpeechToText from '../hooks';
const Main = () => {
const [textInput, setTextInput] = useState('');
const {isListening, transcript, startListening, stopListening} = useSpeechToText({continous:true})
const startStopListening = () => {
isListening ? stopVoiceInput() : startListening()
}
const stopVoiceInput = () => {
setTextInput(prevVal => prevVal + (transcript.length ? (prevVal.length ? ' ' : '') + transcript : ''))
stopListening()
}
return(
<div style={{display:'block', margin:'0 auto', width:'400px', textAlign:'center', marginTop:'200px'}}>
<button
onClick={() => {startStopListening()}}
style={{
backgroundColor: isListening ? "#d62d20" : "#008744",
color: "white",
padding: "10px 20px",
border: 'none',
borderRadius: '5px',
cursor: 'pointer',
transition: 'background-colo 0.3s ease',
}}>
{isListening? 'Stop listening' : 'Listen'}
</button>
<textarea
style={{
marginTop: '20px',
width: '100%',
height: '150px',
padding: '10px',
border: '1px solid #ccc',
borderRadius: '5px',
transition: 'border-color 0.3s ease',
resize: 'none',
backgroundColor: '#f8f8f8',
color: '#333',
}}
disabled={isListening}
value ={isListening ? textInput + (transcript.length ? (textInput.length ? ' ' : '') + transcript: '') : textInput}
onChange={(e)=>{setTextInput(e.target.value)}}
/>
</div>
)
}
export default Main
index.jsx:
import React, { useState, useRef, useEffect } from 'react';
const useSpeechToText = (options) => {
const [isListening, setIsListening] = useState(false)
const [transcript, setTranscript] = useState("")
const [noReason, setNoReason] = useState(true);
const recgonitionRef = useRef(null)
useEffect(()=>{
if(!('webkitSpeechRecognition' in window)){
console.error("Web speech api is not supported")
return;
}
recgonitionRef.current = new window.webkitSpeechRecognition()
const recognition = recgonitionRef.current
recognition.interimResults = options.interimResults || true
recognition.lang = "en-US"
recognition.continous = true
if("webkitSpeechGrammarList" in window){
const grammar = "#JSFG V1.0; grammar punctuation; public <punc> = . | , | ? | ! | ; | : ;"
const speechRecognitionList = new window.webkitSpeechGrammarList()
speechRecognitionList.addFromString(grammar, 1)
recognition.grammars = speechRecognitionList
}
recognition.onresult = (event) => {
let text = ""
for (let i=0; i<event.results.length; i++){
text += event.results[i][0].transcript
}
setTranscript(text)
setNoReason(false)
}
recognition.onerror = (event) => {
console.error("Speech recognition error:", event.error)
}
recognition.onend = () =>{
if (noReason) {
// If there was no reason for ending, restart the recognition
recgonitionRef.current.start();
setIsListening(true);
setNoReason(true); // Reset for the new session
}
}
return () => {
recognition.stop()
}
}, [])
const startListening = () =>{
if (recgonitionRef.current && !isListening){
recgonitionRef.current.start()
setIsListening(true)
setNoReason(true)
}
}
const stopListening = () =>{
if (recgonitionRef.current && isListening){
recgonitionRef.current.stop()
setIsListening(false);
}
}
return {
isListening,
transcript,
startListening,
stopListening
}
}
export default useSpeechToText
I have tried a bunch of little things but cant get it to work.
Prasun Sapkota is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.