├── .github └── workflows │ └── windows-ci.yml ├── .gitignore ├── .npmignore ├── README.md ├── TextToSpeech.podspec ├── android ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── net │ └── no_mad │ └── tts │ ├── TextToSpeechModule.java │ └── TextToSpeechPackage.java ├── example ├── .buckconfig ├── .flowconfig ├── .gitattributes ├── .gitignore ├── .watchmanconfig ├── App.js ├── README.md ├── __tests__ │ ├── TestReadText.test.js │ └── TestTTSInit.test.js ├── android │ ├── app │ │ ├── BUCK │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── amusetts │ │ │ │ ├── MainActivity.java │ │ │ │ └── MainApplication.java │ │ │ └── res │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ └── values │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── keystores │ │ ├── BUCK │ │ └── debug.keystore.properties │ └── settings.gradle ├── app.json ├── index.js ├── ios │ ├── amuseTts-tvOS │ │ └── Info.plist │ ├── amuseTts-tvOSTests │ │ └── Info.plist │ ├── amuseTts.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ ├── amuseTts-tvOS.xcscheme │ │ │ └── amuseTts.xcscheme │ ├── amuseTts │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Base.lproj │ │ │ └── LaunchScreen.xib │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Info.plist │ │ └── main.m │ └── amuseTtsTests │ │ ├── Info.plist │ │ └── amuseTtsTests.m ├── jest-setups │ ├── jest.setup.js │ └── jest.setup.windows.js ├── metro.config.js ├── package.json ├── windows │ ├── .gitignore │ ├── amuseTts.sln │ └── amuseTts │ │ ├── .gitignore │ │ ├── App.cpp │ │ ├── App.h │ │ ├── App.idl │ │ ├── App.xaml │ │ ├── Assets │ │ ├── LockScreenLogo.scale-200.png │ │ ├── SplashScreen.scale-200.png │ │ ├── Square150x150Logo.scale-200.png │ │ ├── Square44x44Logo.scale-200.png │ │ ├── Square44x44Logo.targetsize-24_altform-unplated.png │ │ ├── StoreLogo.png │ │ └── Wide310x150Logo.scale-200.png │ │ ├── AutolinkedNativeModules.g.cpp │ │ ├── AutolinkedNativeModules.g.h │ │ ├── AutolinkedNativeModules.g.props │ │ ├── AutolinkedNativeModules.g.targets │ │ ├── MainPage.cpp │ │ ├── MainPage.h │ │ ├── MainPage.idl │ │ ├── MainPage.xaml │ │ ├── Package.appxmanifest │ │ ├── PropertySheet.props │ │ ├── ReactPackageProvider.cpp │ │ ├── ReactPackageProvider.h │ │ ├── amuseTts.vcxproj │ │ ├── amuseTts.vcxproj.filters │ │ ├── amuseTts_TemporaryKey.pfx │ │ ├── packages.config │ │ ├── pch.cpp │ │ └── pch.h └── yarn.lock ├── index.d.ts ├── index.js ├── ios ├── TextToSpeech.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── anton.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── anton.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── TextToSpeech.xcscheme │ │ └── xcschememanagement.plist └── TextToSpeech │ ├── TextToSpeech.h │ └── TextToSpeech.m ├── package.json └── windows ├── .gitignore ├── README.md ├── RNTTS ├── PropertySheet.props ├── RNTTS.cpp ├── RNTTS.def ├── RNTTS.h ├── RNTTS.vcxproj ├── RNTTS.vcxproj.filters ├── ReactPackageProvider.cpp ├── ReactPackageProvider.h ├── ReactPackageProvider.idl ├── packages.config ├── pch.cpp └── pch.h ├── RNTTS62.sln └── RNTTS63.sln /.github/workflows/windows-ci.yml: -------------------------------------------------------------------------------- 1 | name: Windows CI 2 | on: [push, pull_request] 3 | 4 | jobs: 5 | run-windows-tests: 6 | name: Build & run tests 7 | runs-on: windows-2019 8 | 9 | steps: 10 | - uses: actions/checkout@v2 11 | name: Checkout Code 12 | 13 | - name: Setup Node.js 14 | uses: actions/setup-node@v1 15 | with: 16 | node-version: '12.18.3' 17 | 18 | - name: Setup MSBuild 19 | uses: microsoft/setup-msbuild@v1 20 | with: 21 | vs-version: 16.5 22 | 23 | - name: Install example modules 24 | run: | 25 | cd example 26 | yarn --pure-lockfile 27 | - name: Build release 28 | run: | 29 | cd example 30 | npx react-native run-windows --release --no-packager --no-launch --logging 31 | - name: Start Appium server 32 | shell: powershell 33 | run: | 34 | cd example 35 | Start-Process PowerShell -ArgumentList "yarn appium" 36 | - name: Run tests 37 | run: | 38 | cd example 39 | yarn test:windows_nosound_ci 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .vscode 3 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .github/ 2 | example/ 3 | android/.gradle/ 4 | android/build/ 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React Native TTS 2 | 3 | React Native TTS is a text-to-speech library for [React Native](https://facebook.github.io/react-native/) on iOS, Android and Windows. 4 | 5 | ## Documentation 6 | 7 | - [Install](#install) 8 | - [Usage](#usage) 9 | - [License](#license) 10 | - [Example project](#example) 11 | 12 | ## Install 13 | 14 | ```shell 15 | npm install --save react-native-tts 16 | ``` 17 | 18 | ## Usage 19 | 20 | ### Imports 21 | 22 | ```js 23 | import Tts from 'react-native-tts'; 24 | ``` 25 | 26 | #### Windows 27 | 28 | 1. In `windows/myapp.sln` add the `RNTTS` project to your solution: 29 | 30 | - Open the solution in Visual Studio 2019 31 | - Right-click Solution icon in Solution Explorer > Add > Existing Project 32 | - Select `node_modules\react-native-tts\windows\RNTTS\RNTTS.vcxproj` 33 | 34 | 2. In `windows/myapp/myapp.vcxproj` add a reference to `RNTTS` to your main application project. From Visual Studio 2019: 35 | 36 | - Right-click main application project > Add > Reference... 37 | - Check `RNTTS` from Solution Projects. 38 | 39 | 3. In `pch.h` add `#include "winrt/RNTTS.h"`. 40 | 41 | 4. In `app.cpp` add `PackageProviders().Append(winrt::RNTTS::ReactPackageProvider());` before `InitializeComponent();`. 42 | 43 | ### Speaking 44 | 45 | Add utterance to TTS queue and start speaking. Returns promise with utteranceId. 46 | 47 | ```js 48 | Tts.speak('Hello, world!'); 49 | ``` 50 | 51 | Additionally, speak() allows to pass platform-specific options. 52 | 53 | ```js 54 | // IOS 55 | Tts.speak('Hello, world!', { 56 | iosVoiceId: 'com.apple.ttsbundle.Moira-compact', 57 | rate: 0.5, 58 | }); 59 | // Android 60 | Tts.speak('Hello, world!', { 61 | androidParams: { 62 | KEY_PARAM_PAN: -1, 63 | KEY_PARAM_VOLUME: 0.5, 64 | KEY_PARAM_STREAM: 'STREAM_MUSIC', 65 | }, 66 | }); 67 | ``` 68 | 69 | For more detail on `androidParams` properties, please take a look at [official android documentation](https://developer.android.com/reference/android/speech/tts/TextToSpeech.Engine.html). Please note that there are still unsupported key with this wrapper library such as `KEY_PARAM_SESSION_ID`. The following are brief summarization of currently implemented keys: 70 | 71 | - `KEY_PARAM_PAN` ranges from `-1` to `+1`. 72 | 73 | - `KEY_PARAM_VOLUME` ranges from `0` to `1`, where 0 means silence. Note that `1` is a default value for Android. 74 | 75 | - For `KEY_PARAM_STREAM` property, you can currently use one of `STREAM_ALARM`, `STREAM_DTMF`, `STREAM_MUSIC`, `STREAM_NOTIFICATION`, `STREAM_RING`, `STREAM_SYSTEM`, `STREAM_VOICE_CALL`, 76 | 77 | The supported options for IOS are: 78 | 79 | - `iosVoiceId` which voice to use, check [voices()](#list-voices) for available values 80 | - `rate` which speech rate this line should be spoken with. Will override [default rate](#set-default-speech-rate) if set for this utterance. 81 | 82 | Stop speaking and flush the TTS queue. 83 | 84 | ```js 85 | Tts.stop(); 86 | ``` 87 | 88 | ### Waiting for initialization 89 | 90 | On some platforms it could take some time to initialize TTS engine, and Tts.speak() will fail to speak until the engine is ready. 91 | 92 | To wait for successfull initialization you could use getInitStatus() call. 93 | 94 | ```js 95 | Tts.getInitStatus().then(() => { 96 | Tts.speak('Hello, world!'); 97 | }); 98 | ``` 99 | 100 | ### Ducking 101 | 102 | Enable lowering other applications output level while speaking (also referred to as "ducking"). 103 | 104 | *(not supported on Windows)* 105 | 106 | ```js 107 | Tts.setDucking(true); 108 | ``` 109 | 110 | ### List Voices 111 | 112 | Returns list of available voices 113 | 114 | *(not supported on Android API Level < 21, returns empty list)* 115 | 116 | ```js 117 | Tts.voices().then(voices => console.log(voices)); 118 | 119 | // Prints: 120 | // 121 | // [ { id: 'com.apple.ttsbundle.Moira-compact', name: 'Moira', language: 'en-IE', quality: 300 }, 122 | // ... 123 | // { id: 'com.apple.ttsbundle.Samantha-compact', name: 'Samantha', language: 'en-US' } ] 124 | ``` 125 | 126 | |Voice field|Description| 127 | |-----|-------| 128 | |id |Unique voice identifier (e.g. `com.apple.ttsbundle.Moira-compact`)| 129 | |name |Name of the voice *(iOS only)*| 130 | |language|BCP-47 language code (e.g. 'en-US')| 131 | |quality|Voice quality (300 = normal, 500 = enhanced/very high)| 132 | |latency|Expected synthesizer latency (100 = very low, 500 = very high) *(Android only)*| 133 | |networkConnectionRequired|True when the voice requires an active network connection *(Android only)*| 134 | |notInstalled|True when the voice may need to download additional data to be fully functional *(Android only)*| 135 | 136 | 137 | ### Set default Language 138 | 139 | ```js 140 | Tts.setDefaultLanguage('en-IE'); 141 | ``` 142 | 143 | ### Set default Voice 144 | 145 | Sets default voice, pass one of the voiceId as reported by a call to Tts.voices() 146 | 147 | *(not available on Android API Level < 21)* 148 | 149 | ```js 150 | Tts.setDefaultVoice('com.apple.ttsbundle.Moira-compact'); 151 | ``` 152 | 153 | ### Set default Speech Rate 154 | 155 | Sets default speech rate. The rate parameter is a float where where 0.01 is a slowest rate and 0.99 is the fastest rate. 156 | 157 | ```js 158 | Tts.setDefaultRate(0.6); 159 | ``` 160 | 161 | There is a significant difference to how the rate value is interpreted by iOS, Android and Windows native TTS APIs. To provide unified cross-platform behaviour, translation is applied to the rate value. However, if you want to turn off the translation, you can provide optional `skipTransform` parameter to `Tts.setDefaultRate()` to pass rate value unmodified. 162 | 163 | Do not translate rate parameter: 164 | 165 | ```js 166 | Tts.setDefaultRate(0.6, true); 167 | ``` 168 | 169 | ### Set default Pitch 170 | 171 | Sets default pitch. The pitch parameter is a float where where 1.0 is a normal pitch. On iOS min pitch is 0.5 and max pitch is 2.0. On Windows, min pitch is 0.0 and max pitch is 2.0. 172 | 173 | ```js 174 | Tts.setDefaultPitch(1.5); 175 | ``` 176 | 177 | ### Controls the iOS silent switch behavior 178 | 179 | Platforms: iOS 180 | 181 | - "inherit" (default) - Use the default behavior 182 | - "ignore" - Play audio even if the silent switch is set 183 | - "obey" - Don't play audio if the silent switch is set 184 | 185 | ```js 186 | Tts.setIgnoreSilentSwitch("ignore"); 187 | ``` 188 | 189 | ### Events 190 | 191 | Subscribe to TTS events 192 | 193 | ```js 194 | Tts.addEventListener('tts-start', (event) => console.log("start", event)); 195 | Tts.addEventListener('tts-progress', (event) => console.log("progress", event)); 196 | Tts.addEventListener('tts-finish', (event) => console.log("finish", event)); 197 | Tts.addEventListener('tts-cancel', (event) => console.log("cancel", event)); 198 | ``` 199 | 200 | ### Support for multiple TTS engines 201 | 202 | Platforms: Android 203 | 204 | Functions to list available TTS engines and set an engine to use. 205 | 206 | ```js 207 | Tts.engines().then(engines => console.log(engines)); 208 | Tts.setDefaultEngine('engineName'); 209 | ``` 210 | 211 | ### Install (additional) language data 212 | 213 | Shows the Android Activity to install additional language/voice data. 214 | 215 | ```js 216 | Tts.requestInstallData(); 217 | ``` 218 | 219 | ## Troubleshooting 220 | 221 | ### No text to speech engine installed on Android 222 | 223 | On Android, it may happen that the Text-to-Speech engine is not (yet) installed on the phone. 224 | When this is the case, `Tts.getInitStatus()` returns an error with code `no_engine`. 225 | You can use the following code to request the installation of the default Google Text to Speech App. 226 | The app will need to be restarted afterwards before the changes take affect. 227 | 228 | ```js 229 | Tts.getInitStatus().then(() => { 230 | // ... 231 | }, (err) => { 232 | if (err.code === 'no_engine') { 233 | Tts.requestInstallEngine(); 234 | } 235 | }); 236 | ``` 237 | 238 | ## Example 239 | 240 | There is an example project which shows use of react-native-tts on Android/iOS/Windows: https://github.com/themostaza/react-native-tts-example 241 | 242 | ## License 243 | 244 | The MIT License (MIT) 245 | ===================== 246 | 247 | Copyright © `2016` `Anton Krasovsky` 248 | 249 | Permission is hereby granted, free of charge, to any person 250 | obtaining a copy of this software and associated documentation 251 | files (the “Software”), to deal in the Software without 252 | restriction, including without limitation the rights to use, 253 | copy, modify, merge, publish, distribute, sublicense, and/or sell 254 | copies of the Software, and to permit persons to whom the 255 | Software is furnished to do so, subject to the following 256 | conditions: 257 | 258 | The above copyright notice and this permission notice shall be 259 | included in all copies or substantial portions of the Software. 260 | 261 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, 262 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 263 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 264 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 265 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 266 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 267 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 268 | OTHER DEALINGS IN THE SOFTWARE. 269 | -------------------------------------------------------------------------------- /TextToSpeech.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "TextToSpeech" 3 | s.version = "4.1.1" 4 | s.summary = "React Native Text-To-Speech library for Android and iOS" 5 | 6 | s.homepage = "https://github.com/ak1394/react-native-tts" 7 | 8 | s.license = "MIT" 9 | s.authors = "Anton Krasovsky" 10 | s.platform = :ios, "9.0" 11 | 12 | s.source = { :git => "https://github.com/ak1394/react-native-tts.git" } 13 | 14 | s.source_files = "ios/TextToSpeech/*.{h,m}" 15 | 16 | s.dependency 'React-Core' 17 | end 18 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | def safeExtGet(prop, fallback) { 2 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback 3 | } 4 | 5 | buildscript { 6 | repositories { 7 | jcenter() 8 | } 9 | 10 | dependencies { 11 | classpath 'com.android.tools.build:gradle:1.3.1' 12 | } 13 | } 14 | 15 | apply plugin: 'com.android.library' 16 | 17 | android { 18 | compileSdkVersion safeExtGet('compileSdkVersion', 26) 19 | buildToolsVersion safeExtGet('buildToolsVersion', '26.0.3') 20 | 21 | defaultConfig { 22 | minSdkVersion safeExtGet('minSdkVersion', 16) 23 | targetSdkVersion safeExtGet('targetSdkVersion', 26) 24 | versionCode 1 25 | versionName "1.0" 26 | } 27 | } 28 | 29 | repositories { 30 | mavenCentral() 31 | } 32 | 33 | dependencies { 34 | implementation 'com.facebook.react:react-native:+' 35 | } 36 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /android/src/main/java/net/no_mad/tts/TextToSpeechPackage.java: -------------------------------------------------------------------------------- 1 | package net.no_mad.tts; 2 | 3 | import com.facebook.react.ReactPackage; 4 | import com.facebook.react.bridge.JavaScriptModule; 5 | import com.facebook.react.bridge.NativeModule; 6 | import com.facebook.react.bridge.ReactApplicationContext; 7 | import com.facebook.react.uimanager.ViewManager; 8 | 9 | import java.util.ArrayList; 10 | import java.util.Collections; 11 | import java.util.List; 12 | 13 | public class TextToSpeechPackage implements ReactPackage { 14 | 15 | @Override 16 | public List createNativeModules(ReactApplicationContext reactContext) { 17 | List modules = new ArrayList<>(); 18 | modules.add(new TextToSpeechModule(reactContext)); 19 | return modules; 20 | } 21 | 22 | // Deprecated in RN 0.47 23 | public List> createJSModules() { 24 | return Collections.emptyList(); 25 | } 26 | 27 | @Override 28 | public List createViewManagers(ReactApplicationContext reactContext) { 29 | return Collections.emptyList(); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /example/.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /example/.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | ; We fork some components by platform 3 | .*/*[.]android.js 4 | 5 | ; Ignore "BUCK" generated dirs 6 | /\.buckd/ 7 | 8 | ; Ignore unexpected extra "@providesModule" 9 | .*/node_modules/.*/node_modules/fbjs/.* 10 | 11 | ; Ignore duplicate module providers 12 | ; For RN Apps installed via npm, "Libraries" folder is inside 13 | ; "node_modules/react-native" but in the source repo it is in the root 14 | .*/Libraries/react-native/React.js 15 | 16 | ; Ignore polyfills 17 | .*/Libraries/polyfills/.* 18 | 19 | ; Ignore metro 20 | .*/node_modules/metro/.* 21 | 22 | [include] 23 | 24 | [libs] 25 | node_modules/react-native/Libraries/react-native/react-native-interface.js 26 | node_modules/react-native/flow/ 27 | node_modules/react-native/flow-github/ 28 | 29 | [options] 30 | emoji=true 31 | 32 | module.system=haste 33 | 34 | munge_underscores=true 35 | 36 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' 37 | 38 | module.file_ext=.js 39 | module.file_ext=.jsx 40 | module.file_ext=.json 41 | module.file_ext=.native.js 42 | 43 | suppress_type=$FlowIssue 44 | suppress_type=$FlowFixMe 45 | suppress_type=$FlowFixMeProps 46 | suppress_type=$FlowFixMeState 47 | 48 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 49 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ 50 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 51 | suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError 52 | 53 | [version] 54 | ^0.67.0 55 | -------------------------------------------------------------------------------- /example/.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text 2 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | 33 | # node.js 34 | # 35 | node_modules/ 36 | npm-debug.log 37 | yarn-error.log 38 | 39 | # BUCK 40 | buck-out/ 41 | \.buckd/ 42 | *.keystore 43 | 44 | # fastlane 45 | # 46 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 47 | # screenshots whenever they are needed. 48 | # For more information about the recommended setup visit: 49 | # https://docs.fastlane.tools/best-practices/source-control/ 50 | 51 | */fastlane/report.xml 52 | */fastlane/Preview.html 53 | */fastlane/screenshots 54 | 55 | # Bundle artifact 56 | *.jsbundle 57 | -------------------------------------------------------------------------------- /example/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /example/App.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @flow 3 | */ 4 | 5 | import React, { Component } from "react"; 6 | import { 7 | Platform, 8 | StyleSheet, 9 | Text, 10 | View, 11 | Button, 12 | FlatList, 13 | Slider, 14 | TextInput, 15 | Keyboard 16 | } from "react-native"; 17 | import Tts from "react-native-tts"; 18 | 19 | type Props = {}; 20 | export default class App extends Component { 21 | state = { 22 | voices: [], 23 | ttsStatus: "initiliazing", 24 | selectedVoice: null, 25 | speechRate: 0.5, 26 | speechPitch: 1, 27 | text: "This is an example text" 28 | }; 29 | 30 | constructor(props) { 31 | super(props); 32 | Tts.addEventListener("tts-start", event => 33 | this.setState({ ttsStatus: "started" }) 34 | ); 35 | Tts.addEventListener("tts-finish", event => 36 | this.setState({ ttsStatus: "finished" }) 37 | ); 38 | Tts.addEventListener("tts-cancel", event => 39 | this.setState({ ttsStatus: "cancelled" }) 40 | ); 41 | Tts.setDefaultRate(this.state.speechRate); 42 | Tts.setDefaultPitch(this.state.speechPitch); 43 | Tts.getInitStatus().then(this.initTts); 44 | } 45 | 46 | initTts = async () => { 47 | const voices = await Tts.voices(); 48 | const availableVoices = voices 49 | .filter(v => !v.networkConnectionRequired && !v.notInstalled) 50 | .map(v => { 51 | return { id: v.id, name: v.name, language: v.language }; 52 | }); 53 | let selectedVoice = null; 54 | if (voices && voices.length > 0) { 55 | selectedVoice = voices[0].id; 56 | try { 57 | await Tts.setDefaultLanguage(voices[0].language); 58 | } catch (err) { 59 | // My Samsung S9 has always this error: "Language is not supported" 60 | console.log(`setDefaultLanguage error `, err); 61 | } 62 | await Tts.setDefaultVoice(voices[0].id); 63 | this.setState({ 64 | voices: availableVoices, 65 | selectedVoice, 66 | ttsStatus: "initialized" 67 | }); 68 | } else { 69 | this.setState({ ttsStatus: "initialized" }); 70 | } 71 | }; 72 | 73 | readText = async () => { 74 | Tts.stop(); 75 | Tts.speak(this.state.text); 76 | }; 77 | 78 | setSpeechRate = async rate => { 79 | await Tts.setDefaultRate(rate); 80 | this.setState({ speechRate: rate }); 81 | }; 82 | 83 | setSpeechPitch = async rate => { 84 | await Tts.setDefaultPitch(rate); 85 | this.setState({ speechPitch: rate }); 86 | }; 87 | 88 | onVoicePress = async voice => { 89 | try { 90 | await Tts.setDefaultLanguage(voice.language); 91 | } catch (err) { 92 | // My Samsung S9 has always this error: "Language is not supported" 93 | console.log(`setDefaultLanguage error `, err); 94 | } 95 | await Tts.setDefaultVoice(voice.id); 96 | this.setState({ selectedVoice: voice.id }); 97 | }; 98 | 99 | renderVoiceItem = ({ item }) => { 100 | return ( 101 |