Tauri Plugin TTS (Text-to-Speech)
Native Text-to-Speech plugin for Tauri 2.x applications. Provides cross-platform TTS functionality for desktop (Windows, macOS, Linux) and mobile (iOS, Android).
Features
- π£οΈ Speak text with customizable rate, pitch, and volume
- π Multi-language support - Set language/locale for speech
- ποΈ Voice selection - Get available voices and filter by language
- βΉοΈ Control playback - Stop speech and check speaking status
- π¬ Preview voices - Test voices before using them
- π Queue mode - Interrupt or queue speech requests
- βΈοΈ Pause/Resume - Control playback on iOS (platform-specific)
- π± Cross-platform - Works on desktop and mobile
Installation
Rust
Add the plugin to your Cargo.toml:
[]
= "0.1"
TypeScript
Install the JavaScript guest bindings:
# or
# or
Setup
Register Plugin
In your Tauri app setup:
Permissions
Add permissions to your capabilities/default.json:
For granular permissions, you can specify individual commands:
Usage
Basic Examples
import { speak, stop, getVoices, isSpeaking } from "tauri-plugin-tts-api";
// Simple speech
await speak({ text: "Hello, world!" });
// With options
await speak({
text: "OlΓ‘, mundo!",
language: "pt-BR",
rate: 0.8, // 0.1 to 4.0 (1.0 = normal)
pitch: 1.2, // 0.5 to 2.0 (1.0 = normal)
volume: 1.0, // 0.0 to 1.0 (1.0 = full)
});
// Stop speaking
await stop();
// Get all voices
const voices = await getVoices();
// Get voices for a specific language
const englishVoices = await getVoices("en");
// Check if speaking
const speaking = await isSpeaking();
Advanced Features
Queue Mode
Control how new speech requests interact with ongoing speech:
// Default: interrupt current speech (flush)
await speak({ text: "First sentence" });
await speak({ text: "Second sentence" }); // Interrupts first
// Queue mode: add to queue
await speak({ text: "First sentence" });
await speak({ text: "Second sentence", queueMode: "add" }); // Waits for first
Voice Preview
Preview voices before selecting them:
import { getVoices, previewVoice } from "tauri-plugin-tts-api";
// Get available voices
const voices = await getVoices("en");
// Preview a voice with default text
await previewVoice({ voiceId: voices[0].id });
// Preview with custom text
await previewVoice({
voiceId: voices[0].id,
text: "This is how I sound!",
});
Pause and Resume (iOS only)
import { speak, pauseSpeaking, resumeSpeaking } from "tauri-plugin-tts-api";
await speak({ text: "Long text to speak..." });
// Pause (iOS only)
const pauseResult = await pauseSpeaking();
if (pauseResult.success) {
console.log("Speech paused");
// Resume later
const resumeResult = await resumeSpeaking();
if (resumeResult.success) {
console.log("Speech resumed");
}
} else {
console.log("Pause not supported:", pauseResult.reason);
}
Platform Support
| Platform | Status | Engine |
|---|---|---|
| Windows | β Full support | SAPI |
| macOS | β Full support | AVSpeechSynthesizer |
| Linux | β Full support | speech-dispatcher |
| iOS | β Full support + pause/resume | AVSpeechSynthesizer |
| Android | β Full support | TextToSpeech |
Feature Support Matrix
| Feature | Windows | macOS | Linux | iOS | Android |
|---|---|---|---|---|---|
speak() |
β | β | β | β | β |
stop() |
β | β | β | β | β |
getVoices() |
β | β | β | β | β |
isSpeaking() |
β | β | β | β | β |
previewVoice() |
β | β | β | β | β |
queueMode |
β | β | β | β | β |
pauseSpeaking() |
β | β | β | β | β |
resumeSpeaking() |
β | β | β | β | β |
API Reference
speak(options: SpeakOptions): Promise<void>
Speak the given text.
Options:
text(required): The text to speaklanguage: Language/locale code (e.g., "en-US", "pt-BR")voiceId: Specific voice ID fromgetVoices()(takes priority overlanguage)rate: Speech rate (0.1 to 4.0, where 1.0 = normal speed, 2.0 = double, 0.5 = half)pitch: Voice pitch (0.5 to 2.0, where 1.0 = normal, 2.0 = high, 0.5 = low)volume: Volume level (0.0 to 1.0, where 0.0 = silent, 1.0 = full)queueMode: "flush" (default, interrupts current speech) or "add" (queues after current)
stop(): Promise<void>
Stop any ongoing speech immediately.
getVoices(language?: string): Promise<Voice[]>
Get available voices, optionally filtered by language.
Returns: Array of Voice objects with:
id: Unique voice identifiername: Display namelanguage: Language code (e.g., "en-US")
isSpeaking(): Promise<boolean>
Check if TTS is currently speaking.
previewVoice(options: PreviewVoiceOptions): Promise<void>
Preview a voice with sample text.
Options:
voiceId(required): Voice ID to previewtext: Optional custom preview text (uses default if not provided)
pauseSpeaking(): Promise<PauseResumeResponse> (iOS only)
Pause the current speech.
Returns:
success: Whether pause succeededreason: Optional failure reason (e.g., "Not supported on this platform")
resumeSpeaking(): Promise<PauseResumeResponse> (iOS only)
Resume paused speech.
Returns: Same as pauseSpeaking()
Troubleshooting
Linux: "No TTS backend available"
Solution: Install speech-dispatcher:
# Debian/Ubuntu
# Fedora
# Arch
Android: No voices available
Solution: Ensure a TTS engine is installed:
- Open Android Settings β Accessibility β Text-to-Speech
- Install "Google Text-to-Speech" from Play Store if missing
- Download language data for your desired languages
iOS: Voices sound robotic
Solution: Download enhanced voices:
- Open iOS Settings β Accessibility β Spoken Content β Voices
- Select your language and download "Enhanced Quality" voices
Rate/Pitch not working as expected
Note: Platform engines may have different interpretations:
- Windows SAPI: Limited pitch control
- Linux: Depends on speech-dispatcher backend
- Mobile: Full support for rate and pitch
Pause/Resume not working
Note: pauseSpeaking() and resumeSpeaking() are only supported on iOS. Other platforms will return { success: false, reason: "Not supported" }.
Examples
See the examples/tts-example directory for a complete working demo with React + Material UI.
Building
# Build Rust
# Build TypeScript
# Run tests
License
MIT