|
|
||
|---|---|---|
| .forgejo/workflows | ||
| .githooks | ||
| examples | ||
| src | ||
| .gitignore | ||
| .test-main-branch | ||
| CHANGELOG.md | ||
| INTEGRATION.md | ||
| package.json | ||
| PACKAGE_SUMMARY.md | ||
| README.md | ||
| tsconfig.json | ||
| tsup.config.ts | ||
@transquinnftw/tts-client
Reusable TypeScript client library for text-to-speech (TTS) services. Supports multiple providers with a consistent API.
Features
- Multi-provider support: Browser Web Speech API, Piper TTS, Chatterbox TTS
- Type-safe: Full TypeScript support with strict typing
- Event-driven: Configurable handlers for speech lifecycle events
- Resource management: Proper cleanup and cancellation support
- Zero dependencies: Lightweight with no runtime dependencies
Supported Providers
Browser Web Speech API
Built-in browser speech synthesis. Works in any modern browser.
Piper TTS
Neural text-to-speech via Piper and speech-synthesis-service. High-quality voices with low latency.
Chatterbox TTS
Emotional/expressive TTS with voice cloning capabilities. Configurable emotion exaggeration and voice characteristics.
Installation
npm install @transquinnftw/tts-client
# or
pnpm add @transquinnftw/tts-client
# or
yarn add @transquinnftw/tts-client
Usage
Browser Web Speech API
import { BrowserTTSClient } from '@transquinnftw/tts-client';
const client = new BrowserTTSClient(
{
rate: 1.0,
pitch: 1.0,
volume: 1.0,
},
{
onStart: () => console.log('Speech started'),
onEnd: () => console.log('Speech ended'),
onError: (error) => console.error('Speech error:', error),
}
);
// Get available voices
const voices = await client.waitForVoices();
console.log('Available voices:', voices);
// Select a voice
const englishVoice = voices.find(v => v.lang.startsWith('en'));
client.updateConfig({ voice: englishVoice });
// Speak
client.speak('Hello, world!');
// Control playback
client.pause();
client.resume();
client.cancel();
// Cleanup
client.dispose();
Piper TTS
import { PiperTTSClient } from '@transquinnftw/tts-client';
const client = new PiperTTSClient(
{
endpoint: 'http://localhost:5000',
voice: 'en_US-lessac-medium',
speed: 1.0,
},
{
onStart: () => console.log('Synthesis started'),
onEnd: () => console.log('Synthesis completed'),
onError: (error) => console.error('Synthesis error:', error),
}
);
// Synthesize and play
await client.speak('This is Piper neural TTS.');
// Cancel
client.cancel();
// Change configuration
client.updateConfig({ voice: 'en_US-amy-medium', speed: 1.2 });
// Cleanup
client.dispose();
Chatterbox TTS
import { ChatterboxTTSClient } from '@transquinnftw/tts-client';
const client = new ChatterboxTTSClient(
{
endpoint: 'http://localhost:8000',
voiceId: 'custom-voice-1',
exaggeration: 0.7,
cfgWeight: 3.5,
},
{
onStart: () => console.log('Synthesis started'),
onEnd: () => console.log('Synthesis completed'),
onError: (error) => console.error('Synthesis error:', error),
}
);
// Synthesize with emotion
await client.speak('I am excited about this feature!');
// Adjust emotion parameters
client.updateConfig({ exaggeration: 0.9, cfgWeight: 4.0 });
// Cleanup
client.dispose();
API Reference
Common Interface: TTSClient
All clients implement the TTSClient interface:
interface TTSClient {
speak(text: string): Promise<void> | void;
cancel(): void;
isSpeaking(): boolean;
}
Event Handlers: TTSEventHandlers
interface TTSEventHandlers {
onStart?: () => void;
onEnd?: () => void;
onError?: (error: Error) => void;
onPause?: () => void;
onResume?: () => void;
}
BrowserTTSClient
Methods:
speak(text: string): void- Synthesize and speak textpause(): void- Pause ongoing speechresume(): void- Resume paused speechcancel(): void- Cancel ongoing speechisSpeaking(): boolean- Check if speakingisPaused(): boolean- Check if pausedgetVoices(): SpeechSynthesisVoice[]- Get available voiceswaitForVoices(): Promise<SpeechSynthesisVoice[]>- Wait for voices to loadupdateConfig(config: Partial<BrowserSpeechConfig>): void- Update configurationdispose(): void- Clean up resources
Static Methods:
isSupported(): boolean- Check if Web Speech API is supported
PiperTTSClient
Methods:
speak(text: string): Promise<void>- Synthesize and speak textcancel(): void- Cancel ongoing synthesisisSpeaking(): boolean- Check if speakingupdateConfig(config: Partial<PiperConfig>): void- Update configurationdispose(): void- Clean up resources
ChatterboxTTSClient
Methods:
speak(text: string): Promise<void>- Synthesize and speak textcancel(): void- Cancel ongoing synthesisisSpeaking(): boolean- Check if speakingupdateConfig(config: Partial<ChatterboxConfig>): void- Update configurationdispose(): void- Clean up resources
Types
Core Types
type SpeechProvider = 'browser' | 'piper' | 'chatterbox';
interface PiperConfig {
endpoint: string;
voice: string;
speed?: number;
}
interface ChatterboxConfig {
endpoint: string;
voiceId?: string | null;
exaggeration?: number;
cfgWeight?: number;
}
interface BrowserSpeechConfig {
voice?: SpeechSynthesisVoice | null;
rate?: number;
pitch?: number;
volume?: number;
}
Voice Types
interface PiperVoice {
id: string;
name: string;
language: string;
quality: 'low' | 'medium' | 'high' | 'x-low';
modelPath?: string;
packageId: string;
}
interface SavedVoicePreset {
id: string;
name: string;
voiceId: string;
voiceName: string;
exaggeration: number;
cfgWeight: number;
createdAt: string;
updatedAt: string;
}
interface FavoriteVoice {
id: string;
provider: SpeechProvider;
voiceId: string;
displayName: string;
addedAt: string;
}
Error Handling
All clients provide error handling through the onError event handler:
const client = new PiperTTSClient(config, {
onError: (error) => {
console.error('TTS error:', error.message);
// Handle error appropriately
}
});
Errors are also thrown from speak() methods (for Piper and Chatterbox), so you can use try/catch:
try {
await client.speak('Hello');
} catch (error) {
console.error('Speech failed:', error);
}
Resource Management
Always call dispose() when done with a client to clean up resources:
const client = new PiperTTSClient(config);
// Use the client...
await client.speak('Hello');
// Clean up when done
client.dispose();
Browser Compatibility
- BrowserTTSClient: Requires Web Speech API support (modern browsers)
- PiperTTSClient: Requires fetch API and Audio element
- ChatterboxTTSClient: Requires fetch API, Audio element, and atob (base64 decoding)
Architecture
This package follows SOLID principles:
- Single Responsibility: Each client handles one TTS provider
- Open/Closed: Easy to extend with new providers
- Liskov Substitution: All clients implement
TTSClientinterface - Interface Segregation: Clean, focused interfaces
- Dependency Inversion: Depend on abstractions (TTSClient interface)
License
MIT
Contributing
Issues and pull requests welcome at the GitLab repository.