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

React Native俄文语音转文字实现及Voice.startSpeech报错修复求助

React Native俄文语音转文字实现及Voice.startSpeech错误修复

错误原因分析

出现[TypeError: null is not an object (evaluating 'Voice.startSpeech')]的核心原因:

  • 语音识别模块未正确安装、链接或初始化
  • 模块方法调用版本不兼容(旧版startSpeech与新版start接口差异)
  • 缺少必要的麦克风和语音识别权限配置

分步修复方案

1. 确保依赖正确安装与配置

使用维护中的官方包@react-native-voice/voice替代旧版react-native-voice:

# 安装依赖
npm install @react-native-voice/voice --save
# iOS需执行Pod安装
cd ios && pod install && cd ..

权限配置

  • iOS:在Info.plist中添加权限描述:
<key>NSSpeechRecognitionUsageDescription</key>
<string>需要使用语音识别功能</string>
<key>NSMicrophoneUsageDescription</key>
<string>需要使用麦克风进行语音输入</string>
  • Android:在AndroidManifest.xml中添加权限:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />

2. 代码关键修复

以下是修改后的完整代码,标注核心修改点:

import React, { useState, useEffect } from 'react';
import { View, Image, Pressable, Text, StyleSheet } from 'react-native';
import Voice from '@react-native-voice/voice'; // 确保正确导入官方包
import { useAuth } from './your-auth-module-path'; // 替换为实际的useAuth路径

const Train = () => {
  const [user] = useAuth();
  const [pitch, setPitch] = useState('');
  const [error, setError] = useState('');
  const [end, setEnd] = useState('');
  const [started, setStarted] = useState('');
  const [results, setResults] = useState([]);
  const [partialResults, setPartialResults] = useState([]);

  useEffect(() => {
    // 改用addEventListener绑定回调(替代直接赋值onXXX方法,避免初始化异常)
    Voice.addEventListener('speechStart', onSpeechStart);
    Voice.addEventListener('speechEnd', onSpeechEnd);
    Voice.addEventListener('speechError', onSpeechError);
    Voice.addEventListener('speechResults', onSpeechResults);
    Voice.addEventListener('speechPartialResults', onSpeechPartialResults);
    Voice.addEventListener('speechVolumeChanged', onSpeechVolumeChanged);

    return () => {
      // 组件卸载时清理监听器与识别实例
      Voice.removeAllListeners();
      Voice.destroy().catch(err => console.error(err));
    };
  }, []);

  const onSpeechStart = (e) => {
    console.log('onSpeechStart: ', e);
    setStarted('√');
  };

  const onSpeechEnd = (e) => {
    console.log('onSpeechEnd: ', e);
    setEnd('√');
  };

  const onSpeechError = (e) => {
    console.log('onSpeechError: ', e);
    setError(JSON.stringify(e.error));
  };

  const onSpeechResults = (e) => {
    console.log('onSpeechResults: ', e);
    setResults(e.value);
  };

  const onSpeechPartialResults = (e) => {
    console.log('onSpeechPartialResults: ', e);
    setPartialResults(e.value);
  };

  const onSpeechVolumeChanged = (e) => {
    console.log('onSpeechVolumeChanged: ', e);
    setPitch(e.value);
  };

  const startRecognizing = async () => {
    try {
      // 俄文语音识别使用locale参数 'ru-RU'
      await Voice.start('ru-RU');
      setPitch('');
      setError('');
      setStarted('');
      setResults([]);
      setPartialResults([]);
      setEnd('');
    } catch (e) {
      console.error(e);
    }
  };

  const stopRecognizing = async () => {
    try {
      await Voice.stop();
    } catch (e) {
      console.error(e);
    }
  };

  const cancelRecognizing = async () => {
    try {
      await Voice.cancel();
    } catch (e) {
      console.error(e);
    }
  };

  const destroyRecognizer = async () => {
    try {
      await Voice.destroy();
      setPitch('');
      setError('');
      setStarted('');
      setResults([]);
      setPartialResults([]);
      setEnd('');
    } catch (e) {
      console.error(e);
    }
  };

  return (
    <View style={styles.container}>
      <View style={styles.header}>
        <Image
          source={require('../assets/images/Logo_small.png')}
          style={styles.logo_s}
          resizeMode='contain'
        />
      </View>
      <View style={styles.main_cont}>
        {/* 替换为你的Train_word组件 */}
        {/* <Train_word marginBottom={34}/>
        <Train_word_2 marginBottom={55}/> */}
        <Pressable marginBottom={190} onPress={startRecognizing}>
          <Image
            source={require('../assets/images/Start_img.png')}
            style={styles.start_img}
          />
        </Pressable>
        <Pressable style={styles.result} onPress={() => console.log('当前识别结果:', results)}>
          <Text style={styles.text_result}>Получить результат</Text>
        </Pressable>
        {/* 添加识别结果展示区域 */}
        {results.length > 0 && (
          <View style={styles.resultTextContainer}>
            <Text style={styles.resultText}>识别结果:{results[0]}</Text>
          </View>
        )}
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
  },
  header: {
    paddingTop: 20,
    alignItems: 'center',
  },
  logo_s: {
    width: 100,
    height: 100,
  },
  main_cont: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  start_img: {
    width: 150,
    height: 150,
  },
  result: {
    paddingHorizontal: 30,
    paddingVertical: 15,
    backgroundColor: '#007AFF',
    borderRadius: 8,
  },
  text_result: {
    color: '#fff',
    fontSize: 16,
  },
  resultTextContainer: {
    marginTop: 20,
    padding: 10,
    backgroundColor: '#f0f0f0',
    borderRadius: 8,
  },
  resultText: {
    fontSize: 16,
    color: '#333',
  },
});

export default Train;

3. 额外注意事项

  • 测试时确保设备联网(语音识别依赖云端服务)
  • 确认设备系统支持俄文语音识别(可在系统设置中添加俄文语言)
  • Android设备需确保已安装Google语音识别服务

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 17:50:36