반응형
TTS (Text To Speach)
- 한국어로는 음성합성'이라고 칭한다.
- 컴퓨터의 프로그램을 통해 사람의 목소리를 구현해 내는 것을 말한다.
- 말 그대로 컴퓨터가 특정 글자들을 읽어주는 것을 말한다.
포스팅에서 설명하는 프로젝트는 아래의 링크에서 다운받을 수 있습니다.
TTS Package Setting (설치 및 설정)
TTS 패키지 설치
텍스트를 읽어주기 위해서는 우선 필요한 패키지를 설치를 해야한다.
flutter pub add flutter_tts
안드로이드 설정
- android - app - build.gradle
- 해당 경로의 파일을 열어 defaultConfig의 minSdkVersion을 21로 변경한다.
minSdkVersion 21
- android - app - src - main - AndroidManifest.xml
- 해당 경로의 파일을 열어 <manifest> 하위 트리에 아래와 같이 내용 추가한다.
<queries>
<intent>
<action android:name="android.intent.action.TTS_SERVICE" />
</intent>
</queries>
iOS 설정
- 초기 설정은 따로 존재 하지 않는다.
- 단, iOS 전용 코드 설정이 존재하므로 필요에 따라 설정해주자.
- 공유 오디오 인스턴스 설정
- 백그라운드 음악과 앱 내 오디오 세션 동시 사용 설정
// tts 인스턴스 생성
FlutterTts flutterTts = FlutterTts();
// iOS 전용 옵션 : 공유 오디오 인스턴스 설정
await flutterTts.setSharedInstance(true);
// 배경 음악와 인앱 오디오 세션을 동시에 사용
await flutterTts.setIosAudioCategory(
IosTextToSpeechAudioCategory.ambient,
[
IosTextToSpeechAudioCategoryOptions.allowBluetooth,
IosTextToSpeechAudioCategoryOptions.allowBluetoothA2DP,
IosTextToSpeechAudioCategoryOptions.mixWithOthers
],
IosTextToSpeechAudioMode.voicePrompt);
TTS 초기 설정
tts 인스턴스 생성 (FlutterTts)
- tts 인스턴스 객체 생성하는 코드이다.
FlutterTts flutterTts = FlutterTts();
언어 설정 (setLanguage)
- 설정한 언어로 tts가 글자를 읽어준다.
- 지원되는 언어는 getLanguage를 통해서 확인 가능하다.
/* 언어 설정
한국어 = "ko-KR"
일본어 = "ja-JP"
영어 = "en-US"
중국어 = "zh-CN"
프랑스어 = "fr-FR"
*/
flutterTts.setLanguage("ko-KR");
지원되는 언어 확인하기 (getLanguages)
- 지원되는 언어를 확인할 수 있다.
- ISO3166-1 alpah-2의 코드를 확인하면 어떤 국가인지 쉽게 식별 가능하다.
flutterTts.getLanguages;
/* print */
// [ko-KR, mr-IN, ru-RU, zh-TW, hu-HU, th-TH, ur-PK,
// nb-NO, da-DK, tr-TR, et-EE, bs, sw, pt-PT, vi-VN,
// en-US,sv-SE, ar, su-ID, bn-BD, gu-IN, kn-IN, el-GR,
// hi-IN, fi-FI, km-KH, bn-IN, fr-FR, uk-UA, pa-IN, en-AU,
// lv-LV, nl-NL, fr-CA, sr, pt-BR, ml-IN, si-LK, de-DE, ku,
// cs-CZ, pl-PL, sk-SK, fil-PH, it-IT, ne-NP, ms-MY, hr,
// en-NG, nl-BE, zh-CN, es-ES, cy, ta-IN, ja-JP, bg-BG,
// sq, yue-HK, en-IN, es-US, jv-ID, la, id-ID, te-IN,
// ro-RO, ca, en-GB]
음성 선택하기 (setVoice)
- tts가 읽어주는 음성을 선택할 수 있다.
- 남성과 여성의 목소리로 각 나라별 음성을 설정할 수 있다.
- 관련된 정보를 찾다가 도저히 못 찾겠어서 타 사이트의 제공된 문서를 통해 확인하였다.
- crosstables.com에서 제공된 RTVoice 문서에서 자세히 확인 할 수 있다. (40쪽부터 ~)
- RT-Voice Pro Documentation 보러 가기
/* 음성 설정
영어 여성 {"name": "en-us-x-tpf-local", "locale": "en-US"}
일본어 여성 {"name": "ja-JP-language", "locale": "ja-JP"}
중국어 여성 {"name": "cmn-cn-x-ccc-local", "locale": "zh-CN"}
중국어 남성 {"name": "cmn-cn-x-ccd-local", "locale": "zh-CN"}
*/
// 한국어 여성 음성으로 설정
flutterTts.setVoice({"name": "ko-kr-x-ism-local", "locale": "ko-KR"});
지원되는 음성 확인하기 (getVoice)
'name'과 'locale'로 구성된 지원되는 음성 값을 확인할 수 있다.
음성이 너무 많아 확인이 어려울 경우, 문자열이 포함되어 있는지 확인하는 contains 메서드를 활용하여 찾아보자.
flutterTts.getVoices;
/* 한국어 음성 찾기
List<Object?> objVoices = await flutterTts.getVoices;
List<String> ttsVoices = [];
for (var item in objVoices) {
if (item.toString().contains('ko-KR')) {
ttsVoices.add(item.toString());
}
}
*/
음성의 음높이 설정 (setPitch)
- tts가 읽어주는 음성의 음높이를 의미한다.
- 기본값은 1.0이며, 0.5와 2.0 사이의 값으로 조절한다.
flutterTts.setPitch(1.0);
음성의 속도 설정 (setSpeechRate)
- tts가 글자를 읽어주는 속도를 의미한다.
- 값은 0.0에 가까울수록 느려지며, 1.0에 가까울수록 빠르게 말한다.
flutterTts.setSpeechRate(0.5);
음성 볼륨 설정 (setVolume)
- tts가 읽어주는 볼륨을 설정한다.
- 값은 0.0에 가까울수록 조용하며, 1.0에 가까울수록 소리가 커진다.
flutterTts.setVolume(0.8);
TTS로 읽어주기 (speak)
TTS를 통해 해당 문자열을 읽어주는 것은 생각보다 간단하다.
.speak의 메서드에 읽을 문자열을 넣어주면 된다.
flutterTts.speak(text);
구현
텍스트필드에 내용을 입력하고 버튼을 누르면,
입력한 내용을 TTS로 읽어주는 간단한 기능을 구현해보자.
초기 변수 설정
FlutterTts flutterTts = FlutterTts();
/* 언어 설정
한국어 = "ko-KR"
일본어 = "ja-JP"
영어 = "en-US"
중국어 = "zh-CN"
프랑스어 = "fr-FR"
*/
String language = "ko-KR";
/* 음성 설정
한국어 여성 {"name": "ko-kr-x-ism-local", "locale": "ko-KR"}
영어 여성 {"name": "en-us-x-tpf-local", "locale": "en-US"}
일본어 여성 {"name": "ja-JP-language", "locale": "ja-JP"}
중국어 여성 {"name": "cmn-cn-x-ccc-local", "locale": "zh-CN"}
중국어 남성 {"name": "cmn-cn-x-ccd-local", "locale": "zh-CN"}
*/
Map<String, String> voice = {"name": "ko-kr-x-ism-local", "locale": "ko-KR"};
String engine = "com.google.android.tts";
double volume = 0.8;
double pitch = 1.0;
double rate = 0.5;
// 사용자의 입력 값을 받을 컨트롤러
final TextEditingController textEditingController = TextEditingController();
초기화
@override
void initState() {
super.initState();
// TTS 초기 설정
initTts();
}
// TTS 초기 설정
initTts() async {
await initTtsIosOnly(); // iOS 설정
flutterTts.setLanguage(language);
flutterTts.setVoice(voice);
flutterTts.setEngine(engine);
flutterTts.setVolume(volume);
flutterTts.setPitch(pitch);
flutterTts.setSpeechRate(rate);
}
// TTS iOS 옵션
Future<void> initTtsIosOnly() async {
// iOS 전용 옵션 : 공유 오디오 인스턴스 설정
await flutterTts.setSharedInstance(true);
// 배경 음악와 인앱 오디오 세션을 동시에 사용
await flutterTts.setIosAudioCategory(
IosTextToSpeechAudioCategory.ambient,
[
IosTextToSpeechAudioCategoryOptions.allowBluetooth,
IosTextToSpeechAudioCategoryOptions.allowBluetoothA2DP,
IosTextToSpeechAudioCategoryOptions.mixWithOthers
],
IosTextToSpeechAudioMode.voicePrompt);
}
TTS로 읽기
// TTS로 읽어주기
Future _speak(voiceText) async {
flutterTts.speak(voiceText);
}
UI 디자인 및 버튼 클릭 이벤트 기능 구현
- 버튼을 누를 경우, TTS로 읽어주는 함수를 호출하여 입력한 내용을 TTS가 읽어주기
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
controller: textEditingController,
),
ElevatedButton(
onPressed: () {
_speak(textEditingController.text);
},
child: const Text('내용 읽기')),
],
),
);
}
전체 소스 코드
import 'package:flutter/material.dart';
import 'package:flutter_tts/flutter_tts.dart';
void main() {
runApp(const MaterialApp(
home: Scaffold(
body: SafeArea(child: MyTts()),
),
));
}
class MyTts extends StatefulWidget {
const MyTts({super.key});
@override
State<MyTts> createState() => _MyTtsState();
}
class _MyTtsState extends State<MyTts> {
FlutterTts flutterTts = FlutterTts();
/* 언어 설정
한국어 = "ko-KR"
일본어 = "ja-JP"
영어 = "en-US"
중국어 = "zh-CN"
프랑스어 = "fr-FR"
*/
String language = "ko-KR";
/* 음성 설정
한국어 여성 {"name": "ko-kr-x-ism-local", "locale": "ko-KR"}
영어 여성 {"name": "en-us-x-tpf-local", "locale": "en-US"}
일본어 여성 {"name": "ja-JP-language", "locale": "ja-JP"}
중국어 여성 {"name": "cmn-cn-x-ccc-local", "locale": "zh-CN"}
중국어 남성 {"name": "cmn-cn-x-ccd-local", "locale": "zh-CN"}
*/
Map<String, String> voice = {"name": "ko-kr-x-ism-local", "locale": "ko-KR"};
String engine = "com.google.android.tts";
double volume = 0.8;
double pitch = 1.0;
double rate = 0.5;
// 사용자의 입력 값을 받을 컨트롤러
final TextEditingController textEditingController = TextEditingController();
@override
void initState() {
super.initState();
// TTS 초기 설정
initTts();
}
// TTS 초기 설정
initTts() async {
await initTtsIosOnly(); // iOS 설정
flutterTts.setLanguage(language);
flutterTts.setVoice(voice);
flutterTts.setEngine(engine);
flutterTts.setVolume(volume);
flutterTts.setPitch(pitch);
flutterTts.setSpeechRate(rate);
}
// TTS iOS 옵션
Future<void> initTtsIosOnly() async {
// iOS 전용 옵션 : 공유 오디오 인스턴스 설정
await flutterTts.setSharedInstance(true);
// 배경 음악와 인앱 오디오 세션을 동시에 사용
await flutterTts.setIosAudioCategory(
IosTextToSpeechAudioCategory.ambient,
[
IosTextToSpeechAudioCategoryOptions.allowBluetooth,
IosTextToSpeechAudioCategoryOptions.allowBluetoothA2DP,
IosTextToSpeechAudioCategoryOptions.mixWithOthers
],
IosTextToSpeechAudioMode.voicePrompt);
}
// TTS로 읽어주기
Future _speak(voiceText) async {
flutterTts.speak(voiceText);
}
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TextField(
controller: textEditingController,
),
ElevatedButton(
onPressed: () {
_speak(textEditingController.text);
},
child: const Text('내용 읽기')),
],
),
);
}
}
참고
반응형