kokorosay 0.1.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.
- kokorosay-0.1.0/.github/workflows/publish.yml +35 -0
- kokorosay-0.1.0/.gitignore +10 -0
- kokorosay-0.1.0/.python-version +1 -0
- kokorosay-0.1.0/AGENTS.md +235 -0
- kokorosay-0.1.0/PKG-INFO +234 -0
- kokorosay-0.1.0/README.md +219 -0
- kokorosay-0.1.0/pyproject.toml +46 -0
- kokorosay-0.1.0/src/kokorosay/__init__.py +10 -0
- kokorosay-0.1.0/src/kokorosay/__main__.py +5 -0
- kokorosay-0.1.0/src/kokorosay/audio_io.py +77 -0
- kokorosay-0.1.0/src/kokorosay/cli.py +177 -0
- kokorosay-0.1.0/src/kokorosay/py.typed +0 -0
- kokorosay-0.1.0/src/kokorosay/setup_cmd.py +30 -0
- kokorosay-0.1.0/src/kokorosay/synth.py +58 -0
- kokorosay-0.1.0/src/kokorosay/voices.py +128 -0
- kokorosay-0.1.0/tests/conftest.py +117 -0
- kokorosay-0.1.0/tests/test_audio_io.py +76 -0
- kokorosay-0.1.0/tests/test_cli.py +245 -0
- kokorosay-0.1.0/tests/test_integration.py +31 -0
- kokorosay-0.1.0/tests/test_setup_cmd.py +73 -0
- kokorosay-0.1.0/tests/test_synth.py +55 -0
- kokorosay-0.1.0/tests/test_voices.py +80 -0
- kokorosay-0.1.0/uv.lock +2336 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: Upload Python Package
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*.*.*'
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
publish:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
permissions:
|
|
15
|
+
# Required for PyPI Trusted Publishing via OIDC token
|
|
16
|
+
id-token: write
|
|
17
|
+
|
|
18
|
+
steps:
|
|
19
|
+
# 1. Check out code
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
|
|
22
|
+
# 2. Install and configure uv
|
|
23
|
+
- name: Set up uv
|
|
24
|
+
uses: astral-sh/setup-uv@v8.2.0
|
|
25
|
+
with:
|
|
26
|
+
enable-cache: true
|
|
27
|
+
|
|
28
|
+
# 3. Build release distributions (dist/)
|
|
29
|
+
- name: Build release distributions
|
|
30
|
+
run: uv build
|
|
31
|
+
|
|
32
|
+
# 4. Publish directly to PyPI
|
|
33
|
+
# uv detects GitHub's id-token and handles OIDC exchange with PyPI without API tokens
|
|
34
|
+
- name: Publish to PyPI
|
|
35
|
+
run: uv publish
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.14
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
Guidelines for AI agents and contributors working on **kokorosay**, a command-line
|
|
4
|
+
text-to-speech tool built on top of [Kokoro](https://github.com/hexgrad/kokoro).
|
|
5
|
+
|
|
6
|
+
## Language Policy
|
|
7
|
+
|
|
8
|
+
- **Conversation**: Reply to the user in the same language the user writes in.
|
|
9
|
+
- **Artifacts**: Everything committed to the repository MUST be in English:
|
|
10
|
+
code comments, docstrings, identifiers, log/error messages, CLI help text,
|
|
11
|
+
commit messages, `README.md`, and any other documentation.
|
|
12
|
+
|
|
13
|
+
## Keeping This Document in Sync
|
|
14
|
+
|
|
15
|
+
- This file is the source of truth for the project's specification.
|
|
16
|
+
- Any code change that adds, removes, or alters behavior covered here (CLI
|
|
17
|
+
arguments, options, subcommands, defaults, exit codes, supported formats,
|
|
18
|
+
module layout, dependencies, tooling, testing requirements, etc.) MUST update
|
|
19
|
+
`AGENTS.md` **in the same change**.
|
|
20
|
+
- A task is not considered done while the code and `AGENTS.md` disagree.
|
|
21
|
+
|
|
22
|
+
## Tooling
|
|
23
|
+
|
|
24
|
+
| Purpose | Tool |
|
|
25
|
+
| ------------------ | ----------------------------- |
|
|
26
|
+
| Package / env mgmt | [uv](https://docs.astral.sh/uv/) (`uv.lock` is committed) |
|
|
27
|
+
| Lint + format | [ruff](https://docs.astral.sh/ruff/) |
|
|
28
|
+
| Tests | [pytest](https://docs.pytest.org/) |
|
|
29
|
+
| Build backend | hatchling + hatch-vcs (version derived from git tags) |
|
|
30
|
+
| Python | `>=3.14` (see `.python-version`) |
|
|
31
|
+
|
|
32
|
+
Common commands:
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
uv sync # install runtime + dev dependencies
|
|
36
|
+
uv add <pkg> # add a runtime dependency
|
|
37
|
+
uv add --dev <pkg> # add a dev dependency
|
|
38
|
+
uv run ruff check . # lint
|
|
39
|
+
uv run ruff check --fix . # lint with autofix
|
|
40
|
+
uv run ruff format . # format
|
|
41
|
+
uv run pytest # run tests
|
|
42
|
+
uv run kokorosay --help # run the CLI from source
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Rules:
|
|
46
|
+
|
|
47
|
+
- Never edit `uv.lock` by hand; always go through `uv add` / `uv remove` / `uv lock`.
|
|
48
|
+
- Do not use `pip install` directly in this project.
|
|
49
|
+
- Code must pass `ruff check` and `ruff format --check` before a task is considered done.
|
|
50
|
+
- All tests must pass before a task is considered done.
|
|
51
|
+
|
|
52
|
+
## Project Layout (src layout)
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
kokorosay/
|
|
56
|
+
├── AGENTS.md
|
|
57
|
+
├── README.md
|
|
58
|
+
├── pyproject.toml
|
|
59
|
+
├── uv.lock
|
|
60
|
+
├── src/
|
|
61
|
+
│ └── kokorosay/
|
|
62
|
+
│ ├── __init__.py
|
|
63
|
+
│ ├── __main__.py # enables `python -m kokorosay`
|
|
64
|
+
│ ├── cli.py # argument parsing and entry point `main()`
|
|
65
|
+
│ ├── setup_cmd.py # `--setup`: UniDic dictionary download
|
|
66
|
+
│ ├── voices.py # voice catalog, language-code mapping
|
|
67
|
+
│ ├── synth.py # Kokoro pipeline wrapper, segment merging
|
|
68
|
+
│ ├── audio_io.py # writing WAV/MP3, playback
|
|
69
|
+
│ └── py.typed
|
|
70
|
+
└── tests/
|
|
71
|
+
├── conftest.py # fake kokoro / sounddevice / stdin fixtures
|
|
72
|
+
└── test_*.py
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
- The console script is registered in `pyproject.toml` as
|
|
76
|
+
`kokorosay = "kokorosay.cli:main"`.
|
|
77
|
+
- Keep modules small and focused; the module list above is a guideline, not a contract.
|
|
78
|
+
- Inside the package, reference sibling modules with **relative imports**
|
|
79
|
+
(e.g. `from .voices import resolve_lang_code`, `from . import audio_io`),
|
|
80
|
+
never `from kokorosay.xxx import ...`. Tests (outside the package) import via
|
|
81
|
+
the absolute package name `kokorosay`.
|
|
82
|
+
|
|
83
|
+
## CLI Specification
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
kokorosay INPUT [OUTPUT] [OPTIONS]
|
|
87
|
+
kokorosay --list-voices
|
|
88
|
+
kokorosay --setup
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### `--setup` option
|
|
92
|
+
|
|
93
|
+
`kokorosay --setup` downloads the full UniDic dictionary required by the
|
|
94
|
+
Japanese G2P backend (the `unidic` package is a runtime dependency, but its
|
|
95
|
+
dictionary data must be fetched separately). Implementation sketch:
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
import subprocess
|
|
99
|
+
import sys
|
|
100
|
+
|
|
101
|
+
subprocess.check_call([sys.executable, "-m", "unidic", "download"])
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
- `--setup` is a standalone mode like `--list-voices`: `INPUT` is not required,
|
|
105
|
+
and the program exits after the download.
|
|
106
|
+
- `--setup` cannot be combined with `INPUT`/`OUTPUT` or `--list-voices`; doing
|
|
107
|
+
so is a usage error (exit code `2`).
|
|
108
|
+
- Use `sys.executable` so the download runs in the same environment kokorosay
|
|
109
|
+
is installed in. Do not invoke `python`/`pip` from `PATH`.
|
|
110
|
+
- Progress output from the child process goes straight to the terminal. If the
|
|
111
|
+
child exits non-zero (`CalledProcessError`) or cannot be started, print a
|
|
112
|
+
concise error to stderr and exit with code `1`.
|
|
113
|
+
- Must not import `kokoro` or `torch`.
|
|
114
|
+
|
|
115
|
+
### Positional arguments
|
|
116
|
+
|
|
117
|
+
| Argument | Description |
|
|
118
|
+
| -------- | ----------- |
|
|
119
|
+
| `INPUT` | Text to synthesize. If it is exactly `-`, read the text from stdin. |
|
|
120
|
+
| `OUTPUT` | Optional output file path. If omitted, the audio is played directly. |
|
|
121
|
+
|
|
122
|
+
### Options
|
|
123
|
+
|
|
124
|
+
| Option | Default | Description |
|
|
125
|
+
| ------ | ------- | ----------- |
|
|
126
|
+
| `--voice NAME` | `af_heart` | Voice name, e.g. `jf_nezumi`. The language is derived from the **first letter** of the voice name; there is no separate language option. |
|
|
127
|
+
| `--speed FLOAT` | `1.0` | Speech rate multiplier passed to Kokoro. |
|
|
128
|
+
| `--split-pattern REGEX` | `None` | Regex used to split text into segments. When not given, do **not** pass `split_pattern` so Kokoro's own default applies. |
|
|
129
|
+
| `--list-voices` | – | Print all supported voices grouped by language, then exit. `INPUT` is not required in this mode; combining it with `INPUT`/`OUTPUT` is a usage error (exit code `2`). |
|
|
130
|
+
| `--setup` | – | Download the full UniDic dictionary, then exit. `INPUT` is not required in this mode. See [`--setup` option](#--setup-option). |
|
|
131
|
+
| `--version` | – | Print the package version (from git tags via hatch-vcs), then exit. |
|
|
132
|
+
|
|
133
|
+
### Behavior requirements
|
|
134
|
+
|
|
135
|
+
1. **Stdin input (`-`)**
|
|
136
|
+
- Read raw bytes from `sys.stdin.buffer` and decode as UTF-8 explicitly
|
|
137
|
+
(use `utf-8-sig` so a leading BOM, common from PowerShell, is stripped).
|
|
138
|
+
- Never rely on the platform default encoding; Windows consoles often use a
|
|
139
|
+
non-UTF-8 code page.
|
|
140
|
+
- Bytes that are not valid UTF-8 are a runtime failure (exit code `1`).
|
|
141
|
+
- Text that is empty or whitespace-only (from `INPUT` or stdin) is a usage
|
|
142
|
+
error (exit code `2`).
|
|
143
|
+
- Text starting with `-` can be passed after `--` (argparse convention).
|
|
144
|
+
2. **Output file**
|
|
145
|
+
- Only `.mp3` and `.wav` are supported (extension check is case-insensitive).
|
|
146
|
+
Any other extension is a usage error and must be rejected **before** loading
|
|
147
|
+
the model.
|
|
148
|
+
- Files are written with `soundfile` (libsndfile, which supports MP3).
|
|
149
|
+
- Existing files are overwritten without prompting.
|
|
150
|
+
- Missing parent directories are created automatically
|
|
151
|
+
(`Path.parent.mkdir(parents=True, exist_ok=True)`).
|
|
152
|
+
3. **Segment merging**
|
|
153
|
+
- Kokoro yields one audio chunk per segment. When writing to a file, all chunks
|
|
154
|
+
MUST be concatenated in order and written as a **single** file, regardless of
|
|
155
|
+
whether `--split-pattern` was supplied.
|
|
156
|
+
4. **Playback (no `OUTPUT`)**
|
|
157
|
+
- Play the synthesized audio on the default output device using
|
|
158
|
+
`sounddevice` (PortAudio).
|
|
159
|
+
- Chunks are played sequentially as they are generated to reduce latency; the
|
|
160
|
+
output stream is opened when the first chunk arrives.
|
|
161
|
+
5. **Voice → language**
|
|
162
|
+
- `lang_code = voice[0]`, passed to `KPipeline(lang_code=..., repo_id="hexgrad/Kokoro-82M")`
|
|
163
|
+
(passing `repo_id` explicitly suppresses Kokoro's stdout warning).
|
|
164
|
+
- An unknown voice or unsupported language prefix is a usage error with a
|
|
165
|
+
helpful message (suggest `--list-voices`).
|
|
166
|
+
- Other argument validation (`--speed` must be positive, `--split-pattern`
|
|
167
|
+
must be a valid regex) also happens before loading the model and is a usage
|
|
168
|
+
error.
|
|
169
|
+
6. **Exit codes**
|
|
170
|
+
- `0` success, `1` runtime failure, `2` usage error (argparse convention),
|
|
171
|
+
`130` interrupted with Ctrl+C.
|
|
172
|
+
- Synthesis that produces no audio at all is a runtime failure.
|
|
173
|
+
- Errors go to stderr; stdout is reserved for user-requested output
|
|
174
|
+
(e.g. `--list-voices`). Anything third-party libraries print to stdout
|
|
175
|
+
during synthesis is redirected to stderr, and warnings emitted by `torch`
|
|
176
|
+
are suppressed.
|
|
177
|
+
|
|
178
|
+
### Kokoro reference
|
|
179
|
+
|
|
180
|
+
- Audio sample rate is **24000 Hz**.
|
|
181
|
+
- Language prefixes:
|
|
182
|
+
|
|
183
|
+
| Prefix | Language |
|
|
184
|
+
| ------ | -------- |
|
|
185
|
+
| `a` | American English |
|
|
186
|
+
| `b` | British English |
|
|
187
|
+
| `e` | Spanish |
|
|
188
|
+
| `f` | French |
|
|
189
|
+
| `h` | Hindi |
|
|
190
|
+
| `i` | Italian |
|
|
191
|
+
| `j` | Japanese |
|
|
192
|
+
| `p` | Brazilian Portuguese |
|
|
193
|
+
| `z` | Mandarin Chinese |
|
|
194
|
+
|
|
195
|
+
- Basic pipeline usage:
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
from kokoro import KPipeline
|
|
199
|
+
|
|
200
|
+
pipeline = KPipeline(lang_code="j")
|
|
201
|
+
for graphemes, phonemes, audio in pipeline(text, voice="jf_nezumi", speed=1.0):
|
|
202
|
+
...
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Coding Conventions
|
|
206
|
+
|
|
207
|
+
- Target Python 3.14; use modern syntax (type hints everywhere, `pathlib.Path`,
|
|
208
|
+
`from __future__ import annotations` is unnecessary).
|
|
209
|
+
- Public functions have English docstrings.
|
|
210
|
+
- Keep heavy imports (`kokoro`, `torch`) lazy, inside the functions that need them,
|
|
211
|
+
so `--help`, `--list-voices`, `--setup`, and argument validation stay fast.
|
|
212
|
+
- Prefer the standard library (`argparse`) for CLI parsing unless a dependency is
|
|
213
|
+
explicitly approved by the user.
|
|
214
|
+
- Do not add new runtime dependencies without the user's approval.
|
|
215
|
+
- Approved runtime dependencies: `kokoro`, `misaki[en,ja,ko,vi,zh]`, `unidic`
|
|
216
|
+
(Japanese dictionary), `soundfile` (WAV/MP3 writing), `sounddevice`
|
|
217
|
+
(playback). `numpy` comes in transitively and may be used directly.
|
|
218
|
+
|
|
219
|
+
## Testing
|
|
220
|
+
|
|
221
|
+
- Tests live in `tests/` and use pytest.
|
|
222
|
+
- Unit tests MUST NOT download models or require audio hardware: mock
|
|
223
|
+
`KPipeline` and the playback backend. `tests/conftest.py` provides the
|
|
224
|
+
`fake_kokoro`, `fake_sounddevice`, and `set_stdin` fixtures, which install fake
|
|
225
|
+
`kokoro` / `sounddevice` modules into `sys.modules`.
|
|
226
|
+
- Tests that need the real model or a sound device are marked
|
|
227
|
+
`@pytest.mark.integration` and deselected by default (`addopts` in
|
|
228
|
+
`pyproject.toml`); run them with `uv run pytest -m integration`.
|
|
229
|
+
- Cover at least: argument parsing, stdin UTF-8 decoding (including BOM and
|
|
230
|
+
non-ASCII text), output extension validation, parent directory creation,
|
|
231
|
+
segment concatenation, voice-to-language mapping, `--list-voices` grouping,
|
|
232
|
+
and `--setup` handling (mock `subprocess.check_call`; never actually download
|
|
233
|
+
UniDic in unit tests; verify the command uses `sys.executable`, that a
|
|
234
|
+
failing child results in exit code `1`, and that combining `--setup` with
|
|
235
|
+
`INPUT` or `--list-voices` results in exit code `2`).
|
kokorosay-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: kokorosay
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A CLI tool for Kokoro
|
|
5
|
+
Project-URL: Homepage, https://github.com/ecator/kokorosay
|
|
6
|
+
Project-URL: Repository, https://github.com/ecator/kokorosay
|
|
7
|
+
Author-email: Martin <qule520@126.com>
|
|
8
|
+
Requires-Python: >=3.14
|
|
9
|
+
Requires-Dist: kokoro>=0.9.4
|
|
10
|
+
Requires-Dist: misaki[en,ja,ko,vi,zh]>=0.9.4
|
|
11
|
+
Requires-Dist: sounddevice>=0.5.6
|
|
12
|
+
Requires-Dist: soundfile>=0.14.0
|
|
13
|
+
Requires-Dist: unidic>=1.1.0
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# kokorosay
|
|
17
|
+
|
|
18
|
+
[](https://pypi.org/project/kokorosay/)
|
|
19
|
+
[](https://pypi.org/project/kokorosay/)
|
|
20
|
+
|
|
21
|
+
`kokorosay` is a fast, lightweight command-line text-to-speech (TTS) tool built on top of [Kokoro](https://github.com/hexgrad/kokoro).
|
|
22
|
+
|
|
23
|
+
Pass text as an argument or pipe it via standard input; `kokorosay` will immediately stream speech through your speakers or export it to high-quality WAV or MP3 audio files.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Features
|
|
28
|
+
|
|
29
|
+
- ⚡ **Fast & Lightweight**: Built on the open-weights 82M parameter Kokoro model (`hexgrad/Kokoro-82M`).
|
|
30
|
+
- 🔊 **Direct Low-Latency Playback**: Streams audio chunks to your default audio device in real time as they are generated.
|
|
31
|
+
- 💾 **WAV & MP3 Export**: Concatenates synthesized chunks into a seamless 24 kHz audio file; parent directories are created automatically.
|
|
32
|
+
- 🌐 **9 Languages & 50+ Voices**: Supports English, Japanese, Mandarin Chinese, Spanish, French, Hindi, Italian, and Brazilian Portuguese.
|
|
33
|
+
- 🔀 **Automatic Language Detection**: The target language is derived directly from the voice name prefix (e.g. `jf_nezumi` → Japanese, `zf_xiaobei` → Mandarin, `af_heart` → American English).
|
|
34
|
+
- 📥 **Pipeline & Stdin Friendly**: Supports `-` as input with explicit UTF-8 and BOM decoding, ideal for shell pipes and automation scripts.
|
|
35
|
+
- 🎛️ **Synthesis Controls**: Easily adjust speech rate multiplier (`--speed`) or provide custom segment-splitting regexes (`--split-pattern`).
|
|
36
|
+
- 🛡️ **Clean CLI & Standard Exit Codes**: Suppresses third-party noise, outputs errors to `stderr`, and adheres to standard exit codes (`0`, `1`, `2`, `130`).
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Installation
|
|
41
|
+
|
|
42
|
+
`kokorosay` requires **Python 3.14+**.
|
|
43
|
+
|
|
44
|
+
### Recommended: Using [uv](https://docs.astral.sh/uv/)
|
|
45
|
+
|
|
46
|
+
Install `kokorosay` as a globally isolated command-line tool:
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
uv tool install kokorosay
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Alternative: Using [pipx](https://github.com/pypa/pipx) or pip
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
# Using pipx
|
|
56
|
+
pipx install kokorosay
|
|
57
|
+
|
|
58
|
+
# Using standard pip (inside an active virtual environment)
|
|
59
|
+
pip install kokorosay
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### System Prerequisites (Linux only)
|
|
63
|
+
|
|
64
|
+
On Windows and macOS, audio dependencies are bundled automatically. On Linux systems, `portaudio` might be needed for direct speaker playback:
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
# Debian / Ubuntu
|
|
68
|
+
sudo apt-get install libportaudio2
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Setup
|
|
74
|
+
|
|
75
|
+
Before first use, run the one-time dictionary setup:
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
kokorosay --setup
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
- **Japanese UniDic**: `kokorosay --setup` downloads the full UniDic dictionary required for Japanese G2P (grapheme-to-phoneme) processing.
|
|
82
|
+
- **Model weights**: The Kokoro-82M model and voice weights (~330 MB) are automatically fetched from Hugging Face on your first speech synthesis and cached locally for future offline use.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Quick Start & Examples
|
|
87
|
+
|
|
88
|
+
### 1. Direct Playback
|
|
89
|
+
|
|
90
|
+
Provide text in quotes to play speech instantly through the default audio device:
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
# Play using default voice (af_heart - American English female)
|
|
94
|
+
kokorosay "Hello! Kokorosay brings text to life right from your terminal."
|
|
95
|
+
|
|
96
|
+
# British English voice, slightly faster
|
|
97
|
+
kokorosay "Mind the gap between the train and the platform." --voice bm_george --speed 1.15
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### 2. Exporting to Audio Files (`.wav` / `.mp3`)
|
|
101
|
+
|
|
102
|
+
Specify an output file path as the second positional argument. Only `.mp3` and `.wav` formats are supported (case-insensitive). Missing directories will be created automatically:
|
|
103
|
+
|
|
104
|
+
```sh
|
|
105
|
+
# Save as MP3
|
|
106
|
+
kokorosay "Speech saved to an MP3 file." output.mp3
|
|
107
|
+
|
|
108
|
+
# Japanese voice saved to a nested directory
|
|
109
|
+
kokorosay "こんにちは、世界。" audio/japanese/hello.wav --voice jf_nezumi
|
|
110
|
+
|
|
111
|
+
# Mandarin Chinese voice
|
|
112
|
+
kokorosay "你好,欢迎使用文本转语音工具。" out/welcome.mp3 --voice zf_xiaobei
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 3. Piping from Stdin (`-`)
|
|
116
|
+
|
|
117
|
+
Pass `-` as `INPUT` to read text from standard input. `kokorosay` decodes standard input as UTF-8 (and strips PowerShell's UTF-8 BOM if present):
|
|
118
|
+
|
|
119
|
+
```sh
|
|
120
|
+
# Pipe the output of any command
|
|
121
|
+
fortune | kokorosay -
|
|
122
|
+
|
|
123
|
+
# Read from a file via stdin
|
|
124
|
+
cat story.txt | kokorosay - story.mp3 --voice bf_emma
|
|
125
|
+
|
|
126
|
+
# In PowerShell:
|
|
127
|
+
Get-Content notes.txt -Raw | kokorosay - notes.wav
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### 4. Text Starting with Hyphens (`--`)
|
|
131
|
+
|
|
132
|
+
If your input text begins with a dash or minus sign, use `--` so the argument parser does not interpret it as a flag:
|
|
133
|
+
|
|
134
|
+
```sh
|
|
135
|
+
kokorosay -- "-5 degrees Celsius outside today."
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## CLI Reference
|
|
141
|
+
|
|
142
|
+
### Synopsis
|
|
143
|
+
|
|
144
|
+
```sh
|
|
145
|
+
kokorosay INPUT [OUTPUT] [OPTIONS]
|
|
146
|
+
kokorosay --list-voices
|
|
147
|
+
kokorosay --setup
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Arguments and Options
|
|
151
|
+
|
|
152
|
+
| Argument / Option | Default | Description |
|
|
153
|
+
| ----------------- | ------- | ----------- |
|
|
154
|
+
| `INPUT` | – | Text to synthesize. Use `-` to read UTF-8 text from stdin. |
|
|
155
|
+
| `OUTPUT` | – | Output audio path (`.wav` or `.mp3`). If omitted, audio plays directly. |
|
|
156
|
+
| `--voice NAME` | `af_heart` | Voice identifier (e.g. `jf_nezumi`, `bf_emma`). First letter sets language. |
|
|
157
|
+
| `--speed FLOAT` | `1.0` | Speech rate multiplier (must be a positive number). |
|
|
158
|
+
| `--split-pattern REGEX` | Kokoro default | Regular expression to split input text into segments. |
|
|
159
|
+
| `--list-voices` | – | Print all supported voices grouped by language and exit. |
|
|
160
|
+
| `--setup` | – | Download the UniDic dictionary for Japanese support and exit. |
|
|
161
|
+
| `--version` | – | Show version number and exit. |
|
|
162
|
+
| `-h`, `--help` | – | Show command help and exit. |
|
|
163
|
+
|
|
164
|
+
> **Note:** `--setup` and `--list-voices` are standalone modes. They cannot be combined with positional arguments (`INPUT` / `OUTPUT`) or with each other.
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Supported Languages & Voices
|
|
169
|
+
|
|
170
|
+
Kokoro determines the language from the **first letter** of the voice name. The **second letter** indicates voice gender (`f` for female, `m` for male).
|
|
171
|
+
|
|
172
|
+
| Prefix | Language | Example Voices |
|
|
173
|
+
| :---: | --- | --- |
|
|
174
|
+
| `a` | American English | `af_heart` (default), `af_alloy`, `af_bella`, `am_adam`, `am_michael` |
|
|
175
|
+
| `b` | British English | `bf_alice`, `bf_emma`, `bm_daniel`, `bm_george` |
|
|
176
|
+
| `e` | Spanish | `ef_dora`, `em_alex`, `em_santa` |
|
|
177
|
+
| `f` | French | `ff_siwis` |
|
|
178
|
+
| `h` | Hindi | `hf_alpha`, `hf_beta`, `hm_omega`, `hm_psi` |
|
|
179
|
+
| `i` | Italian | `if_sara`, `im_nicola` |
|
|
180
|
+
| `j` | Japanese | `jf_alpha`, `jf_gongitsune`, `jf_nezumi`, `jf_tebukuro`, `jm_kumo` |
|
|
181
|
+
| `p` | Brazilian Portuguese | `pf_dora`, `pm_alex`, `pm_santa` |
|
|
182
|
+
| `z` | Mandarin Chinese | `zf_xiaobei`, `zf_xiaoni`, `zf_xiaoxiao`, `zm_yunjian`, `zm_yunyang` |
|
|
183
|
+
|
|
184
|
+
To view the complete list of available voices grouped by language, run:
|
|
185
|
+
|
|
186
|
+
```sh
|
|
187
|
+
kokorosay --list-voices
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Exit Codes
|
|
193
|
+
|
|
194
|
+
| Code | Meaning |
|
|
195
|
+
| :---: | --- |
|
|
196
|
+
| `0` | **Success**: Audio played or written successfully, or `--help` / `--list-voices` completed. |
|
|
197
|
+
| `1` | **Runtime Failure**: Network error downloading weights, synthesis failure, missing audio device, or invalid UTF-8 bytes on stdin. |
|
|
198
|
+
| `2` | **Usage Error**: Missing `INPUT`, invalid argument, unknown voice name, unsupported output extension, or empty text. |
|
|
199
|
+
| `130` | **Interrupted**: Execution aborted by `SIGINT` (Ctrl+C). |
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## Development
|
|
204
|
+
|
|
205
|
+
If you wish to contribute or modify `kokorosay`:
|
|
206
|
+
|
|
207
|
+
```sh
|
|
208
|
+
# Clone repository
|
|
209
|
+
git clone https://github.com/ecator/kokorosay.git
|
|
210
|
+
cd kokorosay
|
|
211
|
+
|
|
212
|
+
# Install runtime and dev dependencies
|
|
213
|
+
uv sync
|
|
214
|
+
|
|
215
|
+
# Lint and check formatting
|
|
216
|
+
uv run ruff check .
|
|
217
|
+
uv run ruff format --check .
|
|
218
|
+
|
|
219
|
+
# Run unit tests (offline, mocked Kokoro/sounddevice)
|
|
220
|
+
uv run pytest
|
|
221
|
+
|
|
222
|
+
# Run integration tests (requires real model weights & audio device)
|
|
223
|
+
uv run pytest -m integration
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
See [AGENTS.md](AGENTS.md) for full architecture specifications and coding conventions.
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Acknowledgments
|
|
231
|
+
|
|
232
|
+
- [Kokoro](https://github.com/hexgrad/kokoro) for the TTS model.
|
|
233
|
+
- [Misaki](https://github.com/hexgrad/misaki) for G2P text pre-processing.
|
|
234
|
+
- [UniDic](https://github.com/polm/unidic-py) for Japanese morphological analysis.
|