# tts-audiobook-generator
Generate audiobooks from books (epub, txt, pdf) using text-to-speech backends such as `audio.cpp` and `qwen-tts`. Installs and manages
## Overview
The converter sends text extracted from your books to a locally running TTS server and assembles the returned audio into a single audiobook file.
- Input: `.txt`, `.pdf`, or `.epub`
- Output: `.m4b`, `.mp3`, `.ogg`, or `.flac`
- Supports [audio.cpp](https://github.com/0xShug0/audio.cpp), [qwen-tts](https://pypi.org/project/qwen-tts/), and [faster-qwen3-tts](https://github.com/andimarafioti/faster-qwen3-tts) backend servers
- Output a single file or one per chapter
- Automatic metadata (title/artist/album tags, chapter track numbers) and a generated cover
- Supports text-to-speech, voice cloning, voice design, and per-model controls like emotion/speed
| Backend | Description |
| -------------------------------------------------------------------- | ------------------------------------------------------ |
| [audio.cpp](https://github.com/0xShug0/audio.cpp) | Newer C++ TTS backend that supports many recent models |
| [Qwen-TTS](https://pypi.org/project/qwen-tts/) | Qwen demo server (qwen-tts-demo); one model at a time — CustomVoice, Base or VoiceDesign |
| [Faster-Qwen-TTS](https://github.com/andimarafioti/faster-qwen3-tts) | Qwen server with 2-8x faster inference for NVidia GPUs |
## Prerequisites
- Python 3.12+
- ffmpeg
## Quick Start
1. Download the project
```bash
git clone https://git.historia.vg/git/tts-audiobook-generator
cd tts-audiobook-generator
```
2. Put your files in the directories
- `./input` - Text files to be processed (`epub`, etc.)
- `./output` - Audio files will output here
- `./voices` - `.wav` files of voices to clone (10-20 seconds)
3. Run `audiobook.py`. It will automatically create the app's virtual environment and install its requirements (each pip-installed TTS backend later gets a managed venv of its own under `app/envs/`).
```
python audiobook.py
```
4. When the TUI comes up, go to `Configure Backends > Install Backend`. Install `audio.cpp`, which supports numerous TTS models.
5. On the "Select TTS models to host" screen, install one or more TTS models. `qwen3_tts_1_7b_base_q8_0` is a good model for cloning and `qwen3_tts_1_7b_customvoice_q8_0` is good for built-in speakers.
6. Run through the rest of the wizard. The defaults are probably all correct. The script will simultaneously build audiocpp_server and download the model files. This will take a while.
## CLI Options
Everything the TUI does can also be scripted with flags: `python audiobook.py --backend audiocpp --model higgs --voice narrator`.
## Options
| Flag | Description |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--backend {audiocpp,qwen,faster}` | TTS server to use (default `audiocpp`). |
| `--format {mp3,m4b,ogg,flac}` | Output format (default `m4b`). |
| `--input
` | Directory containing the books to convert (default `./input`). |
| `--output ` | Directory to write finished audiobooks to (default `./output`). |
| `--speed ` | Playback speed, pitch-preserving (`1.0` = normal). A normal-speed copy is also output. |
| `--single-file` | Merge all chapters into a single file. `m4b` is always one file. |
| `--language ` | Output language for the synthesized speech. Can add an accent even if the text is English. |
| `--debug` | Dump each chunk's raw audio and sent text to `debug/` and log every request. |
| `--model ` | `audiocpp`: Choose the model from `server.json` |
| `--instructions "..."` | `audiocpp`: voice design or style instruction (required for voice design models, task `vdes`). `qwen`: selects the VoiceDesign model and describes the voice to synthesize with. |
| `--option KEY=VALUE` | `audiocpp`: Some models support custom options (e.g. `emotion=netural`) that can be passed with this flag |
| `--voice ` | `audiocpp`, `faster`: Voice to request. `audiocpp`: on the Qwen3-TTS CustomVoice entry a built-in speaker (e.g. `Vivian`, `Ryan`, `Uncle_Fu`); on every other family a `voice_preset`/`voice_dir` entry for cloning (with `AUDIOCPP_CLONE_MODEL_ID` set it reroutes to the clone model — typically the Qwen Base model). `faster`: a key in the server's `voices.json`. |
| `--clone ` | `qwen`: Reference audio (`wav`) for voice cloning. |
| `--transcription "..."` | `qwen`: Override whisper auto-transcription with manual audio transcript. |
| `--no-transcription` | `qwen`: Skip auto-transcription of the reference audio. |
| `--api-url ` | URL of the TTS server to talk to, overriding the configured endpoint for the selected backend. Accepts `host:port` or a full `http(s)://` URL. |
Other options — including backend server URLs, ports, and the remote-server URLs the hub probes for `[remote]` entries — are configured in `app/converter/config.py` (or the TUI's **Settings** menu, whose **Default Language** entry is the same static language picker).
The **Generate audiobooks** TUI form exposes the same per-run controls as these flags: for `audiocpp` the Model picker labels each entry's voice capability (`speaker` / `clone` / `design`), the Voice field is labelled **Built-in voice** on CustomVoice entries and **Voice to clone** everywhere else, Instructions work on every entry (required for `vdes`, optional style/delivery control elsewhere — or the voice itself on families without built-in speakers), a Request options field accepts `KEY=VALUE` items (the `--option` equivalent, shown only for model families whose audio.cpp spec declares request options), and Language (a static picker over the languages of audio.cpp's WebUI menus, hinting "Check model documentation for supported languages." while editing) overrides the global setting per run (hidden for `faster`, which owns language server-side). For `qwen-tts` a single **Model** picker selects which demo the server hosts — Base (voice cloning), CustomVoice (built-in voices) or VoiceDesign (design) — with the matching controls shown below it; the choice is remembered, and switching models restarts the managed server on its single port. The Instructions and Request options editors show dim hints with examples while editing.
## Manual TTS Backend Setup
If the TUI auto-install doesn't work, you may need to set up the backends manually.
- [audio.cpp instructions](app/docs/backend-audiocpp.md)
- [qwen-tts instructions](app/docs/backend-qwen.md)
- [faster-qwen-tts instructions](app/docs/backend-faster.md)
`./audiobook.py` can also connect to external servers running these backends. Point the relevant `*_REMOTE_URL` in `app/converter/config.py` (or the **Settings** → remote URL fields) at the server's `host:port` — the hub probes it and offers a `[remote]` entry in **Generate audiobooks…** next to the managed one. The defaults are the local ports (`127.0.0.1:`), so a server started outside this tool on the local port is picked up automatically. For scripting, `--api-url` targets any server directly.
## Development
The test suite runs against any Python that has the app's dependencies
(the managed venv works fine):
```bash
pytest app/tests # from the repo root
```
## Tips
Transcription affects the output a lot. Whisper does not always give perfect transcription. Manual transcription is better.
Even tiny amounts of pause between phrases in the sample audio can have a big impact. Try increasing or decreasing them or find a sample with different cadence.
## License
MIT
## Credits
- [Qwen3-Audiobook-Converter](https://github.com/WhiskeyCoder/Qwen3-Audiobook-Converter) by WhiskeyCoder. This project was originally built upon this.
- [Qwen3-TTS](https://github.com/QwenLM/Qwen3-TTS) voice model.
- [audio.cpp](https://github.com/0xShug0/audio.cpp) inference engine for the `audiocpp` backend.