React Native Voice(음성인식) 사용

I.목표

앱상에서 주소검색등의 화면에 음성인식 기능을 추가하여 편리성을 향상시키려고 한다.

 

II. 연구및 개발내용

1. 설치

npm i @react-native-voice/voice –save

2. 사용방법

 

import Voice from “@react-native-voice/voice”;

class AddrSearch extends PureComponent

{

constructor(props)

{

super(props);

 

this.state = {

title               : “”,

voiceStat           : “”

};

Voice.onSpeechStart         = this.onSpeechStart;

Voice.onSpeechEnd           = this.onSpeechEnd;

Voice.onSpeechError         = this.onSpeechError;

Voice.onSpeechRecognized    = this.onSpeechRecognized;

Voice.onSpeechResults       = this.onSpeechResults;

this.mClsVoiceTimer         = null;

}

/**

* componentDidMount 이벤트

*/

componentDidMount()

{

// 음석인식 종료 타이머

this.mClsVoiceTimer = new mosaic.timer.TimerMgr();

this.mClsVoiceTimer.setInterval(5000);  // 5초후에 음성인식 종료

this.mClsVoiceTimer.addTickHandler(()=> {

console.log(“타이머 루틴”);

this.doStopVoice();             // 음석인식 종료

this.doAddrSearch();            // 주소 검색

});

}

/**

* componentWillUnmount 이벤트

*/

componentWillUnmount()

{

Voice.destroy().then(Voice.removeAllListeners);

if(this.mClsVoiceTimer != null)

{

this.mClsVoiceTimer.stop();

this.mClsVoiceTimer = null;

}

}

doAddrSearch = () => {

 

}

doStartVoice = async() =>

{

this.setState({ voiceStat: “원하시는 주소를 말씀해주세요.” });

this.mClsVoiceTimer.stop(); // 타이머 종료

this.mClsVoiceTimer.start();

try { await Voice.start(“ko-KR”); } catch (e) { console.error(e); }

}

doStopVoice = async() =>

{

this.mClsVoiceTimer.stop(); // 타이머 종료

try { await Voice.stop(); } catch (e) { console.error(e); }

}

onSpeechStart = (e) => {

//console.log(“onSpeechStart: “, e);

this.setState({ voiceStat: “음성인식을 시작하였습니다.” });

};

 

onSpeechEnd = (e) => {

console.log(“onSpeechEnd: “, e);

this.setState({voiceStat : “” });

};

onSpeechError = (e) => {

console.log(“onSpeechError: “, e);

if(e.error.code != 5)

{

// {“error”: {“code”: “5”, “message”: “5/Client side error”}} 가 아닌 경우만 출력

this.setState({ voiceStat : “음성인식에 실패하였습니다. 다시 시도하여 주세요.”});

}

};

onSpeechRecognized = (e) => {

//console.log(“onSpeechRecognized: “, e);

this.setState({ voiceStat: “음성인식이 되었습니다.” });

};

onSpeechResults = async(e) => {

console.log(” 음성인식결과: “, e);

let arrData = e.value;

if(arrData.length > 0)

{

this.setState({voiceStat: “”, searchValue : arrData[0]}, ()=>{

this.doAddrSearch();

});

}

};

/**

* 화면 렌더

*/

render()

{

const {title, voiceStat} = this.state

return (

<BottomSheetView style={baseStyle.bottomSheetBox}>

<View style={baseStyle.bottomSheetBoxBody}>

<View style={baseStyle.bottomSheetBoxBodyTitH3}>

<Text style={baseStyle.bottomSheetTitH3}><Text style={baseStyle.bottomSheetTitBoldH3}>주소</Text>검색</Text>

</View>

<View style={{position:”relative”, width:”100%”, alignItems:”center”, paddingHorizontal:15, paddingTop:10, paddingBottom:5 }}>

<View style={{ width: “100%”, backgroundColor:”#f3f3f3″, borderRadius:10, justifyContent:”center”}}>

<TextInput

style={{paddingVertical:13, paddingHorizontal:15, fontSize:fonts.getFontSize(15, this.props.appData), fontWeight:”400″, color: colors.PLACEHOLDER, fontFamily:fonts.GMARKET_MEDIUM }}

numberOfLines={1}

autoCorrect={false}

underlineColorAndroid={“transparent”}

placeholder={“주소나 건물 이름을 입력하세요”}

placeholderTextColor={colors.PLACEHOLDER}

returnKeyType={“search”}

onChangeText={(strText) => this.setState({ searchValue: strText })}

value={this.state.searchValue}

onSubmitEditing={this.doAddrSearch}/>

<TouchableOpacity style={{position:”absolute”, right: 35, paddingVertical:10, paddingHorizontal:10 }} activeOpacity={0.6} onPress={this.doAddrSearch}>

<IconFa6 name=”magnifying-glass” solid style={{fontSize: fonts.getFontSize(22, this.props.appData), fontWeight:”700″, opacity:0.7, color: colors.PLACEHOLDER}} />

</TouchableOpacity>

<TouchableOpacity style={{position:”absolute”, right: 0, paddingVertical:10, paddingHorizontal:10 }} activeOpacity={0.6} onPress={this.doStartVoice}>

<IconFa6 name=”microphone” solid style={{fontSize: fonts.getFontSize(22, this.props.appData), fontWeight:”700″, opacity:0.7, color: colors.DARK}} />

</TouchableOpacity>

</View>

</View>

<View style={{position:”relative”, width:”100%”, alignItems:”center”, paddingHorizontal:10, paddingTop:5, paddingBottom:5, }}>

<Text style={{color: colors.PRIMARY, padding:0, fontSize: fonts.getFontSize(13, this.props.appData), fontWeight:”bold”, fontFamily: fonts.NANUNM_REGULAR}}>{voiceStat}</Text>

</View>

<View style={{width: (width – 40), flex:1 }}>

<FlatList

data={this.state.addrLocation}

keyExtractor={item => item.addrSeq.toString()}

renderItem={this.renderItem}

contentContainerStyle={{backgroundColor: colors.WHITE}}

ListEmptyComponent={this.renderNoDataItem}

/>

</View>

</View>

</BottomSheetView>

);

}

}

 

III. 결론

가끔씩  onSpeechError로 오류가 리턴되어, 아래와 같이 code가 5번인 경우는 제외하고 보여주도록 하였다.

{“error”: {“code”: “5”, “message”: “5/Client side error”}}

 

태그