par-cli-tts 0.4.2__tar.gz → 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {par_cli_tts-0.4.2 → par_cli_tts-0.5.0}/.claude/output-styles/tts-summary.md +10 -10
- par_cli_tts-0.5.0/.gitignore +111 -0
- {par_cli_tts-0.4.2 → par_cli_tts-0.5.0}/PKG-INFO +186 -92
- {par_cli_tts-0.4.2 → par_cli_tts-0.5.0}/README.md +173 -80
- par_cli_tts-0.5.0/par_cli_tts/__init__.py +18 -0
- par_cli_tts-0.5.0/par_cli_tts/providers/__init__.py +4 -0
- par_cli_tts-0.5.0/par_tts/__init__.py +67 -0
- par_cli_tts-0.4.2/src/utils.py → par_cli_tts-0.5.0/par_tts/audio.py +32 -146
- par_cli_tts-0.5.0/par_tts/cli/__init__.py +1 -0
- {par_cli_tts-0.4.2/src → par_cli_tts-0.5.0/par_tts/cli}/config_file.py +75 -10
- {par_cli_tts-0.4.2/src → par_cli_tts-0.5.0/par_tts/cli}/install_claude_style.py +4 -34
- {par_cli_tts-0.4.2/src → par_cli_tts-0.5.0/par_tts/cli}/kokoro_cli.py +2 -2
- {par_cli_tts-0.4.2/src → par_cli_tts-0.5.0/par_tts/cli}/tts_cli.py +244 -120
- {par_cli_tts-0.4.2/src → par_cli_tts-0.5.0/par_tts}/defaults.py +5 -1
- par_cli_tts-0.5.0/par_tts/errors.py +136 -0
- {par_cli_tts-0.4.2/src → par_cli_tts-0.5.0/par_tts}/http_client.py +2 -3
- {par_cli_tts-0.4.2/src → par_cli_tts-0.5.0/par_tts}/model_downloader.py +40 -75
- par_cli_tts-0.5.0/par_tts/providers/__init__.py +39 -0
- {par_cli_tts-0.4.2/src → par_cli_tts-0.5.0/par_tts}/providers/base.py +83 -11
- par_cli_tts-0.5.0/par_tts/providers/deepgram.py +297 -0
- {par_cli_tts-0.4.2/src → par_cli_tts-0.5.0/par_tts}/providers/elevenlabs.py +9 -19
- par_cli_tts-0.5.0/par_tts/providers/gemini.py +221 -0
- {par_cli_tts-0.4.2/src → par_cli_tts-0.5.0/par_tts}/providers/kokoro_onnx.py +18 -50
- {par_cli_tts-0.4.2/src → par_cli_tts-0.5.0/par_tts}/providers/openai.py +13 -34
- par_cli_tts-0.5.0/par_tts/py.typed +0 -0
- par_cli_tts-0.5.0/par_tts/utils.py +107 -0
- {par_cli_tts-0.4.2/src → par_cli_tts-0.5.0/par_tts}/voice_cache.py +91 -38
- {par_cli_tts-0.4.2 → par_cli_tts-0.5.0}/pyproject.toml +35 -25
- par_cli_tts-0.4.2/.gitignore +0 -272
- par_cli_tts-0.4.2/src/__init__.py +0 -3
- par_cli_tts-0.4.2/src/config.py +0 -66
- par_cli_tts-0.4.2/src/errors.py +0 -148
- par_cli_tts-0.4.2/src/providers/__init__.py +0 -14
- {par_cli_tts-0.4.2 → par_cli_tts-0.5.0}/LICENSE +0 -0
- {par_cli_tts-0.4.2/src → par_cli_tts-0.5.0/par_cli_tts}/py.typed +0 -0
- {par_cli_tts-0.4.2/src → par_cli_tts-0.5.0/par_tts/cli}/console.py +0 -0
|
@@ -8,7 +8,7 @@ description: Audio task completion announcements with TTS
|
|
|
8
8
|
You are Claude Code with an experimental TTS announcement feature designed to communicate directly with the user about what you've accomplished.
|
|
9
9
|
|
|
10
10
|
## Variables
|
|
11
|
-
- **USER_NAME**:
|
|
11
|
+
- **USER_NAME**: {{USER_NAME}}
|
|
12
12
|
|
|
13
13
|
## Standard Behavior
|
|
14
14
|
Respond normally to all user requests, using your full capabilities for:
|
|
@@ -23,8 +23,8 @@ Respond normally to all user requests, using your full capabilities for:
|
|
|
23
23
|
**At the very END of EVERY response**, you MUST provide an audio summary for the user:
|
|
24
24
|
|
|
25
25
|
1. Write a clear separator: `---`
|
|
26
|
-
2. Add the heading: `## Audio Summary for
|
|
27
|
-
3. Craft a message that speaks DIRECTLY to
|
|
26
|
+
2. Add the heading: `## Audio Summary for {{USER_NAME}}`
|
|
27
|
+
3. Craft a message that speaks DIRECTLY to {{USER_NAME}} about what you did for them
|
|
28
28
|
4. **IMMEDIATELY execute the TTS command using the Bash tool** - do NOT just display it in a code block
|
|
29
29
|
|
|
30
30
|
### How to Execute the TTS Command
|
|
@@ -33,13 +33,13 @@ You MUST use the Bash tool to actually run the command. Do NOT wrap it in a mark
|
|
|
33
33
|
|
|
34
34
|
**CORRECT** - Execute with Bash tool:
|
|
35
35
|
```
|
|
36
|
-
[Bash tool call with command: par-tts "
|
|
36
|
+
[Bash tool call with command: par-tts "{{USER_NAME}}, I've completed the task."]
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
**WRONG** - Just displaying (DO NOT DO THIS):
|
|
40
40
|
```markdown
|
|
41
41
|
```bash
|
|
42
|
-
par-tts "
|
|
42
|
+
par-tts "{{USER_NAME}}, I've completed the task."
|
|
43
43
|
```
|
|
44
44
|
```
|
|
45
45
|
|
|
@@ -47,9 +47,9 @@ The user should hear the audio playback, not just see the command text.
|
|
|
47
47
|
|
|
48
48
|
## Communication Guidelines
|
|
49
49
|
|
|
50
|
-
- **Address
|
|
50
|
+
- **Address {{USER_NAME}} directly** when appropriate: "{{USER_NAME}}, I've updated your..." or "Fixed the bug in..."
|
|
51
51
|
- **Focus on outcomes** for the user: what they can now do, what's been improved
|
|
52
|
-
- **Be conversational** - speak as if telling
|
|
52
|
+
- **Be conversational** - speak as if telling {{USER_NAME}} what you just did
|
|
53
53
|
- **Highlight value** - emphasize what's useful about the change
|
|
54
54
|
- **Keep it concise** - one clear sentence (under 20 words)
|
|
55
55
|
|
|
@@ -59,11 +59,11 @@ The user should hear the audio playback, not just see the command text.
|
|
|
59
59
|
|
|
60
60
|
---
|
|
61
61
|
|
|
62
|
-
## Audio Summary for
|
|
62
|
+
## Audio Summary for {{USER_NAME}}
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
{{USER_NAME}}, I've created three new output styles to customize how you receive information.
|
|
65
65
|
|
|
66
|
-
[Bash tool call: par-tts "
|
|
66
|
+
[Bash tool call: par-tts "{{USER_NAME}}, I've created three new output styles to customize how you receive information."]
|
|
67
67
|
|
|
68
68
|
## Important Rules
|
|
69
69
|
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
dist/
|
|
13
|
+
*.egg-info/
|
|
14
|
+
*.egg
|
|
15
|
+
MANIFEST
|
|
16
|
+
|
|
17
|
+
# PyInstaller
|
|
18
|
+
*.manifest
|
|
19
|
+
*.spec
|
|
20
|
+
|
|
21
|
+
# Installer logs
|
|
22
|
+
pip-log.txt
|
|
23
|
+
pip-delete-this-directory.txt
|
|
24
|
+
|
|
25
|
+
# Unit test / coverage reports
|
|
26
|
+
htmlcov/
|
|
27
|
+
.tox/
|
|
28
|
+
.nox/
|
|
29
|
+
.coverage
|
|
30
|
+
.coverage.*
|
|
31
|
+
.cache
|
|
32
|
+
coverage.xml
|
|
33
|
+
*.cover
|
|
34
|
+
.hypothesis/
|
|
35
|
+
.pytest_cache/
|
|
36
|
+
|
|
37
|
+
# Environments
|
|
38
|
+
.env
|
|
39
|
+
.env.local
|
|
40
|
+
.env.*.local
|
|
41
|
+
.venv
|
|
42
|
+
venv/
|
|
43
|
+
env/
|
|
44
|
+
|
|
45
|
+
# Type checkers
|
|
46
|
+
.mypy_cache/
|
|
47
|
+
.dmypy.json
|
|
48
|
+
.pyre/
|
|
49
|
+
.pytype/
|
|
50
|
+
.ruff_cache/
|
|
51
|
+
|
|
52
|
+
# Editors / IDEs
|
|
53
|
+
.idea/
|
|
54
|
+
*.iml
|
|
55
|
+
.vscode/
|
|
56
|
+
*.code-workspace
|
|
57
|
+
.history/
|
|
58
|
+
*.sublime-project
|
|
59
|
+
*.sublime-workspace
|
|
60
|
+
|
|
61
|
+
# OS
|
|
62
|
+
.DS_Store
|
|
63
|
+
Thumbs.db
|
|
64
|
+
$RECYCLE.BIN/
|
|
65
|
+
|
|
66
|
+
# Project: generated audio outputs
|
|
67
|
+
*.mp3
|
|
68
|
+
*.wav
|
|
69
|
+
*.m4a
|
|
70
|
+
*.ogg
|
|
71
|
+
*.flac
|
|
72
|
+
audio_output/
|
|
73
|
+
temp_audio/
|
|
74
|
+
test_*.mp3
|
|
75
|
+
test_*.wav
|
|
76
|
+
|
|
77
|
+
# Profiling
|
|
78
|
+
*.prof
|
|
79
|
+
*.lprof
|
|
80
|
+
profile_report.json
|
|
81
|
+
*.pyinstrument
|
|
82
|
+
|
|
83
|
+
# Local-only / scratch files
|
|
84
|
+
*.tmp
|
|
85
|
+
*.bak
|
|
86
|
+
*.swp
|
|
87
|
+
*.local
|
|
88
|
+
*.local.*
|
|
89
|
+
*-mcp.json
|
|
90
|
+
config.local.yaml
|
|
91
|
+
config.local.yml
|
|
92
|
+
claude_scratch/
|
|
93
|
+
|
|
94
|
+
# Logs
|
|
95
|
+
logs/
|
|
96
|
+
*.log
|
|
97
|
+
|
|
98
|
+
# Claude Code session state and artifacts
|
|
99
|
+
.claude/.cc2cc-session-id
|
|
100
|
+
.claude/scheduled_tasks.lock
|
|
101
|
+
.claude/statusline-*.local.json
|
|
102
|
+
.claude/settings.local.json
|
|
103
|
+
.claude/*.local.json
|
|
104
|
+
|
|
105
|
+
# Documentation builds
|
|
106
|
+
docs/_build/
|
|
107
|
+
docs/.doctrees/
|
|
108
|
+
|
|
109
|
+
# Misc
|
|
110
|
+
settings.local.json
|
|
111
|
+
docs/superpowers
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: par-cli-tts
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: PAR
|
|
3
|
+
Version: 0.5.0
|
|
4
|
+
Summary: PAR TTS — Text-to-speech library and CLI supporting ElevenLabs, OpenAI, Kokoro ONNX, Deepgram, and Gemini
|
|
5
5
|
Project-URL: Homepage, https://github.com/paulrobello/par-cli-tts
|
|
6
6
|
Project-URL: Documentation, https://github.com/paulrobello/par-cli-tts/blob/main/README.md
|
|
7
7
|
Project-URL: Repository, https://github.com/paulrobello/par-cli-tts
|
|
@@ -32,7 +32,7 @@ License: MIT License
|
|
|
32
32
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
33
33
|
SOFTWARE.
|
|
34
34
|
License-File: LICENSE
|
|
35
|
-
Keywords: audio,cli,elevenlabs,text-to-speech,tts
|
|
35
|
+
Keywords: audio,cli,deepgram,elevenlabs,gemini,kokoro,library,openai,text-to-speech,tts
|
|
36
36
|
Classifier: Development Status :: 4 - Beta
|
|
37
37
|
Classifier: Environment :: Console
|
|
38
38
|
Classifier: Intended Audience :: Developers
|
|
@@ -50,15 +50,16 @@ Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
|
|
|
50
50
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
51
51
|
Classifier: Typing :: Typed
|
|
52
52
|
Requires-Python: >=3.11
|
|
53
|
-
Requires-Dist: elevenlabs
|
|
54
|
-
Requires-Dist:
|
|
55
|
-
Requires-Dist:
|
|
56
|
-
Requires-Dist:
|
|
57
|
-
Requires-Dist:
|
|
58
|
-
Requires-Dist:
|
|
59
|
-
Requires-Dist:
|
|
60
|
-
Requires-Dist:
|
|
61
|
-
Requires-Dist:
|
|
53
|
+
Requires-Dist: elevenlabs<3.0,>=2.44.0
|
|
54
|
+
Requires-Dist: httpx<1.0,>=0.28.1
|
|
55
|
+
Requires-Dist: kokoro-onnx<1.0,>=0.5.0
|
|
56
|
+
Requires-Dist: openai<3.0,>=2.32.0
|
|
57
|
+
Requires-Dist: platformdirs<5.0,>=4.9.6
|
|
58
|
+
Requires-Dist: python-dotenv<2.0,>=1.2.2
|
|
59
|
+
Requires-Dist: pyyaml<7.0,>=6.0.3
|
|
60
|
+
Requires-Dist: rich<20.0,>=15.0.0
|
|
61
|
+
Requires-Dist: soundfile<1.0,>=0.13.1
|
|
62
|
+
Requires-Dist: typer<1.0,>=0.24.2
|
|
62
63
|
Description-Content-Type: text/markdown
|
|
63
64
|
|
|
64
65
|
# PAR CLI TTS
|
|
@@ -68,10 +69,13 @@ Description-Content-Type: text/markdown
|
|
|
68
69
|

|
|
69
70
|
|
|
70
71
|

|
|
71
|
-

|
|
72
73
|

|
|
73
74
|
|
|
74
|
-
A
|
|
75
|
+
A text-to-speech library and command-line tool supporting multiple TTS providers (ElevenLabs, OpenAI, Kokoro ONNX, Deepgram, and Google Gemini) with intelligent voice caching, name resolution, and flexible output options.
|
|
76
|
+
|
|
77
|
+
**Use as a CLI** — `par-tts "Hello world"`
|
|
78
|
+
**Use as a library** — `from par_tts import get_provider`
|
|
75
79
|
|
|
76
80
|
[](https://buymeacoffee.com/probello3)
|
|
77
81
|
|
|
@@ -103,52 +107,22 @@ A powerful command-line text-to-speech tool supporting multiple TTS providers (E
|
|
|
103
107
|
|
|
104
108
|
## What's New
|
|
105
109
|
|
|
106
|
-
### v0.
|
|
107
|
-
- **
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
- **
|
|
113
|
-
|
|
114
|
-
- **
|
|
115
|
-
|
|
116
|
-
### v0.3.0
|
|
117
|
-
- Major code refactoring with better modularity and code organization
|
|
118
|
-
- New utility modules for shared console, defaults, and HTTP client
|
|
119
|
-
- Test suite with 46 tests for better reliability
|
|
120
|
-
- Documentation synced to match current implementation
|
|
121
|
-
|
|
122
|
-
### v0.2.2
|
|
123
|
-
- Updated all HTTP requests and downloaders to ignore SSL certificate errors
|
|
124
|
-
- Improves compatibility with corporate proxies and development environments
|
|
125
|
-
|
|
126
|
-
### v0.2.1
|
|
127
|
-
- Updated dependencies
|
|
128
|
-
- Ensured Python 3.13 compatibility
|
|
129
|
-
|
|
130
|
-
### v0.2.0
|
|
131
|
-
|
|
132
|
-
**Major Update**: Configuration files, smarter caching, consistent error handling, and more!
|
|
133
|
-
|
|
134
|
-
### New Features
|
|
135
|
-
- **Configuration File Support** - Set defaults in `~/.config/par-tts/config.yaml`
|
|
136
|
-
- **Smarter Voice Cache** - Change detection, manual refresh, and voice sample caching
|
|
137
|
-
- **Consistent Error Handling** - Clear error messages with proper exit codes
|
|
138
|
-
- **Multiple Input Methods** - Direct text, stdin piping, and file input (`@filename`)
|
|
139
|
-
- **Volume Control** - Adjust playback volume (0.0 to 5.0) across all platforms (macOS, Linux, Windows)
|
|
140
|
-
- **Voice Preview** - Test voices with sample text before using
|
|
110
|
+
### v0.5.0 (Latest)
|
|
111
|
+
- **Library API surface** -- `import par_tts` is now a proper Python library with
|
|
112
|
+
`get_provider()`, `list_providers()`, and typed per-provider options.
|
|
113
|
+
See [Library Usage](#library-usage) for examples.
|
|
114
|
+
- **Import package renamed** -- canonical import is now `par_tts` (was `par_cli_tts`).
|
|
115
|
+
Old imports still work with a deprecation warning.
|
|
116
|
+
- **Decoupled from Rich** -- library modules use `stdlib logging` instead of Rich
|
|
117
|
+
console, enabling headless/embedded use without Rich installed.
|
|
118
|
+
- **Audio playback extracted** -- `play_audio_bytes` and `play_audio_with_player`
|
|
119
|
+
moved to dedicated `par_tts.audio` module.
|
|
141
120
|
|
|
142
|
-
|
|
143
|
-
- **Enhanced Security** - API key sanitization in debug output
|
|
144
|
-
- **Memory Efficiency** - Stream audio directly to files without buffering
|
|
145
|
-
- **Model Verification** - SHA256 checksum verification for downloads
|
|
146
|
-
- **Better CLI** - All options now have short versions for quick access
|
|
147
|
-
- **Cache Management** - New commands for cache refresh and cleanup
|
|
121
|
+
For the full version history, see [CHANGELOG.md](CHANGELOG.md).
|
|
148
122
|
|
|
149
123
|
## Features
|
|
150
124
|
|
|
151
|
-
- **Multiple TTS Providers** - Support for ElevenLabs, OpenAI,
|
|
125
|
+
- **Multiple TTS Providers** - Support for ElevenLabs, OpenAI, Kokoro ONNX, Deepgram (Aura / Aura-2), and Google Gemini with easy provider switching
|
|
152
126
|
- **Configuration File** - Set default preferences in YAML config file (`~/.config/par-tts/config.yaml`)
|
|
153
127
|
- **Flexible Input Methods** - Accept text from command line, stdin pipe, or files (`@filename`)
|
|
154
128
|
- **Voice Name Support** - Use voice names like "Juniper" or "nova" instead of cryptic IDs
|
|
@@ -171,6 +145,8 @@ A powerful command-line text-to-speech tool supporting multiple TTS providers (E
|
|
|
171
145
|
- **ElevenLabs SDK** - Official ElevenLabs API client for high-quality voices
|
|
172
146
|
- **OpenAI SDK** - Official OpenAI API client for TTS
|
|
173
147
|
- **Kokoro ONNX** - Offline TTS with ONNX Runtime for fast inference
|
|
148
|
+
- **Deepgram REST** - Direct httpx integration for Aura / Aura-2 voices (no SDK)
|
|
149
|
+
- **Google Gemini REST** - `generateContent` audio modality with PCM→WAV wrapping (no SDK)
|
|
174
150
|
- **Typer** - Modern CLI framework with automatic help generation
|
|
175
151
|
- **Rich** - Terminal formatting and beautiful output
|
|
176
152
|
- **Pydantic** - Data validation and settings management
|
|
@@ -447,25 +423,41 @@ Edit `~/.claude/output-styles/tts-summary.md` to personalize the experience:
|
|
|
447
423
|
Create a configuration file to set your default preferences:
|
|
448
424
|
|
|
449
425
|
```bash
|
|
450
|
-
# Create a sample config file
|
|
426
|
+
# Create a sample config file (prompts before overwriting if one exists)
|
|
451
427
|
par-tts --create-config
|
|
452
428
|
|
|
429
|
+
# Skip the overwrite prompt with -y / --yes (e.g. for scripted setup)
|
|
430
|
+
par-tts --create-config -y
|
|
431
|
+
|
|
453
432
|
# Edit the config file
|
|
454
|
-
$EDITOR ~/.config/par-tts/config.yaml
|
|
433
|
+
$EDITOR ~/.config/par-tts/config.yaml # macOS: ~/Library/Application\ Support/par-tts/config.yaml
|
|
455
434
|
```
|
|
456
435
|
|
|
457
436
|
Example configuration file:
|
|
458
437
|
|
|
459
438
|
```yaml
|
|
460
|
-
# Default provider (elevenlabs, openai, kokoro-onnx)
|
|
439
|
+
# Default provider (elevenlabs, openai, kokoro-onnx, deepgram, gemini)
|
|
461
440
|
provider: kokoro-onnx
|
|
462
441
|
|
|
463
|
-
#
|
|
442
|
+
# Legacy default voice. Only applied when the active provider matches `provider`
|
|
443
|
+
# above — prefer the per-provider `voices:` mapping below for multi-provider use.
|
|
464
444
|
voice: Rachel
|
|
465
445
|
|
|
446
|
+
# Per-provider default voices (recommended). Each entry is used when that provider
|
|
447
|
+
# is active (via -P/--provider, TTS_PROVIDER, or `provider` above), regardless of
|
|
448
|
+
# which provider this file was originally written for. Takes precedence over `voice`.
|
|
449
|
+
voices:
|
|
450
|
+
elevenlabs: Juniper
|
|
451
|
+
openai: nova
|
|
452
|
+
kokoro-onnx: af_sarah
|
|
453
|
+
deepgram: aura-2-thalia-en
|
|
454
|
+
gemini: Kore
|
|
455
|
+
|
|
466
456
|
# API keys (optional - can also be set via environment variables)
|
|
467
457
|
# elevenlabs_api_key: your-elevenlabs-api-key-here
|
|
468
458
|
# openai_api_key: your-openai-api-key-here
|
|
459
|
+
# deepgram_api_key: your-deepgram-api-key-here
|
|
460
|
+
# gemini_api_key: your-google-gemini-api-key-here
|
|
469
461
|
|
|
470
462
|
# Output settings
|
|
471
463
|
output_dir: ~/Documents/audio
|
|
@@ -484,6 +476,17 @@ play_audio: true
|
|
|
484
476
|
debug: false
|
|
485
477
|
```
|
|
486
478
|
|
|
479
|
+
**Voice resolution order** (highest priority first):
|
|
480
|
+
|
|
481
|
+
1. CLI `-v` / `--voice` or `TTS_VOICE_ID` env var
|
|
482
|
+
2. `voices.<active-provider>` entry in the config file
|
|
483
|
+
3. The legacy `voice` field, but only when the active provider equals `config.provider`
|
|
484
|
+
4. Provider-specific env var (`ELEVENLABS_VOICE_ID`, `OPENAI_VOICE_ID`, `KOKORO_VOICE_ID`, `DEEPGRAM_VOICE_ID`, `GEMINI_VOICE_ID`)
|
|
485
|
+
5. Built-in provider default
|
|
486
|
+
|
|
487
|
+
This means switching providers with `-P openai` will pick the right voice for that
|
|
488
|
+
provider — it will not silently inherit a voice ID belonging to a different one.
|
|
489
|
+
|
|
487
490
|
### Environment Variables
|
|
488
491
|
|
|
489
492
|
Create a `.env` file in your project directory with your API keys:
|
|
@@ -492,19 +495,23 @@ Create a `.env` file in your project directory with your API keys:
|
|
|
492
495
|
# Required API keys (at least one for cloud providers)
|
|
493
496
|
ELEVENLABS_API_KEY=your_elevenlabs_key_here
|
|
494
497
|
OPENAI_API_KEY=your_openai_key_here
|
|
498
|
+
DEEPGRAM_API_KEY=your_deepgram_key_here # DG_API_KEY is also accepted
|
|
499
|
+
GEMINI_API_KEY=your_gemini_key_here # GOOGLE_API_KEY is also accepted
|
|
495
500
|
|
|
496
501
|
# Optional: Kokoro ONNX model paths (auto-downloads if not set)
|
|
497
502
|
# Set these only if you want to use custom model locations
|
|
498
503
|
# KOKORO_MODEL_PATH=/path/to/kokoro-v1.0.onnx
|
|
499
504
|
# KOKORO_VOICE_PATH=/path/to/voices-v1.0.bin
|
|
500
505
|
|
|
501
|
-
# Optional: Default provider (elevenlabs, openai,
|
|
506
|
+
# Optional: Default provider (elevenlabs, openai, kokoro-onnx, deepgram, or gemini)
|
|
502
507
|
TTS_PROVIDER=kokoro-onnx
|
|
503
508
|
|
|
504
509
|
# Optional: Default voices
|
|
505
|
-
ELEVENLABS_VOICE_ID=Juniper
|
|
506
|
-
OPENAI_VOICE_ID=nova
|
|
507
|
-
KOKORO_VOICE_ID=af_sarah
|
|
510
|
+
ELEVENLABS_VOICE_ID=Juniper # or use voice ID
|
|
511
|
+
OPENAI_VOICE_ID=nova # alloy, echo, fable, onyx, nova, shimmer, ...
|
|
512
|
+
KOKORO_VOICE_ID=af_sarah # See available voices with --list
|
|
513
|
+
DEEPGRAM_VOICE_ID=aura-2-thalia-en # Aura/Aura-2 model ID (the model IS the voice)
|
|
514
|
+
GEMINI_VOICE_ID=Kore # One of 30 prebuilt names (Kore, Zephyr, Aoede, ...)
|
|
508
515
|
|
|
509
516
|
# Optional: General voice (overrides provider-specific)
|
|
510
517
|
TTS_VOICE_ID=Juniper
|
|
@@ -512,6 +519,52 @@ TTS_VOICE_ID=Juniper
|
|
|
512
519
|
|
|
513
520
|
## Usage
|
|
514
521
|
|
|
522
|
+
### Library Usage
|
|
523
|
+
|
|
524
|
+
PAR TTS can be used as a Python library in your own projects:
|
|
525
|
+
|
|
526
|
+
```python
|
|
527
|
+
from par_tts import get_provider, list_providers, Voice
|
|
528
|
+
|
|
529
|
+
# List available providers
|
|
530
|
+
print(list_providers())
|
|
531
|
+
# ['deepgram', 'elevenlabs', 'gemini', 'kokoro-onnx', 'openai']
|
|
532
|
+
|
|
533
|
+
# Get a provider class and instantiate it
|
|
534
|
+
KokoroTTS = get_provider("kokoro-onnx")
|
|
535
|
+
provider = KokoroTTS() # no API key needed for offline providers
|
|
536
|
+
|
|
537
|
+
# Generate speech
|
|
538
|
+
audio = provider.generate_speech("Hello world", voice="af_sarah")
|
|
539
|
+
|
|
540
|
+
# Save to file
|
|
541
|
+
provider.save_audio(audio, "output.wav")
|
|
542
|
+
|
|
543
|
+
# List available voices
|
|
544
|
+
voices: list[Voice] = provider.list_voices()
|
|
545
|
+
for voice in voices:
|
|
546
|
+
print(f" {voice.id}: {voice.name}")
|
|
547
|
+
|
|
548
|
+
# Resolve a voice name to an ID
|
|
549
|
+
voice_id = provider.resolve_voice("sarah") # partial match -> "af_sarah"
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
Cloud providers require an API key:
|
|
553
|
+
|
|
554
|
+
```python
|
|
555
|
+
from par_tts import get_provider
|
|
556
|
+
|
|
557
|
+
OpenAITTS = get_provider("openai")
|
|
558
|
+
provider = OpenAITTS(api_key="sk-...")
|
|
559
|
+
|
|
560
|
+
audio = provider.generate_speech(
|
|
561
|
+
"Hello from OpenAI",
|
|
562
|
+
voice="nova",
|
|
563
|
+
speed=1.2,
|
|
564
|
+
)
|
|
565
|
+
provider.save_audio(audio, "greeting.mp3")
|
|
566
|
+
```
|
|
567
|
+
|
|
515
568
|
### Quick Start
|
|
516
569
|
|
|
517
570
|
If installed from PyPI:
|
|
@@ -674,7 +727,7 @@ par-tts --refresh-cache --provider elevenlabs
|
|
|
674
727
|
par-tts --clear-cache-samples --provider elevenlabs
|
|
675
728
|
|
|
676
729
|
# Or use Makefile commands
|
|
677
|
-
make
|
|
730
|
+
make update-cache # Force refresh voice cache
|
|
678
731
|
make clear-cache # Clear voice cache including samples
|
|
679
732
|
```
|
|
680
733
|
|
|
@@ -693,7 +746,7 @@ make clear-cache # Clear voice cache including samples
|
|
|
693
746
|
| Option | Short | Description | Default |
|
|
694
747
|
|--------|-------|-------------|---------|
|
|
695
748
|
| `text` | | Text to convert to speech (required) | |
|
|
696
|
-
| `--provider` | `-P` | TTS provider to use (elevenlabs, openai, kokoro-onnx) | kokoro-onnx |
|
|
749
|
+
| `--provider` | `-P` | TTS provider to use (elevenlabs, openai, kokoro-onnx, deepgram, gemini) | kokoro-onnx |
|
|
697
750
|
| `--voice` | `-v` | Voice name or ID to use | Provider default |
|
|
698
751
|
| `--output` | `-o` | Output file path | None (temp file) |
|
|
699
752
|
| `--model` | `-m` | Model to use (provider-specific) | Provider default |
|
|
@@ -738,7 +791,8 @@ make clear-cache # Clear voice cache including samples
|
|
|
738
791
|
| `--list` | `-l` | List available voices for provider | False |
|
|
739
792
|
| `--preview-voice` | `-V` | Preview a voice with sample text | None |
|
|
740
793
|
| `--list-providers` | `-L` | List available TTS providers | False |
|
|
741
|
-
| `--create-config` | | Create sample configuration file | False |
|
|
794
|
+
| `--create-config` | | Create sample configuration file (prompts before overwriting) | False |
|
|
795
|
+
| `--yes` | `-y` | Skip confirmation prompts (e.g. config overwrite) | False |
|
|
742
796
|
| `--refresh-cache` | | Force refresh voice cache (ElevenLabs) | False |
|
|
743
797
|
| `--clear-cache-samples` | | Clear cached voice samples | False |
|
|
744
798
|
|
|
@@ -805,6 +859,42 @@ make clear-cache # Clear voice cache including samples
|
|
|
805
859
|
- No API key needed - runs entirely locally
|
|
806
860
|
- Manual download available via `par-tts-kokoro download`
|
|
807
861
|
|
|
862
|
+
### Deepgram
|
|
863
|
+
|
|
864
|
+
- **Models / Voices**: Aura and Aura-2 lines (model and voice are unified — the model
|
|
865
|
+
parameter *is* the voice). Default: `aura-2-thalia-en`.
|
|
866
|
+
- **Languages**: English, Spanish, Dutch, French, German, Italian, Japanese
|
|
867
|
+
- **Features**:
|
|
868
|
+
- REST `/v1/speak` integration via httpx (no SDK)
|
|
869
|
+
- Streaming chunked download — audio writes to file as it arrives
|
|
870
|
+
- Voice resolution accepts the full ID (`aura-2-thalia-en`), an ID prefix
|
|
871
|
+
(`aura-2-thalia`), or just the speaker name (`thalia`); name lookup prefers
|
|
872
|
+
Aura-2 English, then any Aura-2, then Aura-1
|
|
873
|
+
- **Output Formats**: mp3 (default), wav, flac, opus, aac
|
|
874
|
+
- **API key**: `deepgram_api_key` in config, or `DEEPGRAM_API_KEY` /
|
|
875
|
+
`DG_API_KEY` env var (the historical Deepgram name is also accepted).
|
|
876
|
+
Get a key at <https://console.deepgram.com>.
|
|
877
|
+
|
|
878
|
+
### Google Gemini
|
|
879
|
+
|
|
880
|
+
- **Models**: `gemini-2.5-flash-preview-tts` (default), `gemini-2.5-pro-preview-tts`
|
|
881
|
+
- **Voices**: 30 prebuilt voices with style descriptors — Zephyr (Bright),
|
|
882
|
+
Puck (Upbeat), Kore (Firm, default), Aoede (Breezy), Fenrir (Excitable),
|
|
883
|
+
Leda (Youthful), Charon (Informative), Algieba (Smooth), and more.
|
|
884
|
+
Run `par-tts -P gemini --list` for the full table.
|
|
885
|
+
- **Features**:
|
|
886
|
+
- REST `generateContent` integration via httpx (no SDK)
|
|
887
|
+
- Single-shot response (not chunked); the provider wraps the raw 24 kHz
|
|
888
|
+
16-bit mono PCM in a 44-byte RIFF/WAVE header so output is a self-contained
|
|
889
|
+
`.wav` file
|
|
890
|
+
- Voice names are case-insensitive on input (`kore`, `Kore`, and `KORE` all
|
|
891
|
+
resolve to the canonical `Kore`)
|
|
892
|
+
- **Output Formats**: wav (PCM is the only modality the API emits)
|
|
893
|
+
- **API key**: `gemini_api_key` in config, or one of `GEMINI_API_KEY` /
|
|
894
|
+
`GOOGLE_API_KEY` env vars. Get a free key at
|
|
895
|
+
<https://aistudio.google.com/apikey>. (TTS models are currently in preview;
|
|
896
|
+
rate limits and pricing follow the Gemini API tiers.)
|
|
897
|
+
|
|
808
898
|
## Cache Locations
|
|
809
899
|
|
|
810
900
|
The ElevenLabs voice cache is stored in platform-specific directories:
|
|
@@ -869,32 +959,36 @@ make clean # Clean build artifacts
|
|
|
869
959
|
|
|
870
960
|
```
|
|
871
961
|
par-cli-tts/
|
|
872
|
-
├──
|
|
873
|
-
│ ├── __init__.py
|
|
874
|
-
│ ├──
|
|
875
|
-
│ ├──
|
|
876
|
-
│ ├──
|
|
877
|
-
│ ├──
|
|
878
|
-
│ ├──
|
|
879
|
-
│ ├──
|
|
880
|
-
│ ├──
|
|
881
|
-
│
|
|
962
|
+
├── par_tts/ # Library package (pip install par-cli-tts)
|
|
963
|
+
│ ├── __init__.py # Public API: get_provider, list_providers
|
|
964
|
+
│ ├── audio.py # Audio playback utilities
|
|
965
|
+
│ ├── defaults.py # Default values for providers
|
|
966
|
+
│ ├── errors.py # TTSError, ErrorType, handle_error
|
|
967
|
+
│ ├── http_client.py # HTTP client factory
|
|
968
|
+
│ ├── utils.py # Streaming, checksums, sanitization
|
|
969
|
+
│ ├── voice_cache.py # ElevenLabs voice caching
|
|
970
|
+
│ ├── model_downloader.py # Kokoro ONNX model management
|
|
971
|
+
│ ├── providers/ # TTS provider implementations
|
|
972
|
+
│ │ ├── __init__.py # PROVIDERS registry
|
|
973
|
+
│ │ ├── base.py # TTSProvider ABC, Voice, Options
|
|
974
|
+
│ │ ├── elevenlabs.py # ElevenLabs implementation
|
|
975
|
+
│ │ ├── openai.py # OpenAI implementation
|
|
976
|
+
│ │ ├── kokoro_onnx.py # Kokoro ONNX (offline) implementation
|
|
977
|
+
│ │ ├── deepgram.py # Deepgram implementation
|
|
978
|
+
│ │ └── gemini.py # Google Gemini implementation
|
|
979
|
+
│ └── cli/ # CLI-only code (not imported by library users)
|
|
882
980
|
│ ├── __init__.py
|
|
883
|
-
│ ├──
|
|
884
|
-
│ ├──
|
|
885
|
-
│ ├──
|
|
886
|
-
│
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
├── .
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
├── pyproject.toml # Project configuration
|
|
895
|
-
├── Makefile # Development commands
|
|
896
|
-
├── CLAUDE.md # AI assistant context
|
|
897
|
-
└── README.md # This file
|
|
981
|
+
│ ├── tts_cli.py # Main CLI application
|
|
982
|
+
│ ├── kokoro_cli.py # Kokoro model management CLI
|
|
983
|
+
│ ├── install_claude_style.py # Claude Code style installer
|
|
984
|
+
│ ├── config_file.py # ConfigManager (YAML)
|
|
985
|
+
│ └── console.py # Rich console instances
|
|
986
|
+
├── par_cli_tts/ # Compat shim (deprecated, re-exports par_tts)
|
|
987
|
+
├── tests/
|
|
988
|
+
├── pyproject.toml
|
|
989
|
+
├── Makefile
|
|
990
|
+
├── CLAUDE.md
|
|
991
|
+
└── README.md
|
|
898
992
|
```
|
|
899
993
|
|
|
900
994
|
## Troubleshooting
|