Skip to main content

Convert EPUB and MOBI/AZW files to M4B audiobooks using Microsoft Edge TTS

Project description

Audiobookify

CI PyPI Python License

Convert EPUB and MOBI/AZW files to high-quality M4B audiobooks using Microsoft Edge's cloud-based text-to-speech.

Forked from epub2tts-edge with enhanced chapter detection, batch processing, and a terminal UI.

Requires an internet connection. Edge TTS is a cloud service: the text of every book you convert is sent to Microsoft's speech endpoint. There is no offline mode yet — see ROADMAP.md.

Features

  • Multi-Format Support - EPUB, MOBI, AZW, and AZW3 files
  • Enhanced Chapter Detection - Parses Table of Contents (EPUB2/EPUB3) and HTML headings
  • Batch Processing - Convert entire folders of ebooks at once
  • Terminal UI - Interactive interface for easy conversion
  • Smart Resume - Picks up where it left off if interrupted
  • Chapter Markers - Proper M4B chapter navigation
  • Cover Art - Automatically embeds cover images
  • Fast - Parallel sentence processing for quick conversion

New in v2.3.0

  • MOBI/AZW Support - Parse Kindle format ebooks (MOBI, AZW, AZW3)
  • Docker Support - Containerized deployment with docker-compose
  • Calibre Plugin - Convert books directly from Calibre library

New in v2.2.0

  • Audio Normalization - Consistent volume across chapters (--normalize)
  • Silence Trimming - Remove excessive pauses (--trim-silence)
  • Custom Pronunciation - Dictionary for proper nouns (--pronunciation)
  • Multiple Voices - Different voices for characters (--voice-mapping)

New in v2.1.0

  • Voice Preview - Listen to voices before converting (--preview-voice)
  • Speed/Volume Control - Adjust speech rate and volume (--rate, --volume)
  • Chapter Selection - Convert only specific chapters (--chapters "1-5")
  • Pause/Resume - Continue interrupted conversions (--resume)

Note: EPUB and MOBI/AZW files must be DRM-free

Quick Start

# Install (use pipx for isolated environment)
pipx install audiobookifier
# Or: pip install audiobookifier

# Convert a single EPUB
audiobookify mybook.epub              # Export to text
audiobookify mybook.txt               # Convert to audiobook

# Convert a MOBI/AZW file
audiobookify mybook.mobi              # Export to text
audiobookify mybook.azw3              # Export to text

# Or use the short alias
abfy mybook.epub

# Batch convert a folder
audiobookify /path/to/books --batch

# Launch interactive TUI
audiobookify --tui

Docker

The image runs as a non-root user (uid 1000). A bind-mounted directory keeps its host ownership, so pass --user "$(id -u):$(id -g)" unless your host uid already happens to be 1000 — otherwise the container cannot write the finished audiobook back into the mount, and you get a "Could not move audiobook" warning with the output stranded inside the container.

# Build the image
docker build -t audiobookify .

# Export EPUB to text
docker run --rm --user "$(id -u):$(id -g)" -e HOME=/tmp \
    -v $(pwd)/books:/books audiobookify /books/mybook.epub

# Convert to audiobook
docker run --rm --user "$(id -u):$(id -g)" -e HOME=/tmp \
    -v $(pwd)/books:/books audiobookify /books/mybook.txt

# Batch processing
docker run --rm --user "$(id -u):$(id -g)" -e HOME=/tmp \
    -v $(pwd)/books:/books audiobookify /books --batch

# Using docker-compose
docker-compose build
docker-compose run audiobookify /books/mybook.epub

-e HOME=/tmp is needed alongside --user because the overridden uid has no home directory in the image, and the job scratch directory lives under $HOME. Output is written next to the source file, so it lands in your mounted folder.

Calibre Plugin

Convert books directly from your Calibre library:

# Build the plugin
cd calibre_plugin
./build_plugin.sh

# Install in Calibre:
# 1. Preferences → Plugins → Load plugin from file
# 2. Select audiobookify-calibre.zip
# 3. Restart Calibre

See calibre_plugin/README.md for detailed instructions.

Usage

Single File Conversion

# Step 1: Export EPUB to text (review/edit chapters)
audiobookify mybook.epub

# Step 2: Convert text to audiobook
audiobookify mybook.txt --cover mybook.png

Batch Processing

# Process all EPUBs in a folder
audiobookify /path/to/books --batch

# Recursive (include subfolders)
audiobookify /path/to/library --batch --recursive

# Export only (no audio conversion)
audiobookify /path/to/books --batch --export-only

# Custom output directory
audiobookify /path/to/books --batch -o /path/to/audiobooks

Terminal UI

# Launch TUI
audiobookify /path/to/books --tui

# Or use dedicated command
audiobookify-tui /path/to/books

# Short alias
abfy-tui

Keyboard Shortcuts:

Key Action
s Start processing
Esc Stop
r Refresh files
a Select all
d Deselect all
p Preview voice
q Quit

Voice Preview & Adjustment (v2.1.0)

# List available voices
audiobookify --list-voices

# Preview a voice before converting
audiobookify --preview-voice                           # Preview default voice
audiobookify --preview-voice --speaker en-US-JennyNeural  # Preview specific voice

# Adjust speech rate
audiobookify mybook.txt --rate "+20%"   # 20% faster
audiobookify mybook.txt --rate "-10%"   # 10% slower

# Adjust volume
audiobookify mybook.txt --volume "+50%"  # Louder
audiobookify mybook.txt --volume "-25%"  # Quieter

# Combine adjustments
audiobookify mybook.txt --rate "+20%" --volume "-10%"

Chapter Selection (v2.1.0)

# Convert specific chapters only
audiobookify mybook.txt --chapters "1-5"       # Chapters 1 through 5
audiobookify mybook.txt --chapters "1,3,7"     # Chapters 1, 3, and 7
audiobookify mybook.txt --chapters "5-"        # Chapter 5 to end
audiobookify mybook.txt --chapters "1,3,5-7"   # Mix of single and ranges

Pause/Resume (v2.1.0)

# Resume an interrupted conversion
audiobookify mybook.txt --resume

# Start fresh (ignore saved progress)
audiobookify mybook.txt --no-resume

Conversions automatically save progress and can be resumed after Ctrl+C interruption.

Audio Normalization (v2.2.0)

# Normalize volume across chapters
audiobookify mybook.txt --normalize

# Custom target loudness (default: -16 dBFS)
audiobookify mybook.txt --normalize --normalize-target -14.0

# Use RMS method instead of peak
audiobookify mybook.txt --normalize --normalize-method rms

Silence Trimming (v2.2.0)

# Trim excessive silence
audiobookify mybook.txt --trim-silence

# Custom silence threshold (default: -40 dBFS)
audiobookify mybook.txt --trim-silence --silence-thresh -50

# Maximum silence duration (default: 2000ms)
audiobookify mybook.txt --trim-silence --max-silence 1500

Custom Pronunciation (v2.2.0)

Create a pronunciation dictionary file:

JSON format (pronunciation.json):

{
  "Hermione": "Her-my-oh-nee",
  "Voldemort": "Vol-de-mor",
  "Nguyen": "Win"
}

Text format (pronunciation.txt):

# Comments start with #
Hermione = Her-my-oh-nee
Voldemort = Vol-de-mor
# Use pronunciation dictionary
audiobookify mybook.txt --pronunciation pronunciation.json

# Case-sensitive matching
audiobookify mybook.txt --pronunciation pronunciation.txt --pronunciation-case-sensitive

Multiple Voices (v2.2.0)

Create a voice mapping file (voices.json):

{
  "default_voice": "en-US-AndrewNeural",
  "narrator_voice": "en-US-GuyNeural",
  "character_voices": {
    "Harry": "en-GB-RyanNeural",
    "Hermione": "en-GB-SoniaNeural",
    "Dumbledore": "en-GB-ThomasNeural"
  }
}
# Use voice mapping for multi-voice narration
audiobookify mybook.txt --voice-mapping voices.json

# Just set a different narrator voice (non-dialogue)
audiobookify mybook.txt --narrator-voice en-US-GuyNeural

The multi-voice processor automatically detects dialogue (quoted text) and attributes speakers.

Tip: See the examples/ folder for sample pronunciation and voice mapping files you can use as templates.

Chapter Detection Options

# Detection method
audiobookify mybook.epub --detect toc        # Table of Contents only
audiobookify mybook.epub --detect headings   # HTML headings only
audiobookify mybook.epub --detect combined   # Both (default)
audiobookify mybook.epub --detect auto       # Auto-select best

# Hierarchy display style
audiobookify mybook.epub --hierarchy flat       # Chapter 1
audiobookify mybook.epub --hierarchy numbered   # 1.1 Chapter 1
audiobookify mybook.epub --hierarchy arrow      # Part 1 > Chapter 1
audiobookify mybook.epub --hierarchy breadcrumb # Part 1 / Chapter 1

# Preview chapters without converting
audiobookify mybook.epub --preview

# Limit chapter depth
audiobookify mybook.epub --max-depth 2

All Options

Option Description
--speaker VOICE TTS voice (default: en-US-AndrewNeural)
--cover IMAGE Cover image (jpg/png)
--detect METHOD Detection: toc, headings, combined, auto
--hierarchy STYLE Display: flat, numbered, arrow, breadcrumb, indented
--max-depth N Maximum chapter depth
--preview Preview chapters only
--legacy Use original detection algorithm
--batch Batch processing mode
--recursive Scan subfolders
--output-dir DIR Output directory
--export-only Export to text only
--no-skip Don't skip already processed
--tui Launch terminal UI
--paragraphpause MS Pause between paragraphs (default: 1200)
--sentencepause MS Pause between sentences (default: 1200)
v2.1.0 Options
--list-voices List available voices
--preview-voice Preview the selected voice
--rate RATE Speech rate (e.g., "+20%", "-10%")
--volume VOL Volume adjustment (e.g., "+50%", "-25%")
--chapters RANGE Select chapters (e.g., "1-5", "1,3,7")
--resume Resume interrupted conversion
--no-resume Start fresh, ignore saved progress
v2.2.0 Options
--normalize Normalize audio volume across chapters
--normalize-target DBFS Target loudness (default: -16.0 dBFS)
--normalize-method METHOD Normalization method: peak or rms
--trim-silence Trim excessive silence from audio
--silence-thresh DBFS Silence threshold (default: -40 dBFS)
--max-silence MS Max silence duration before trimming (default: 2000)
--pronunciation FILE Path to pronunciation dictionary
--pronunciation-case-sensitive Case-sensitive pronunciation matching
--voice-mapping FILE Path to voice mapping JSON file
--narrator-voice VOICE Voice for narration (non-dialogue)

List available voices: audiobookify --list-voices or edge-tts --list-voices

Installation

Requirements: Python 3.11+, FFmpeg, espeak-ng

Quick Install (PyPI)

# Recommended: use pipx for isolated CLI installation
pipx install audiobookifier

# Or with pip in a virtual environment
pip install audiobookifier

Platform-Specific Setup

Linux
# Install system dependencies
sudo apt install espeak-ng ffmpeg python3-venv pipx

# Option 1: pipx (recommended for CLI tools)
pipx install audiobookifier

# Option 2: Virtual environment
git clone https://github.com/loganrooks/audiobookify
cd audiobookify
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
macOS
# Install system dependencies
brew install espeak ffmpeg pipx

# Option 1: pipx (recommended for CLI tools)
pipx install audiobookifier

# Option 2: Virtual environment
git clone https://github.com/loganrooks/audiobookify
cd audiobookify
python3 -m venv .venv
source .venv/bin/activate
pip install -e .
Windows
  1. Install Python 3.11+
  2. Install espeak-ng (x64 msi)
  3. Install FFmpeg and add to PATH
# Option 1: pipx (recommended)
pip install pipx
pipx install audiobookifier

# Option 2: Virtual environment
git clone https://github.com/loganrooks/audiobookify
cd audiobookify
py -m venv .venv
.venv\Scripts\activate
pip install -e .
Docker

The image runs as uid 1000; pass --user so it can write into your bind mount (see Docker above).

docker build . -t audiobookify

# Export EPUB
docker run --rm --user "$(id -u):$(id -g)" -e HOME=/tmp \
    -v ~/Books:/files audiobookify "/files/mybook.epub"

# Convert to audiobook
docker run --rm --user "$(id -u):$(id -g)" -e HOME=/tmp \
    -v ~/Books:/files audiobookify "/files/mybook.txt"

Development Install

git clone https://github.com/loganrooks/audiobookify
cd audiobookify
./scripts/setup-dev.sh   # system deps, venv, dev extras, NLTK data, pre-commit
./scripts/doctor.sh      # report what your environment can verify

Running Tests

# Run all tests (no network calls; TTS is mocked)
python -m pytest tests/

# Run with coverage
python -m pytest tests/ --cov=epub2tts_edge --cov-report=html

Tests requiring ffmpeg skip automatically if it isn't installed. The live Edge TTS connectivity tests in tests/test_tts_connectivity.py do make real network calls — set SKIP_TTS_TESTS=1 to skip them (CI does this, and runs them separately on a schedule).

Documentation

For users

For contributors

  • CONTRIBUTING.md - Development setup and contribution guidelines
  • Project Review - Current state of the codebase and infrastructure
  • Uplift Plan - Sequenced engineering priorities
  • docs/ - Architecture notes, testing strategy, and design records

Credits

Original Author: Christopher Aedo (epub2tts-edge)

Fork Maintainer: loganrooks

Contributing

Contributions welcome! See CONTRIBUTING.md.

License

GPL 3.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

audiobookifier-2.6.0.tar.gz (211.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

audiobookifier-2.6.0-py3-none-any.whl (159.6 kB view details)

Uploaded Python 3

File details

Details for the file audiobookifier-2.6.0.tar.gz.

File metadata

  • Download URL: audiobookifier-2.6.0.tar.gz
  • Upload date:
  • Size: 211.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for audiobookifier-2.6.0.tar.gz
Algorithm Hash digest
SHA256 b1794a9ffac59393b286a067220c48212b3d515e4bc9751e1eb49841e95631c5
MD5 6360461cda1e81f57e0fd75aaafa39b0
BLAKE2b-256 948ad4107aa75cc0135d1f3676e98528e8e0c26d931b2b0c3cafd81073ad88a9

See more details on using hashes here.

Provenance

The following attestation bundles were made for audiobookifier-2.6.0.tar.gz:

Publisher: release.yml on loganrooks/audiobookify

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file audiobookifier-2.6.0-py3-none-any.whl.

File metadata

  • Download URL: audiobookifier-2.6.0-py3-none-any.whl
  • Upload date:
  • Size: 159.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for audiobookifier-2.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 35c3eb0cf932d67f3d2e93b3f693242ef843cfb3074961768ae8b90b7d6909a8
MD5 a5266291369de7a04f7a4f0419a0528b
BLAKE2b-256 274de48094e91d8a3611161066d1040b4b47e3095eb69f4cb2d06a6a15e108ab

See more details on using hashes here.

Provenance

The following attestation bundles were made for audiobookifier-2.6.0-py3-none-any.whl:

Publisher: release.yml on loganrooks/audiobookify

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page