Android (안드로이드)

[Android] 앱에서 TTS 사용해보기

Oscar:) 2024. 12. 21. 12:00
728x90

 

 

 

TTS는 Text To Speech의 약자로, 직역하면 텍스트 음성 변환 또는 음성합성이다.

흔히 생각할 수 있는 글자를 음성으로 읽어주는 기능을 의미한다.

 

Android는 내장 클래스로서 TTS 기능을 제공한다.

(android.speech.tts.TextToSpeech)

 

 

이제 TTS 예제를 만들어 보자.

 

 

 


 

 

 

✅ TTS 초기화

class MainActivity: AppCompatActivity() {

  // TTS 객체 nullable 초기화
  private var tts: TextToSpeech? = null
  
  override fun onCreate() {
    ...
    initTTS()
  }
  
  private fun initTTS() {
    tts = TextToSpeech(Context) { // TTS 초기화 콜백 리스너
      if (it == TextToSpeech.SUCCESS) {
        setTTS() // TTS 세팅 함수 호출
      }
    }
  }

}

 

먼저 TTS 객체를 nullable 타입으로 초기화해준다.

TTS는 TextToSpeechService와 통신하며 기기에서 TTS 엔진을 가동시키 때문에,

nullable 타입으로 관리하며 초기화 & 메모리 해제를 확실하게 해줘야 한다.

 

TTS 객체의 생성자 파라미터에는 Context를 작성해주고,

OnInitListener 라는 콜백 리스너를 장착해야 사용할 수 있다.

초기화 성공 여부에 따라 SUCCESS or ERROR에 해당하는 Int 값을 반환한다.

 

 

 

TTS 초기화에 성공하면 TTS를 세팅하는 함수를 호출했다.

 

 

 

 

 

 

✅ TTS 세팅

private fun setTTS() {
  tts?.language = resources.configuration.locales[0] // 언어 세팅
  tts?.setPitch(0.5f) // 톤 세팅
  tts?.setSpeechRate(1.2f) // 속도 세팅
  
  playTTS()
}

 

위에 작성한 함수말고도 다양한 세팅 함수가 존재하지만, 대표적인 3가지만 사용했다.

 

 

- language

음성 출력할 언어의 지역을 세팅한다.

{Locale.KOREA} 처럼 특정 지역을 세팅해도 된다.

 

하지만 필자는 다국어를 지원하는 프로젝트를 진행중이라서

기기의 현재 설정된 언어로 출력되게끔 위와 같이 세팅해주었다.

 

기기 내 언어 설정에 세팅된 첫 번째 언어로 출력된다.

 

 

 

 

- setPitch(Float)

음성 피치를 설정하며 매개변수로는 Float 값을 받는다.

값은 0.0 ~ 1.0 까지 세팅할 수 있으며,

값이 낮을수록 음성의 톤이 낮아진다.

 

 

- setSpeechRate(Float)

음성 속도를 설정하며 마찬가지로 Float 값을 받는다.

값은 0.0 ~ 2.0 까지 세팅할 수 있으며 1.0 이 정상 속도다.

 

 

 

세팅이 모두 끝나고 TTS를 실행하는 함수를 호출했다.

 

 

 

 

 

 

✅ TTS 실행

private fun playTTS() {
  tts?.speak("테스트 입니다", TextToSpeech.QUEUE_FLUSH, null, "TTS") // 음성 출력
}

 

TTS.speak() 함수 한 줄로 TTS를 실행할 수 있다.

파라미터는 4개를 받는데, 간단한 설명은 다음과 같다.

 

- 실행할 문자열

음성 출력할 문자열을 작성해주면 된다.

 

- Queue Mode

음성 출력을 Queue 방식(대기열 형태)으로 관리하며, 어떻게 처리할 것인지 명시한다.

QUEUE_FLUSH는 현재 진행 중인 출력이나 대기열을 모두 비우고 새로운 TTS를 즉시 출력한다.

 

- Bundle

Bundle 타입으로 추가 옵션을 지정할 수 있다.

TTS 객체에서 호출할 수 있는 함수를 제외하고도 더욱 다양한 옵션을 지정해줄 수 있다.

 

- 식별자 문자열

TTS 객체에 대한 식별자 역할을 한다.

이를 통해 특정 TTS의 작업을 추적하는 등의 관리를 할 수 있다.

 

 

 

 

 

 

✅ TTS 종료

private fun finishTTS() {
  tts?.stop() // 정지
  tts?.shutdown() // 종료
  tts = null // 메모리 해제
}

 

TTS를 정지 · 종료해준 뒤, null 초기화를 진행하여 참조 해제해주면 GC가 수집한다.

TTS를 종료하는 위 함수는 각자 상황에 맞게 위치시켜주면 되겠다.

 

 

 

 

 

 

✅ 전체 코드

class MainActivity: AppCompatActivity() {

  private var tts: TextToSpeech? = null
  
  override fun onCreate() {
    ...
    button.setOnClickListener {
      playTTS()
    }
  }
  
  override fun onStop() {
    finishTTS()
  }
  
  private fun playTTS() {
    tts = TextToSpeech(this) {
      if (it == TextToSpeech.SUCCESS) {
        tts?.apply {
          language = resource.configuration.locales[0]
          setPitch(0.5f)
          setSpeechRate(1.2f)
          
          speak("테스트 입니다", TextToSpeech.QUEUE_FLUSH, null, "TTS")
        }
      }
    }
  }
  
  private fun finishTTS() {
    stop()
    shutdown()
    tts = null
  }
  
}

 

버튼을 누르면 TTS 초기화 · 세팅 · 실행까지 한번에 이루어지는 예제다.

그리고 위 예제에서는 Activity 생명주기가 onStop()일 때 TTS를 종료시켰다.

 

실제 프로젝트에서 사용할 때는 TTS 객체를 싱글톤 적용하여

초기화 · 세팅 / 실행 ·  종료를 구분지어 사용하기도 한다.

 

각자 상황에 맞게 적용하면 된다.

 

 

 

 

 

 

✅ 번외 - 언어팩 설치

 

타 국가의 언어를 세팅했을 때, 음성이 나오지 않는 현상이 발생할 수 있다.

실행한 기기에 해당 언어의 언어팩이 설치되어 있지 않아서 그렇다.

 

당황하지 말고 설정 앱에서 언어팩을 설치해주자.

 

 

당연히 해당 언어를 사용하는 국가에서는 해당 언어팩이 설치되어 있을 것이다.

 

 

 

 

 

 

✅ 번외 - 설정된 언어와 다른 언어 출력 시

 

문득 Locale 세팅 값문자열이 다른 언어일 때는 어떤 음성이 출력될 지 궁금해졌다.

재미있게도, 번역은 해주지 않지만 발음만 세팅한 Locale로 출력된다.

 

● Ex 1

"Banana" + 한국 Locale → 명확하게 '바나나' 출력 (영어권 Locale은 '버내너'에 가까운 발음)

 

● Ex 2

"테스트 입니다" + 일본 Locale → '테스뚜 이무니다' 출력

 

 

 

 

 


 

 

 

 

 

오늘은 안드로이드 앱에 TTS 기능을 적용하는 방법을 알아보았다.

여러모로 유용하게 사용할 수 있을 것 같다.

 



728x90