The audiobook generator that reads for you.
An open-source audiobook generator that turns public-domain classics into narrated audiobooks with distinct voices per character — 100% free either way, and offline-capable if you want zero cloud dependency.
It parses a book (TXT or EPUB only — no PDF yet, see below), detects who speaks each line with an LLM, assigns a consistent voice to every character, and synthesizes natural-sounding audio with a neural TTS engine. Both the LLM and the TTS engine are swappable between a local, fully offline provider and a free cloud API — see Prerequisites.
Why I built this.
Reading is a joy; finding the time is not. I wanted a tool that reads a book to me the way I would read it aloud myself — with different voices for different characters, and no cloud dependency deciding whether the project works today. Everything here runs on your own machine, and it costs nothing.
Status: ✅ v0.2.0 Desktop GUI & CLI Production Ready. All core pipeline capabilities across text/EPUB parsing, LLM-based dialog attribution, voice mapping, neural TTS synthesis with Piper/Edge, SQLite persistence, BYOK (Bring Your Own Key) for cloud providers (NVIDIA NIM, OpenRouter, Gemini), and a native Desktop GUI (Tauri v2 + Vue 3) with full i18n support (Spanish 🇪🇸 / English 🇺🇸) are fully implemented and verified.
A structured pipeline that turns plain text into a multi-voice audiobook via a Desktop GUI or CLI:
parse ──► extract characters ──► assign voices ──► attribute dialog ──► synthesize ──► assemble
│ (LLM) (tone-aware) (LLM, chunked) (TTS) (audio)
v v v v v v
TXT/EPUB Who's in the Unique voice Who says each Per-line MP3 / M4B
→ paragraphs book? Canonical per character, line, with speech, with
IDs + aliases filtered by emotion async, chapter
gender/age/tone metadata
The core pipeline is provider-agnostic: every external dependency (LLM, TTS) sits behind a small interface. Run it fully offline with Ollama + Piper if you have the hardware, or fully via cloud APIs with BYOK (NVIDIA NIM, OpenRouter, Gemini, Edge TTS) if you don't — see Extension model.
Supported input: TXT and EPUB only — no PDF. This was a deliberate scope decision (see the dev plan's tech-stack notes): OCR quality on scanned classics is poor and would quietly wreck dialog attribution, while EPUB already ships clean chapter/paragraph structure. If you have a PDF, convert it to EPUB or TXT first — Calibre does this for free. PDF support is a welcome contribution if someone wants to tackle a solid extraction path (e.g. pdfplumber + layout-aware chapter detection) behind the same BookParser interface as TextParser/EpubParser — see Extension model and Contributing.
- Python 3.10+ — required either way.
- ffmpeg — required either way (audio assembly).
- Rust & Node.js (Optional) — required only if building the Desktop GUI from source (
cargo tauri dev).
Pick one LLM path and one TTS path; they're independent, so you can mix (e.g. cloud LLM + local TTS):
| Local (offline, $0, no account) | Cloud (API, BYOK / Free Tier, no local compute) | |
|---|---|---|
| LLM | Ollama running (ollama serve) with a model: ollama pull qwen2.5:7b |
NVIDIA NIM (nim), OpenRouter (openrouter), or Gemini (gemini) with your own API Key (BYOK) |
| TTS | Piper binary on PATH (lightweight, CPU-only — models auto-download on first use) |
AUDIOBARD_TTS_PROVIDER=edge (Microsoft Edge TTS, no API key, no SLA) |
If your machine can't comfortably run a local 7B model (no GPU, limited RAM), the cloud path with BYOK (Bring Your Own Key) needs nothing more than Python — no local model download at all. You can enter your API Key directly in the Desktop GUI Settings modal or set a working .env:
# Example: NVIDIA NIM Cloud Provider (build.nvidia.com)
AUDIOBARD_LLM_PROVIDER=nim
AUDIOBARD_LLM_MODEL=meta/llama-3.3-70b-instruct
NVIDIA_NIM_API_KEY=nvapi-your_key_here
AUDIOBARD_TTS_PROVIDER=edgeYou can also use NVIDIA NIM models, OpenRouter (AUDIOBARD_LLM_PROVIDER=openrouter), or Google Gemini (AUDIOBARD_LLM_PROVIDER=gemini).
# Clone and install dependencies
git clone https://github.com/oscarbol09/audiobard.git
cd audiobard
pip install -e ".[dev,llm-gemini,llm-ollama,tts-piper]"
# Launch the Desktop GUI
cargo tauri devThe Desktop GUI features:
- 📄 Drag & Drop Upload: Simply drop any
.txtor.epubfile to start. - 🌐 Multi-Language UI (i18n): Instant toggle between Spanish (🇪🇸) and English (🇺🇸).
- ⚙️ BYOK Settings Modal: Configure API keys, server URLs, custom models, themes, output directory, and cache cleaner.
- 📚 Personal Audiobook Library: Search, play, or regenerate previously converted audiobooks.
# Generate an audiobook via CLI
audiobard generate book.epub --output audiobook.mp3
# Or run a dry-run to test character extraction and dialog attribution without synthesis
audiobard generate book.epub --dry-run📖 PDF2Bard — PDF to EPUB Converter for AudioBard
AudioBard accepts EPUB and TXT files natively. If your book is currently in PDF format, use our dedicated companion converter:
👉 PDF2Bard (oscarbol09/pdf2bard)
- 🧩 Smart Paragraph Reflow: Unwraps hard visual line breaks while respecting genuine paragraph and dialogue boundaries.
- ✂️ Automatic De-Hyphenation: Reconnects split words across margins without altering legitimate hyphenated words.
- 🧹 Header & Footer Stripper: Detects and strips page numbers, running headers, and disclaimers so the narrator doesn't read them aloud.
- 💬 Dialogue Integrity: Preserves and normalizes em-dashes (
—), guillemets («»), and quotes for character attribution.
| Command / Interface | What it does |
|---|---|
cargo tauri dev |
Launch the Desktop GUI in development mode |
cargo tauri build |
Build standalone desktop executable installer (.exe / .msi) |
audiobard generate <book> -o <out> |
Full CLI pipeline: parse → attribute → synthesize → assemble |
audiobard generate <book> --dry-run |
Parse + LLM attribution only — no synthesis (fast prompt iteration) |
audiobard doctor |
Check environment, dependencies, FFmpeg, Piper, Ollama, API keys, and cache |
audiobard benchmark --llm <provider> |
Attribution accuracy against the gold standard (see eval/README.md) |
audiobard stats |
Cache hit rate, books processed, and disk cache usage |
audiobard voices --locale en_US |
List available TTS voices for a locale |
audiobard validate-config |
Check config, providers, and ethics guardrails |
audiobard/
├── src/audiobard/
│ ├── cli.py # CLI entry point (Typer app)
│ ├── config.py # Pydantic settings
│ ├── doctor.py # Environment diagnostics
│ ├── parser/ # TXT/EPUB parsers (BookParser ABC)
│ ├── llm/ # LLM clients (LLMClient ABC) + versioned prompts
│ ├── tts/ # TTS providers (TTSProvider ABC) + voice mapper
│ ├── audio/ # Audio assembly (pydub/ffmpeg)
│ ├── pipeline.py # Orchestrator
│ └── persistence.py # SQLite: speakers, voices, cache, runs
├── gui/ # Vue 3 + Tailwind CSS frontend
├── src-tauri/ # Tauri v2 native desktop application wrapper
├── tests/ # pytest suite (236+ unit & integration tests)
├── eval/
│ ├── gold_standard/ # Hand-labeled dialog attribution (immutable)
│ └── benchmark.py # Accuracy scorer
├── data/
│ ├── books/ # Sample books (gitignored — public domain only)
│ └── voices/ # Regional voice metadata pools (en_US, es_MX, es_CO, es_ES)
├── tools/
│ ├── guards.py # Security & supply-chain guards run by CI
│ └── lint_skills.py # Prompt/skill linting
├── .github/workflows/ # CI, benchmark, notifications
└── docs/ # Provider and prompt-engineering guides
The generate command runs the pipeline above:
- Parse — TXT/EPUB → paragraphs with chapter and line metadata; Project Gutenberg headers/footers stripped.
- Extract characters (LLM) — the LLM returns canonical IDs (
Character_A, …), aliases, tone, and gender/age hints, validated against a Pydantic schema. - Assign voices — voices are chosen from a tone-aware pool: filtered by gender/age first, scored by tone similarity, with a deterministic hash tie-break so the same book always maps to the same voices.
- Attribute dialog (LLM, chunked) — every line gets a speaker + emotion; chunks of ~1500 words with a 5-paragraph sliding window resolve ambiguous attribution; results validated by Pydantic (drop-and-retry on schema mismatch).
- Synthesize (TTS, async) — per-line speech with emotion→prosody mapping (rate/pitch/pause), local disk cache keyed by
(text, voice, emotion). - Assemble — clips joined with configurable silence gaps, volume normalized, exported as MP3 or M4B with chapter metadata. CPU-bound audio work runs in a thread pool; the LLM/TTS I/O is fully async.
Two properties make the output trustworthy:
- Voice consistency across chapters — the speaker↔voice mapping is persisted in SQLite (
book_id + canonical_id), so a character never changes voice between chapters, and never gets re-assigned. - No fabricated speech — the LLM may only output speaker IDs from the canonical character list extracted in step 2; anything else is retried, then rejected.
External dependencies are pluggable by design, with zero code changes — just config:
# config.yaml
llm:
provider: ollama # ollama | gemini | openrouter
model: qwen2.5:7b
tts:
provider: piper # piper | edge
locale: en_USLLMClient—ollama_client(offline, primary),gemini_client(opt-in cloud, native JSON mode),openrouter_client(opt-in fallback).TTSProvider—piper_provider(offline, primary),edge_provider(opt-in cloud; note it has no SLA — see SECURITY.md).BookParser—text_parser,epub_parser.
Adding a provider = one class in one file + one config example + tests. See docs/adding-a-provider.md for the walkthrough and docs/prompt-engineering.md for how the versioned LLM prompts are structured and tuned.
Thinking about a PR? Read CONTRIBUTING.md first — it states the one rule everything follows from, what gets merged, what gets declined, and why. All contributions are governed by the Code of Conduct.
Quick orientation for new contributors: the repo ships labeled issues — good first issue for onboarding, help wanted for meatier tasks, and ethics-review for features that touch identity or consent.
AudioBard converts public-domain text to audio. The following are explicitly out of scope, and require an ethics-review RFC before any implementation PR is accepted: voice cloning without consent, DRM circumvention, impersonation/deepfakes, and bulk generation for spam. Full policy in the development plan, §10 and the ethics-review issue.
AudioBard is designed exclusively for public-domain works (e.g., Project Gutenberg, LibriVox, Standard Ebooks). The user is solely responsible for verifying the copyright status of any text before processing it.
- This software does not validate, enforce, or assume copyright ownership of input material.
- Generating audiobooks from copyrighted works without authorization may infringe the rights of authors, publishers, and voice artists.
- The tool is provided "as is" under the MIT License — see LICENSE. The authors disclaim all warranties and liability for how the software is used, including any copyright infringement by end users.
- No warranty of fitness for a particular purpose, non-infringement, or merchantability is implied.
If you are a rights holder and believe this software is being used to infringe your copyright, please follow standard DMCA/notice-and-takedown procedures with the hosting platform.
MIT — see LICENSE. The gold standard dataset (eval/gold_standard/) is CC0.