FlutterでTTSを利用してテキストを読み上げる方法
TTS(Text To Speexh)を利用してテキストから音声を再生する方法
TTSとは
「Text To Speech」の略です。
Flutterのパッケージです。プラグインとも呼ばれるようです。
このパッケージ機能は、テキストから音声を合成して発音します。
環境
flutter: 3.19.5
flutter_tts: 4.0.2
emulator: Pixel 7 API 30 “R” Android 11.0
emulator: Pixel 8 API 33 “Tiramisu” Android 13.0
実機: Pixel 6a API 34 “Upside Down Cake” Android 14
注意事項
わたくしはFlutterの一年生です。やってみたら上手くいったことを記述しています。なので、セオリーに反していることがあるかもしれません。
よろしくおねがいします。
TTS導入手順
Androidターゲットで説明しております。
TTSパッケージをインストールします
Flutterのパッケージは、pub.devより「flutter tts」で検索できます。
インストールの方法は、installing のタブで確認できまね。方法は2つありますね。どっちか好きな方法でインストールしましょう。
1.flutterコマンドを実行する方法
flutter pub add flutter_tts
最新のVersionがインストールされます。
インストール後は、pubspec.yamlファイルが自動で更新されています。
2.pubspec.yamlファイルを編集する方法
dependencies:
flutter_tts: ^4.0.2
pubspex.yamlを自分で編集します。
「dependencies:」のところに、「flutter_tts: ^4.0.2」を追記します。
この方法は、パッケージのVersion を指定できます。
編集後は、flutterコマンド「flutter pub get」を実行する必要があります。
flutter pub get
VSCodeを使用している場合は、ファイルを保存したときに自動で実行されます。
TTSパッケージ導入に伴う設定
さて、パッケージをインストールできました。
Androidターゲットであれば、ここでAppを実行するとエラーが発生するかもしれません。
落ち着いて、flutter_tts の Readme を確認してみましょう。
Androidでの注意事項が2つありますね。設定してみましょう。
設定1.minSdkVersionの値を21以上に設定する
場所:android/app/build.gradle
修正:minSdkVersion flutter.minSdkVersion ➡ minSdkVersion 21
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.tts10"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
// minSdkVersion flutter.minSdkVersion
minSdkVersion 21
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
build.gradleはandroid直下にもあるので間違わないことです。ただ中身が全然違うので気づくと思います。
設定2.AndroidManifest.xmlのqueriesに新しいintentを追加する
ターゲットのAndroidのversionが11の場合以下の設定も必要です。
場所:android/app/src/main/AndroidManifest.xml
修正:"<action android:name="android.intent.action.TTS_SERVICE" />"
を追加する。
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT" />
<data android:mimeType="text/plain" />
</intent>
<intent>
<action android:name="android.intent.action.TTS_SERVICE" />
</intent>
</queries>
flutterのversionによっては、元々intentがなかったりします。flutter version 3.19.5 では上記のようにすでにintentでactionが定義されていました。
intentにはactionは1つまでしか記述できないようです。
よって、すでにintentがある場合は、あたらしく、intentから記述します。
Kotlinのversion違いによるエラーの対応
それでもまだ、以下のようなエラーが発生するかもしれません。VSCodeの「デバッグコンソール」で確認してください。
“Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.9.0, expected version is 1.7.1.”
訳:モジュールは互換性の無いVersionでコンパイルされていますよ。バイナリは、1.9.0ですね。1.7.1が期待されていました。 ➡ TTSパッケージは1.9.0で、私の環境が1.7,1のようです。
~~
~~
Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.9.0, expected version is 1.7.1.
~~
~~
┌─ Flutter Fix ────────────────────────────────────────────────────────
│ [!] Your project requires a newer version of the Kotlin Gradle plugin.
│ Find the latest version on https://kotlinlang.org/docs/releases.html#release-details, then
│ update C:\htdocs\flutter\3_package\tts\tts10\android\build.gradle:
│ ext.kotlin_version = '<latest-version>'
└──────────────────────────────────────────────────────────────────────
Error: Gradle task assembleDebug failed with exit code 1
Webで調べても、Chat-GPTでも情報は取れませんでした。Kotlin開発の情報はあったような気はしますが。
がしかし、発見しました。方法は2つあります。
flutter_ttsのkotlinのversionは?
解決方法の前にTTSパッケージのChangeLogを確認してみましょう。
TTSのVersion4.0.0のときに、”Kotlin 1.9.10″ が使用されていることがわかりますね。
方法1.settings.gradleで、kotlinのversionを指定しましょう。
場所:android/settings.gradle
修正:id “org.jetbrains.kotlin.android” version “1.7.10” apply false ➡ id “org.jetbrains.kotlin.android” version “1.9.10” apply false
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.3.0" apply false
id "org.jetbrains.kotlin.android" version "1.9.10" apply false
}
方法2.flutter_ttsのversionをちょっと古いものを指定する
場所:pubspec.yaml
修正:flutter_tts: ^4.0.2 ➡ flutter_tts: ^3.8.5
3.8.5だとそのまま動作しました。
すきな方法で対応してくださいね。
プログラミング
さて、色々と大変でしたがコードを書いていきましょう。
import 'package:flutter/material.dart';
import 'package:flutter_tts/flutter_tts.dart'; // 1. パッケージをインポート。
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'TTS Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const Home(),
);
}
}
class Home extends StatefulWidget {
const Home({super.key});
@override
State<Home> createState() => _HomeState();
}
/// 初期化をinitState()で行う為に、Statefulを選択。
/// constructorの中で、非同期処理は呼ばないのセオリーのようだ。
class _HomeState extends State<Home> {
final FlutterTts tts = FlutterTts(); // 2. インスタンスを生成。
final String _text = 'おはよう。こんにちは。松田です。';
@override
void initState() {
super.initState();
initializeTts(); // 3.初期化処理
}
// 3.初期化処理
initializeTts() async {
await tts.setLanguage('ja-JA');
await tts.setSpeechRate(0.6);
await tts.setPitch(1.0);
await tts.awaitSpeakCompletion(false); // 発話の完了まで待機。
await tts.awaitSynthCompletion(true); // ファイルの合成まで待機。
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('TTS Demo'),
),
body: Center(
child: Column(
children: [
ElevatedButton(
onPressed: () async {
await tts.speak(_text); // 4. 発話を行う。
},
child: const Text('Play!')),
],
),
),
);
}
}
パッケージをimportして、インスタンスを生成して、初期設定をして、テキストを準備して、speak()メソッドを実行します。
emulatorですと雑音がはいりました。実機ですと綺麗な音声で再生されました。
言語コード
他の言語でも再生してみたいですよね。
言語コードをsetLanguageで設定すればいいですね。
言語コードは以下を参考にしました。
Flutterで音声読み上げライブラリ(flutter_tts)を使ってみる
どうやら、言語コードと国コードのセットようですね。
以上