marcogenna /
epub2audiobook
Convert EPUB books to M4B audiobooks with AI-powered TTS (Edge TTS, Kokoro, Piper)
44/100 healthLoading repository data…
moonblade / repository
AI-powered EPUB to audiobook converter with expressive multi-voice narration, speaker detection, and natural prosody
A transparent discovery signal based on current public GitHub metadata.
This score does not audit code, security, maintainers, documentation quality, or suitability. Verify the repository and its current documentation before adoption.
AI-powered EPUB to audiobook converter with expressive multi-voice narration
Convert your EPUB ebooks into natural-sounding audiobooks with automatic speaker detection, multi-voice dialogue, and professional-grade prosody. Powered by Kokoro TTS.
Most EPUB-to-audio tools produce monotonous, robotic narration. This converter creates audiobooks that feel professionally narrated:
***, ---, ### markers| Content Type | Speed | Pause After |
|---|---|---|
| Narration | 1.0x | 0.3s |
| Dialogue | 1.05x | 0.2s |
| Internal thoughts | 0.92x | 0.25s |
| Chapter start | 0.95x | 1.5s |
| Scene break | — | 1.2s |
| Paragraph | — | 0.6s |
# Clone the repository
git clone https://github.com/moonblade/epub-to-audiobook.git
cd epub-to-audiobook
# Setup and run (models download automatically)
make run
Open http://localhost:3002 in your browser.
That's it! Upload an EPUB, select a voice, and watch the conversion progress in real-time.
make setup # Create venv, install deps, download models
make run # Start the server on port 3002
# Create virtual environment
python3.12 -m venv .venv
source .venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Download TTS models (~500MB)
mkdir -p models
curl -L -o models/kokoro-v1.0.onnx \
https://github.com/nazdridoy/kokoro-tts/releases/download/v1.0.0/kokoro-v1.0.onnx
curl -L -o models/voices-v1.0.bin \
https://github.com/nazdridoy/kokoro-tts/releases/download/v1.0.0/voices-v1.0.bin
# Run the server
uvicorn main:app --host 0.0.0.0 --port 3002
docker run -d \
--name epubtoaudio \
-p 3002:3002 \
-v ./input:/data/input \
-v ./output:/data/output \
ghcr.io/moonblade/epubtoaudio:latest
Or with docker-compose:
services:
epubtoaudio:
image: ghcr.io/moonblade/epubtoaudio:latest
ports:
- "3002:3002"
volumes:
- ./input:/data/input
- ./output:/data/output
restart: unless-stopped
The Docker image includes:
# Upload and start conversion
curl -X POST http://localhost:3002/upload \
-F "file=@mybook.epub" \
-F "voice=af_bella"
# Check job status
curl http://localhost:3002/jobs/{job_id}
# Download chapter
curl -O http://localhost:3002/jobs/{job_id}/audio/1
import requests
# Upload EPUB
with open("mybook.epub", "rb") as f:
response = requests.post(
"http://localhost:3002/upload",
files={"file": f},
data={"voice": "am_adam"}
)
job_id = response.json()["job_id"]
# Poll for completion
while True:
status = requests.get(f"http://localhost:3002/jobs/{job_id}").json()
if status["status"] == "completed":
break
time.sleep(5)
# Download audio
audio = requests.get(f"http://localhost:3002/jobs/{job_id}/audio/1")
| Variable | Default | Description |
|---|---|---|
EPUBTOAUDIO_UPLOAD_PATH | ./input | Directory for uploaded EPUB files |
EPUBTOAUDIO_OUTPUT_PATH | ./output | Directory for generated audio files |
# Custom paths
EPUBTOAUDIO_UPLOAD_PATH=/data/books \
EPUBTOAUDIO_OUTPUT_PATH=/data/audiobooks \
make run
Logs are stored in ~/Library/Logs/epubtoaudio/ with daily rotation.
# Tail the logs
make logs
| Male | Female |
|---|---|
| am_adam (default) | af_alloy |
| am_echo | af_aoede |
| am_eric | af_bella |
| am_fenrir | af_heart |
| am_liam | af_jessica |
| am_michael | af_kore |
| am_onyx | af_nicole |
| am_puck | af_nova |
| af_river | |
| af_sarah | |
| af_sky |
| Male | Female |
|---|---|
| bm_daniel | bf_alice |
| bm_fable | bf_emma |
| bm_george | bf_isabella |
| bm_lewis | bf_lily |
Voice preview: The web interface includes sample audio for each voice.
| Method | Endpoint | Description |
|---|---|---|
GET | / | Web interface |
POST | /upload | Upload EPUB and start conversion |
GET | /jobs | List all conversion jobs |
GET | /jobs/{id} | Get job status and progress |
POST | /jobs/{id}/stop | Pause a running conversion |
POST | /jobs/{id}/resume | Resume a paused conversion |
DELETE | /jobs/{id} | Delete job and all associated files |
GET | /jobs/{id}/logs | SSE stream of conversion logs |
GET | /jobs/{id}/audio/{chapter} | Download specific chapter MP3 |
GET | /voices | List all available voices |
POST /upload
Content-Type: multipart/form-data
file: EPUB file (required)
voice: Voice ID (default: am_adam)
upload_path: Custom input directory (optional)
output_path: Custom output directory (optional)
// Job Status
{
"job_id": "a1b2c3d4",
"status": "processing", // pending, processing, completed, failed, paused
"voice": "am_adam",
"epub_filename": "mybook.epub",
"progress": 45.2,
"current_chapter": 5,
"total_chapters": 12,
"error": null,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:35:00Z"
}
For 86-90% speaker attribution accuracy, install BookNLP:
pip install booknlp>=1.0.7
BookNLP uses BERT-based coreference resolution to attribute dialogue more accurately. It runs on CPU (~1.5-3GB memory).
Character voices are saved per book in voice_mappings/. When converting multiple chapters of the same book:
File naming convention: YYYY-MM-DD - Book Title - Chapter N.epub
epub-to-audiobook/
├── main.py # FastAPI application & endpoints
├── converter.py # EPUB parsing + TTS conversion engine
├── preprocessor.py # Expressive preprocessing (NEW)
├── voice_mapping_store.py # Persistent character-voice mappings (NEW)
├── job_manager.py # Job state persistence
├── log_store.py # Log persistence for SSE
├── models.py # Pydantic models
├── config.py # Configuration
├── logger.py # Logging with daily rotation
├── templates/ # Jinja2 HTML templates
├── static/ # CSS, favicon, voice samples
├── models/ # TTS model files (gitignored)
├── input/ # Uploaded EPUBs (gitignored)
├── output/ # Generated audio (gitignored)
├── jobs/ # Job state JSON (gitignored)
└── voice_mappings/ # Character voice assignments (gitignored)
make download-models
make logs for progressaf_bella and am_adam tend to sound best"Hello" not 'Hello'"text," said Johnpip install booknlpContributions are welcome! Please:
git checkout -b feature/amazing-featuremake testMIT License - see LICENSE for details.
Selected from shared topics, language and repository description—not editorial ratings.
marcogenna /
Convert EPUB books to M4B audiobooks with AI-powered TTS (Edge TTS, Kokoro, Piper)
44/100 health