Giter Club home page Giter Club logo

flutter_tts's Introduction

Text To Speech

pub package

A flutter text to speech plugin (Swift,Kotlin)

Features

  • Android, iOS, Web, Windows & macOS
    • speak
    • stop
    • get languages
    • set language
    • set speech rate
    • set speech volume
    • set speech pitch
  • Android, iOS, Web & macOS
    • is language available
  • Android, iOS, Web, & Windows
    • get voices
    • set voice
  • Android, iOS
    • speech marks (requires iOS 7+ and Android 26+)
    • synthesize to file (requires iOS 13+)
  • Android, iOS, Web, & Windows
    • pause
  • Android
    • set silence
    • is language installed
    • are languages installed
    • get engines
    • set engine
    • get default engine
    • get default voice
    • set queue mode
    • get max speech input length
  • iOS
    • set shared instance
    • set audio session category

Usage

macOS

OSX version: 10.15

Example App from the macOS_app branch

Web

Website from the example directory.

Android

Change the minimum Android sdk version to 21 (or higher) in your android/app/build.gradle file.

minSdkVersion 21

Apps targeting Android 11 that use text-to-speech should declare TextToSpeech.Engine.INTENT_ACTION_TTS_SERVICE in the queries elements of their manifest.

<queries>
  <intent>
    <action android:name="android.intent.action.TTS_SERVICE" />
  </intent>
</queries>

Pausing on Android

Android TTS does not support the pause function natively, so we have implemented a work around. We utilize the native onRangeStart() method to determine the index of start when pause is invoked. We use that index to create a new text the next time speak is invoked. Due to using onRangeStart(), pause works on SDK versions >= 26. Also, if using start and end offsets inside of setProgressHandler(), you'll need to keep a track of them if using pause since they will update once the new text is created when speak is called after being paused.

await flutterTts.pause()

iOS

There's a known issue with integrating plugins that use Swift into a Flutter project created with the Objective-C template. Flutter#16049

Example

To use this plugin :

  dependencies:
    flutter:
      sdk: flutter
    flutter_tts:
  • instantiate FlutterTts
FlutterTts flutterTts = FlutterTts();

To set shared audio instance (iOS only):

await flutterTts.setSharedInstance(true);

To set audio category and options with optional mode (iOS only). The following setup allows background music and in-app audio session to continue simultaneously:

await flutterTts.setIosAudioCategory(IosTextToSpeechAudioCategory.ambient,
     [
          IosTextToSpeechAudioCategoryOptions.allowBluetooth,
          IosTextToSpeechAudioCategoryOptions.allowBluetoothA2DP,
          IosTextToSpeechAudioCategoryOptions.mixWithOthers
     ],
     IosTextToSpeechAudioMode.voicePrompt
);

To await speak completion.

await flutterTts.awaitSpeakCompletion(true);

To await synthesize to file completion.

await flutterTts.awaitSynthCompletion(true);

speak, stop, getLanguages, setLanguage, setSpeechRate, setVoice, setVolume, setPitch, isLanguageAvailable, setSharedInstance

Future _speak() async{
    var result = await flutterTts.speak("Hello World");
    if (result == 1) setState(() => ttsState = TtsState.playing);
}

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

List<dynamic> languages = await flutterTts.getLanguages;

await flutterTts.setLanguage("en-US");

await flutterTts.setSpeechRate(1.0);

await flutterTts.setVolume(1.0);

await flutterTts.setPitch(1.0);

await flutterTts.isLanguageAvailable("en-US");

// iOS, Android and Web only
//see the "Pausing on Android" section for more info
await flutterTts.pause();

// iOS, macOS, and Android only
await flutterTts.synthesizeToFile("Hello World", Platform.isAndroid ? "tts.wav" : "tts.caf");

await flutterTts.setVoice({"name": "Karen", "locale": "en-AU"});

// iOS only
await flutterTts.setSharedInstance(true);

// Android only
await flutterTts.setSilence(2);

await flutterTts.getEngines;

await flutterTts.getDefaultVoice;

await flutterTts.isLanguageInstalled("en-AU");

await flutterTts.areLanguagesInstalled(["en-AU", "en-US"]);

await flutterTts.setQueueMode(1);

await flutterTts.getMaxSpeechInputLength;

Listening for platform calls

flutterTts.setStartHandler(() {
  setState(() {
    ttsState = TtsState.playing;
  });
});

flutterTts.setCompletionHandler(() {
  setState(() {
    ttsState = TtsState.stopped;
  });
});

flutterTts.setProgressHandler((String text, int startOffset, int endOffset, String word) {
  setState(() {
    _currentWord = word;
  });
});

flutterTts.setErrorHandler((msg) {
  setState(() {
    ttsState = TtsState.stopped;
  });
});

flutterTts.setCancelHandler((msg) {
  setState(() {
    ttsState = TtsState.stopped;
  });
});

// Android, iOS and Web
flutterTts.setPauseHandler((msg) {
  setState(() {
    ttsState = TtsState.paused;
  });
});

flutterTts.setContinueHandler((msg) {
  setState(() {
    ttsState = TtsState.continued;
  });
});

Getting Started

For help getting started with Flutter, view our online documentation.

For help on editing plugin code, view the documentation.

flutter_tts's People

Contributors

adriandev0 avatar alexandergottlieb avatar augustg avatar bcaspe avatar brouxco avatar bungeefan avatar colton127 avatar divshekhar avatar dlutton avatar fishjacky avatar fleoparra avatar georgi0u avatar harrowmykel avatar hsangtini avatar josephcrowell avatar khalilamor avatar khjde1207 avatar mafanwei avatar marcotta avatar mo-aro-etailer avatar putraxor avatar ryanheise avatar sashko avatar sososdk avatar syutkin avatar twogood avatar vagoston avatar wackymax avatar wexder avatar zigadolar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

flutter_tts's Issues

Error when using in Flutter

πŸ› Bug Report

I get this error when I try run on a real device:

  • What went wrong:
    Execution failed for task ':app:processDebugManifest'.

Manifest merger failed : uses-sdk:minSdkVersion 16 cannot be smaller than version 21 declared in library [:flutter_tts] C:\my-dev\Projects\flutter\mijn_italiaans\build\flutter_tts\intermediates\manifests\full\debug\AndroidManifest.xml as the library might be using APIs not available in 16
Suggestion: use a compatible library with a minSdk of at most 16,
or increase this project's minSdk version to at least 21,
or use tools:overrideLibrary="com.eyedeadevelopers.fluttertts" to force usage (may lead to runtime failures)

Expected behavior

Reproduction steps

Configuration

Version: 0.1.x

Platform:

  • πŸ“± iOS
  • πŸ€– Android

Flutter_TTS issue in iOS

πŸ’¬ Questions and Help

hi,
its my first flutter app ... i don't know much about iOS and Flutter thats why i am asking here

why i am getting that error ??
i tried that package with Swift/C++ support option..
anyone help me out ??

46908713-5d998980-cf40-11e8-83f7-4bc7d36e6e7e

i am stuck here.. please guide me :(

Issues trying to build with flutter_tts and flutter_twitter_login

πŸ› Bug Report

When adding flutter_tts and flutter_twitter_login to an objective-c enabled flutter project we get compiler issues.

Expected behavior

Adding flutter_tts on its own works without issue & there is no need to create a swift enabled project.

Just need to ensure :

  • use_frameworks!
  • specify swift_version = 4
  • add a swift file to the project that will also create the bridging header file.

Reproduction steps

Follow the steps above to add flutter_tts to your Obj-c flutter project. Now add flutter_twitter_login (https://pub.dev/packages/flutter_twitter_login) and ensure in your podfile you set podfile:ios, '11'

do a pod deintegrate and then flutter clean, followed by flutter pub get and finally a pod install.
Ensure one of your files (say main) imports from flutter_twitter_login.

This will install the flutter_twitter_login.

Compiler errors

When you try and run, you will get lots of compiler issues - a snapshot is shown here - the issue appears to be one of linking whereby the header files are not found.

/Users/xamgea/workspace/_projects/uajsh/ios/Pods/Protobuf/objectivec/google/protobuf/Wrappers.pbobjc.m:17:10: warning: non-portable path to file '<protobuf/Wrappers.pbobjc.h>'; specified path differs in case from file name on disk [-Wnonportable-include-path]
#import <Protobuf/Wrappers.pbobjc.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
<protobuf/Wrappers.pbobjc.h>
1 warning generated.
/Users/xamgea/.pub-cache/git/flutter_twitter_login-04b9d63fe6217cebf8c97f0ccf41719d44554c70/ios/Classes/TwitterLoginPlugin.m:2:9: fatal error: 'TwitterKit/TwitterKit.h' file not found
#import <TwitterKit/TwitterKit.h>
^~~~~~~~~~~~~~~~~~~~~~~~~
1 error generated.
Could not build the application for the simulator.
Error launching application on iPhone Xs.

Works perfect on Android but not on IOS.

I followed the Example properly, and it works perfectly on android, but it just doesn't work on IOS. Please help. Thanks a ton.
It doesn't work on the IOS speaker nor the Headphones.

Can we have voice selection, at least for android?

πŸš€ Feature Requests

Android Voice Selection.

tts.setvoice() implementation (so we can select male or female voices) can be done by setting de voice number in default voice in setup, but it would be nice to be able to do this from the app.

Platforms affected (mark all that apply)

  • πŸ“± iOS
  • [X ] πŸ€– Android

registerWith gives NPE when using Flutter's background execution on Android

πŸ› Bug Report

Flutter's new background execution feature (described here: https://medium.com/flutter-io/executing-dart-in-the-background-with-flutter-plugins-and-geofencing-2b3e40a1a124) allows plugins to be registered in a background context (e.g. a Service). The problem is that flutter_tts assumes that the context for plugin registration is an activity with this line of code:

channel.setMethodCallHandler(new FlutterTtsPlugin(registrar.activity(), channel));

registrar.activity() may now return null, and this leads to a NPE:

E/AndroidRuntime(12425): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.app.Activity.getApplicationContext()' on a null object reference
E/AndroidRuntime(12425): 	at com.eyedeadevelopers.fluttertts.FlutterTtsPlugin.<init>(FlutterTtsPlugin.java:32)
E/AndroidRuntime(12425): 	at com.eyedeadevelopers.fluttertts.FlutterTtsPlugin.registerWith(FlutterTtsPlugin.java:82)
E/AndroidRuntime(12425): 	at io.flutter.plugins.GeneratedPluginRegistrant.registerWith(GeneratedPluginRegistrant.java:23)

The solution is to change the above line of code to this:

channel.setMethodCallHandler(new FlutterTtsPlugin(registrar.activeContext() , channel));

(and change the declared type of the constructor's first parameter accordingly from Activity to the more general Context).

I am unaware of whether there is a similar bug on the iOS side.

Expected behavior

No NPE.

Reproduction steps

There are 3 sample projects from Google that I am aware of that demonstrate background execution:

https://github.com/bkonyi/FlutterGeofencing
https://github.com/flutter/plugins/tree/master/packages/android_alarm_manager
https://github.com/flutter/plugins/tree/master/packages/location_background

The first is for Android/iOS. The second is Android only. The third is iOS only.

To reproduce the problem, just add the flutter_tts plugin as a dependency to one of the first two projects and run the app (you may need to use the appropriate feature of the app that triggers background execution).

Configuration

Version: 0.1.1

Platform:

  • πŸ“± iOS
  • πŸ€– Android

isLanguageAvailable does not return correct result on Android

πŸ› Bug Report

isLanguageAvailable returns false even if language is available.

Expected behavior

isLanguageAvailable should return true if locale is in list obtained from getLanguages function

Reproduction steps

  • set locale to 'hr'
  • check if available

Configuration

Version: 0.5.1

Platform:

  • πŸ“± iOS
  • πŸ€– Android

TTS Engine not Bound

I am receiving the following error : W/TextToSpeech( 8234): speak failed: not bound to TTS engine.

Do you know how to resolve it?

collection == null - (known issue with API 21 & 22)

πŸ’¬ Questions and Help

Provide question related to this flutter plugin.
I encountered this problem, but the android version 5.0.1 cannot be changed, how should I modify the code to solve this problem

'setCategory' is unavailable in Swift / AVAudioSessionCategoryPlayback' has been renamed to 'AVAudioSession.Category.playback'

πŸ› Bug Report

/Users/user/Downloads/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_tts-0.2.3/ios/Classes/SwiftFlutterTtsPlugin.swift:23:43: error: 'setCategory' is unavailable in Swift
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
^~~~~~~~~~~
AVFoundation.AVAudioSession:23:15: note: 'setCategory' has been explicitly marked unavailable here
open func setCategory(_ category: AVAudioSession.Category) throws
^
/Users/user/Downloads/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_tts-0.2.3/ios/Classes/SwiftFlutterTtsPlugin.swift:23:55: error: 'AVAudioSessionCategoryPlayback' has been renamed to 'AVAudioSession.Category.playback'
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
AVAudioSession.Category.playback
AVFoundation.AVAudioSessionCategoryPlayback:3:12: note: 'AVAudioSessionCategoryPlayback' was obsoleted in Swift 3
public let AVAudioSessionCategoryPlayback: AVAudioSession.Category
^

Version: 0.2.3

Platform:

  • [ X] πŸ“± iOS
  • πŸ€– Android

speak failed: not bound to TTS engine

FlutterTts flutterTts = FlutterTts();
//List languages = await flutterTts.getLanguages;
//print(languages);
await flutterTts.setLanguage("en-US");
await flutterTts.setSpeechRate(1.0);
await flutterTts.setVolume(1.0);
await flutterTts.setPitch(1.0);
//await _stop();
_speak("Hello World");

Future _speak(String text) async {
var result = await flutterTts.speak(text);
}

//List languages = await flutterTts.getLanguages;
//print(languages);

Hot Reload :
getAvailableLanguages failed: not bound to TTS engine
E/MethodChannel#flutter_tts( 3179): Failed to handle method call

W/TextToSpeech( 3179): isLanguageAvailable failed: not bound to TTS engine
W/TextToSpeech( 3179): speak failed: not bound to TTS engine

EDIT.

For the first time it works without giving any voice. After hot-reload, the above errors are thorwn

First Time :

I/flutter ( 3554): [de, es-ES, es, fr, en, it-IT, it, fr-FR, en-US, de-DE, en-GB]
I/1.gpu ( 3554): type=1400 audit(0.0:1627): avc: denied { open } for path="/data/data/com.example.my_app/cache/flutter_engine/....AEQABQAAAAAAAA6IAAAADAAAEAAAAAAAAAAAAAAACAAAAAQAALMAA" dev="sdb3" ino=106021 scontext=u:r:untrusted_app:s0:c512,c768 tcontext=u:object_r:system_data_file:s0:c512,c768 tclass=file permissive=1
I/TextToSpeech( 3554): Asked to disconnect from ComponentInfo{com.svox.pico/com.svox.pico.PicoService}
I/TextToSpeech( 3554): Connected to ComponentInfo{com.svox.pico/com.svox.pico.PicoService}
I/TextToSpeech( 3554): Set up connection to ComponentInfo{com.svox.pico/com.svox.pico.PicoService}

Adapt to higher Dart SDK

Running "flutter packages get" in project_activity...
The current Dart SDK version is 2.3.0-dev.0.5.flutter-a1668566e5.

Because project_activity depends on flutter_tts >=0.0.2 <0.0.7 which requires SDK version >=1.8.0 <=2.0.0, version solving failed.

pub get failed (1)
Process finished with exit code 1

The volume can not be changed.

πŸ› Bug Report

The does not change.

Expected behavior

One should here a difference with respect to the sound volume, after setting this statement in the initTts() method:

 flutterTts.setVolume(1.0);
or
 flutterTts.setVolume(10.0);  //the sound should be louder

Reproduction steps

see the statements above.

Configuration

Latest version of flutter_tts

Male Offline Voice

πŸ’¬ Questions and Help

I wanna get male offline voice in android 21 too. can i get it.

play speed too fast

πŸ›

text is played too fast,
Configuration:

     _flutterTts = new FlutterTts();
    await _flutterTts.setLanguage("es-ES");
    await _flutterTts.setSpeechRate(1.0);
    await _flutterTts.setVolume(1.0);
    await _flutterTts.setPitch(0.5);
    await _flutterTts.isLanguageAvailable("es-ES");

Version: 0.2.1

Platform:

  • [ x ] πŸ“± iOS

Caught a RuntimeException from the binder stub implementation.

I've follow the example and I've inserted flutter_tts in a view of my app.
When I'm playng I see this error from the last update of flutter engine:

W/Binder (26640): Caught a RuntimeException from the binder stub implementation. W/Binder (26640): java.lang.RuntimeException: Methods marked with @UiThread must be executed on the main thread. Current thread: Binder:26640_3 W/Binder (26640): at io.flutter.embedding.engine.FlutterJNI.ensureRunningOnMainThread(FlutterJNI.java:605) W/Binder (26640): at io.flutter.embedding.engine.FlutterJNI.dispatchPlatformMessage(FlutterJNI.java:515) W/Binder (26640): at io.flutter.embedding.engine.dart.DartMessenger.send(DartMessenger.java:74) W/Binder (26640): at io.flutter.embedding.engine.dart.DartExecutor.send(DartExecutor.java:163) W/Binder (26640): at io.flutter.view.FlutterNativeView.send(FlutterNativeView.java:152) W/Binder (26640): at io.flutter.plugin.common.MethodChannel.invokeMethod(MethodChannel.java:95) W/Binder (26640): at io.flutter.plugin.common.MethodChannel.invokeMethod(MethodChannel.java:82) W/Binder (26640): at com.tundralabs.fluttertts.FlutterTtsPlugin$1.onStart(FlutterTtsPlugin.java:42) W/Binder (26640): at android.speech.tts.TextToSpeech$Connection$1.onStart(TextToSpeech.java:2143) W/Binder (26640): at android.speech.tts.ITextToSpeechCallback$Stub.onTransact(ITextToSpeechCallback.java:56) W/Binder (26640): at android.os.Binder.execTransact(Binder.java:731)

How can I fix it?

IOS integration not using create i-swift for flutter tts

I am having an issue with the IOS integration for this plugin.

Background:
I know there is an known issue using the Objective-C template but I am trying to add this plugin to my app that has a lot of custom iOS already in it (specifically a ShareExtension) and it would be a pain to recreate the app using the Swift template.

Somewhat solution:
I followed the advice seen here: https://github.com/flutter/flutter/issues/16049#issuecomment-382664356 and was able to get rid of the Swift version fault but now I am encountering another fault (shown below) and have been unable to fix it. My Swift programming is very minimal so I would appreciate any help you can give. Thanks!

Xcode's output:
↳
:0: error: module map file 'xxx/build/ios/Debug-iphonesimulator/flutter_tts/
flutter_tts.modulemap' not found
:0: error: module map file 'xxx/build/ios/Debug-iphonesimulator/flutter_tts/
flutter_tts.modulemap' not found
:0: error: module map file 'xxx/build/ios/Debug-iphonesimulator/flutter_tts/
flutter_tts.modulemap' not found
:0: error: module map file 'xxx/build/ios/Debug-iphonesimulator/flutter_tts/
flutter_tts.modulemap' not found

Can't change language in iOS

πŸ› Bug Report

Hi Friend
I my app i use two language en-us, en-gb
When i call func speak() and use
await flutterTts.setLanguage(language);
But it not work in iOS, and work fine in android.

Hope you check it.
Thanks.

Expected behavior

Reproduction steps

Configuration

Version: 0.1.x

Platform:

  • [v] πŸ“± iOS
  • πŸ€– Android

getting error when `flutter run --release`

πŸ› Bug Report

error: invalid file path '/Users//Github//mobile/build/flutter_tts/intermediates/manifests/aapt/release/AndroidManifest.xml'.

error: invalid file path '/Users//Github//mobile/build/flutter_tts/intermediates/manifests/aapt/release/output.json'.

* What went wrong:
Execution failed for task ':flutter_tts:verifyReleaseResources'.
> java.util.concurrent.ExecutionException: java.util.concurrent.ExecutionException: com.android.tools.aapt2.Aapt2Exception: AAPT2 error: check logs for details

Expected behavior

I believe this worked before but seems not after upgrading to flutter_tts: 0.2.0. Tested Android only.

Reproduction steps

flutter run --release

Configuration

Version: 0.2.0

Platform:

  • πŸ“± iOS
  • πŸ€– Android

is Arabic language not Supported ?

πŸ› Bug Report

await flutterTts.setLanguage("ar-sa");
// or
await flutterTts.setLanguage("ar-ar");
// or
await flutterTts.setLanguage("ar-eg");

Expected behavior

Arabic language is not available

Reproduction steps

print(await flutterTts.isLanguageAvailable('ar-sa')); // false = ar-eg, ar-a.

Configuration

Version: 0.1.x
0.2.6
Platform:

  • πŸ€– Android

Sometimes the completion handler doesn't call and the plugin doesn't talk

πŸ› Bug Report

Sometimes the completion handler doesn't call and it doesn't talk. Others is does, but I noticed when I switch to a new a page in my app that also has an instance of the plugin, sometimes when I return to the original page the completionhandler doesn't fire and it doesn't talk. I've narrowed it down to being this, but I'm not sure why.

I'm on the latest version of the plugin.

How to add swift support

I already have a project and there is no dependency on Swift anywhere.
When I try to add flutter_tts there start to appear build errors.

Invalid int: "OS" FlutterTtsPlugin.java line 67

πŸ› Bug Report

Fatal Exception: java.lang.IllegalArgumentException
Invalid int: "OS"
com.eyedeadevelopers.fluttertts.FlutterTtsPlugin$2.onInit (FlutterTtsPlugin.java:67)

Device

Device
Brand: samsung
Model: Galaxy Note3
Orientation: Portrait
RAM free: 473.27 MB
Disk free: 12.46 GB
Operating System
Version: 5.0
Orientation: Portrait
Rooted: No
Crash
Date: Dec 31, 2018, 5:04:00 PM
App version: 3.3.21 (3321)

Configuration

Version: flutter_tts: ^0.1.1

Platform:

  • πŸ“± iOS
  • πŸ€– Android

Is setting other language working?

πŸ› Bug Report

when calling

await flutterTts.setLanguage("ko-KR");
print(await flutterTts.isLanguageAvailable('ko-KR'));

or even with ko, I get

D/TTS     (26190): Language is not available - ko
D/TTS     (26190): Language is not available - ko-kr

Expected behavior

Korean language should be available

Reproduction steps

await flutterTts.setLanguage("ko-KR");
print(await flutterTts.isLanguageAvailable('ko-KR'));

Configuration

Version: 0.1.2

Platform:

  • πŸ“± iOS
  • πŸ€– Android

Callback registered in ttsInitHandler is never called

πŸ› Bug Report

Expected behavior

this._flutterTts = FlutterTts();
this._flutterTts.ttsInitHandler(() {
print("init");
});

I expect it to output "init" in the console.

Callbacks registered in other handlers setStartHandler/setCompletionHandler are called when speak is called.

Configuration

Version: 0.2.6

Android: 5.1.1
Flutter: git master 83a8a575eed882c49b629effedf7c95b6184515d
TTS engine: com.google.android.tts/com.google.android.tts.service.GoogleTTSService

Platform:

  • πŸ“± iOS
  • πŸ€– Android

Whether to support mixed Speech of two languages

πŸš€ Feature Requests

Whether to support mixed Speech of two languages

For example: English and Chinese are in a paragraph. If I set the English mode, the voice cannot read another language correctly.
Text case: 'testοΌŒζ΅‹θ―•'(ζ΅‹θ―• is Chinese after translation)

Silence before speak needed

πŸš€ Feature Requests

I need to play a silence before starting to speak.

Contextualize the feature

When using Bluetooth headsets with batteries the Headsets normally switches off the audio when there is no signal from the device for a while in order to save battery. When flutter_tts starts to speak some headsets needs 500-1500ms to restart and play the audio file. Without a trailing signal the user will not hear the first second of the audio.

When playing the silence the Headset will detect the (silent) signal and starts up.

Describe the feature

So I ask to add a feature to define a silence period in milliseconds before starting the speech.

Optional: For advanced functionality another parameter could be added to define that the silence period will be omitted if the last speech is not older than x seconds. (assuming that the headset is still active)

In android I had the following code snippet:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        if (silenceMs > 0)
            tts.playSilentUtterance(silenceMs, TextToSpeech.QUEUE_ADD, utteranceId);
        tts.speak(speak, TextToSpeech.QUEUE_ADD, null, utteranceId);
} else {
        if (silenceMs > 0)
            tts.playSilence(silenceMs, TextToSpeech.QUEUE_ADD, null);
        tts.speak(speak, TextToSpeech.QUEUE_ADD, null);
}

Platforms affected (mark all that apply)

  • πŸ“± iOS
  • πŸ€– Android

Speak only works the first time, probably due to Dart 2.3 upgrade

πŸ› Bug Report

I updated flutter to version 1.6.3 and Dart to version 2.3. Before these two, I had no problems with the flutter_tts package. However, after upgrading, it behaves weirdly. It speaks the first thing I throw at it, but I am receiving the error below, and after that it won't speak anything anymore.

W/Binder  (25778): Caught a RuntimeException from the binder stub implementation.
W/Binder  (25778): java.lang.RuntimeException: Methods marked with @UiThread must be executed on the main thread. Current thread: Binder:25778_4
W/Binder  (25778): 	at io.flutter.embedding.engine.FlutterJNI.ensureRunningOnMainThread(FlutterJNI.java:605)
W/Binder  (25778): 	at io.flutter.embedding.engine.FlutterJNI.dispatchPlatformMessage(FlutterJNI.java:515)
W/Binder  (25778): 	at io.flutter.embedding.engine.dart.DartMessenger.send(DartMessenger.java:76)
W/Binder  (25778): 	at io.flutter.embedding.engine.dart.DartExecutor.send(DartExecutor.java:166)
W/Binder  (25778): 	at io.flutter.view.FlutterNativeView.send(FlutterNativeView.java:155)
W/Binder  (25778): 	at io.flutter.plugin.common.MethodChannel.invokeMethod(MethodChannel.java:98)
W/Binder  (25778): 	at io.flutter.plugin.common.MethodChannel.invokeMethod(MethodChannel.java:84)
W/Binder  (25778): 	at com.tundralabs.fluttertts.FlutterTtsPlugin$1.onStart(FlutterTtsPlugin.java:42)
W/Binder  (25778): 	at android.speech.tts.TextToSpeech$Connection$1.onStart(TextToSpeech.java:2143)
W/Binder  (25778): 	at android.speech.tts.ITextToSpeechCallback$Stub.onTransact(ITextToSpeechCallback.java:56)
W/Binder  (25778): 	at android.os.Binder.execTransact(Binder.java:752)
W/Binder  (25778): Caught a RuntimeException from the binder stub implementation.
W/Binder  (25778): java.lang.RuntimeException: Methods marked with @UiThread must be executed on the main thread. Current thread: Binder:25778_5
W/Binder  (25778): 	at io.flutter.embedding.engine.FlutterJNI.ensureRunningOnMainThread(FlutterJNI.java:605)
W/Binder  (25778): 	at io.flutter.embedding.engine.FlutterJNI.dispatchPlatformMessage(FlutterJNI.java:515)
W/Binder  (25778): 	at io.flutter.embedding.engine.dart.DartMessenger.send(DartMessenger.java:76)
W/Binder  (25778): 	at io.flutter.embedding.engine.dart.DartExecutor.send(DartExecutor.java:166)
W/Binder  (25778): 	at io.flutter.view.FlutterNativeView.send(FlutterNativeView.java:155)
W/Binder  (25778): 	at io.flutter.plugin.common.MethodChannel.invokeMethod(MethodChannel.java:98)
W/Binder  (25778): 	at io.flutter.plugin.common.MethodChannel.invokeMethod(MethodChannel.java:84)
W/Binder  (25778): 	at com.tundralabs.fluttertts.FlutterTtsPlugin$1.onDone(FlutterTtsPlugin.java:47)
W/Binder  (25778): 	at android.speech.tts.TextToSpeech$Connection$1.onSuccess(TextToSpeech.java:2127)
W/Binder  (25778): 	at android.speech.tts.ITextToSpeechCallback$Stub.onTransact(ITextToSpeechCallback.java:64)
W/Binder  (25778): 	at android.os.Binder.execTransact(Binder.java:752)
W/IInputConnectionWrapper(25778): getExtractedText on inactive InputConnection
W/IInputConnectionWrapper(25778): getTextBeforeCursor on inactive InputConnection

Reproduction steps

Here's the code I'm calling:

Future<void> speakText(
    BuildContext context, String language, String text) async {
  final bool result = await TTS().speak(language, text);
  if (result == false)
    showToast(AppLocalization.of(context).languageNotAvailable, "bottom");
}

Here is the TTS class I am using, I made it following the example:

import 'dart:async';
import 'package:flutter_tts/flutter_tts.dart';
import './models/language.dart';

enum TTSState { playing, stopped }

class TTS {
  static final TTS _singleton = TTS._internal();
  FlutterTts _flutterTts;
  TTSState _ttsState;

  factory TTS() {
    return _singleton;
  }

  TTS._internal() {
    _flutterTts = FlutterTts();
    _flutterTts.setStartHandler(() {
      _ttsState = TTSState.playing;
    });
    _flutterTts.setCompletionHandler(() {
      _ttsState = TTSState.stopped;
    });
    _flutterTts.setErrorHandler((msg) {
      _ttsState = TTSState.stopped;
    });
  }

  Future<bool> _setSpeakingLanguage(String language) async {
    String ttsAbbreviation = await getTTSLanguageAbbreviation(language);
    if (ttsAbbreviation == null) return false;
    if ((await _flutterTts.isLanguageAvailable(ttsAbbreviation)) == false)
      return false;
    _flutterTts.setLanguage(ttsAbbreviation);
    return true;
  }

  Future<String> getTTSLanguageAbbreviation(String language) async {
    String googleTranslateAbbreviation = allLanguages.keys
        .toList()[allLanguages.values.toList().indexOf(language)];
    List ttsLanguages = await _flutterTts.getLanguages;
    if (ttsLanguages == null) return null;
    List filtered = ttsLanguages
        .where((item) => item.startsWith(googleTranslateAbbreviation))
        .toList();
    if (filtered == null) return null;
    if (filtered.length == 0) return null;

    if (filtered.length > 1) {
      List doubleFiltered = filtered
          .where((item) =>
              item.toLowerCase().endsWith(googleTranslateAbbreviation))
          .toList();
      if (doubleFiltered.length > 0) return doubleFiltered.first as String;
    }

    return filtered.first as String;
  }

  Future<bool> speak(String language, String text) async {
    if (_ttsState == TTSState.playing) return true;
    if (await _setSpeakingLanguage(language) == false) return false;

    var result = await _flutterTts.speak(text);
    if (result == 1) _ttsState = TTSState.playing;
    return true;
  }

  Future<void> stop() async {
    var result = await _flutterTts.stop();
    if (result == 1) _ttsState = TTSState.stopped;
  }

  void dispose() {
    _flutterTts.stop();
  }

  get isPlaying => _ttsState == TTSState.playing;
  get isStopped => _ttsState == TTSState.stopped;
}

Configuration

Flutter 1.6.3, Dart 2.3, flutter_tts 0.2.4

Platform:
Only tested it on Android, as I can't run iOS yet due to some different issues.

setLanguage function ignores the country code

On Android, the setLanguage function ignores the country code:

flutterTts.setLanguage("en-GB") // doesn’t work, "en-US" is choosen

The problematic java line:

void setLanguage(String language, Result result) {
Locale locale = new Locale(language);		// You should split the language: new Locale("en", "GB");

unable to play hindi langauge

I tried adding

await flutterTts.setLanguage("hi-IN");

I also made sure that hi-IN language is available

but each time I was getting an error via error handler as

Error from TextToSpeech

not sure what exactly is the issue

[Android] Using deprecated API

πŸ› Bug Report

When compiling my app I had this warning:

Note: /home/colas/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_tts-0.2.6/android/src/main/java/com/tundralabs/fluttertts/FlutterTtsPlugin.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.

I added this in the build.gradle file to have the details:

allprojects {
    tasks.withType(JavaCompile) {
        options.compilerArgs << "-Xlint:deprecation"
    }
}

And I got this result:

/home/colas/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_tts-0.2.6/android/src/main/java/com/tundralabs/fluttertts/FlutterTtsPlugin.java:77: warning: [deprecation] getDefaultLanguage() in TextToSpeech has been deprecated
                      : tts.getDefaultLanguage();
                           ^
1 warning

Looking at the API reference for getDefaultLanguage() it says that it's deprecated since API level 21.

However in build.gradle we do specify:

minSdkVersion 21

That's why I think that the following ternary should be replaced:

Locale locale = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
                      ? tts.getDefaultVoice().getLocale()
                      : tts.getDefaultLanguage();

This gets the job done without any warning and is valid since our minSdkVersion is 21:

Locale locale = tts.getDefaultVoice().getLocale();

Expected behavior

No warning.

Reproduction steps

Building a project using the flutter_tts plugin for Android.

Configuration

Version: 0.2.6

Platform:

  • πŸ“± iOS
  • πŸ€– Android

Support for onRangeStart in UtteranceProgressListener

Great plugin! Any chance you can add support for onRangeStart (Android) and willSpeakRangeOfSpeechString (IOS)??

I'm porting my Swift/IOS app to Flutter/Android, it uses this callback to highlight each utterance as it is spoken, giving useful feedback to the user that the app is actually speaking (if the volume is off, for example).

I'd do a pull request but I'm running flat out to hit a hard deadline at the moment ;) but FWIW I implemented a quick version in a local copy (Android only) with the following:

// In FlutterTtsPlugin.java within utteranceProgressListener..
// ...
@OverRide
public void onRangeStart(String utteranceId, int start, int end, int frame) {
ArrayList offsets = new ArrayList<>(3);
offsets.add(Integer.valueOf(start));
offsets.add(Integer.valueOf(end));
offsets.add(Integer.valueOf(frame));
channel.invokeMethod("speak.onRangeStart", offsets);
}
// ...

// In flutter_tts.dart..

typedef void RangeHandler(dynamic offset);

// Within FlutterTts
RangeHandler onRangeStartHandler;

void setRangeHandler(RangeHandler callback) {
onRangeStartHandler = callback;
}

// New case

Future platformCallHandler(MethodCall call) async {
switch (call.method)
// ...
case "speak.onRangeStart":
if (onRangeStartHandler != null) {
onRangeStartHandler(call.arguments);
}
break;
// ...

Voice selection for iOS.

πŸš€ Feature Requests

Hi, is it possible to do voice selection on iOS? I've seen #16 which implement for Android, not sure whether native iOS allow similar behavior. Thanks!

IOS build fails due to undefined swift version.

πŸ› Bug Report

- `flutter_tts` does not specify a Swift version and none of the targets (`Runner`) integrating it have the `SWIFT_VERSION` attribute set. Please contact the author or set the `SWIFT_VERSION` attribute in at least one of the targets that integrate this pod.

flutter: 1.2.1
flutter_tts: 0.2.4

Continuously facing this issue. The method 'speak' was called on null. Receiver: null

Is there any way to make it work? I have tried nearly all the code available for flutter_tts. It is still not working for me. It will be a huge favor if you can guide me a little.

import 'package:flutter/material.dart';

import 'dart:async';
import 'dart:io';
import 'package:easelang/Modals/Alphabets.dart';
import 'package:flutter_tts/flutter_tts.dart';

class AlphabetRow extends StatefulWidget {
  final Alphabet alphabet;
  final bool horizontal;

  AlphabetRow(this.alphabet, {this.horizontal = true});
  AlphabetRow.vertical(this.alphabet) : horizontal = false;

  @override
  _AlphabetRowState createState() => _AlphabetRowState();
}

enum TtsState { playing, stopped }

class _AlphabetRowState extends State<AlphabetRow> {
  var alphabet;
  FlutterTts flutterTts;
  dynamic languages;
  dynamic voices;
  String language;
  String voice;

  TtsState ttsState = TtsState.stopped;

  get isPlaying => ttsState == TtsState.playing;
  get isStopped => ttsState == TtsState.stopped;

  @override
  void initState() {
    super.initState();
    initSpeak();
  }

  initSpeak() async {
    FlutterTts flutterTts = FlutterTts();

    if (Platform.isAndroid) {
      flutterTts.ttsInitHandler(() {
        _getLanguages();
        _getVoices();
      });
    } else if (Platform.isIOS) {
      _getLanguages();
      _getVoices();
    }

    flutterTts.setStartHandler(() {
      print("runtimeType is: ${widget.runtimeType}");
      setState(() {
        ttsState = TtsState.playing;
      });
    });

    flutterTts.setCompletionHandler(() {
      setState(() {
        ttsState = TtsState.stopped;
      });
      print("setCompletionHandler called");
    });

    flutterTts.setErrorHandler((msg) {
      setState(() {
        ttsState = TtsState.stopped;
      });
    });
  }

  Future _getLanguages() async {
    languages = await flutterTts.getLanguages;
    if (languages != null) setState(() => languages);
  }

  Future _getVoices() async {
    voices = await flutterTts.getVoices;
    if (voices != null) setState(() => voices);
  }

  Future<dynamic> _speak() async {
    if (widget.alphabet.letter != null) {
      if (widget.alphabet.letter.isNotEmpty) {
        var result = await flutterTts.speak(widget.alphabet.letter);
        if (result == 1) setState(() => ttsState = TtsState.playing);
      }
    }
  }

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

  @override
  void dispose() {
    super.dispose();
    flutterTts.stop();
  }

  @override
  Widget build(BuildContext context) {
    final alphabetSound = Container(
      margin: EdgeInsets.symmetric(
        vertical: 24.0,
      ),
      alignment: widget.horizontal
          ? FractionalOffset.centerRight
          : FractionalOffset.center,
      child: MaterialButton(
        padding: EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
        shape:
            RoundedRectangleBorder(borderRadius: BorderRadius.circular(100.0)),
        highlightColor: Colors.white,
        color: Colors.white,
        splashColor: Colors.red[800],
        height: 25.0,
        minWidth: 65.0,
        child: Icon(
          Icons.volume_up,
          size: 25.0,
        ),
        onPressed: () {
          _speak();
        },
      ),
    );
}
}

requires SDK version >=1.8.0 <=2.0.0

[music_player] flutter packages get
Running "flutter packages get" in music_player...
The current Dart SDK version is 2.1.0-dev.5.0.flutter-a2eb050044.

Because sample_app depends on tts any which requires SDK version >=1.8.0 <=2.0.0, version solving failed.

pub get failed (1)
exit code 1

Multiple Instances in Same Tree are Problematic

Having multiple instances of a StatefulWidget that instantiates FlutterTts (in the same tree) presents a problem. The state of the last instance overrides the state of any previous instance in the tree. It seems as though this plugin doesn't support multiple instances...

Error while trying to start the example code with a fresh flutter instalation IOS

Hi,

i have a fresh installation of flutter and i just tried to run the code provided in the example folder. For Android seems to work fine but on ios i get the following error:

Command CompileSwift failed with a nonzero exit code
    /Users/tfilipovici/Library/Flutter/.pub-cache/hosted/pub.dartlang.org/flutter_tts-0.2.6/ios/Classes/
    SwiftFlutterTtsPlugin.swift:24:43: error: 'setCategory' is unavailable in Swift
          try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
                                              ^~~~~~~~~~~
    AVFoundation.AVAudioSession:23:15: note: 'setCategory' has been explicitly marked unavailable here
        open func setCategory(_ category: AVAudioSession.Category) throws
                  ^
    /Users/tfilipovici/Library/Flutter/.pub-cache/hosted/pub.dartlang.org/flutter_tts-0.2.6/ios/Classes/
    SwiftFlutterTtsPlugin.swift:24:55: error: 'AVAudioSessionCategoryPlayback' has been renamed to
    'AVAudioSession.Category.playback'
          try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
                                                          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                                          AVAudioSession.Category.playback
    AVFoundation.AVAudioSessionCategoryPlayback:3:12: note: 'AVAudioSessionCategoryPlayback' was
    obsoleted in Swift 3
    public let AVAudioSessionCategoryPlayback: AVAudioSession.Category
               ^
    note: Using new build systemnote: Planning buildnote: Constructing build description

Could not build the application for the simulator.
Error launching application on iPhone X.

This is my pubspec:

version: 1.0.0+1

environment:
  sdk: ">=2.1.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  speech_recognition: "^0.3.0"  
  flutter_tts:

speak failed: not bound to TTS engine

πŸ› Bug Report

Expected behavior

Reproduction steps

Configuration

Version: 0.1.x

Platform:

  • πŸ“± iOS
  • πŸ€– Android

speak failed: not bound to TTS engine

Asked to disconnect from ComponentInfo{com.google.android.tts/com.google.android.tts.service.GoogleTTSService}

plugin no longer works with latest flutter version

The latest flutter update (today) gives this error when including the plugin :

Running "flutter packages get" in kbml_viewer...
The current Dart SDK version is 2.1.0-dev.1.0.flutter-69fce633b7.

Because flutter_tts 0.0.6 requires SDK version >=1.8.0 <=2.0.0 and no versions of flutter_tts match >0.0.6 <0.1.0, flutter_tts ^0.0.6 is forbidden.
So, because kbml_viewer depends on flutter_tts ^0.0.6, version solving failed.
pub get failed (1)

Not working on Mac

I tried opening my project in xcode with flutter_tts 0.0.6 on my mac, but I get an error on startup.

flutter_tts

Flutter Tts Error Looking for missing header file

Whenever I try to build my project, the build seems to complete and then throws this error and I'm stuck. I have searched all through the internet still haven't seen anything that works.

Xcode's output:
↳ === BUILD TARGET url_launcher OF PROJECT Pods WITH CONFIGURATION Debug === <module-includes>:1:9: note: in file included from <module-includes>:1: #import "Headers/flutter_tts-umbrella.h"
^
/Users/User/myFlutterProjects/news/ios/Pods/Target Support Files/flutter_tts/flutter_tts-umbrella.h:13:9: note: in file included from /Users/User/myFlutterProjects/news/ios/Pods/Target Support Files/flutter_tts/flutter_tts-umbrella.h:13: #import "FlutterTtsPlugin.h"
^
/Users/User/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_tts-0.0.7/ios/Classes/FlutterTtsPlugin.h:2:9: error: 'flutter_tts/flutter_tts-Swift.h' file not found
#import <flutter_tts/flutter_tts-Swift.h>
^
<unknown>:0: error: could not build Objective-C module 'flutter_tts' Could not build the application for the simulator. Error launching application on iPhone X.

I must add this is only specific to IOS.
Everything works fine in android.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.