Flutter text to speech with natural voices
In Flutter, text to speech usually means the flutter_tts plugin, which speaks with the voices of the phone itself. That works offline and costs nothing, but the voice changes from one device to the next and rarely sounds like your brand or your characters.
The free SuperClonica engine gives an app the same natural voice on every phone, in two ways: pre-voiced audio files shipped with the app, or a speech server your app calls. This guide shows both with ready Dart code and says when flutter_tts is still the right choice.
Three ways to make a Flutter app speak
Most apps mix them: assets for the interface, a server for user text, the system voice as a fallback.
- flutter_tts: the voices installed on the phone, offline and free, different on every device.
- Pre-voiced assets: every fixed line voiced once with SuperClonica and shipped in the app.
- A speech server: the app sends text to your SuperClonica server and plays the answer, for text that changes.
- SuperClonica speaks 31 languages; Chinese is not supported yet.
Pick a voice free online
On the page of any voice, type a line of your app, 30 to 100 characters, choose the language and press Voice it. In a few seconds you hear whether it fits your app, with no account, also on your phone.
Ship pre-voiced lines as assets
MP3 keeps the app small; a one-sentence line is a few dozen kilobytes.
- Voice each line on your computer with the engine: python -m pip install superclonica-cpu, then superclonica --text "Welcome back!" --voice F1 --lang en --output assets/voice/welcome.mp3.
- List the folder under flutter: assets: in pubspec.yaml.
- Play a line with the audioplayers package: await AudioPlayer().play(AssetSource('voice/welcome.mp3'));
- Assets work offline and add no delay, but every change means a new app version.
Call your own speech server
Run the server on a machine you control: docker run -d -p 8000:8000 -v superclonica-models:/models superclonica/superclonica:cpu. Put it behind HTTPS, which iOS and Android expect by default, and set SUPERCLONICA_API_KEY so only your app can use it. With the http, path_provider and audioplayers packages, a line is one request: final res = await http.post(Uri.parse('https://tts.example.com/synthesize'), headers: {'Content-Type': 'application/json'}, body: jsonEncode({'text': 'Your order is on its way.', 'voice': 'F1', 'lang': 'en'})); final file = File('${(await getTemporaryDirectory()).path}/line.wav'); await file.writeAsBytes(res.bodyBytes); await AudioPlayer().play(DeviceFileSource(file.path)); Add an Authorization: Bearer header with the key, and cache files of lines that repeat.
When flutter_tts is enough
flutter_tts is enough when the voice only has to be understood: reading a notification, an accessibility helper, a prototype, or an app that must speak without any network and has no fixed lines. Choose SuperClonica when the voice is part of the product: a tutor, a game character, a guided meditation, a brand that should sound the same on every phone.