Speech to Text Conversion in React Native - Using Hooks (Use useState and useEffect)

Gilshaan Jabbar
5 min readApr 3, 2020

This is an example to show how to do Speech to Text Conversion in React Native — Voice Recognition. This is a very demanding feature from many of the customers after the success of intelligent voice assistances like Google Home and Amazon Alexa. To make your app different from another app you can implement voice recognition features while making search filters. In the current scenario, many applications have voice search with text input search where they provide either search by text input or can search by voice.

Here we are going to see how can we convert voice to text and can get the texts as a result with the help of voice recognition.

Voice Recognition in React Native

For the voice recognition in React Native or we can say that for the speech to text conversion we are going to use Voicecomponent provided by react-native-voice library which has a number of events which can be used to start or stop the voice recognition and to get the status and of voice recognition.

When we initialize the screen we set some event callbacks in the constructor which looks like the code snippet given below. You can see we are providing a function for the SpeechStart or for the Speech End and so on. So this is the callbacks basically which will be called automatically when the event happens.

Voice.onSpeechStart = onSpeechStart;
Voice.onSpeechEnd = onSpeechEnd;
Voice.onSpeechError = onSpeechError;
Voice.onSpeechResults = onSpeechResults;
Voice.onSpeechPartialResults = onSpeechPartialResults;
Voice.onSpeechVolumeChanged = onSpeechVolumeChanged;

So these were the callback events to get the status of voice recognition. Now let’s see how to start, stop, cancel and destroy the voice recognition process.

Start Voice Recognition

_startRecognizing = async () => {
setPitch('')
setError('')
setStarted('')
setResults([])
setPartialResults([])
setEnd('')
try {
await Voice.start('en-US');
} catch (e) {
console.error(e);
}
};

Stop Voice Recognition

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

Cancel Voice Recognition

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

Destroy the session of Voice Recognition

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

In this example, we are going to make a screen with a mike icon which will be the clickable button for us and after clicking onto that we will start voice recognition. In the whole process, we will get the status of everything in the functions we have set for the callback. We can also stop the speech to text conversion by using stop, cancel and destroy button.

One more point I want to add in this is we will get two types of results while and after voice recognition which are:

  1. Result: It comes when Speech Recognizer finishes recognization.
  2. Partial Results: It comes during the computation of results, so this is the kind of words that voice recognizer recognizes before the final result. Partial results can be many for a single recognition as it is an intermediate result.

To Make a React Native App

Install the package using npm

npm install @react-native-community/voice --save

Please use the following command to install CocoaPods

cd ios && pod install && cd ..

Permission to use microphone and speech recognition for IOS

Need to include permissions for NSMicrophoneUsageDescription and NSSpeechRecognitionUsageDescription inside Info.plist for iOS. See the included VoiceTest for how to handle these cases.

<dict>
...
<key>NSMicrophoneUsageDescription</key>
<string>Description of why you require the use of the microphone</string>
<key>NSSpeechRecognitionUsageDescription</key>
<string>Description of why you require the use of the speech recognition</string>
...
</dict>

Code to Convert Speech to Text

Now Open App.js in any code editor and replace the code with the following code

App.js

import React, { useState, useEffect } from 'react';
import {
StyleSheet,
Text,
View,
SafeAreaView,
Image,
TouchableHighlight,
ScrollView,
Platform} from 'react-native';
import Voice from '@react-native-community/voice';export default function TextToSpeech() {useEffect(() => {
function onSpeechStart(e) {
console.log('onSpeechStart: ', e);
setStarted('√')
};
function onSpeechResults(e) {
console.log('onSpeechResults: ', e);
setResults(e.value)
};
function onSpeechPartialResults(e) {
console.log('onSpeechPartialResults: ', e);
setPartialResults(e.value)
};
function onSpeechVolumeChanged(e) {
console.log('onSpeechVolumeChanged: ', e);
setPitch(e.value)
};
Voice.onSpeechStart = onSpeechStart;
Voice.onSpeechEnd = onSpeechEnd;
Voice.onSpeechError = onSpeechError;
Voice.onSpeechResults = onSpeechResults;
Voice.onSpeechPartialResults = onSpeechPartialResults;
Voice.onSpeechVolumeChanged = onSpeechVolumeChanged;
return () => {
Voice.destroy().then(Voice.removeAllListeners);
};
}, []);
_startRecognizing = async () => {
setPitch('')
setError('')
setStarted('')
setResults([])
setPartialResults([])
setEnd('')
try {
await Voice.start('en-US');
} catch (e) {
console.error(e);
}
};
_stopRecognizing = async () => {
//Stops listening for speech
try {
await Voice.stop();
} catch (e) {
console.error(e);
}
};
_cancelRecognizing = async () => {
//Cancels the speech recognition
try {
await Voice.cancel();
} catch (e) {
console.error(e);
}error(e);
}
};
_destroyRecognizer = async () => {
//Destroys the current SpeechRecognizer instance
try {
await Voice.destroy();
} catch (e) {
console.error(e);
}
setPitch('')
setError('')
setStarted('')
setResults([])
setPartialResults([])
setEnd('')
};
return (
<SafeAreaView style={{ flex: 1 }}>
<View style={styles.container}>
<Text style={styles.welcome}>
Example of Speech to Text conversion / Voice Recognition
</Text>
<Text style={styles.instructions}>
Press mike to start Recognition
</Text>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: 10,
}}>
<Text
style={{
flex: 1,
textAlign: 'center',
color: '#B0171F',
}}>{`Started: ${started}`}</Text>
<Text
style={{
flex: 1,
textAlign: 'center',
color: '#B0171F',
}}>{`End: ${end}`}</Text>
</View>
<View
style={{
flexDirection: 'row',
justifyContent: 'space-between',
paddingVertical: 10,
}}>
<Text
style={{
flex: 1,
textAlign: 'center',
color: '#B0171F',
}}>{`Pitch \n ${pitch}`}</Text>
<Text
style={{
flex: 1,
textAlign: 'center',
color: '#B0171F',
}}>{`Error \n ${error}`}</Text>
</View>
<TouchableHighlight
onPress={this._startRecognizing}
style={{ marginVertical: 20 }}>
<Image
style={styles.button}
source={{
uri:
'https://raw.githubusercontent.com/AboutReact/sampleresource/master/microphone.png',
}}
/>
</TouchableHighlight>
<Text
style={{
textAlign: 'center',
color: '#B0171F',
marginBottom: 1,
fontWeight: '700',
}}>
Partial Results
</Text>
<ScrollView>
{partialResults.map((result, index) => {
return (
<Text
key={`partial-result-${index}`}
style={{
textAlign: 'center',
color: '#B0171F',
marginBottom: 1,
fontWeight: '700',
}}>
{result}
</Text>
);
})}
</ScrollView>
<Text style={styles.stat}>Results</Text>
<ScrollView style={{ marginBottom: 42 }}>
{results.map((result, index) => {
return (
<Text key={`result-${index}`} style={styles.stat}>
{result}
</Text>
);
})}
</ScrollView>
<View
style={{
flexDirection: 'row',
alignItems: 'space-between',
position: 'absolute',
bottom: 0,
}}>
<TouchableHighlight
onPress={this._stopRecognizing}
style={{ flex: 1, backgroundColor: 'red' }}>
<Text style={styles.action}>Stop</Text>
</TouchableHighlight>
<TouchableHighlight
onPress={this._cancelRecognizing}
style={{ flex: 1, backgroundColor: 'red' }}>
<Text style={styles.action}>Cancel</Text>
</TouchableHighlight>
<TouchableHighlight
onPress={this._destroyRecognizer}
style={{ flex: 1, backgroundColor: 'red' }}>
<Text style={styles.action}>Destroy</Text>
</TouchableHighlight>
</View>
</View>
</SafeAreaView>
)}const styles = StyleSheet.create({
button: {
width: 50,
height: 50,
},
container: {
flex: 1,
flexDirection: 'column',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 20,
textAlign: 'center',
margin: 10,
},
action: {
width: '100%',
textAlign: 'center',
color: 'white',
paddingVertical: 8,
marginVertical: 5,
fontWeight: 'bold',
},
instructions: {
textAlign: 'center',
color: '#333333',
marginBottom: 5,
},
stat: {
textAlign: 'center',
color: '#B0171F',
marginBottom: 1,
marginTop: 30,
},
});

This is how you can do speech to text conversion / Voice Recognition in React Native.

Hope you liked it. 🙂

--

--