Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[flutter_tts] Update flutter_tts to 4.2.0 #775

Merged
merged 4 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/flutter_tts/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
## NEXT
## 1.5.0

* Update minimum Flutter and Dart version to 3.13 and 3.1.
* Update flutter_tts 3.6.3 to 4.2.0.
* Update the example app.
* Add isLanguageAvailable, getVoices and setVoice APIs which were not implemented.


## 1.4.0

Expand Down
7 changes: 5 additions & 2 deletions packages/flutter_tts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ This package is not an _endorsed_ implementation of `flutter_tts`. Therefore, yo

```yaml
dependencies:
flutter_tts: ^3.6.3
flutter_tts_tizen: ^1.4.0
flutter_tts: ^4.2.0
flutter_tts_tizen: ^1.5.0
```

Then you can import `flutter_tts` in your Dart code:
Expand All @@ -31,6 +31,9 @@ The features supported by Tizen are as follows. Other features are not supported
- [x] pause
- [x] get languages
- [x] set language
- [x] is language available
- [x] get voices
- [x] set voice
- [x] set speech rate
- [x] set speech volume (requires privilege `http://tizen.org/privilege/volume.set` in `tizen_manifest.xml`)
- [x] get default voice
Expand Down
51 changes: 32 additions & 19 deletions packages/flutter_tts/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,26 @@ class _MyAppState extends State<MyApp> {

TtsState ttsState = TtsState.stopped;

get isPlaying => ttsState == TtsState.playing;
get isStopped => ttsState == TtsState.stopped;
get isPaused => ttsState == TtsState.paused;
get isContinued => ttsState == TtsState.continued;
bool get isPlaying => ttsState == TtsState.playing;
bool get isStopped => ttsState == TtsState.stopped;
bool get isPaused => ttsState == TtsState.paused;
bool get isContinued => ttsState == TtsState.continued;

@override
initState() {
super.initState();
initTts();
}

initTts() {
dynamic initTts() {
flutterTts = FlutterTts();

_setAwaitOptions();

_getDefaultVoice();

_getSupportedVoices();

flutterTts.setStartHandler(() {
setState(() {
print("Playing");
Expand Down Expand Up @@ -85,16 +87,23 @@ class _MyAppState extends State<MyApp> {
});
}

Future<dynamic> _getLanguages() => flutterTts.getLanguages;
Future<dynamic> _getLanguages() async => await flutterTts.getLanguages;

Future _getDefaultVoice() async {
Future<void> _getDefaultVoice() async {
var voice = await flutterTts.getDefaultVoice;
if (voice != null) {
print(voice);
print('_getDefaultVoice(): $voice');
}
}

Future _speak() async {
Future<void> _getSupportedVoices() async {
var voices = await flutterTts.getVoices;
if (voices != null) {
print('_getSupportedVoices(): $voices');
}
}

Future<void> _speak() async {
await flutterTts.setVolume(volume);
await flutterTts.setSpeechRate(rate);

Expand All @@ -105,16 +114,16 @@ class _MyAppState extends State<MyApp> {
}
}

Future _setAwaitOptions() async {
Future<void> _setAwaitOptions() async {
await flutterTts.awaitSpeakCompletion(true);
}

Future _stop() async {
Future<void> _stop() async {
var result = await flutterTts.stop();
if (result == 1) setState(() => ttsState = TtsState.stopped);
}

Future _pause() async {
Future<void> _pause() async {
var result = await flutterTts.pause();
if (result == 1) setState(() => ttsState = TtsState.paused);
}
Expand All @@ -126,16 +135,19 @@ class _MyAppState extends State<MyApp> {
}

List<DropdownMenuItem<String>> getLanguageDropDownMenuItems(
dynamic languages) {
List<dynamic> languages) {
var items = <DropdownMenuItem<String>>[];
for (dynamic type in languages) {
items.add(DropdownMenuItem(
value: type as String?, child: Text(type as String)));
value: type as String?, child: Text((type as String))));
}
return items;
}

void changedLanguageDropDownItem(String? selectedType) {
void changedLanguageDropDownItem(String? selectedType) async {
var result = await flutterTts.isLanguageAvailable(selectedType!);
if (result == 0) return;

setState(() {
language = selectedType;
flutterTts.setLanguage(language!);
Expand Down Expand Up @@ -175,7 +187,7 @@ class _MyAppState extends State<MyApp> {
future: _getLanguages(),
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.hasData) {
return _languageDropDownSection(snapshot.data);
return _languageDropDownSection(snapshot.data as List<dynamic>);
} else if (snapshot.hasError) {
return Text('Error loading languages...');
} else
Expand All @@ -191,6 +203,7 @@ class _MyAppState extends State<MyApp> {
onChanged: (String value) {
_onChange(value);
},
controller: TextEditingController(text: _newVoiceText),
));

Widget _btnSection() {
Expand All @@ -210,7 +223,7 @@ class _MyAppState extends State<MyApp> {
);
}

Widget _languageDropDownSection(dynamic languages) => Container(
Widget _languageDropDownSection(List<dynamic> languages) => Container(
padding: EdgeInsets.only(top: 10.0),
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [
DropdownButton(
Expand Down Expand Up @@ -272,7 +285,7 @@ class _MyAppState extends State<MyApp> {
min: 0.0,
max: 1.0,
divisions: 10,
label: "Volume: $volume");
label: "Volume: ${volume.toStringAsFixed(1)}");
}

Widget _rate() {
Expand All @@ -284,7 +297,7 @@ class _MyAppState extends State<MyApp> {
min: 0.0,
max: 1.0,
divisions: 10,
label: "Rate: $rate",
label: "Rate: ${rate.toStringAsFixed(1)}",
activeColor: Colors.green,
);
}
Expand Down
2 changes: 1 addition & 1 deletion packages/flutter_tts/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ environment:
dependencies:
flutter:
sdk: flutter
flutter_tts: ^3.6.3
flutter_tts: ^4.2.0
flutter_tts_tizen:
path: ../

Expand Down
2 changes: 1 addition & 1 deletion packages/flutter_tts/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: flutter_tts_tizen
description: The Tizen implementation of flutter_tts plugin.
homepage: https://github.com/flutter-tizen/plugins
repository: https://github.com/flutter-tizen/plugins/tree/master/packages/flutter_tts
version: 1.4.0
version: 1.5.0

environment:
sdk: ">=3.1.0 <4.0.0"
Expand Down
64 changes: 62 additions & 2 deletions packages/flutter_tts/tizen/src/flutter_tts_tizen_plugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <flutter/standard_method_codec.h>

#include <algorithm>
#include <map>
#include <memory>
#include <optional>
#include <string>
Expand All @@ -22,6 +23,19 @@ namespace {
typedef flutter::MethodChannel<flutter::EncodableValue> FlMethodChannel;
typedef flutter::MethodResult<flutter::EncodableValue> FlMethodResult;

template <typename T>
bool GetValueFromEncodableMap(flutter::EncodableMap &map, std::string key,
T &out) {
auto iter = map.find(flutter::EncodableValue(key));
if (iter != map.end() && !iter->second.IsNull()) {
if (auto pval = std::get_if<T>(&iter->second)) {
out = *pval;
return true;
}
}
return false;
}

class FlutterTtsTizenPlugin : public flutter::Plugin {
public:
static void RegisterWithRegistrar(flutter::PluginRegistrar *registrar) {
Expand Down Expand Up @@ -103,13 +117,19 @@ class FlutterTtsTizenPlugin : public flutter::Plugin {
} else if (method_name == "setLanguage") {
OnSetLanguage(arguments);
} else if (method_name == "getLanguages") {
OnGetLanguage();
OnGetLanguages();
} else if (method_name == "getDefaultVoice") {
OnGetDefaultVoice();
} else if (method_name == "setVoice") {
OnSetVoice(arguments);
} else if (method_name == "getVoices") {
OnGetVoices();
} else if (method_name == "getMaxSpeechInputLength") {
OnGetMaxSpeechInputLength();
} else if (method_name == "setVolume") {
OnSetVolume(arguments);
} else if (method_name == "isLanguageAvailable") {
OnIsLanguageAvailable(arguments);
} else {
result_->NotImplemented();
}
Expand Down Expand Up @@ -195,7 +215,7 @@ class FlutterTtsTizenPlugin : public flutter::Plugin {
SendResult(flutter::EncodableValue(0));
}

void OnGetLanguage() {
void OnGetLanguages() {
flutter::EncodableList list;
for (auto language : tts_->GetSupportedLanaguages()) {
list.push_back(flutter::EncodableValue(language));
Expand All @@ -219,6 +239,35 @@ class FlutterTtsTizenPlugin : public flutter::Plugin {
SendResult(flutter::EncodableValue(default_voice_map));
}

void OnSetVoice(const flutter::EncodableValue &arguments) {
if (std::holds_alternative<flutter::EncodableMap>(arguments)) {
auto voice = std::get<flutter::EncodableMap>(arguments);

std::string voice_name;
if (GetValueFromEncodableMap(voice, "name", voice_name)) {
tts_->SetDefaultVoiceType(voice_name);
SendResult(flutter::EncodableValue(1));
return;
}
}
SendResult(flutter::EncodableValue(0));
}

void OnGetVoices() {
flutter::EncodableList list;
for (auto voice : tts_->GetSupportedVoiceTypes()) {
flutter::EncodableMap map;
map.insert(std::pair<flutter::EncodableValue, flutter::EncodableValue>(
flutter::EncodableValue("name"),
flutter::EncodableValue(voice["name"])));
map.insert(std::pair<flutter::EncodableValue, flutter::EncodableValue>(
flutter::EncodableValue("locale"),
flutter::EncodableValue(voice["locale"])));
list.push_back(flutter::EncodableValue(map));
}
SendResult(flutter::EncodableValue(list));
}

void OnGetMaxSpeechInputLength() {
std::optional<int32_t> length = tts_->GetMaxSpeechInputLength();
SendResult(length.has_value() ? flutter::EncodableValue(*length)
Expand All @@ -236,6 +285,17 @@ class FlutterTtsTizenPlugin : public flutter::Plugin {
SendResult(flutter::EncodableValue(0));
}

void OnIsLanguageAvailable(const flutter::EncodableValue &arguments) {
if (std::holds_alternative<std::string>(arguments)) {
std::string language = std::move(std::get<std::string>(arguments));
if (!language.empty() && tts_->IsLanguageAvailable(language)) {
SendResult(flutter::EncodableValue(1));
return;
}
}
SendResult(flutter::EncodableValue(0));
}

void SendResult(const flutter::EncodableValue &result) {
if (result_) {
result_->Success(result);
Expand Down
Loading
Loading