0
votes

I am working on a project and I need to translate speech into text I used Expo and React-native-voice. **[Unhandled promise rejection: TypeError: null is not an object (evaluating 'Voice.onSpeechStart = null')] - node_modules\react-native-voice\src\index.js:23:10 in removeAllListeners - node_modules\promise\setimmediate\core.js:37:14 in tryCallOne - ... 9 more stack frames

import React from "react";
import { StyleSheet, Text, View, TouchableOpacity } from "react-native";
import Voice from "react-native-voice";
import * as Permissions from "expo-permissions";

export default class App extends React.Component {
  constructor() {
    super();
    this.state = {
      results: [],
    };
    Voice.onSpeechStart = this.onSpeechStart;
    Voice.onSpeechRecognized = this.onSpeechRecognized;
    Voice.onSpeechEnd = this.onSpeechEnd;
    Voice.onSpeechError = this.onSpeechError;
    Voice.onSpeechResults = this.onSpeechResults;
    Voice.onSpeechPartialResults = this.onSpeechPartialResults;
    Voice.onSpeechVolumeChanged = this.onSpeechVolumeChanged;
  }
  async componentDidMount() {
    const {status} = await Permissions.askAsync(
      Permissions.AUDIO_RECORDING
    );
  }
  componentWillMount(){
    Voice.destroy().then(Voice.removeAllListeners)
  }



  onSpeechStart = (e)=> {
    console.log('onSpeechStart',e);
    
  };
  onSpeechRecognized =(e)=>{
    console.log('onSpeechRecognized',e); 
  }
  onSpeechEnd = (e)=>{
    console.log('onSpeechEnd'+e);
  }
  onSpeechError =(e)=>{
    console.log('onSpeechError'); 
  }
  onSpeechResults =  e => {
    console.log('onSpeechResults'+e);
    this.setState({
      results: e.value,
    });
  }
  onSpeechPartialResults = e =>{
    console.log('onSpeechPartialResults' + e.value);
  }
  onSpeechVolumeChanged = e =>{
    console.log('onSpeechVolumeChanged');
  }
  _startRecognizing=async()=>{
    try{
      await Voice.start('en-US')
    } catch(e) {
      console.error(e);
    }
  }
  _stopRecognizing = async()=>{
    try{
      await Voice.stop()
    }catch(e){
      console.error(e);
      
    }
  }

  render() {
    return (
      <View style={styles.container}>
        <TouchableOpacity
          onPress={this._startRecognizing}
          style={{
            backgroundColor: "green",
            height: 40,
            width: 100,
            marginBottom: 10,
          }}
        >
          <Text style={{ 
            fontSize: 20, 
            alignSelf: "center" 
            }}>
              Starts
              </Text>
        </TouchableOpacity>
        <TouchableOpacity
          onPress={this._stopRecognizing}
          style={{ 
            backgroundColor: "red", 
            height: 40, 
            width: 100 
          }}
        >
          <Text style={{ 
            fontSize: 20, 
            alignSelf: "center" 
            }}>
              Stop
              </Text>
        </TouchableOpacity>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "#fff",
    alignItems: "center",
    justifyContent: "center",
  },
});

from framework internals**

2

2 Answers

2
votes

Update for Expo 41+

With the release of the Expo SDK 41, config plugins were added. The 3.2.0 release of react-native-voice/voice added support for config plugins.

You install the dependency as you normally would

yarn add @react-native-voice/voice

And then you must update your app.json


"expo": {
  "plugins": [
    [
      "@react-native-voice/voice",
      {
        "microphonePermission": "Allow $(PRODUCT_NAME) to access your microphone",
        "speechRecogntionPermission": "Allow $(PRODUCT_NAME) to securely recognize user speech"
      }
    ]
  ]
}

You will probably need to create a new build as you may get an invariant violation.

You should now read the documentation for usage

—-

Expo 40 and older

Unfortunately react-native-voice is not compatible with Expo.

The reason for this is that Expo abstracts the native iOS and Android code away from you, this makes it quick and easy to make builds and develop but the downside is that you cannot add dependencies that require you to use native code.

react-native-voice requires the use of native code. You can see this by the fact that the installation instructions require you to link the native code. See here for the documentation.

If you wish to use this dependency in your Expo project then you will need to eject it. You can find more info about ejecting, and the pros and cons of doing so on the Expo documentation website here

1
votes

With Expo SDK42 you can use the react-native-voice plugin, here is what they have in the docs here