ebook2audiobook(E2A)完整实战指南:从电子书到有声书的全流程转换、声音克隆与 1158+ 语言支持
ebook2audiobook(E2A)完整实战指南:从电子书到有声书的全流程转换、声音克隆与 1158+ 语言支持
本文是 ebook2audiobook(E2A)开源项目的完整技术指南。E2A 是一个运行在 CPU/GPU 上的电子书转有声书转换器,支持章节检测与元数据写入、多种高级 TTS 引擎、可选的声音克隆以及 1158+ 语言。读完本文,你将掌握:本地 GUI 与命令行(headless)两种转换方式、全部 CLI 参数的语义与默认值、SML 标签控制朗读节奏与切换声音、自定义模型上传、Docker 部署以及声音克隆与微调模型的完整工作流。文中所有结论均以仓库当前源码与官方文档为准,并给出对应文件路径供继续深挖。
项目定位与核心能力
E2A 的核心定位一句话概括:把电子书(E-Book)转换成带章节和元数据的有声书(Audiobook)。它面向的是合法获取、无 DRM 的电子书内容(官方文档在 README 基线 开头即声明:本工具仅用于非 DRM、合法获取的电子书,作者不对任何滥用或由此产生的法律后果负责)。
从 功能特性清单 与源码结构可以梳理出它的完整能力矩阵:
- 多 TTS 引擎支持:
XTTSv2、Bark、Fairseq、VITS、Tacotron2、Tortoise、GlowTTS、YourTTS(以及预设列表中的Piper)。引擎枚举定义在 lib/conf_models.py 的TTS_ENGINES字典中,每个引擎的实际实现位于 lib/classes/tts_engines/(xtts.py、bark.py、fairseq.py、vits.py、tacotron.py、tortoise.py、glowtts.py、yourtts.py、piper.py)。 - 多格式电子书输入:
.epub、.mobi、.azw3、.fb2、.lrf、.rb、.snb、.tcr、.pdf、.txt、.rtf、.doc、.docx、.html、.odt、.azw、.tiff、.tif、.png、.jpg、.jpeg、.bmp、.zip(含.pptx,见 lib/conf.py 的ebook_formats列表)。 - 文本直转:GUI 内提供文本输入框(TextArea),可把一段短文直接合成音频,无需电子书文件。
- OCR 扫描:对以图片形式呈现的文本页(PDF 扫描件、JPG/BMP/PNG/TIFF 图片)启用 OCR 识别。
- 可选声音克隆:上传任意语音文件即可克隆音色。
- 低资源友好:官方标注最低 2GB RAM / 1GB VRAM 即可运行。
- 多输出格式:mono/stereo 双声道,支持
aac、flac、mp3、m4b、m4a、mp4、mov、ogg、wav、webm。 - SML 标签:细粒度控制停顿、呼吸间隙、中途切换声音等(详见下文专节)。
- 自定义模型:可上传自己训练的 XTTSv2 / VITS / FAIRSEQ / PIPER 模型。
- 微调预设模型:由 E2A 团队训练的预设模型可直接选用。
- 会话恢复(Session):转换中断或崩溃后可通过
--session恢复,也可复用自定义模型与克隆声音(对应 app.py 中SessionContext/SessionTracker的实现)。
从 lib/core.py 的 convert_ebook(args) 主入口可以看到完整链路:会话校验 → 语言代码规范化(ISO-639-3)→ 翻译开关判定 → 按 ebook_mode(single/directory/text)分发 → 逐文件转换。GUI 界面则全部由 lib/gradio.py 的 build_interface(args) 构建,基于 Gradio Blocks/Tabs 架构。
硬件要求与设备后端
官方在 Hardware Requirements 中给出的资源红线如下:
- RAM:最低 2GB,推荐 8GB。
- VRAM:最低 1GB,推荐 4GB。
- 虚拟化:Windows 上使用 Docker 需开启虚拟化。
- 支持的算力后端:CPU、XPU(Intel/AMD/ARM)、CUDA、ROCm、JETSON、MPS(Apple Silicon)。
注意官方附注:现代 TTS 引擎在 CPU 上非常慢,CPU 环境建议选用 YourTTS、Tacotron2 这类轻量引擎。这一结论与 lib/conf_models.py 中每个引擎的 rating 评分一致(例如 YourTTS:VRAM 1 / CPU 5 / RAM 1;Tacotron2:VRAM 1 / CPU 5)。
lib/conf.py 中维护了一张设备矩阵 torch_matrix,按设备键(cpu、cu118~cu132、rocm5.7~rocm7.2、mps、xpu、jetson51/60/61)映射操作系统、CPU 架构与 torch/torchaudio/torchcodec 版本基线。默认设备为 CPU(default_device),当 CUDA 或 MPS 不可用时会回退到 CPU——这一回退逻辑实现在 app.py 的参数归一化阶段(args<a href="https://link.gitcode.com/i/2f51bb0a5ccc6625be30fad40f98d529" target="_blank">'device'] = devices.get(...))。启动时,[components/detect_gpu.py 与 lib/classes/device_installer.py 负责探测 GPU 并按需安装对应后端包。
支持的语言、电子书格式与输出格式
语言支持
E2A 官方列出了 26 种常见语言(ISO-639-3 码),并通过 MMS 系列 TTS 模型扩展至 1158+ 语言与方言:
| 阿拉伯语 ar | 中文 zh | 英语 en | 西班牙语 es |
|---|---|---|---|
| 法语 fr | 德语 de | 意大利语 it | 葡萄牙语 pt |
| 波兰语 pl | 土耳其语 tr | 俄语 ru | 荷兰语 nl |
| 捷克语 cs | 日语 ja | 印地语 hi | 孟加拉语 bn |
| 匈牙利语 hu | 韩语 ko | 越南语 vi | 瑞典语 sv |
| 波斯语 fa | 约鲁巴语 yo | 斯瓦希里语 sw | 印尼语 id |
| 斯洛伐克语 sk | 克罗地亚语 hr | 泰米尔语 ta | 丹麦语 da |
代码层面,每种引擎声明了自己的语言子集,例如 lib/conf_models.py 中 XTTSv2 支持 17 种语言(ara/ces/deu/eng/fra/hin/hun/ita/jpn/kor/nld/pol/por/rus/spa/tur/zho),而 Fairseq 的语言字典长达数千行,覆盖几百种小语种与方言(含 urd-script_devanagari、cak-dialect_* 等脚本/方言变体)。命令行中语言码默认使用 ISO-639-3(如 ita=意大利语、eng=英语、deu=德语),同时兼容 ISO-639-1 两位码。默认语言为 eng,定义在 lib/conf_lang.py 的 default_language_code。
电子书输入格式
官方支持的格式清单:
.epub、.pdf、.mobi、.txt、.html、.rtf、.chm、.lit、.pdb、.fb2、.odt、.cbr、.cbz、.prc、.lrf、.pml、.snb、.cbc、.rb、.tcr
最佳实践:官方明确建议优先使用
.epub或.mobi,因为只有这两种格式能可靠地做自动章节检测。此外官方提醒:EPUB 没有统一的"章节/段落/前言"结构标准,转换前建议手动剔除任何不想被朗读成音频的文本。
仓库 ebooks/tests/ 目录内置了大量测试电子书(覆盖几十种语言的 .azw3 与 .txt 配对样本),可用来快速验证转换流程。
输出与中间处理格式
输出格式:.m4b、.m4a、.mp4、.webm、.mov、.mp3、.flac、.wav、.ogg、.aac。默认输出为 m4b(见 lib/conf.py 的 default_output_format),默认声道为 mono(default_output_channel)。
中间处理格式在 lib/conf.py 中配置:default_audio_proc_format = 'flac'(可改为 ogg 或 wav,但 wav 仅适合小于 4GB 的处理文件),采样率默认 24000(default_audio_proc_samplerate)。官方原话是"Process format can be changed in lib/conf.py",对应文件即 lib/conf.py。
SML 标签:细粒度控制朗读节奏与声音切换
SML(Speech Markup Language 风格的轻量标签)是 E2A 最有特色的能力之一。官方支持的四种标签:
| 标签 | 效果 | 说明 |
|---|---|---|
[break] |
静音 | 随机范围 0.3–0.6 秒 |
[pause] |
静音 | 随机范围 1.0–1.6 秒 |
[pause:N] |
固定停顿 | 固定 N 秒(例如 [pause:3] 停 3 秒) |
[voice:/path/to/voice/file]...[/voice] |
切换声音 | 在默认/已选声音与指定声音之间切换 |
官方提示:如果觉得停顿不够,直接插入 [pause:3] 即可获得 3 秒停顿。
从源码看,SML 的实现相当系统化:
- 标签定义在 lib/conf_models.py 的
TTS_SML字典:break、pause(无配对)与voice(配对标签),并用SML_TAG_PATTERN正则(支持可选值、可选闭标签、忽略空白)解析。 - 文本处理管线在 lib/core.py:转换前会把
[break]/[pause]等静态标签替换进文本(例如连续换行被替换为[pause]),随后escape_sml()将标签转义为私有区字符(sml_escape_tag = 0xE000)以避免被后续标点清洗、分句逻辑破坏;分句阶段用_split_sentence_on_sml保证永不切断 SML 分组,最后restore_sml()还原标签。 - 非文本过滤:
NonTextFilter(lib/classes/non_text_filter.py)会在送入 TTS 前剔除不被允许的内容,SML 标签以白名单形式保留(见 lib/core.py 中NonTextFilter(sml_pattern=SML_TAG_PATTERN, ...)的调用)。 - 配套工具:官方维护了独立的 E2A-SML 仓库,用于给电子书自动插入 SML 标签。
快速开始:本地安装与运行
1. 克隆仓库
git clone https://github.com/DrewThomasson/ebook2audiobook.git
cd ebook2audiobook
2. 启动脚本(自动安装依赖)
| 平台 | 命令 | 说明 |
|---|---|---|
| Linux / macOS | ./ebook2audiobook.command |
macOS 会用 homebrew 安装缺失的程序 |
| macOS(双击启动) | 双击 Mac Ebook2Audiobook Launcher.command |
— |
| Windows | ebook2audiobook.cmd(或双击) |
用 scoop 在无管理员权限下安装缺失程序 |
脚本会完成虚拟环境创建、Python 依赖安装与设备包探测。从 app.py 的 check_virtual_env()/check_python_version() 可以看到启动前的校验逻辑:项目要求 Python 3.10–3.12(min_python_version=(3,10)、max_python_version=(3,12),见 lib/conf.py),并要求在项目自建的 python_env(由 uv 创建)中运行,混用 conda 环境或系统 Python 会被拒绝并提示删除 python_env 后重跑启动脚本。
3. 打开 Web GUI
启动完成后,终端会输出访问地址,默认是:
http://localhost:7860/
这是 Gradio 服务(端口定义见 lib/conf.py 的 interface_port = 7860,监听 0.0.0.0)。在 GUI 中你可以:上传电子书文件、粘贴文本、选择语言与 TTS 引擎、上传克隆声音、选择输出格式,并**预览章节(Chapters Preview)**后再开始转换。
重要提醒:如果脚本停止后再次运行,需要刷新 Gradio 页面,让网页重新连接新的 socket。
取消转换:GUI 模式下想取消正在进行的转换,直接点击电子书上传组件上的
[X]即可。
GUI 界面的真实形态可参考 assets/demo_web_gui.gif 演示动画与 assets/gui_1.png 截图(更多截图见 assets/gui_2.png、assets/gui_3.png)。
4. 获取公网分享链接
./ebook2audiobook.command --share # Linux/macOS
ebook2audiobook.cmd --share # Windows
python app.py --share # 所有平台
--share 仅适用于 GUI 模式,源码中若与 --headless 同时传入会被拒绝(见 app.py 的校验:--share option is only allowed in non-headless mode)。
Headless 命令行模式:基本用法
不需要浏览器时,可以用命令行直接转换:
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:电子书文件路径。--voice:(可选)声音克隆文件路径。--language:ISO-639-3 语言码(如ita=意大利语、eng=英语、deu=德语)。默认eng,可选;也支持 ISO-639-1 两位码。默认语言定义在 lib/conf_lang.py。
headless 模式还有两种输入变体:
--ebooks_dir:批量转换整个目录。目录内会按自然排序处理所有受支持格式的文件,跳过不支持格式并打印提示;可通过--voice_map(JSON,键为电子书路径或 basename,值为该文件专属声音路径,缺省项回退到--voice)为不同书籍指定不同声音。相关逻辑见 app.py 中ebook_mode = 'directory'的分支。--text:直接传入原始文本进行转换(与--ebook/--ebooks_dir互斥,限制 1024 字符,max_ebook_textarea_length)。
查看完整帮助
./ebook2audiobook.command --help # Linux/macOS
ebook2audiobook.cmd --help # Windows
python app.py --help # 所有平台
全部 CLI 参数详解(官方 --help 全量对照)
以下是官方帮助输出的完整参数清单(与 app.py 中 argparse 定义一一对应),按分组整理以便查阅:
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]
全局选项
| 参数 | 说明 |
|---|---|
-h, --help |
显示帮助并退出 |
--session SESSION |
中断、崩溃后恢复转换的会话 ID;也可用于复用自定义模型与克隆声音 |
--version |
显示脚本版本并退出(对应 VERSION.txt 中的版本号) |
GUI 模式专属
| 参数 | 说明 |
|---|---|
--share |
(可选)启用 Gradio 公网分享链接 |
Headless 模式专属
| 参数 | 说明 |
|---|---|
--headless |
以命令行模式运行 |
--ebook EBOOK |
单个电子书文件路径;与 --ebooks_dir 互斥 |
--ebooks_dir EBOOKS_DIR |
待转换文件所在目录(相对或绝对路径);与 --ebook 互斥 |
--text TEXT |
直接转换的原始文本;与 --ebook/--ebooks_dir 互斥 |
--language LANGUAGE |
电子书语言;默认取 lib/conf_lang.py 中设置的 eng,兼容语言码同文件 |
可选参数(含引擎级采样参数)
| 参数 | 适用范围 | 说明 |
|---|---|---|
--translate ISO3 |
全局 | 转换前用 argostranslate 将电子书翻译为目标语言(ISO-639-3,如 eng/fra/deu);目标语言成为本次有效 TTS 语言;源电子书会生成 _<iso3> 后缀副本,使翻译与未翻译输出相互隔离(独立进程目录、音频块与最终文件)。源码见 app.py 与 lib/core.py 的 translate_enabled 逻辑 |
--voice VOICE |
全局 | 声音克隆文件路径;缺省用默认声音 |
--voice_map VOICE_MAP |
--ebooks_dir 专用 |
JSON 文件,映射 ebook 路径 -> voice 路径;每项覆盖 --voice,缺失/为 null 的项回退到 --voice;键可为绝对路径或 basename。示例:{"book1.epub": "/voices/eng/adult/female/alice.wav", "/abs/path/book2.epub": null} |
--device {CPU,CUDA,MPS,ROCM,XPU,JETSON} |
全局 | 处理器单元类型;默认见 lib/conf.py,CUDA/MPS 不可用时回退 CPU |
--tts_engine |
全局 | 首选 TTS 引擎(可选 XTTS/BARK/VITS/FAIRSEQ/TACOTRON/YOURTTS 及其小写变体);默认随所选语言而定,需与语言兼容 |
--custom_model |
全局 | 自定义模型 zip 路径,内含各引擎必需文件,参见 lib/conf_models.py 中各引擎 files 字段 |
--fine_tuned FINE_TUNED |
全局 | 微调模型路径;默认内置模型(internal) |
--output_format |
全局 | 输出音频格式;默认 m4b(lib/conf.py) |
--output_channel |
全局 | 输出声道;默认 mono(lib/conf.py) |
--output_dir |
全局 | 输出目录;默认见 lib/conf.py |
--abs_url / --abs_api_token / --abs_library |
全局 | Audiobookshelf 服务器 URL(如 http://localhost:13378)、API Token、库 ID,用于直接发布到 Audiobookshelf(对应 lib/classes/audiobookshelf.py) |
XTTSv2 专属采样参数(默认均取自模型 config.json,自定义模型不应用):
| 参数 | 说明 |
|---|---|
--temperature |
模型温度;越高输出越有创意,默认 0.75 |
--length_penalty |
自回归解码器长度惩罚,默认 1.0 |
--num_beams |
探索的备选序列数,须 ≥ length penalty,默认 1 |
--repetition_penalty |
防止自回归解码器重复的惩罚,默认 2.0 |
--top_k |
Top-k 采样;越低输出越"稳"且生成越快,默认 40 |
--top_p |
Top-p 采样;越低越稳越快,默认 0.95 |
--speed |
语速因子,默认 1.0 |
--enable_text_splitting |
启用 TTS 文本切分(官方标注效果不佳) |
Bark 专属采样参数:
| 参数 | 说明 |
|---|---|
--text_temp |
文本温度,默认 0.22 |
--waveform_temp |
波形温度,默认 0.44 |
以上 XTTS/Bark 默认值均可在 lib/conf_models.py 的 default_engine_settings 中核对;--output_split、--output_split_hours(默认 6 小时,最终时长超过 12 小时自动按 6 小时拆分)等 GUI 参数在 app.py 中注入。
参数使用要点(源码级)
- 互斥校验:headless 模式下
--ebook、--ebooks_dir、--text三选一,多传会报错;--share与--headless不可同时出现(app.py)。 - 路径校验:
--voice、--custom_model会转为绝对路径;--output_dir必须已存在;--ebooks_dir必须存在且至少含一个受支持格式文件(app.py)。 - 语言归一化:传入的语言码会经
iso639库统一为 ISO-639-3,再与 lib/conf_lang.py 的language_mapping比对,不支持的会明确报错(lib/core.py 的convert_ebook)。 - 会话体系:headless 每次转换都有会话 ID(未传
--session时自动生成 UUID),支持中断续跑(app.py + lib/core.py 的SessionContext)。
自定义模型:XTTSv2 zip 上传
E2A 支持上传自己的训练模型。CLI 用法:
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>
<custom_model_path>:指向model_name.zip,其中必须包含该 TTS 引擎的全部必需文件(见 lib/conf_models.py)。例如 XTTSv2 需要:config.json、model.pth、vocab.json、ref.wav;VITS 需要config.json、best_model.pth、ref.wav;FAIRSEQ 需要config.json、G_100000.pth、vocab.txt、ref.wav;Piper 需要config.onnx.json、model.onnx、ref.wav。- 注意:自定义模型的
ref.wav就是转换时实际使用的声音(voice reference)。 - 支持自定义模型的引擎有 XTTSv2、VITS、FAIRSEQ、Piper(
tts_engines_with_custom_model,lib/conf_models.py);GUI 上传上限max_custom_model = 100、自定义声音上限max_custom_voices = 1000。
Docker / Podman 部署
Docker 方案完全自包含,是规避依赖问题的最稳妥途径。仓库提供 Dockerfile、docker-compose.yml 与 podman-compose.yml。
1. 克隆仓库
git clone https://github.com/DrewThomasson/ebook2audiobook.git
cd ebook2audiobook
2. 构建镜像
| 平台 | Docker | Docker Compose | Podman Compose |
|---|---|---|---|
| Windows | ebook2audiobook.cmd --script_mode build_docker |
ebook2audiobook.cmd --script_mode build_docker --docker_mode compose |
ebook2audiobook.cmd --script_mode build_docker --docker_mode podman |
| Linux / macOS | ./ebook2audiobook.command --script_mode build_docker |
./ebook2audiobook.command --script_mode build_docker --docker_mode compose |
./ebook2audiobook.command --script_mode build_docker --docker_mode podman |
(源码中 --script_mode build_docker 是容器的唯一合法值;--script_mode full_docker 仅容器内部使用,外部调用会报错。)
3. 运行容器(GUI 模式)
镜像 tag 按后端区分:athomasson2/ebook2audiobook:cpu、cu[118/122/124/126 ...]、rocm[6.0/6.1/6.4 ...]、xpu、jetson[51/60/61 ...]。目录挂载统一为 ./ebooks、./audiobooks、./models、./voices、./tmp。
# CPU
docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" \
-v "./voices:/app/voices" -v "./tmp:/app/tmp" --rm -it -p 7860:7860 athomasson2/ebook2audiobook:cpu
# CUDA(注意 --gpus all)
docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" \
-v "./voices:/app/voices" -v "./tmp:/app/tmp" --gpus all --rm -it -p 7860:7860 athomasson2/ebook2audiobook:cu118
# ROCm
docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" \
-v "./voices:/app/voices" -v "./tmp:/app/tmp" --device=/dev/kfd --device=/dev/dri --rm -it \
-p 7860:7860 athomasson2/ebook2audiobook:rocm6.4
# XPU
docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" \
-v "./voices:/app/voices" -v "./tmp:/app/tmp" --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" --runtime nvidia --rm -it -p 7860:7860 athomasson2/ebook2audiobook:jetson61
4. 运行容器(Headless 模式)
核心技巧:用 -v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" 把宿主机真实路径挂载进容器,再在镜像后追加 headless 参数:
# CPU
docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" \
-v "./voices:/app/voices" -v "./tmp:/app/tmp" \
-v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --rm -it -p 7860:7860 \
ebook2audiobook:cpu --headless --ebook "/app/another_ebook_folder/myfile.pdf" \
[--voice /app/my/voicepath/voice.mp3 ...]
# CUDA
docker run -v "./ebooks:/app/ebooks" -v "./audiobooks:/app/audiobooks" -v "./models:/app/models" \
-v "./voices:/app/voices" -v "./tmp:/app/tmp" \
-v "/my/real/ebooks/folder/absolute/path:/app/another_ebook_folder" --gpus all --rm -it -p 7860:7860 \
ebook2audiobook:cu118 --headless --ebook "/app/another_ebook_folder/myfile.pdf" \
[--voice /app/my/voicepath/voice.mp3 ...]
# ROCm / XPU / JETSON 同理,分别加 --device=/dev/kfd --device=/dev/dri、--device=/dev/dri、--runtime nvidia
在 docker run 命令末尾追加
--help可查看容器内全部参数说明。注意:Docker 不暴露 MPS,Apple Silicon 用户需使用 CPU。
5. Docker Compose / Podman Compose(以 CUDA 12.8 为例)
# Docker Compose —— 运行 Gradio GUI
DEVICE_TAG=cu128 docker compose --profile gpu up --no-log-prefix
# Docker Compose —— 运行 Headless
DEVICE_TAG=cu128 docker compose --profile gpu run --rm ebook2audiobook \
--headless --ebook "/app/ebooks/myfile.pdf" --voice /app/voices/eng/adult/female/some_voice.wav
# Podman Compose —— 运行 Gradio GUI
DEVICE_TAG=cu128 podman-compose -f podman-compose.yml --profile gpu up
# Podman Compose —— 运行 Headless
DEVICE_TAG=cu128 podman-compose -f podman-compose.yml --profile gpu run --rm ebook2audiobook-gpu \
--headless --ebook "/app/ebooks/myfile.pdf" --voice /app/voices/eng/adult/female/some_voice.wav
声音克隆(Cloned Voices)
E2A 的声音克隆流程非常宽松:
- 任意音频格式均可上传(源码中
voice_formats覆盖.mp4/.m4b/.m4a/.mp3/.wav/.aac/.flac/.alac/.ogg/.aiff/.wma/.dsd/.opus/.pcmu/.pcma/.gsm等,见 lib/conf.py)。 - 理想时长 1–5 分钟。
- 无需干净录音:即使背景有噪音或音乐,E2A 会自动做降噪清理(对应"Denoise any background reference audio"路线图条目;内置了语音分割与降噪模型,默认语音分割模型为
drewThomasson/segmentation,见 lib/conf_models.py 的default_voice_detection_model,相关实现在 lib/classes/voice_extractor.py)。 - 内置克隆声音列表以英语为主;需要其他语言的官方预置声音需联系团队审核后添加。
- 若想用声音转换(Voice Conversion)而非克隆,源码还预置了
freevc24、knnvc、openvoice_v1/v2模型(TTS_VOICE_CONVERSION,lib/conf_models.py)。
微调 TTS 模型(Fine-Tuned Models)
E2A 官方链路分为"训练"与"使用"两步:
1. 训练自己的 XTTSv2 模型:官方提供了 Universal_TTS_Finetune 微调工作流,仓库内的 Notebooks/finetune/xtts/colab_xtts_finetune_webui.ipynb 与 Notebooks/finetune/xtts/kaggle-xtts-finetune-webui-gradio-gui.ipynb 可直接在 Colab/Kaggle 上跑微调训练。训练数据建议先用降噪工具(如 DeepFilterNet)清洗。
2. 使用微调模型:官方维护了 Fine-Tuned TTS 模型集合;训练好的 XTTSv2 模型必须包含一段参考音频 ref.wav(这是声音参考,必填)。在 E2A 中用 --fine_tuned <path> 指定模型路径(默认内置模型 internal)。
贡献与自定义:官方欢迎把自训模型加入官方预设列表,只需联系团队审核。
自定义配置:conf.py 与 models.py
官方明确允许用户自定义 lib/conf.py 与 lib/conf_models.py 中的设置。最佳实践:修改前先备份原始文件,每次 E2A 更新后恢复官方原版,再把你的自定义配置覆盖回去。可调项包括但不限于:
- 默认输出格式/声道/采样率(
default_output_format、default_output_channel、default_audio_proc_samplerate); - 输出拆分(
default_output_split、default_output_split_hours); - GUI 显示开关(
interface_component_options:XTTS/Bark 参数 Tab、声音文件分组、自定义模型分组、Audiobookshelf 参数 Tab 的显隐); - 上传大小上限(
max_upload_size = '6GB'); - 并发限制(
interface_concurrency_limit = 1,可改为None放开并行转换); - 各引擎语言子集、采样参数默认值与内置声音列表(lib/conf_models.py)。
远程运行:Colab / Kaggle / Hugging Face
除本地与 Docker 外,项目还提供免费远程运行通道:
- Google Colab:Notebooks/colab_ebook2audiobook.ipynb
- Kaggle:Notebooks/kaggle-ebook2audiobook.ipynb
- Hugging Face Space:官方在线空间(GUI 版)
这些 Notebook 适合没有本地 GPU 的场景,Colab 免费 T4 即可完成转换;assets/ 中的 Google Colab Restart Runtime pic.png 演示了 Notebook 运行中重启 Runtime 的提示界面。
回退到旧版本
git checkout tags/VERSION_NUM # 例如:git checkout tags/v25.7.7
版本号记录在 VERSION.txt,每次发版打 tag;按上述命令切到目标 tag 即可回退。
常见问题与排查
官方整理的常见问题及对策:
- GPU 检测不到(NVIDIA/ROCm/XPU/MPS) → 查阅官方 Wiki 的 GPU ISSUES 专页;启动时 components/detect_gpu.py 会把探测结果写入
device_info_json(.device_info.json,lib/conf.py)。 - CPU 太慢 → 官方确认:CPU 速度明显慢于 GPU,GPU 可接近实时转换;CPU 环境建议换用轻量引擎(YourTTS/Tacotron2 等),尽管没有零样本克隆能力且音质接近 Siri 级别,但速度显著更快。
- 依赖问题 → 直接用 Docker:完全自包含,支持 headless,末尾加
--help查看更多信息。 - 音频截断 → 这是句子切分逻辑相关的问题,官方欢迎在 issue 中反馈具体语言案例,以帮助改进分句逻辑。从源码看,分句由 lib/core.py 结合 lib/conf_lang.py 的多语言标点表(
punctuation_split_hard_set等)实现,中文等 CJK 语言的分句已做专项优化。
提 issue 前:官方强烈建议先在仓库的 open/closed issues 中搜索,确认问题不存在。
路线图与社区状态(截至本文撰写时)
官方路线图(baseline_README.md)中已完成的能力包括:转换前预览章节/块、SML 标签集成、多语言 -h/--help、PDF/JPG/BMP/PNG/TIFF 的 OCR、Notebooks 目录、中文分句优化、Dockerfile/Docker compose/Podman compose、Kaggle/Colab Notebook、Audiobookshelf 集成、电子书翻译、输出格式选择、多进程转换、批量目录转换、GPU 设备检测、克隆声音背景降噪、自定义微调模型上传。未完成项包括:iOS/Android App、逐句编辑(surgical text change)、以及 GPT-SoVITS、OpenVoice、fish-speech、ChatTTS、CosyVoice、F5-TTS 等新一代 TTS 引擎接入。
面向开发者的代码规范
若你打算为 E2A 贡献代码,官方代码规范(见 baseline_README.md)要求:函数与类之间以外不保留空行;除 dict()/JSON 外统一使用单引号、dict['key'] 单引号调用;严格 4 空格缩进、禁用 Tab;所有函数参数与返回值必须严格类型标注,参数与类型间、函数与 -> 及返回值间不留空格。这些规范在 lib/core.py 等现有源码中均有体现,可作为格式参照。
总结
E2A 把"电子书 → 有声书"的完整链路(格式解析 → 章节检测 → 文本清洗与分句 → TTS 合成 → 音频合并与元数据写入)打包为开箱即用的工具,并提供 GUI、headless CLI、Docker、远程 Notebook 四类使用方式。其核心设计要点可以归纳为:多引擎 + 多语言的可组合性(lib/conf_models.py 是引擎与参数的唯一事实来源)、SML 标签对朗读节奏与多声音叙事的精细控制、会话机制支撑的断点续跑,以及 Audiobookshelf 的无缝集成。无论你是想快速把一本 EPUB 变成 m4b,还是想用克隆声音批量制作多语言有声书,本文覆盖的参数表与工作流都可以直接落地使用。
