Convert Ebooks to Audiobooks with [custom] voice samples
Project description
kenkui
Ebook-to-audiobook conversion engine for Python clients.
kenkui is a Python library that converts ebooks into high-quality M4B audiobooks using Kyutai's pocket-tts, running entirely on CPU.
Looking for the interactive CLI? Install kentui — it's the interactive front-end built on top of this library.
Install
pip install kenkui
Or with uv:
uv add kenkui
Quick Start
from pathlib import Path
import kenkui
# Load config (creates default at ~/.config/kenkui/config.toml on first run)
config = kenkui.load_config()
# Build a ProcessingConfig. Client apps own prompts, queues, and transport.
proc = kenkui.ProcessingConfig(
voice="alba",
ebook_path=Path("book.epub"),
output_path=Path("."),
pause_line_ms=config.pause_line_ms,
pause_chapter_ms=config.pause_chapter_ms,
workers=config.workers,
m4b_bitrate=config.m4b_bitrate,
keep_temp=config.keep_temp,
debug_html=False,
chapter_filters=[],
)
# Run the conversion
ok = kenkui.run_job(proc)
Features
- Freaky fast M4B audiobook generation — 100% CPU, no GPU
- Multithreaded chapter processing
- Supports EPUB, MOBI/AZW/AZW3/AZW4, and FB2
- Multi-voice narration via NLP speaker attribution (Ollama, Anthropic, OpenAI, Google, OpenRouter, LiteLLM)
- Voice pool template for automatic voice assignment by role + gender + rank
- Chapter-voice mode: distinct voice per chapter
- Broadcast-quality audio post-processing chain
- Credits chapter: synthesized audio appended to every m4b
- Flexible chapter selection (presets + manual override)
- Series support: cross-book character roster with pinned voice assignments
Library Boundary
kenkui is the reusable core. It owns parsing, config models, NLP/cache logic,
voice selection, rendering workers, post-processing, and public dataclasses.
External clients own user interaction, deployment policy, notifications, and
remote execution. kenkui also exposes the local HTTP API used by GUI clients.
kentui is the interactive terminal client.
API Reference
Config
config = kenkui.load_config() # default config
config = kenkui.load_config("fast-mode") # named config
config = kenkui.load_config("/path/to/cfg.toml")
kenkui.save_config(config)
kenkui.save_config(config, "fast-mode")
names: list[str] = kenkui.list_configs()
Book parsing
result = kenkui.parse_book("book.epub")
# result.chapters, result.metadata, result.book_hash
filtered = kenkui.filter_chapters(result.book_hash, selection)
NLP
# Stage 1-2: entity scan + character clustering
scan = kenkui.fast_scan("book.epub", nlp_model="llama3.2")
# scan.characters: list[CharacterInfo]
# Stages 1-4: full pipeline with speaker attribution
result = kenkui.full_analysis(
"book.epub",
nlp_model="llama3.2",
progress_callback=lambda pct, msg: print(f"{pct}% {msg}"),
)
# result.characters, result.chapters (annotated)
Voices
voices = kenkui.list_voices()
voices = kenkui.list_voices(gender="Female", accent="British", origin="kenkui_compiled")
voice = kenkui.get_voice("alba") # VoiceInfo | None
cast = kenkui.suggest_cast(
roster=scan.characters,
default_voice="sarah",
)
# cast.speaker_voices: dict[character_id, voice_id]
narrator = kenkui.recommend_narrator(scan.characters, default_voice="alba")
kenkui.set_voice_pool_enabled("marius", False)
preview = kenkui.prepare_voice_preview("alba", text="Hello world.")
# preview.audio_path, preview.duration_ms
dl = kenkui.download_voice(force=False) # DownloadResult
Series
series_list = kenkui.list_series()
entry = kenkui.get_series("my-series")
entry = kenkui.create_series("My Series")
kenkui.update_series(entry)
HuggingFace auth
result = kenkui.authenticate_huggingface("hf_token_here")
# result.authenticated, result.username
Job runner
from pathlib import Path
from kenkui import ProcessingConfig
from kenkui.chapter_filter import FilterOperation
config = ProcessingConfig(
voice="alba",
ebook_path=Path("book.epub"),
output_path=Path("."),
pause_line_ms=800,
pause_chapter_ms=2000,
workers=4,
m4b_bitrate="96k",
keep_temp=False,
debug_html=False,
chapter_filters=[FilterOperation("preset", "content-only")],
)
ok: bool = kenkui.run_job(config)
ok: bool = kenkui.run_job(
config,
progress_callback=lambda pct, chapter, eta: print(f"{pct:.0f}% {chapter}"),
)
Voice System
Voices come in three tiers:
| Tier | Source | Auth required? |
|---|---|---|
| Compiled | Downloaded from HuggingFace on first run | No |
| Built-in | Pocket TTS defaults bundled by kenkui | No |
| Custom | User-provided prompt sources compiled locally | No |
Built-in voices: alba, marius, javert, cosette, jean, fantine, eponine, azelma, anna, vera, charles, paul, george, mary, jane, michael, eve, bill_boerst, caro_davy, peter_yearsley, stuart_bell
Configuration
kenkui uses TOML config files stored under the XDG config directory, typically
~/.config/kenkui/. Cache/state files live under the XDG cache directory,
typically ~/.cache/kenkui/.
Settings are environment-aware through the KENKUI_ prefix. Environment values
take precedence when constructing AppConfig; saved TOML files remain the local
convenience path for desktop clients.
| Key | Default | Description |
|---|---|---|
workers |
cpu_count - 2 |
Parallel TTS worker processes |
m4b_bitrate |
96k |
Output audio bitrate |
temp |
0.7 |
Sampling temperature |
lsd_decode_steps |
1 |
LSD decode steps |
default_voice |
alba |
Fallback voice |
nlp_provider |
ollama |
NLP backend |
nlp_model |
llama3.2 |
Model for speaker attribution |
credits_enabled |
true |
Append synthesized credits audio |
Logging is 12-factor friendly: library modules log through Python logging and do not require file logging. Clients may configure stdout/stderr or file handlers. Credentials should be supplied through the environment or explicit client-owned auth flows. Local credential files are convenience only, not the preferred deployment path.
Non-Goals
kenkui is not a general-purpose TTS framework, GUI app, CLI, queue server, cloud control plane, benchmarking system, or MP3 generator. The focus is narrow: fast, high-quality audiobook generation from ebooks.
Special Thanks
Thanks to Project Gutenberg for providing some of the public-domain books included with kenkui.
Voice Dataset Credits
kenkui's compiled voices are derived from two publicly available speech corpora.
CSTR VCTK Corpus
Veaux, Christoph; Yamagishi, Junichi; MacDonald, Kirsten. (2019). CSTR VCTK Corpus: English Multi-speaker Corpus for CSTR Voice Cloning Toolkit. University of Edinburgh. The Centre for Speech Technology Research (CSTR).
Licensed under Creative Commons Attribution 4.0 (CC BY 4.0). Commercial use is permitted with attribution.
EARS Dataset
Licensed under Creative Commons Attribution-NonCommercial 4.0 (CC BY-NC 4.0).
Note: Compiled voices sourced from EARS (identifiable by the
datasetfield viakenkui.list_voices()) may not be used for commercial purposes. If you are building a commercial product with kenkui, use only VCTK-sourced or built-in voices.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kenkui-2.3.0.tar.gz.
File metadata
- Download URL: kenkui-2.3.0.tar.gz
- Upload date:
- Size: 11.0 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9f697df4e470316e8b759513f13ed942b044ad6b02680d76a0f60113336d7211
|
|
| MD5 |
ca78215ec8b2e073c942ce87c512697f
|
|
| BLAKE2b-256 |
b33a9b6af3d59e453ab8c8bbf7c5e11be7eaccf0395dd58441917ddb5e1649d4
|
File details
Details for the file kenkui-2.3.0-py3-none-any.whl.
File metadata
- Download URL: kenkui-2.3.0-py3-none-any.whl
- Upload date:
- Size: 10.9 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.25 {"installer":{"name":"uv","version":"0.11.25","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
30081f65cec7125a502f86ba7324b1b629566cec87b89d779c0c0101340863f2
|
|
| MD5 |
ae2664b89df871c3d51653174bae6eec
|
|
| BLAKE2b-256 |
64313754ee4505c829a1f72e1c498011021be774e4c1c68c25a6a8f2cd577e52
|