와챠의 우당탕탕 코딩 일기장
[Android/Kotlin]음성인식(STT:Speech-To-Text) 만들기 본문
반응형
오늘은 Android Studio로 음성인식 기능을 만들어 보려고 한다
왜냐
그냥 궁금함
만들어보니까 너무나 쉽고 간단...
결과 화면
1. Manifest에 권한 + intent 추가
<!--인터넷 권한-->
<uses-permission android:name="android.permission.INTERNET" />
<!--오디오 사용 권한-->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<queries>
<intent>
<action android:name="android.speech.RecognitionService" />
</intent>
</queries>
2. xml 코드짜기
대충 아래 꺼만 만듦
- 말하기 버튼
- 말한 내용을 보여줄 TextView
- 음성인식 상태 TextView
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="아래 버튼을 눌러 음성인식 시작"
android:textSize="24sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btnSpeech"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="말하기"
android:textSize="18sp"
android:backgroundTint="@color/purple_200"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
<TextView
android:id="@+id/tvState"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="상태 체크"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btnSpeech" />
</androidx.constraintlayout.widget.ConstraintLayout>
3. kt 코드 짜기
설명은 주석에!~
package com.example.mystt
import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.speech.RecognitionListener
import android.speech.RecognizerIntent
import android.speech.SpeechRecognizer
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.example.mystt.databinding.ActivityMainBinding
private lateinit var binding: ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var speechRecognizer: SpeechRecognizer
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
// 권한 설정
requestPermission()
// RecognizerIntent 생성
val intent = Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
intent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, packageName) // 여분의 키
intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, "ko-KR") // 언어 설정
// <말하기> 버튼 눌러서 음성인식 시작
binding.btnSpeech.setOnClickListener {
// 새 SpeechRecognizer 를 만드는 팩토리 메서드
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this@MainActivity)
speechRecognizer.setRecognitionListener(recognitionListener) // 리스너 설정
speechRecognizer.startListening(intent) // 듣기 시작
}
}
// 권한 설정 메소드
private fun requestPermission() {
// 버전 체크, 권한 허용했는지 체크
if (Build.VERSION.SDK_INT >= 23 &&
ContextCompat.checkSelfPermission(this@MainActivity, Manifest.permission.RECORD_AUDIO)
!= PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(this@MainActivity,
arrayOf(Manifest.permission.RECORD_AUDIO), 0)
}
}
// 리스너 설정
private val recognitionListener: RecognitionListener = object : RecognitionListener {
// 말하기 시작할 준비가되면 호출
override fun onReadyForSpeech(params: Bundle) {
Toast.makeText(applicationContext, "음성인식 시작", Toast.LENGTH_SHORT).show()
binding.tvState.text = "이제 말씀하세요!"
}
// 말하기 시작했을 때 호출
override fun onBeginningOfSpeech() {
binding.tvState.text = "잘 듣고 있어요."
}
// 입력받는 소리의 크기를 알려줌
override fun onRmsChanged(rmsdB: Float) {}
// 말을 시작하고 인식이 된 단어를 buffer에 담음
override fun onBufferReceived(buffer: ByteArray) {}
// 말하기를 중지하면 호출
override fun onEndOfSpeech() {
binding.tvState.text = "끝!"
}
// 오류 발생했을 때 호출
override fun onError(error: Int) {
val message = when (error) {
SpeechRecognizer.ERROR_AUDIO -> "오디오 에러"
SpeechRecognizer.ERROR_CLIENT -> "클라이언트 에러"
SpeechRecognizer.ERROR_INSUFFICIENT_PERMISSIONS -> "퍼미션 없음"
SpeechRecognizer.ERROR_NETWORK -> "네트워크 에러"
SpeechRecognizer.ERROR_NETWORK_TIMEOUT -> "네트웍 타임아웃"
SpeechRecognizer.ERROR_NO_MATCH -> "찾을 수 없음"
SpeechRecognizer.ERROR_RECOGNIZER_BUSY -> "RECOGNIZER 가 바쁨"
SpeechRecognizer.ERROR_SERVER -> "서버가 이상함"
SpeechRecognizer.ERROR_SPEECH_TIMEOUT -> "말하는 시간초과"
else -> "알 수 없는 오류임"
}
binding.tvState.text = "에러 발생: $message"
}
// 인식 결과가 준비되면 호출
override fun onResults(results: Bundle) {
// 말을 하면 ArrayList에 단어를 넣고 textView에 단어를 이어줌
val matches = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
for (i in matches!!.indices) binding.textView.text = matches[i]
}
// 부분 인식 결과를 사용할 수 있을 때 호출
override fun onPartialResults(partialResults: Bundle) {}
// 향후 이벤트를 추가하기 위해 예약
override fun onEvent(eventType: Int, params: Bundle) {}
}
}
전체 코드(위에가 전부이긴 함)
https://github.com/minWachya/MySTT
성능
성능은 그닥 좋지 않다고는 하지만... 응?? 잘 모르겠음 기본적인 건 잘 알아 들음
음성인식은 '훠궈'를 인식 못 한다고 해서ㅋㅋ 해봤는데
진짜 못함
음성 인식은 더 발전해야 하는듯
상세 결과 화면
참고
https://hanyeop.tistory.com/128
https://jwsoft91.tistory.com/160
반응형
'코딩 일기장 > Android(Kotlin)' 카테고리의 다른 글
[Android/Kotlin] Lottie Animation/애니메이션 추가하기 (0) | 2022.05.04 |
---|---|
[Android/Kotlin]CustomView: color 속성 추가하기 (0) | 2022.04.26 |
[Android/Kotlin] 지문인식 만들기 (0) | 2022.04.08 |
[Android/Kotlin]Custom View 만들기/Spinner처럼 생긴 TextView 만들기/ClickListener 추가 (0) | 2022.03.20 |
[Android/Kotlin]EditText scollbar custom/cursor color (0) | 2022.03.19 |
Comments