flutterにもiOSのAVSpeechSynthesizerのような音声読み上げをしてくれるライブラリ、
flutter_ttsがあります。
基本的には、AVSpeechSynthesizerと同じで
・音声言語
・再生速度
・音声のピッチ
が選択できます。
※対応SDKが21以上なので、自身で設定しているminSdkが満たしているか留意する必要があります。
##使用可能言語
【言語コード - 国名コード】で指定します。
言語指定で使う表記 | 説明 |
---|---|
nl-BE | オランダ語、ベルギー |
hu-HU | ハンガリー語 |
he-IL | ヘブライ語 |
fi-FI | フィンランド語 |
it-IT | イタリア語 |
pt-BR | ブラジルポルトガル語(ブラジル語) |
en-US | 英語 |
ro-RO | ルーマニア語 |
el-GR | ギリシャ語 |
sk-SK | スロバキア語 |
sv-SE | スウェーデン語 |
th-TH | タイ語 |
no-NO | ノルウェー語 |
zh-CN | 中国語 |
pl-PL | ポーランド語 |
ru-RU | ロシア語 |
tr-TR | トルコ語 |
zh-TW | 中国語、台湾 |
en-GB | 英語 |
en-IN | 英語、イングランド |
cs-CZ | チェコ語 |
es-ES | スペイン語 |
en-AU | 英語、オーストラリア |
pt-PT | ポルトガル語 |
zh-HK | 中国語、香港 |
id-ID | インドネシア語 |
ko-KR | 韓国語 |
en-IE | 英語、アイルランド |
nl-NL | オランダ語 |
hi-IN | ヒンディー語 |
fr-FR | フランス語 |
en-ZA | 英語、南アフリカ |
ja-JP | 日本語 |
es-MX | スペイン語、メキシコ |
da-DK | デンマーク語 |
de-DE | ドイツ語 |
ar-SA | アラビア語 |
fr-CA | フランス語、カナダ |
##簡単な実装
今回こちらを使って、英単語の音声読み上げを行ってみました。
単語帳アプリなどで応用できそうですね。
以下はProvider: StateNotifierで作製したcontrollerクラスの中身です。
final FlutterTts flutterTts = FlutterTts();
void speak() {
await flutterTts.setLangauge("en-US");
await flutterTts.setSpeechRate(0.4); //1.0にするとめちゃくちゃはやかった
await flutterTts.setPich(1.0);
await flutterTts.speak("Autumn");
}
####再生中にボタンアイコンなどを変化させたいとき
UIを少し面白くするために、音声読み上げ中は異なるアイコンを表示させようとしました。
isSpeaking
というbool値を用いて、trueの時は読み上げ中用のアイコンを、falseの時は音声読み上げボタンを表示しています。
final FlutterTts flutterTts = FlutterTts();
void speak() {
state = state.copyWith(isSpeaking: true);
await flutterTts.setLangauge("en-US");
await flutterTts.setSpeechRate(0.4);
await flutterTts.setPich(1.0);
await flutterTts.speak("Autumn");
state = state.copyWith(isSpeaking: false);
}
#####注意
単語のような短いものを読み上げさせるとすぐに終わってしまうので、viewの再描画が追い付かず期待していた変化をさせることができませんでした。
解決法として、speak関数実行後に数ミリ秒Durationさせることで調整しました。
Consumer等で描画範囲を指定することでも解決できるかもしれません。
void speak() {
state = state.copyWith(isSpeaking: true);
await flutterTts.setLangauge("en-US");
await flutterTts.setSpeechRate(0.4);
await flutterTts.setPich(1.0);
await flutterTts.speak("Autumn");
await Future.delayed(Duration(miliseconds: 500));
state = state.copyWith(isSpeaking: false);
}
##参考にさせていただいた記事
https://qiita.com/kazutxt/items/e730e586061efc68b7bf