我正在使用一个返回它的实例的库(语音)。我制作了以下成功使用它的组件
但是我需要在其他组件中使用以下组件的多个实例。每个组件都有一个唯一的
Voice
实例
因此,我需要克隆导入的
Voice
对象,为以下组件的每个实例创建单独/新的实例。
该组件随时接收属性
*unique_key*
进行标识。我还将该密钥绑定到(克隆的)SpeechInstance 以进行识别
import React, { Component } from 'react';
import { Text, View, Button} from 'react-native';
import Voice from '@react-native-voice/voice';
var all_speech_instances = [];
export default class VoiceRecorder extends Component {
constructor(props) {
super(props);
//like all_instances array Voice is global and its an instance returned by libraray
// So i am cloning it to make specific/new for each instance of this component
this.SpeechInstance = Object.assign(Object.create(Object.getPrototypeOf(Voice)), Voice);
this.SpeechInstance.unique_key = props.unique_key;
let obj_this = this;
this.SpeechInstance.onSpeechError = function(e) { obj_this.onSpeechError(e) };
this.SpeechInstance.onSpeechResults = function(e) { obj_this.onSpeechResults(e) };
//Shown for proof of concept
all_speech_instances.push(this.SpeechInstance);
if(all_speech_instances.length > 1){
console.log('Instance 1 => unique_key='+all_speech_instances[0].unique_key); //shows 1
console.log('Instance 2 => unique_key='+all_speech_instances[1].unique_key); //shows 2
}
}
_startRecognizing = async () => {
await this.SpeechInstance.start();
};
_stopRecognizing = async () => {
await this.SpeechInstance.stop();
};
onSpeechError(e) {
// whenever error
console.log('On speech error Key=' + this.SpeechInstance.unique_key);
// always shows 2
};
onSpeechResults(e){
// whenever speech recognized
console.log('On speech results Key=' + this.SpeechInstance.unique_key, e.value);
//always shows 2
};
//Following tow functions are react-native specific
componentWillUnmount() {
this.SpeechInstance.removeAllListeners();
}
render() {
let obj_this = this;
return (
<View style={{padding:10}}>
<Text>unique_key: {this.SpeechInstance.unique_key}</Text>
<View style={{padding: 5}}>
<Button onPress={()=>{ obj_this._startRecognizing()}} title='Start Listening' />
</View>
<View style={{padding: 5}}>
<Button onPress={()=>{ obj_this._stopRecognizing()}} title='Stop Listening' />
</View>
</View>
);
}
}
用法我使用上面的组件非常简单
import React from 'react';
import {View} from 'react-native';
import SpeechComponent from '../voice/SpeechComponent';
export default class VoiceTestScreen extends React.Component {
render(){
return(
<View>
<SpeechComponent unique_key='1'/>
<SpeechComponent unique_key='2'/>
</View>
);
}
}
经过非常仔细的封装以将 SpeechInstance 隐藏在组件实例中,以便它无法在全球共享,我仍然总是结果=>控制台
On speech results Key=2
天气我开始识别(从按钮单击开始)组件的第一个实例或第二个
这个解释需要改进: 我的问题不正确,@begi在评论中进行了修正,并且在阅读了他指出的Api文档之后,我发现这是API特定的问题,因为单个麦克风无法被多个实例监听分别。
所以我尝试了其他方法并得到了解决方案。
import React from 'react';
import {View} from 'react-native';
import SpeechComponent from '../voice/SpeechComponent';
export default class TestMultiVoice extends React.Component {
render(){
return(
<View>
<SpeechComponent unique_key='1'/>
<SpeechComponent unique_key='2'/>
</View>
);
}
}
我欺骗的是在 Voice.start 之前克隆单个静态 API 实例
Voice
,然后在 onError 和 onResult 上完全销毁它。
import React, { Component } from 'react';
import { Text, View, Button} from 'react-native';
import Voice from '@react-native-voice/voice';
export default class SpeechComponent extends Component {
constructor(props) {
super(props);
this.state = {
obtainedText: 'Recognized text will be displayed here'
}
}
_startRecognizing = async () => {
let obj_this = this;
this.SpeechInstance = Object.assign(Object.create(Object.getPrototypeOf(Voice)), Voice);
this.SpeechInstance.onSpeechError = (e) => obj_this.onSpeechError(e);
this.SpeechInstance.onSpeechResults = (e) => this.onSpeechResults(e);
await this.SpeechInstance.start();
};
_stopRecognizing = async () => {
await Voice.stop();
};
onSpeechError(e) {
// whenever error
console.log('On speech error Key=' + Voice.unique_key);
this.onSpeechComplete();
this.setState({obtainedText: e.error.message});
// always shows 2
};
onSpeechResults(e){
// whenever speech recognized
console.log('On speech results Key=' + Voice.unique_key, e.value);
this.onSpeechComplete();
this.setState({obtainedText: e.value[0]})
//always shows 2
};
onSpeechComplete(){
this.SpeechInstance.destroy().then(this.SpeechInstance.removeAllListeners);
}
render() {
let obj_this = this;
return (
<View style={{padding:10}}>
<Text>unique_key: {Voice.unique_key}</Text>
<View style={{padding: 5}}>
<Button onPress={()=>{ obj_this._startRecognizing()}} title='Start Listening' />
</View>
<View style={{padding: 5}}>
<Button onPress={()=>{ obj_this._stopRecognizing()}} title='Stop Listening' />
</View>
<View>
<Text>Obtained Tex: {this.state.obtainedText}</Text>
</View>
</View>
);
}
}