diff options
| author | historia <historiavg@proton.me> | 2026-09-04 12:12:53 -0400 |
|---|---|---|
| committer | historia <historiavg@proton.me> | 2026-09-04 12:12:53 -0400 |
| commit | eadae12c3a8f31d16586a6241bfc3a90461522cc (patch) | |
| tree | de32bd0edc3f1b75c6436e9fd7875c53289e58d6 | |
| parent | 9dd66997033f7d306718c67745b41c16dd034865 (diff) | |
| download | tts-audiobook-generator-eadae12c3a8f31d16586a6241bfc3a90461522cc.tar.gz | |
readme
| -rw-r--r-- | README.md | 124 | ||||
| -rw-r--r-- | app/converter/config.py | 6 | ||||
| -rw-r--r-- | app/demo.webp | bin | 0 -> 27224 bytes |
3 files changed, 43 insertions, 87 deletions
@@ -1,23 +1,25 @@ -# tts-audiobook-generator +# tts-audiobook-generator (TAG) -Generate audiobooks from books (epub, txt, pdf) using text-to-speech backends such as `audio.cpp`, `qwen-tts`, and `SGLang-Omni`. Installs and manages + + +Generate audiobooks from books (epub, txt, pdf) using text-to-speech backends such as `audio.cpp`, `qwen-tts`, and `SGLang-Omni`. TAG installs and manages requirements and backend servers automatically. ## 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` (single file or one-per-chapter) +- Output: `.m4b`, `.mp3`, `.ogg`, or `.flac` - Supports [audio.cpp](https://github.com/0xShug0/audio.cpp), [qwen-tts](https://pypi.org/project/qwen-tts/), [faster-qwen3-tts](https://github.com/andimarafioti/faster-qwen3-tts), and [SGLang-Omni](https://github.com/sgl-project/sglang-omni) backend servers - Automatic metadata (title/artist/album tags, chapter track numbers) and a generated cover - Supports text-to-speech, voice cloning, and voice design -| 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 | -| [SGLang-Omni](https://github.com/sgl-project/sglang-omni) | Multi-model OpenAI-compatible serving stack (NVIDIA GPU + Linux, Python 3.10-3.12) | +| Backend | Description | +| -------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | +| [audio.cpp](https://github.com/0xShug0/audio.cpp) | C++ TTS backend that supports many models | +| [SGLang-Omni](https://github.com/sgl-project/sglang-omni) | Multi-model server for big models and NVidia GPUs | +| [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 @@ -52,41 +54,35 @@ cd tts-audiobook-generator 7. Go to `Generate Audiobooks` in the main menu to process the input files into audiobooks. The script will automatically start and stop the necessary backend server. - With several audio.cpp models installed, the **Model** menu also offers **All (multiple generation)**: every book is generated once per configured model, so their output can be compared. Output file names carry the model (`book_<model>_<voice>.m4b`), the same Voice is sent to every model that accepts it (models it does not fit use their own default voice), and loaded models are unloaded between runs to free VRAM. - -The **SGLang-Omni** backend works the same way (`Configure Backends > -Install Backend > SGLang-Omni`): the wizard provisions a Python -3.10-3.12 venv automatically (downloading a managed interpreter when the -system has none), pip-installs the serving stack, and installs the -models you pick from its catalog (Qwen3-TTS, Higgs Audio v3, MOSS-TTS, -Voxtral TTS, Fish Speech, and more — see -[the backend docs](app/docs/backend-sglomni.md)). It requires Linux with -an NVIDIA GPU; one model is hosted per server process, so the Generate -form's Model pick decides which server boots. - -## Updating - -Run `Configure Backends > Update tts-audiobook-generator` in the hub: it -fetches the latest code and moves the checkout to the remote's default -branch (the same fetch + hard-reset flow the backend checkouts use), then -asks you to restart so the new code loads. Nothing you generate or download -is at risk -— `input/`, `output/`, `voices/`, `app/envs/`, model weights, and logs are -untracked and outside the reset's reach — and **locally modified tracked -files are preserved**: `app/converter/config.py` (your settings) and any -other file you edited are written back after the update, with a notice -when upstream changed them too (merge new options by hand in that case). -A dirty checkout asks before proceeding; an up-to-date checkout skips the -reset entirely. - -After the generator itself updates, run **Update Backends** to refresh the -backend packages (`pip -U` / git + rebuild). When a release changes an -update's requirements, the next launch re-checks the app venv -automatically; backend venvs follow their own wizards. - ## CLI Options -Without `--api-url` the CLI manages the server itself, just like the TUI: it starts the selected backend's managed instance (installed via the TUI), converts, and stops it again. A server already running at the configured endpoint is used as-is and left running when the run ends. `--api-url` points at an external server instead, and never touches server state. +| Flag | Example | Description | +| ------------------------------------------ | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `--backend {audiocpp,qwen,faster,sglomni}` | `audiocpp` | TTS server to use. Required: there is no default backend. | +| `--format {mp3,m4b,ogg,flac}` | `m4b` | Output format (default: the `AUDIO_FORMAT` setting in `app/converter/config.py`, `m4b`). | +| `--voice <name>` | `Vivian` | Voice to request. For `faster` this is the key in `voices.json` (required). For the Qwen CustomVoice model this is the speaker (Ryan, Vivian, etc.). For audio.cpp it is a server-side clone voice: required for clone-only families (e.g. Chatterbox), optional on mixed families and unused by pure-TTS models (e.g. Supertonic). | +| `--input <dir>` | `./input` | Directory containing the books to convert (default: the `INPUT_DIR` setting in `app/converter/config.py`, `./input`; relative paths resolve against the project root). | +| `--output <dir>` | `./output` | Directory to write finished audiobooks to (default: the `OUTPUT_DIR` setting in `app/converter/config.py`, `./output`). | +| `--input-file <file>` | `books/dune.epub` | Convert one specific book (`.txt`/`.pdf`/`.epub`) | +| `--output-file <file>` | `out/dune.mp3` | Base output path for the audiobook from `--input-file` | +| `--instructions "..."` | `"A warm adult female narrator with a British accent"` | Voice design or style instruction. Usually used for voice design models, some clone models also accept this. | +| `--speed <n>` | `1.0` | Playback speed, pitch-preserving (`1.0` = normal). A normal-speed copy is also output. Defaults to the `SPEED` setting in `app/converter/config.py`. | +| `--single-file` | | Merge all chapters into a single file. `m4b` is always one file. | +| `--language <lang>` | `English` | Output language for the synthesized speech. May 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. Forces the `DEBUG` setting in `app/converter/config.py` on for this run. | +| `--api-url <url>` | `http://10.20.30.40:8080` | URL of an external TTS server. Accepts `host:port` or a full `http(s)://` URL. Without it the CLI starts and stops the backend's managed server itself. | +| `--model <id>` | `qwen3_tts_1_7b_base_q8_0` | `audiocpp`: Choose the TTS model from `server.json` (required on multi-model servers; auto-selected on single-model servers). `sglomni`: the catalog model key (e.g. `higgs_audio_v3_tts`; required when several models are installed) | +| `--option KEY=VALUE` | `emotion=neutral` | `audiocpp`: Some models support custom options with this (e.g. `emotion=neutral`) | +| `--clone <path>` | `./voices/speaker.wav` | Path to reference audio (`wav`) for voice cloning (e.g. `./voices`) | +| `--transcription "..."` | `"Hello! This is a sample of my voice."` | Override whisper auto-transcription with manual audio transcript. | +| `--no-transcription` | | Skip auto-transcription of the reference audio. | + +The TUI settings are configured in `app/converter/config.py` + +### Example Commands + +Use `--backend` and `--api-url` to point at an existing backend server. Otherwise without `--api-url`, TAG will start/stop its own managed server instance automatically (if installed via TUI) + ```bash python audiobook.py --backend audiocpp --model qwen3_tts_1_7b_base_q8_0 --voice narrator @@ -103,44 +99,13 @@ python audiobook.py --backend sglomni --model higgs_audio_v3_tts python audiobook.py --backend sglomni --model moss_tts_local --clone voices/narrator.wav python audiobook.py --backend sglomni --model qwen3_tts_1_7b_voicedesign \ - --instructions "A warm adult female narrator with a British accent" + --instructions "Warm adult female narrator with a British accent" python audiobook.py --backend audiocpp --api-url http://10.20.30.40:8080 --voice narrator python audiobook.py --input-file the_odyssey.epub --output-file the_odyssey.mp3 \ --format mp3 --single-file ``` - -## Options - -| Flag | Example | Description | -| ---------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `--backend {audiocpp,qwen,faster,sglomni}` | `audiocpp` | TTS server to use. Required: there is no default backend. | -| `--format {mp3,m4b,ogg,flac}` | `m4b` | Output format (default: the `AUDIO_FORMAT` setting in `app/converter/config.py`, `m4b`). | -| `--voice <name>` | `Vivian` | Voice to request. For `faster` this is the key in `voices.json` (required). For the Qwen CustomVoice model this is the speaker (Ryan, Vivian, etc.). For audio.cpp it is a server-side clone voice: required for clone-only families (e.g. Chatterbox), optional on mixed families and unused by pure-TTS models (e.g. Supertonic). | -| `--input <dir>` | `./input` | Directory containing the books to convert (default: the `INPUT_DIR` setting in `app/converter/config.py`, `./input`; relative paths resolve against the project root). | -| `--output <dir>` | `./output` | Directory to write finished audiobooks to (default: the `OUTPUT_DIR` setting in `app/converter/config.py`, `./output`). | -| `--input-file <file>` | `books/dune.epub` | Convert one specific book (`.txt`/`.pdf`/`.epub`) | -| `--output-file <file>` | `out/dune.mp3` | Base output path for the audiobook from `--input-file` | -| `--instructions "..."` | `"A warm adult female narrator with a British accent"` | Voice design or style instruction. Usually used for voice design models, some clone models also accept this. | -| `--speed <n>` | `1.0` | Playback speed, pitch-preserving (`1.0` = normal). A normal-speed copy is also output. Defaults to the `SPEED` setting in `app/converter/config.py`. | -| `--single-file` | | Merge all chapters into a single file. `m4b` is always one file. | -| `--language <lang>` | `English` | Output language for the synthesized speech. May 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. Forces the `DEBUG` setting in `app/converter/config.py` on for this run. | -| `--api-url <url>` | `http://10.20.30.40:8080` | URL of an external TTS server. Accepts `host:port` or a full `http(s)://` URL. Without it the CLI starts and stops the backend's managed server itself. | -| `--model <id>` | `qwen3_tts_1_7b_base_q8_0` | `audiocpp`: Choose the TTS model from `server.json` (required on multi-model servers; auto-selected on single-model servers). `sglomni`: the catalog model key (e.g. `higgs_audio_v3_tts`; required when several models are installed) | -| `--option KEY=VALUE` | `emotion=neutral` | `audiocpp`: Some models support custom options with this (e.g. `emotion=neutral`) | - -| Flag | Example | Description | -| ----------------------- | ---------------------------------------- | ------------------------------------------------------------------- | -| `--clone <path>` | `./voices/speaker.wav` | Path to reference audio (`wav`) for voice cloning (e.g. `./voices`) | -| `--transcription "..."` | `"Hello! This is a sample of my voice."` | Override whisper auto-transcription with manual audio transcript. | -| `--no-transcription` | | Skip auto-transcription of the reference audio. | - -Other options and defaults are configured in `app/converter/config.py` -(server URLs, output settings, etc.). The backend, model and voice are -always chosen per run — there are no config defaults for them. - ## Manual TTS Backend Setup If the TUI auto-install doesn't work for some reason, you may need to set up the backends manually. @@ -152,18 +117,9 @@ If the TUI auto-install doesn't work for some reason, you may need to set up the `./audiobook.py` can also connect to external servers running these backends if you want to completely manage your own install. The TUI will automatically look for and connect to the API URLs configured in settings. For CLI use, point at `--api-url` for an external server; without it the CLI starts and stops a locally-installed backend server around the run. -## 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. +Transcription affects the output a lot. The automatic Whisper transcript is not always perfect. 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. diff --git a/app/converter/config.py b/app/converter/config.py index d771e46..6fd65dd 100644 --- a/app/converter/config.py +++ b/app/converter/config.py @@ -12,14 +12,14 @@ CHUNK_SIZE = 250 # Where books are read from and where finished audiobooks are written. # Relative paths resolve against the project root. -INPUT_DIR = "./input" -OUTPUT_DIR = "./output" +INPUT_DIR = "/home/workhorse/projects/tts-audiobook-generator/input" +OUTPUT_DIR = "/home/workhorse/projects/tts-audiobook-generator/output" # Where voice-cloning reference .wavs live; the TUI Settings menu exposes # this as "Clone .wav directory" and the qwen-tts Base / SGLang-Omni voice # pickers list the .wav files found here. Relative paths resolve against # the project root. -CLONE_WAV_DIR = "./voices" +CLONE_WAV_DIR = "/home/workhorse/downloads/git/tts-audiobook-generator/voices" # Output audiobook file at a different tempo. SPEED = 1.0 diff --git a/app/demo.webp b/app/demo.webp Binary files differnew file mode 100644 index 0000000..d1c24f3 --- /dev/null +++ b/app/demo.webp |
