Spaces:
Sleeping
Sleeping
| // @ts-ignore | |
| const SpeechRecognitionPolyfill: typeof webkitSpeechRecognition = typeof window !== 'undefined' ? ( | |
| // @ts-ignore | |
| window.SpeechRecognition || | |
| window.webkitSpeechRecognition || | |
| // @ts-ignore | |
| window.mozSpeechRecognition || | |
| // @ts-ignore | |
| window.msSpeechRecognition || | |
| // @ts-ignore | |
| window.oSpeechRecognition | |
| ) as typeof webkitSpeechRecognition : undefined | |
| type subscriber = (msg: string, command?: string) => void | |
| export class SR { | |
| recognition?: SpeechRecognition | |
| onchange?: subscriber | |
| transcript: boolean = false | |
| listening: boolean = false | |
| private commandsRe?: RegExp | |
| constructor(commands: string[]) { | |
| this.recognition = SpeechRecognitionPolyfill ? new SpeechRecognitionPolyfill() : undefined | |
| if (!this.recognition) { | |
| return | |
| } | |
| this.configuration('zh-CN') | |
| if (commands.length) { | |
| this.commandsRe = new RegExp(`^(${commands.join('|')})。?$`) | |
| } | |
| this.recognition.onresult = this.speechRecognition | |
| this.recognition.onerror = (err) => { | |
| console.log('err', err.error) | |
| this.stop() | |
| } | |
| this.recognition.onend = () => { | |
| if (this.recognition && this.listening) { | |
| this.recognition.start() | |
| } | |
| } | |
| } | |
| speechRecognition = (event: SpeechRecognitionEvent) => { | |
| if (!this.listening) return | |
| for (var i = event.resultIndex; i < event.results.length; i++) { | |
| let result = event.results[i] | |
| if (result.isFinal) { | |
| var alt = result[0] | |
| const text = alt.transcript.trim() | |
| if (this.commandsRe && this.commandsRe.test(text)) { | |
| return this.onchange?.('', RegExp.$1) | |
| } | |
| if (!this.transcript) return | |
| this.onchange?.(text) | |
| } | |
| } | |
| } | |
| private configuration = async (lang: string = 'zh-CN') => { | |
| return new Promise((resolve) => { | |
| if (this.recognition) { | |
| this.recognition.continuous = true | |
| this.recognition.lang = lang | |
| this.recognition.onstart = resolve | |
| } | |
| }) | |
| } | |
| start = async () => { | |
| if (this.recognition && !this.listening) { | |
| await this.recognition.start() | |
| this.transcript = true | |
| this.listening = true | |
| } | |
| } | |
| stop = () => { | |
| if (this.recognition) { | |
| this.recognition.stop() | |
| this.transcript = false | |
| this.listening = false | |
| } | |
| } | |
| pause = () => { | |
| if (this.recognition) { | |
| this.transcript = false | |
| } | |
| } | |
| resume = () => { | |
| if (this.recognition) { | |
| this.transcript = true | |
| } | |
| } | |
| abort = () => { | |
| if (this.recognition && this.transcript) { | |
| this.recognition.abort() | |
| this.transcript = false | |
| this.listening = false | |
| } | |
| } | |
| } | |