首页 > 解决方案 > 多个领域的反应语音识别

问题描述

我正在制作一个输入表单,我想使用 React Speech Recognition 包让用户可以选择记录他们的输入,而不是在表单中的两个字段中输入——“review”和“order”。我制作了两个版本的录音机,分别是 ReviewDict 和 OrderDict,并分别向它们传递一个“changeReview/changeOrder”道具来更新该字段。

但是,每当我单击开始录制其中一个时,它都会同时启动它们,并将我所说的文字记录拉到两个输入字段中。

有没有一种简单的方法可以使每个按钮只影响该包的实例?

这是我的代码的相关部分:

输入形式:

              <TextField
                value={postData.review}
                onInput={(e) =>
                  setPostData({ ...postData, review: e.target.value })
                }
              />
            </div>
            <ReviewDict changeReview={dictUpdate} />      
                  
            <div>
              <TextField
                value={postData.order}
                onInput={(e) =>
                  setPostData({ ...postData, order: e.target.value })
                }
              />
            </div>
            <OrderDict changeOrder={orderUpdate} />

然后我的录音机看起来像这样:

import React, { useState } from "react";
import { CardContent } from "@mui/material";
import { useEffect } from "react";
import MicIcon from "@mui/icons-material/Mic";
import MicOffIcon from "@mui/icons-material/MicOff";

import SpeechRecognition, {useSpeechRecognition} from "react-speech-recognition";


export const ReviewDict = ({ changeText, changeOrder, changeReview }) => {
  const [reviewText, setReviewText] = useState("");

  const {
    transcript,
    listening,
    resetTranscript,
    browserSupportsSpeechRecognition,
  } = useSpeechRecognition();

  useEffect(() => {
    setReviewText(" ");

    changeReview(transcript)
  }, [transcript]);

  if (!browserSupportsSpeechRecognition) {
    return <span>Browser doesn't support speech recognition.</span>;
  }

  return (
    <div>
      <CardContent sx={{ paddingTop: 5, fontSize: 25 }}>
        <center>
          {!listening ? (
            <>
              {" "}
              <span onClick={SpeechRecognition.startListening}>
                <MicIcon fontSize="normal" /> review
              </span>
            </>
          ) : (
            <>
              <span onClick={SpeechRecognition.stopListening}>
                <MicOffIcon fontSize="normal" />
              </span>
            </>
          )}
        </center>
      </CardContent>
    </div>
  );
};

import React, { useState } from "react";
import { CardContent } from "@mui/material";
import { useEffect } from "react";
import MicIcon from "@mui/icons-material/Mic";
import MicOffIcon from "@mui/icons-material/MicOff";
import RestartAltIcon from "@mui/icons-material/RestartAlt";

import { Card, Rating, TextField, Box } from "@mui/material";

import SpeechRecognition, {
  useSpeechRecognition,
} from "react-speech-recognition";

export const OrderDict = ({ changeText, changeOrder, changeReview }) => {
  const [reviewText, setReviewText] = useState("");

  const {
    transcript,
    listening,
    resetTranscript,
    browserSupportsSpeechRecognition,
  } = useSpeechRecognition();

  useEffect(() => {
    setReviewText(" ");

    changeOrder(transcript);
  }, [transcript]);

  if (!browserSupportsSpeechRecognition) {
    return <span>Browser doesn't support speech recognition.</span>;
  }

  return (
    <div>
      <CardContent sx={{ paddingTop: 5, fontSize: 25 }}>
        <center>
 


          {!listening ? (
            <>
              {" "}
              <span onClick={SpeechRecognition.startListening}>
                <MicIcon fontSize="normal" /> order
              </span>
            </>
          ) : (
            <>
              <span onClick={SpeechRecognition.stopListening}>
                <MicOffIcon fontSize="normal" />
              </span>
            </>
          )}


{/*
          <br />
          {transcript && (
            <>
            <span onClick={resetTranscript}>
              <RestartAltIcon fontSize="large" />
              Re-record
            </span>
            </>
          )}
          */}
        </center>
      </CardContent>
    </div>
  );
};

非常感谢任何帮助!

标签: reactjs

解决方案


好的,我洗澡的时候解决了这个问题!

问题是语音识别工具的控件是全局的,所以在一个实例上调用 startListening 就是在所有实例上调用它,而且因为我的组件都呈现在页面上,所以我不能没有另一个 - 所以我只需要一次最多渲染一个。

所以我只是用这样的状态初始化了一个 fieldDict 变量:

  const [fieldDict, setFieldDict] = useState(null);

然后根据当前的 fieldDict 值,有条件地将开始录制按钮或相同的外观按钮以 setFieldDict 呈现到右侧字段,如下所示:

            {fieldDict === "review" ? (
              <ReviewDict changeReview={dictUpdate} />
            ) : (
                <center>
                  <MicIcon onClick={() => setFieldDict("review")} />
                </center>
            )}

在语音转文本组件中,我使用 useEffect 在组件渲染后立即开始录制,如下所示:

  useEffect(() => {
    SpeechRecognition.startListening()
  }, []);

这意味着从用户的角度来看,这与我尝试做的相同 - 有一个录制按钮,当您单击它时开始录制并将您的文本转录到正确的字段,但在幕后我只渲染一个实例一次将语音转文本组件,因此我避免在我不想这样做时意外触发它的实例。


推荐阅读