You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React.js语音助手无法自动朗读的问题排查与解决

解决React语音助手自动朗读问题

你的代码无法自动朗读的核心问题有两个:

  • useEffect的依赖数组为空,仅在组件挂载时执行一次,后续transcript更新不会触发朗读逻辑
  • 未针对语音识别的实时输出做响应式处理

以下是具体修复方案:

1. 修正useEffect的依赖项

将transcript和speaking加入依赖数组,确保每次语音识别结果更新或朗读状态变化时,重新执行朗读判断逻辑:

// 初始化监听,仅挂载时执行
useEffect(() => {
  SpeechRecognition.startListening({ continuous: true });
  // 组件卸载时清理资源
  return () => {
    SpeechRecognition.stopListening();
    cancel();
  };
}, []);

// 单独处理自动朗读逻辑,依赖转录内容和朗读状态
useEffect(() => {
  // 避免空内容重复朗读,且当前未在朗读时触发
  if (transcript.trim() && !speaking) {
    speak({ text: `你说的是:${transcript}` });
    // 可选:朗读后清空转录内容,避免重复朗读
    // resetTranscript();
  }
}, [transcript, speaking, speak, resetTranscript]);

2. 优化指令回调的朗读逻辑

原test指令直接朗读transcript会包含指令本身,建议改为明确的响应文本,同时给其他指令添加反馈朗读:

{
  command: 'open *',
  callback: (site) => {
    window.open('https://' + site);
    speak({ text: `正在打开网站${site}` });
  },
},
{
  command: 'navigate to *',
  callback: (pageName) => {
    window.location.href = `https://localhost:44435/${pageName}`;
    speak({ text: `正在跳转到页面${pageName}` });
  },
},
{
  command: 'test',
  callback: () => speak({ text: '测试朗读功能已正常触发' }),
},

3. 避免连续识别的重复朗读(可选)

持续监听时,转录内容会实时更新,可能导致重复朗读同一内容,可添加状态标记已朗读的文本:

// 在组件内新增状态
const [lastSpokenText, setLastSpokenText] = useState('');

// 修改自动朗读逻辑的useEffect
useEffect(() => {
  const currentText = transcript.trim();
  if (currentText && !speaking && currentText !== lastSpokenText) {
    speak({ text: `你说的是:${currentText}` });
    setLastSpokenText(currentText);
  }
}, [transcript, speaking, speak, lastSpokenText]);

完整修复后的代码

import React, { useEffect, useState } from 'react';
import SpeechRecognition, { useSpeechRecognition } from 'react-speech-recognition';
import { useSpeechSynthesis } from 'react-speech-kit';

const Dictaphone = () => {
    const { speak, cancel, speaking } = useSpeechSynthesis();
    const { transcript, resetTranscript } = useSpeechRecognition({
        commands: [
            {
                command: 'reset',
                callback: ({ resetTranscript }) => {
                    resetTranscript();
                    speak({ text: '已重置转录内容' });
                },
            },
            {
                command: 'open *',
                callback: (site) => {
                    window.open('https://' + site);
                    speak({ text: `正在打开网站${site}` });
                },
            },
            {
                command: 'navigate to *',
                callback: (pageName) => {
                    window.location.href = `https://localhost:44435/${pageName}`;
                    speak({ text: `正在跳转到页面${pageName}` });
                },
            },
            {
                command: 'test',
                callback: () => speak({ text: '测试朗读功能已正常触发' }),
            },
        ],
    });

    const [lastSpokenText, setLastSpokenText] = useState('');

    // 初始化语音监听
    useEffect(() => {
        SpeechRecognition.startListening({ continuous: true });
        return () => {
            SpeechRecognition.stopListening();
            cancel();
        };
    }, []);

    // 自动朗读逻辑
    useEffect(() => {
        const currentText = transcript.trim();
        if (currentText && !speaking && currentText !== lastSpokenText) {
            speak({ text: `你说的是:${currentText}` });
            setLastSpokenText(currentText);
            // 可选:朗读后清空转录内容
            // resetTranscript();
        }
    }, [transcript, speaking, speak, lastSpokenText]);

    if (!SpeechRecognition.browserSupportsSpeechRecognition()) {
        return <span>浏览器不支持语音识别功能。</span>;
    }

    return (
        <div>
            <button onClick={() => SpeechRecognition.startListening({ continuous: true })}>开始监听</button>
            <button onClick={SpeechRecognition.stopListening}>停止监听</button>
            <button onClick={resetTranscript}>重置转录</button>
            <button onClick={() => speak({ text: transcript })}>手动朗读</button>
            <p>转录内容:{transcript}</p>
        </div>
    );
};

export default Dictaphone;

额外注意事项

  • 浏览器环境要求:语音合成和识别功能需要HTTPS环境(localhost除外),且需要用户手动授权麦克风权限。
  • 朗读冲突处理:如果指令回调的朗读和自动朗读同时触发,可在指令回调中先调用cancel()终止当前朗读,避免音频重叠。

内容的提问来源于stack exchange,提问作者Peter_Griffindor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 00:52:28