Cześć, posiadam stronę internetową wykonaną w React postawioną za pomocą Express w aplikacji node.js. Zrobiłem sobie proste sterowanie głosowe za pomocą wbudowanego obiektu w przeglądarkę {window}. Aplikacja sama w sobie działa, jak wystawiam serwer react lokalnie (npm start), tzn. wykrywa mikrofon, przechwytuje dźwięk i zwraca za pomocą google speech recognition string, który steruje stroną. Jednak problem się pojawia, gdy stronę już stawiam za pomocą Express na aplikacji node.js. Funkcja przycisku i zmiany stanu (kolor przycisku) w react się wykonuje, jednak rec.start() nie uruchamia się. Myślałem szczerze, że skoro otwieram stronę hostowaną z aplikacji node.js, to obiekt window jest wbudowany w przeglądarkę, w której otwiera się. Więc pytanie: czy istnieje jakiś sposób przebudowania (odniesienia się do obiektu window) bez przebudowywania całego softu nasłuchu i odpowiedzi, który już sobie przygotowałem? Znalazłem również biblioteki dla node.js do przetwarzania mowy (np. react-speech-recognition), ale nie sprawdzałem jeszcze ich, bo może udałoby się bez zmieniania za bardzo kodu uruchomić standardowy {window}? Jeżeli nie ma takiej możliwości, to czy jest ktoś w stanie mi polecić sprawdzoną bibliotkę opartą o zewnętrzną chmurę (jak np. google)?
import React, { useState } from 'react'
import { Button } from 'reactstrap'
import { Mic } from 'react-bootstrap-icons'
import cmds from './commands'
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition
class Controller extends React.Component {
constructor(props) {
super(props)
this.rec = new SpeechRecognition()
this.rec.lang = 'pl-PL'
this.rec.onstart = () => { console.log("Listening...") }
this.rec.onresult = async event => {
const current = event.resultIndex
const transcript = event.results[current][0].transcript
await cmds.readOut(transcript)
}
this.rec.onend = async () => {
await this.rec.abort()
await this.rec.stop()
if (this.state.bttnColor === 'danger')
await this.rec.start()
}
this.state = {
bttnColor: 'primary'
}
}
async startListening() {
await this.rec.abort()
await this.rec.stop()
if (this.state.bttnColor === 'danger')
await this.rec.start()
}
render() {
return (
<>
<Button style={{ float: 'right' }} color={this.state.bttnColor}
onClick={async () => {
await this.setState({ bttnColor: this.state.bttnColor === 'primary' ? 'danger' : 'primary' });
await this.startListening()
}}
><Mic color="white" /></Button>
</>
)
}
}
import axios from 'axios'
const commands = {
states: [
{ state: false, ref: '/upCmd', lastType: '' },
{ state: false, ref: '/downCmd', lastType: '' },
{ state: false, ref: '/leftCmd', lastType: '' },
{ state: false, ref: '/rightCmd', lastType: '' }
],
_voiceHandler: async cmd => {
console.log('cmd', cmd)
let response
switch (cmd.toLowerCase()) {
case 'jedź': case 'przed siebie': case 'przód': case 'prosto': case 'do przodu': case 'jedź przed siebie':
response = 'jadę prosto'
await axios.post('/upCmd', { state: true }); break
case 'skręć w lewo': case 'lewo': case 'w lewo':
response = 'skręcam w lewo'
await axios.post('/leftCmd', { state: true }); break
case 'skręć w prawo': case 'prawo': case 'w prawo':
response = 'skręcam w prawo'
await axios.post('/rightCmd', { state: true }); break
case 'cofaj': case 'tył': case 'do tyłu':
response = 'cofam'
await axios.post('/downCmd', { state: true }); break
case 'stop': case 'zatrzymaj się': case 'stój': case 'nie ruszaj się':
response = 'zatrzymuję się'
await axios.post('/upCmd', { state: false })
await axios.post('/leftCmd', { state: false })
await axios.post('/rightCmd', { state: false })
await axios.post('/downCmd', { state: false })
break
} //await before axioses blocks response speech text without answer
if (response === undefined) response = 'nie rozumiem'
return response
},
readOut: async message => {
const speech = new SpeechSynthesisUtterance()
speech.text = await commands._voiceHandler(message)
speech.volume = 1
speech.rate = 1
speech.pitch = 1
speech.lang = 'pl-PL'
window.speechSynthesis.speak(speech)
}
}
export default commands
Z góry dziękuję.