ebook2audiobook

DrewThomassonApache-2.0活跃维护

把电子书(EPUB 等)一键转成有声书,内置 50 多种 TTS 引擎,支持声音克隆和 1696 种语言,适合批量制作多语言音频书。

Generate audiobooks from e-books, 50+ TTS engines with voice cloning and 1696 languages!

v26.11.1发布于 2026-11-08 13:18 UTC20,527star +13 / 7 天1,750fork同步于 2026-11-10 23:25 UTC

怎么上手

由 README 提炼,执行前请确认
git clone https://github.com/DrewThomasson/ebook2audiobook.git
cd ebook2audiobook
./ebook2audiobook.command
硬件要求按 README 说明

最低 2GB 内存、1GB 显存,推荐 8GB 内存、4GB 显存;支持 CPU、Intel/AMD/ARM XPU、CUDA、ROCm、JETSON 和 Apple Silicon MPS,但现代 TTS 引擎在 CPU 上很慢,建议改用 YourTTS、Tacotron2 等低质量引擎。

支持 Apple Silicon需要 CUDA支持 ROCm / AMD有 Docker 镜像
下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

把电子书转成带章节和元数据的有声书,支持语音克隆和 1696 种语言

把电子书(EPUB 等)一键转成有声书,内置 50 多种 TTS 引擎,支持声音克隆和 1696 种语言,适合批量制作多语言音频书。

核心能力

  • 内置 50+ TTS 引擎,可按质量与速度取舍
  • 自动识别章节并写入有声书元数据
  • 支持用自定义语音文件克隆音色
  • 支持 SML 标签控制停顿、换声与情绪
  • 支持 OCR 扫描图片型文本页

容易踩的坑

首次运行会自动安装依赖,Windows 用 scoop、macOS 用 homebrew,需要联网;Web 界面默认在 http://localhost:7860/,脚本重启后需刷新页面重连;EPUB 没有标准章节结构,转换前应手动删掉不想转成音频的文本。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v26.11.1
  1. v26.11.1最新正式版2026-11-08 · 2026-11-08 13:18 UTC

    What's Changed

    Full Changelog: https://github.com/DrewThomasson/ebook2audiobook/compare/v26.10.1...v26.11.1

    What's new?

    • Added 38 new TTS engines!
    • Hundreds of optimizations and bugs fixed, sound improvment
    • translate_ebook.cmd and translate_ebook.sh to translate ebooks to ebooks in 50+ languages
    • preload_models to load a maximum of models and be free to convert offline (warning depending your language it can take several TB)
    • replacement of knn-vc with seed-vc, chatterbox vc and qwen3-tts
    • Miniforge3 replaced by uv
    • Each sentence converted and interlude editable
    • 538 languages added
    • tooltips option
    • multilingual gradio UI
    • vulkan support for all TTS compatible
  2. v26.10.12026-10-05 · 2026-10-05 02:39 UTC
    查看更新说明

    What's Changed

    Full Changelog: https://github.com/DrewThomasson/ebook2audiobook/compare/v26.9.25...v26.9.26

    Full Changelog: https://github.com/DrewThomasson/ebook2audiobook/compare/v26.9.26...v26.9.27

    Full Changelog: https://github.com/DrewThomasson/ebook2audiobook/compare/v26.9.27...v26.10.1

    New features!

    • Removed Miniforge3 to UV for python venv and all python package management
    • Added cuda 13.2 compat
    • Upgraded to gradio 6.29.1
    • Many other archtecture improvements and fixes
    • Added music interludes generator as optional with music intro and outro
    • GUI gradio interface covers now 22 languages, the language can also be selected via the dropdo
  3. v26.9.72026-09-09 · 2026-09-09 19:15 UTC
    查看更新说明

    What's Changed

    Full Changelog: https://github.com/DrewThomasson/ebook2audiobook/compare/v26.8.20...v26.9.7

    !!! IMPORTANT !!! IF YOU UPDATE with "git pull" DELETE THE CONTENT OF ./tmp and ./run FOLDER BEFORE INSTALLING THIS VERSION. after that if you stilll have errors on installation, remove Miniforge3 and scoop if possible (windows only) from your user root directory.

    NOTE: if you are on windows and crash with DLL missing etc.... just uninstall completely ffmpeg and calibre then reinstall E2A.

  4. v26.8.202026-08-22 · 2026-08-22 21:27 UTC
    查看更新说明

    What's Changed

    Full Changelog: https://github.com/DrewThomasson/ebook2audiobook/compare/v26.8.3...v26.8.20

    New Feature

    • Audiobookshelf (see ./lib/conf.py for default settings for gradio and --help for new headless options)

    !!! IMPORTANT !!! IF YOU UPDATE with "git pull" DELETE THE CONTENT OF ./tmp and ./run FOLDER BEFORE INSTALLING THIS VERSION. after that if you stilll have errors on installation, remove Miniforge3 and scoop if possible (windows only) from your user root directory.

    NOTE: if you are on windows and crash with DLL missing etc.... just uninstall completely ffmpeg and calibre then reinstall E2A.

    Mention: big thanks to @Anonimasu1

  5. v26.7.272026-07-31 · 2026-07-31 02:23 UTC
    查看更新说明

    What's Changed

    New Contributors

    Full Changelog: https://github.com/DrewThomasson/ebook2audiobook/compare/v26.7.16...v26.7.23 https://github.com/DrewThomasson/ebook2audiobook/compare/v26.7.23...v26.7.27

    !!! IMPORTANT !!! IF YOU UPDATE with "git pull" DELETE THE CONTENT OF ./tmp and ./run FOLDER BEFORE INSTALLING THIS VERSION. after that if you stilll have errors on installation, remove Miniforge3 and scoop if possible (windows only) from your user root directory.

    NOTE: if you are on windows and crash with DLL missing etc.... just uninstall completely ffmpeg and calibre then reinstall E2A.

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    📚 ebook2audiobook (E2A)

    CPU/GPU Converter from E-Book to audiobook with chapters and metadata using advanced TTS engines and much more. Supports voice cloning and 1696 languages!

    [!IMPORTANT] This tool is intended for use with non-DRM, legally acquired eBooks only. The authors are not responsible for any misuse of this software or any resulting legal consequences. Use this tool responsibly and in accordance with all applicable laws.

    Discord

    Thanks to support ebook2audiobook developers!

    Run locally

    Quick Start Docker Build Download

    Run Remotely

    Hugging Face Free Google Colab Kaggle

    GUI Interface

    demo_web_gui

    Demos

    New Default Voice Demo

    https://github.com/user-attachments/assets/750035dc-e355-46f1-9286-05c1d9e88cea

    ASMR Voice

    https://github.com/user-attachments/assets/68eee9a1-6f71-4903-aacd-47397e47e422

    Rainy Day Voice

    https://github.com/user-attachments/assets/d25034d9-c77f-43a9-8f14-0d167172b080

    Scarlett Voice

    https://github.com/user-attachments/assets/b12009ee-ec0d-45ce-a1ef-b3a52b9f8693

    David Attenborough Voice

    https://github.com/user-attachments/assets/81c4baad-117e-4db5-ac86-efc2b7fea921

    Example

    Example

    README.md

    Table of Contents

    Features

    • 🔧 TTS Engines supported: XTTSv2, Bark, Fairseq, VITS, Tacotron2, Tortoise, GlowTTS, YourTTS, Piper, Zonos, GPT-SoVITS, OmniVoice, Breeze TTS, Chatterbox, Confucius4 TTS, CosyVoice3, Dots TTS, DramaBox, FireRed Audio, FireRedTTS3, Fish Audio, Higgs Audio TTS, Index TTS2, Irodori TTS, Kokoro TTS, KugelAudio, Magpie TTS, Maya1, MioTTS, Moss TTS Local, Moss TTS Nano, NeuTTS, Pocket TTS, Qwen3 TTS, Supertonic, VibeVoice, VoxCPM2, Voxtral TTS, F5-TTS, Orpheus-TTS, ChatTTS, Spark-TTS, OpenVoice, MeloTTS
    • 📚 Convert multiple file formats: .epub, .mobi, .azw3, .fb2, .lrf, .rb, .snb, .tcr, .pdf, .txt, .rtf, .doc, .docx, .html, .odt, .azw, .tiff, .tif, .png, .jpg, .jpeg, .bmp, .zip
    • 💻 TextArea to convert directly a short text in audio
    • 🔍 OCR scanning for files with text pages as images
    • 🔊 High-quality text-to-speech from near realtime to near real voice
    • 🗣️ Optional voice cloning using your own voice file
    • 🌐 Supports 1696 languages (supported languages list)
    • 💻 Low-resource friendly — runs on 2 GB RAM / 1 GB VRAM (minimum)
    • 🎵 Audiobook output formats: mono or stereo aac, flac, mp3, m4b, m4a, mp4, mov, ogg, wav, webm
    • 🧠 SML tags supported — fine-grained control of breaks, pauses, voice switching and more (see below)
    • 🧩 Optional custom model using your own trained model (XTTSv2, VITS, FAIRSEQ, PIPER, others on request)
    • 🎛️ Fine-tuned preset models trained by the E2A Team (Contact us if you need additional fine-tuned models, or if you’d like to share yours to the official preset list)

    Hardware Requirements

    • 2GB RAM min, 8GB recommended.
    • 1GB VRAM min, 4GB recommended.
    • Virtualization enabled if running on windows (Docker only).
    • CPU, XPU (intel, AMD, ARM)*.
    • CUDA, ROCm, JETSON
    • MPS (Apple Silicon CPU)

    * Modern TTS engines are very slow on CPU, so use lower quality TTS like YourTTS, Tacotron2 etc..

    Supported Languages

    +1696 languages here

    Supported eBook Formats

    • .epub, .pdf, .mobi, .txt, .html, .rtf, .chm, .lit, .pdb, .fb2, .odt, .cbr, .cbz, .prc, .lrf, .pml, .snb, .cbc, .rb, .tcr
    • Best results: .epub or .mobi for automatic chapter detection

    Output and process Formats

    • .m4b, .m4a, .mp4, .webm, .mov, .mp3, .flac, .wav, .ogg, .aac
    • Process format can be changed in lib/conf.py

    SML tags available

    • [break] — silence (random range 0.3–0.6 sec.)
    • [pause] — silence (random range 1.0–1.6 sec.)
    • [pause:N] — fixed pause (N sec.)
    • [voice:/path/to/voice/file]...[/voice] — switch voice from default or selected voice from GUI/CLI
    • [emotion:sadness]...[/emotion] — Zonos only: emotion for a passage (happiness, sadness, disgust, fear, surprise, anger, other, neutral) or a mix like [emotion:sadness=0.7,neutral=0.3]; other engines ignore it

    Check our other repo dedicated to add SML automatically in your ebook -> E2A-SML

    [!IMPORTANT] Before to post an install or bug issue search carefully to the opened and closed issues TAB to be sure your issue does not exist already.

    [!NOTE] EPUB format lacks any standard structure like what is a chapter, paragraph, preface etc. So you should first remove manually any text you don't want to be converted in audio.

    Instructions

    1. Clone repo

      git clone https://github.com/DrewThomasson/ebook2audiobook.git
      cd ebook2audiobook
      
    2. Install / Run ebook2audiobook:

      • Linux/MacOS

        ./ebook2audiobook.command
        

        Note for MacOS users: homebrew is installed to install missing programs.

      • Mac Launcher
        Double click Mac Ebook2Audiobook Launcher.command

      • Windows

        ebook2audiobook.cmd
        

        or Double click ebook2audiobook.cmd

        Note for Windows users: scoop is installed to install missing programs without administrator privileges.

    3. Open the Web App: Click the URL provided in the terminal to access the web app and convert eBooks. http://localhost:7860/

    4. For Public Link: ./ebook2audiobook.command --share (Linux/MacOS) ebook2audiobook.cmd --share (Windows) python app.py --share (all OS)

    [!IMPORTANT] If the script is stopped and run again, you need to refresh your gradio GUI interface to let the web page reconnect to the new connection socket.

    Basic Usage

    • Linux/MacOS:

      ./ebook2audiobook.command --headless --ebook <path_to_ebook_file> --voice <path_to_voice_file> --language <language_code>
      
    • Windows

      ebook2audiobook.cmd --headless --ebook <path_to_ebook_file> --voice <path_to_voice_file> --language <language_code>
      
    • [--ebook]: Path to your eBook file

    • [--voice]: Voice cloning file path (optional)

    • [--language]: Language code in ISO-639-3 (i.e.: ita for italian, eng for english, deu for german...). Default language is eng and --language is optional for default language set in ./lib/lang.py. The ISO-639-1 2 letters codes are also supported.

    Example of Custom Model Zip Upload

    (must be a .zip file containing the mandatory model files. Example for XTTSv2: config.json, model.pth, vocab.json and ref.wav)

    • Linux/MacOS

      ./ebook2audiobook.command --headless --ebook <ebook_file_path> --language <language> --custom_model <custom_model_path>
      
    • Windows

      ebook2audiobook.cmd --headless --ebook <ebook_file_path> --language <language> --custom_model <custom_model_path>
      

      Note: the ref.wav of your custom model is always the voice selected for the conversion

    • <custom_model_path>: Path to model_name.zip file, which must contain (according to the tts engine) all the mandatory files (see ./lib/models.py).

    For Detailed Guide with list of all Parameters to use

    • Linux/MacOS
      ./ebook2audiobook.command --help
      
    • Windows
      ebook2audiobook.cmd --help
      
    • Or for all OS python app.py --help

    usage: app.py [-h] [--session SESSION] [--share] [--headless] [--ebook EBOOK] [--ebooks_dir EBOOKS_DIR]
                  [--language LANGUAGE] [--voice VOICE] [--voice_map VOICE_MAP] [--device {CPU,CUDA,MPS,ROCM,XPU,JETSON}]
                  [--tts_engine {XTTS,BARK,VITS,FAIRSEQ,TACOTRON,YOURTTS,xtts,bark,vits,fairseq,tacotron,yourtts}]
                  [--custom_model CUSTOM_MODEL] [--fine_tuned FINE_TUNED] [--output_format OUTPUT_FORMAT]
                  [--output_channel OUTPUT_CHANNEL] [--temperature TEMPERATURE] [--length_penalty LENGTH_PENALTY]
                  [--num_beams NUM_BEAMS] [--repetition_penalty REPETITION_PENALTY] [--top_k TOP_K] [--top_p TOP_P]
                  [--speed SPEED] [--enable_text_splitting] [--text_temp TEXT_TEMP] [--waveform_temp WAVEFORM_TEMP]
                  [--output_dir OUTPUT_DIR] [--version]
    
    Convert eBooks to Audiobooks using a Text-to-Speech model. You can either launch the Gradio interface or run the script in headless mode for direct conversion.
    
    options:
      -h, --help            show this help message and exit
      --session SESSION     Session to resume the conversion in case of interruption, crash,
                                or reuse of custom models and custom cloning voices.
    
    **** The following option is for gradio/gui mode only:
      --share               (Optional) Enable a public shareable Gradio link.
    
    **** The following options are for --headless mode only:
      --headless            Run the script in headless mode
      --ebook EBOOK         Path to the ebook file for conversion. Cannot be used when --ebooks_dir is present.
      --ebooks_dir EBOOKS_DIR
                            Relative or absolute path of the directory containing the files to convert.
                                Cannot be used when --ebook is present.
      --text TEXT           Raw text for conversion. Cannot be used when --ebook or --ebooks_dir is present.
      --language LANGUAGE   Language of the e-book. Default language is set
                                in ./lib/lang.py sed as default if not present. All compatible language codes are in ./lib/lang.py
    
    optional parameters:
      --translate ISO3      (Optional) Translate ebook to a target language (ISO 639-3 code, e.g. eng, fra, deu) before TTS synthesis.
                                Uses argostranslate. The target language becomes the effective TTS language for the run.
                                A copy of the source ebook is made with the _<iso3> suffix so translated and non-translated
                                outputs stay isolated (independent process folder, audio chunks, and final file).
      --voice VOICE         (Optional) Path to the voice cloning file for TTS engine.
                                Uses the default voice if not present.
      --voice_map VOICE_MAP
                            (Optional, --ebooks_dir only) Path to a JSON file mapping ebook path -> voice path.
                                Each entry overrides --voice for that specific ebook. Missing/null entries fall back to --voice.
                                Keys may be absolute paths or basenames. Example:
                                {"book1.epub": "/voices/eng/adult/female/alice.wav", "/abs/path/book2.epub": null}
      --device {CPU,CUDA,MPS,ROCM,XPU,JETSON}
                            (Optional) Processor unit type for the conversion.
                                Default is set in ./lib/conf.py if not present. Fall back to CPU if CUDA or MPS is not available.
      --tts_engine {XTTS,BARK,VITS,FAIRSEQ,TACOTRON,YOURTTS,xtts,bark,vits,fairseq,tacotron,yourtts}
                            (Optional) Preferred TTS engine (available are: ['XTTS', 'BARK', 'VITS', 'FAIRSEQ', 'TACOTRON', 'YOURTTS', 'xtts', 'bark', 'vits', 'fairseq', 'tacotron', 'yourtts'].
                                Default depends on the selected language. The tts engine should be compatible with the chosen language
      --custom_model CUSTOM_MODEL
                            (Optional) Path to the custom model zip file cntaining mandatory model files.
                                Please refer to ./lib/models.py
      --fine_tuned FINE_TUNED
                            (Optional) Fine tuned model path. Default is builtin model.
      --output_format OUTPUT_FORMAT
                            (Optional) Output audio format. Default is m4b set in ./lib/conf.py
      --output_channel OUTPUT_CHANNEL
                            (Optional) Output audio channel. Default is mono set in ./lib/conf.py
      --temperature TEMPERATURE
                            (xtts only, optional) Temperature for the model.
                                Default to config.json model. Higher temperatures lead to more creative outputs.
      --length_penalty LENGTH_PENALTY
                            (xtts only, optional) A length penalty applied to the autoregressive decoder.
                                Default to config.json model. Not applied to custom models.
      --num_beams NUM_BEAMS
                            (xtts only, optional) Controls how many alternative sequences the model explores. Must be equal or greater than length penalty.
                                Default to config.json model.
      --repetition_penalty REPETITION_PENALTY
                            (xtts only, optional) A penalty that prevents the autoregressive decoder from repeating itself.
                                Default to config.json model.
      --top_k TOP_K         (xtts only, optional) Top-k sampling.
                                Lower values mean more likely outputs and increased audio generation speed.
                                Default to config.json model.
      --top_p TOP_P         (xtts only, optional) Top-p sampling.
                                Lower values mean more likely outputs and increased audio generation speed. Default to config.json model.
      --speed SPEED         (xtts only, optional) Speed factor for the speech generation.
                                Default to config.json model.
      --enable_text_splitting
                            (xtts only, optional) Enable TTS text splitting. This option is known to not be very efficient.
                                Default to config.json model.
      --text_temp TEXT_TEMP
                            (bark only, optional) Text Temperature for the model.
                                Default to config.json model.
      --waveform_temp WAVEFORM_TEMP
                            (bark only, optional) Waveform Temperature for the model.
                                Default to config.json model.
      --output_dir OUTPUT_DIR
                            (Optional) Path to the output directory. Default is set in ./lib/conf.py
      --abs_url ABS_URL     Audiobookshelf server URL (e.g. http://localhost:13378).
      --abs_api_token ABS_API_TOKEN
                            Audiobookshelf API token.
      --abs_library ABS_LIBRARY
                            Audiobookshelf library ID.
      --enable_interlude    Add MusicGen music before the first chapter, between chapters, and at the end of the audiobook. Settings are in ./lib/conf_interlude.py
      --version             Show the version of the script and exit
    
    Example usage:
    Windows:
        Gradio/GUI:
        ebook2audiobook.cmd
        Headless mode:
        ebook2audiobook.cmd --headless --ebook '/path/to/file' --language eng
    Linux/Mac:
        Gradio/GUI:
        ./ebook2audiobook.command
        Headless mode:
        ./ebook2audiobook.command --headless --ebook '/path/to/file' --language eng
    
    SML tags available:
    	[break] — silence (random range **0.3–0.6 sec.**)
    	[pause] — silence (random range **1.0–1.6 sec.**)
    	[pause:N] — fixed pause (**N sec.**)
    	[voice:/path/to/voice/file]...[/voice] — switch voice from default or selected voice from GUI/CLI
    	[emotion:sadness]...[/emotion] — Zonos only: emotion for a passage (happiness, sadness, disgust, fear, surprise, anger, other, neutral) or a mix like [emotion:sadness=0.7,neutral=0.3]; other engines ignore it
    
    

    NOTE: in gradio/gui mode, to cancel a running conversion, just click on the [X] from the ebook upload component. TIP: if it needs some more pause, add '[pause:3]' for 3 sec. etc.

    Docker

    1. Clone the Repository:
       git clone https://github.com/DrewThomasson/ebook2audiobook.git
       cd ebook2audiobook
    
    1. Build the container
        Windows:
            Docker:
                ebook2audiobook.cmd --script_mode build_docker
            Docker Compose:
                ebook2audiobook.cmd --script_mode build_docker --docker_mode compose
            Podman Compose:
                ebook2audiobook.cmd --script_mode build_docker --docker_mode podman
        Linux/Mac
            Docker:
                ./ebook2audiobook.command --script_mode build_docker
            Docker Compose
                ./ebook2audiobook.command --script_mode build_docker --docker_mode compose
            Podman Compose:
                ./ebook2audiobook.command --script_mode build_docker --docker_mode podman
    
    1. Run the Container:
    Docker run image:
        Gradio/GUI:
            CPU:
              docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "./tmp:/app/tmp" -v "e2a_venvs:/app/lib/classes/tts_engines/venvs" --rm -it -p 7860:7860 athomasson2/ebook2audiobook:cpu
            CUDA:
              docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "./tmp:/app/tmp" -v "e2a_venvs:/app/lib/classes/tts_engines/venvs" --gpus all --rm -it -p 7860:7860 athomasson2/ebook2audiobook:cu[118/122/124/126 etc..]
            ROCM:
              docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "./tmp:/app/tmp" -v "e2a_venvs:/app/lib/classes/tts_engines/venvs" --device=/dev/kfd --device=/dev/dri --rm -it -p 7860:7860 athomasson2/ebook2audiobook:rocm[6.0/6.1/6.4 etc..]
            XPU:
              docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "./tmp:/app/tmp" -v "e2a_venvs:/app/lib/classes/tts_engines/venvs" --device=/dev/dri --rm -it -p 7860:7860 athomasson2/ebook2audiobook:xpu
            JETSON:
              docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "./tmp:/app/tmp" -v "e2a_venvs:/app/lib/classes/tts_engines/venvs" --runtime nvidia --rm -it -p 7860:7860 athomasson2/ebook2audiobook:jetson[5/6/7 etc...]
        Headless mode:
            CPU:
              docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "./tmp:/app/tmp" -v "e2a_venvs:/app/lib/classes/tts_engines/venvs" -v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --rm -it -p 7860:7860 athomasson2/ebook2audiobook:cpu --headless --ebook "/app/another_ebook_folder/myfile.pdf" [--voice /app/my/voicepath/voice.mp3 etc..]
            CUDA:
              docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "./tmp:/app/tmp" -v "e2a_venvs:/app/lib/classes/tts_engines/venvs" -v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --gpus all --rm -it -p 7860:7860 athomasson2/ebook2audiobook:cu[118/122/124/126 etc..] --headless --ebook "/app/another_ebook_folder/myfile.pdf" [--voice /app/my/voicepath/voice.mp3 etc..]
            ROCM:
              docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "./tmp:/app/tmp" -v "e2a_venvs:/app/lib/classes/tts_engines/venvs" -v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --device=/dev/kfd --device=/dev/dri --rm -it -p 7860:7860 athomasson2/ebook2audiobook:rocm[6.0/6.1/6.4 etc.] --headless --ebook "/app/another_ebook_folder/myfile.pdf" [--voice /app/my/voicepath/voice.mp3 etc..]
            XPU:
              docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "./tmp:/app/tmp" -v "e2a_venvs:/app/lib/classes/tts_engines/venvs" -v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --device=/dev/dri --rm -it -p 7860:7860 athomasson2/ebook2audiobook:xpu --headless --ebook "/app/another_ebook_folder/myfile.pdf" [--voice /app/my/voicepath/voice.mp3 etc..]
            JETSON:
              docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" -v "./voices:/app/voices" -v "./tmp:/app/tmp" -v "e2a_venvs:/app/lib/classes/tts_engines/venvs" -v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --runtime nvidia --rm -it -p 7860:7860 athomasson2/ebook2audiobook:jetson[5/6/7 etc.] --headless --ebook "/app/another_ebook_folder/myfile.pdf" [--voice /app/my/voicepath/voice.mp3 etc..]
    Docker Compose (i.e. cuda 12.8:
            Run Gradio GUI:
                   DEVICE_TAG=cu128 docker compose --profile cuda up --no-log-prefix
            Run Headless mode:
                   DEVICE_TAG=cu128 docker compose --profile cuda run --rm ebook2audiobook-cuda --headless --ebook "/app/ebooks/myfile.pdf" --voice /app/voices/eng/adult/female/some_voice.wav etc..
    Podman Compose (i.e. cuda 12.8:
            Run Gradio GUI:
                   DEVICE_TAG=cu128 podman-compose -f podman-compose.yml --profile cuda up
            Run Headless mode:
                   DEVICE_TAG=cu128 podman-compose -f podman-compose.yml --profile cuda run --rm ebook2audiobook-cuda --headless --ebook "/app/ebooks/myfile.pdf" --voice /app/voices/eng/adult/female/some_voice.wav etc..
    
    • NOTE: MPS is not exposed in docker so CPU must be used
    • NOTE: the named volume e2a_venvs keeps the TTS engines installed in their own venv (GPT-SoVITS, Zonos, OmniVoice, F5-TTS, Orpheus, Spark-TTS, ChatTTS, OpenVoice, MeloTTS, CSM etc.) across container runs, so they are not reinstalled each time. To reset them: docker volume rm e2a_venvs

    Tools

    Standalone tools, run with e2a's own Python (python_env, created by the first launch of e2a).

    Preload models for offline installs: tools/preload_models.py

    Downloads every model e2a uses (TTS engines and their fine-tunes, voice conversion, stanza, pyannote, demucs, music interludes, argos-translate packages, tesseract data, jieba, and the voices) into one folder laid out exactly like ./models, i.e. a USB key. On the offline machine, copy that folder into e2a's ./models and the voices folder written beside it into e2a's ./voices. Every finished job is recorded in <models_dir>/.e2a_downloads.json: a rerun skips what is done and starts again what was cut (ctrl-c, crash, unplugged key) after removing its partial files.

    • Linux/MacOS
      ./python_env/bin/python tools/preload_models.py /media/user/KEY/models --languages eng,fra
      
    • Windows
      python_env\Scripts\python.exe tools\preload_models.py E:\models --languages eng,fra
      
    • --dry_run lists the jobs and their state (done, interrupted, todo) without downloading anything.
    usage: preload_models.py [-h] [--only ONLY] [--skip SKIP] [--languages LANGUAGES]
                             [--audiocpp_packages AUDIOCPP_PACKAGES] [--refresh] [--dry_run]
                             models_dir
    
    Download every model e2a uses into one folder laid out exactly like ./models (i.e. a USB key for offline
    installs).
    
    positional arguments:
      models_dir            Target folder, i.e. /media/user/KEY/models or E:\models
    
    options:
      -h, --help            show this help message and exit
      --only ONLY           Comma list of categories: common,xtts,bark,tortoise,vits,fairseq,glowtts,tacotron,yo
                            urtts,piper,zonos,audiocpp,audiocpp_server,gptsovits,f5tts,omnivoice,orpheus,sparktt
                            s,chattts,csm,openvoice,melotts,phonon,stanza,pyannote,demucs,interlude,argos,tessda
                            ta,jieba,voices
      --skip SKIP           Comma list of categories to leave out
      --languages LANGUAGES
                            Comma list of e2a ISO-639-3 codes (eng,fra,ita...): single-language models and fine-
                            tunes for these only, multilingual models only for engines speaking one of them
      --audiocpp_packages AUDIOCPP_PACKAGES
                            audiocpp_server category: auto (the packages this machine runs, GPU and CPU), all
                            (every platform, for a key used elsewhere), or a comma list of audiocpp_packages
                            keys from lib/conf_models.py
      --refresh             Run every job again, even those already marked done (files already there are still
                            not downloaded twice)
      --dry_run             List every download job with its state (done, interrupted, todo) and exit
    

    Translate ebooks out of e2a: translate_ebook.sh / translate_ebook.cmd

    Translates EPUB/AZW3 files, a whole folder (-r for its subfolders) or a list of paths (@list.txt) into translated ebooks, offline, with the Argos Translate calibre plugin shipped in tools/argostranslate-calibre-plugin.zip. Independent of the audiobook conversion: it only writes ebooks. It needs calibre (already required by e2a) and runs on e2a's python_env and argos-translate packages: a language pair e2a already uses is not downloaded again, a missing one is downloaded on first use. The plugin is installed on first use into e2a's own calibre profile (./run), your calibre is left untouched. --to fra,ara,spa translates into several languages at once, one ebook per language, and --to all into every language the source reaches (--from, else each book's own language; installed ones only with --no_download). --list --from eng lists the languages English translates into (installed, downloadable, or through English for another source). Other formats calibre's ebook-convert reads (PDF, DOCX, MOBI, TXT, ...) are converted to EPUB once, before the first language, and translated as EPUB: --from is needed when they carry no language, as PDF and TXT often do. Without -o or --output_dir, each translation is saved beside its book as <name>.<lang>.<ext>, and a book whose translation already exists is skipped (--overwrite to translate it again). The launchers in e2a's folder run tools/translate_ebook.py with python_env, nothing to activate, from any folder (relative paths are taken from where it is started):

    • Linux/MacOS
      ./translate_ebook.sh /path/to/books -r --to fra,spa --output_dir /path/to/books_translated
      
    • Windows
      translate_ebook.cmd C:\books -r --to fra,spa --output_dir C:\books_translated
      
    • Or directly with python_env's Python: ./python_env/bin/python tools/translate_ebook.py ... (Windows: python_env\Scripts\python.exe tools\translate_ebook.py ...). Started with any other Python, the script starts itself again with python_env's.
    • Docker: run it inside the e2a container, e.g. docker exec -it <container> python3 tools/translate_ebook.py ... with paths seen from the container.
    • Speed: argostranslate runs on its own defaults (CTranslate2 picks the threads and the fastest compute type, int8 on CPU), not on e2a's 1 thread in float32. Set ARGOS_INTRA_THREADS or ARGOS_COMPUTE_TYPE to override them.
    usage: translate_ebook.py [-h] [-t LANG[,LANG...]] [-f LANG] [-r] [-o OUTPUT] [--output_dir OUTPUT_DIR]
                              [--overwrite] [-m {replace,bilingual}] [--device {cpu,cuda,auto}]
                              [--batch_size BATCH_SIZE] [--no_cache] [--no_download] [--allow_changes] [--list]
                              [books ...]
    
    Translate ebooks offline, out of e2a, with the Argos Translate calibre plugin
    (tools/argostranslate-calibre-plugin.zip). EPUB/AZW3 are translated as they are, the other formats
    calibre's ebook-convert reads (PDF, DOCX, MOBI, ...) are converted to EPUB once, before the first
    language, and their translations saved as EPUB. It runs on e2a's python_env and argos-translate packages
    (models/argos-translate): a language pair e2a already uses is not downloaded again, a missing one is
    downloaded on first use (direct or through English). The plugin is installed into e2a's own calibre
    profile (run/) on first use, your calibre setup is left untouched.
    Translated paths are printed on stdout, progress and logs on stderr.
    
    positional arguments:
      books                 Ebook files (EPUB, AZW3, or PDF, DOCX, MOBI... converted to EPUB first) or folders
                            to translate; @list.txt reads paths from a file, one per line
    
    options:
      -h, --help            show this help message and exit
      -t, --to LANG[,LANG...]
                            Target language(s), ISO-639-1 or ISO-639-3 codes, comma separated for several (fr,
                            fra or fra,ara,spa): one translated ebook per language. all: every language the
                            source reaches (see --list --from), installed ones only with --no_download
      -f, --from LANG       Source language, ISO-639-1 or ISO-639-3 code (default: read from each book)
      -r, --recursive       Also look for books in the subfolders of the given folders
      -o, --output OUTPUT   Output file, single input only, same extension as the input, .epub for a converted
                            one (default: <name>.<lang>.<ext> next to the input)
      --output_dir OUTPUT_DIR
                            Write the translations into this folder (subfolders are mirrored with -r) instead of
                            next to each book
      --overwrite           Translate again even if the output file already exists (skipped otherwise)
      -m, --mode {replace,bilingual}
                            replace: the translation replaces the text. bilingual: each paragraph is followed by
                            its translation, saved as <name>.<lang>.bilingual.<ext> (default: replace)
      --device {cpu,cuda,auto}
                            Device argostranslate runs on (default: cpu)
      --batch_size BATCH_SIZE
                            Segments sent to the translation worker per request (default: 16)
      --no_cache            Neither read nor write the translation cache (run/argos_translate/cache.sqlite), the
                            one that makes a second run of the same book near instant
      --no_download         Never download a missing argos-translate package, fail instead
      --allow_changes       Only when argostranslate is missing from python_env: install it even if packages
                            already there would change version
      --list                List the installed and the downloadable language pairs, then exit. With --from
                            and/or --to: only their pairs, plus the targets a source reaches through English
    
    examples:
      translate_ebook.py book.epub --to fr
      translate_ebook.py book.epub --to fra,ara,spa
      translate_ebook.py book.azw3 --from en --to deu -o /path/to/book_deu.azw3
      translate_ebook.py /path/to/books -r --to es,it --output_dir /path/to/books_translated
      translate_ebook.py book.epub --from eng --to all
      translate_ebook.py @books.txt --to ita --mode bilingual
      translate_ebook.py --list
      translate_ebook.py --list --from eng
    

    Cloned Voices

    You can upload any voice audio in any of the supported audio formats, the ideal duration is around 1 to 5 mn. It doesn't matter if the recording has a noisy background or music playing over it — E2A will clean up the voice for you.

    The built-in cloned voices list is mainly in English. If you need voices in other languages to be officially added to the list, please contact us and we'll add them after review.

    Fine Tuned TTS models

    Fine Tune your own TTS model

    Universal_TTS_Finetune

    De-noise training data

    Hugging Face GitHub Repo

    Fine Tuned TTS Collection

    Hugging Face

    For an XTTSv2 custom model a ref audio clip of the voice reference is mandatory:

    Your own Ebook2Audiobook customization

    You are free to modify libs/conf.py to add or remove the settings you wish. If you plan to do it just make a copy of the original conf.py so on each ebook2audiobook update you will backup your modified conf.py and put back the original one. You must plan the same process for models.py. If you wish to make your own custom model as an official ebook2audiobook fine tuned model so please contact us and we'll add it to the presets list.

    Reverting to older Versions

    Releases can be found -> here

    git checkout tags/VERSION_NUM # Locally/Compose -> Example: git checkout tags/v25.7.7
    

    Common Issues:

    • My NVIDIA/ROCm/XPU/MPS GPU isn't being detected?? -> GPU ISSUES Wiki Page
    • CPU is slow (better on server smp CPU) while GPU can have almost real time conversion. Discussion about this (It doesn't have zero-shot voice cloning though, and is Siri quality voices, but it is much faster on cpu).
    • "I'm having dependency issues" - Just use the docker, its fully self contained and has a headless mode, add --help parameter at the end of the docker run command for more information.
    • "I'm getting a truncated audio issue!" - PLEASE MAKE AN ISSUE OF THIS, we don't speak every language and need advise from users to fine tune the sentence splitting logic.😊

    ***** ROADMAP *****

    • All Features open to public Contributions ⭐
    • Any help from people speaking any of the supported languages to help us improve the models ⭐
    • Preview Blocks/Chapters before to start the conversion
    • Edit by sentence converted for surgical text change
    • Generate music intros, interludes, and endings; edit interludes and endings
    • SML tags integration for voice, pause, break, and more changes
    • -h -help parameter info in different languages
    • OCR scanning for PDF / JPG / BMP / PNG / TIFF
    • Notebooks Folder Talked about here
    • Make Chinese text splitting not split words and improve pause timing Talked about here
    • Dockerfile
    • Docker compose
    • Podman compose
    • Kaggle Notebook
    • Google Colab Notebook
    • Audiobookshelf integration
    • Ebook Translation option
    • Output format choices
    • Multiprocessing conversion
    • Batch ebook folder conversion
    • GPU Device detection
    • Denoise any background reference audio for voice cloning upload
    • Custom fine-tuned model upload
    • IOS app
    • Android app
    User Requests
    • Add European Portuguese language model for xttsv2, fairseq, vits, piper at least (help welcome)
    • Add Sindhi language model for xttsv2, fairseq, vits, piper at least (help welcome)
    TTS engines
    Readme Translation
    • Arabic (ara)
    • Chinese (zho)
    • English (eng)
    • Spanish (spa)
    • French (fra)
    • German (deu)
    • Italian (ita)
    • Portuguese (por)
    • Polish (pol)
    • Turkish (tur)
    • Russian (rus)
    • Dutch (nld)
    • Czech (ces)
    • Japanese (jpn)
    • Hindi (hin)
    • Bengali (ben)
    • Hungarian (hun)
    • Korean (kor)
    • Vietnamese (vie)
    • Swedish (swe)
    • Persian (fas)
    • Yoruba (yor)
    • Swahili (swa)
    • Indonesian (ind)
    • Slovak (slk)
    • Croatian (hrv)
    💻 OS Compatibility
    • 🪟 Windows x86
    • 🪟 ARM Windows
    • 🍎 Mac Intel x86
    • 🍎 Apple Silicon Mac
    • 🐧 Linux x86
    • 🐧 ARM Linux

    Extra Overkill for training models and such (All supported Coqui-tts models and piper-tts in one easy command)

    Python Code normalization information for contributors

    • no blank line between code, unless between functions and classes.
    • single quote used for all key unless for dict() and json. dict['key'] always called with single quote
    • 4 spaces indentation, not tab at all
    • strict typing for all functions and its arguments declaration and return values
    • no space between the argument and its typing, no space between the function, the "->" and the return value

    Example:

    import json
    from typing import Optional
    
    def get_user(user_id:int, users:list[dict])->Optional[dict]:
        for user in users:
            if user['id'] == user_id:
                return user
        return None
    
    def summarize(user:dict)->str:
        return f"User {user['name']} is {'active' if user['is_active'] else 'inactive'}."
    
    def to_json(user:dict)->str:
        return json.dumps({"id": user['id'], "name": user['name'], "email": user['email']})
    
    users:list = [
        dict(id=1, name="alice", email="[email protected]", role="admin", is_active=True),
        dict(id=2, name="bob", email="[email protected]", role="editor", is_active=False),
        dict(id=3, name="carol", email="[email protected]", role="viewer", is_active=True),
    ]
    config = {
        "max_users": 100,
        "default_role": "viewer",
        "allow_signup": True,
    }
    roles = ['admin', 'editor', 'viewer']
    found = get_user(1, users)
    if found:
        print(summarize(found))
        print(found['email'])
        print(to_json(found))
    if config['default_role'] in roles:
        print(config['default_role'])
    

    Hardware donation for beta tests wanted

    We accept any kind of hardware to test our development like:

    • Nvidia supporting cuda >= 11.8
    • XPU intel cards
    • ROCm AMD cards supporting ROCm >=5.7

    @DrewThomasson if you want to help out at all! 😃

    Credits

    • Coqui-tts -- A deep learning toolkit for Text-to-Speech, battle-tested in research and production.
    • Piper-tts -- Fast and local neural text-to-speech engine.
    • Zonos2.cpp -- ggml inference code for Zonos2.
    • Audio.cpp -- An all-in-one, pure C++ inference engine for audio models, powered by ggml.

    Special Thanks

    To all financial and code contributors, each contribution and suggestion helps to improve the quality of E2A.