Найти в Дзене
expert-x

Как создать профессиональную аудиокнигу из EPUB на Linux с озвучкой через Azure и прослушиванием на iPhone

Хочешь слушать книги, которых нет в озвучке, — в мужском голосе, с паузами между главами, на своём iPhone или в Apple Books? Рассказываю, как я превратил электронную книгу EPUB в .m4b аудиофайл с высоким качеством синтеза речи. 📘 Что мы будем делать ✅ Что понадобится 🔐 Регистрация и получение Azure Speech API ключа Перейди в созданный ресурс → вкладка “Ключи и конечная точка” Скопируй: ❗ Не публикуй свой ключ публично — это доступ к твоим лимитам. ⚙️ Установка зависимостей и создание окружения создаем директорию mkdir -p ~/epub_to_m4b cd ~/epub_to_m4b # затем загрузка файла EPUB через Termius → Local Files → Upload ставим системные зависимости sudo apt update sudo apt install ffmpeg python3-venv -y создаем и активируем окружение python3 -m venv venv source venv/bin/activate Ставим зависимости python в окружении pip install ebooklib beautifulsoup4 requests pydub mutagen 📜 Создаем скрипт: epub_to_m4b_with_meta.py nano epub_to_m4b_with_meta.py Вставь содержимое ниже, замен

Хочешь слушать книги, которых нет в озвучке, — в мужском голосе, с паузами между главами, на своём iPhone или в Apple Books?

Рассказываю, как я превратил электронную книгу EPUB в .m4b аудиофайл с высоким качеством синтеза речи.

📘 Что мы будем делать

  • Возьмём файл в формате .epub
  • Озвучим его голосом Дмитрия (Azure TTS) — реалистичный мужской голос
  • Добавим метаданные: название, автора
  • Сохраним в формате .m4b, который поддерживают iPhone и BookPlayer
  • Получим файл, идеально подходящий для офлайн-прослушивания на телефоне

✅ Что понадобится

  • Сервер или компьютер с Linux (подойдёт Ubuntu 20+)
  • Python 3.10+
  • Аккаунт в Microsoft Azure
  • Базовые знания командной строки

🔐 Регистрация и получение Azure Speech API ключа

  1. Зарегистрируйся на https://portal.azure.com
  2. Создай ресурс типа “Speech”:
  • Группа ресурсов: любая
  • Регион: East US или East US 2
  • Тариф: Free F0 (включает до 5 часов озвучки в месяц)

Перейди в созданный ресурс → вкладка “Ключи и конечная точка”

Скопируй:

  • Key 1 — это будет твой API ключ
  • Endpoint — например: https://eastus2.api.cognitive.microsoft.com/

❗ Не публикуй свой ключ публично — это доступ к твоим лимитам.

⚙️ Установка зависимостей и создание окружения

создаем директорию

mkdir -p ~/epub_to_m4b
cd ~/epub_to_m4b
# затем загрузка файла EPUB через Termius → Local Files → Upload

ставим системные зависимости

sudo apt update
sudo apt install ffmpeg python3-venv -y

создаем и активируем окружение

python3 -m venv venv
source venv/bin/activate

Ставим зависимости python в окружении

pip install ebooklib beautifulsoup4 requests pydub mutagen

📜 Создаем скрипт: epub_to_m4b_with_meta.py

nano epub_to_m4b_with_meta.py

Вставь содержимое ниже, замени ключ и регион на свои:

import os

import time

import glob

import requests

from ebooklib import epub

from ebooklib import ITEM_DOCUMENT

from bs4 import BeautifulSoup

from pydub import AudioSegment

from mutagen.mp4 import MP4

# ✅ Azure Speech настройки

AZURE_KEY = 'ВСТАВЬ_СЮДА_СВОЙ_API_КЛЮЧ'

AZURE_REGION = 'eastus2'

VOICE = 'ru-RU-DmitryNeural'

HEADERS = {

   'Ocp-Apim-Subscription-Key': AZURE_KEY,

   'Content-Type': 'application/ssml+xml',

   'X-Microsoft-OutputFormat': 'audio-16khz-32kbitrate-mono-mp3'

}

# 🔍 Поиск первого EPUB в текущей директории

def find_epub_file():

   epub_files = glob.glob("*.epub")

   if not epub_files:

     raise FileNotFoundError("❌ EPUB-файл не найден в текущей директории.")

   return epub_files[0]

# 📖 Чтение названия и автора (с защитой)

def get_metadata(epub_path):

   try:

     book = epub.read_epub(epub_path)

   except KeyError as e:

     raise Exception(f"❌ EPUB повреждён: отсутствует файл {e}") from None

   title = book.get_metadata('DC', 'title')

   creator = book.get_metadata('DC', 'creator')

   return (

     title[0][0] if title else "EPUB AudioBook",

     creator[0][0] if creator else "Unknown Author"

   )

# 📚 Извлечение глав с текстом

def extract_chapters(epub_path):

   try:

     book = epub.read_epub(epub_path)

   except KeyError as e:

     raise Exception(f"❌ Ошибка чтения EPUB: {e}") from None

   chapters = []

   for item in book.get_items():

     if item.get_type() == ITEM_DOCUMENT:

       soup = BeautifulSoup(item.content, 'html.parser')

       text = soup.get_text(separator=' ', strip=True)

       if len(text.strip()) > 200:

         title = item.get_name().split('/')[-1]

         chapters.append((title, text))

   return chapters

# 🗣️ Синтез одной главы

def synthesize(text, filename):

   ssml = f"""<speak version='1.0' xml:lang='ru-RU'>

   <voice xml:lang='ru-RU' xml:gender='Male' name='{VOICE}'>{text}</voice></speak>"""

   url = f"https://{AZURE_REGION}.tts.speech.microsoft.com/cognitiveservices/v1"

   response = requests.post(url, headers=HEADERS, data=ssml.encode('utf-8'))

   if response.status_code == 200:

     with open(filename, 'wb') as f:

       f.write(response.content)

   else:

     raise Exception(f"TTS failed: {response.status_code} {response.text}")

# 🎧 Объединение mp3 в .m4b и добавление метаданных

def build_m4b(chapters_folder, output_file, title, author):

   if os.path.exists(output_file):

     os.remove(output_file)

   chapters = sorted(os.listdir(chapters_folder))

   full_audio = AudioSegment.empty()

   for ch in chapters:

     path = os.path.join(chapters_folder, ch)

     audio = AudioSegment.from_mp3(path)

     full_audio += audio

   full_audio.export(output_file, format='mp4')

   audio_file = MP4(output_file)

   audio_file["\xa9nam"] = title

   audio_file["\xa9ART"] = author

   audio_file["\xa9alb"] = title

   audio_file["trkn"] = [(1, 1)]

   audio_file.save()

# 🚀 Точка входа

if __name__ == "__main__":

   EPUB_FILENAME = find_epub_file()

   print(f"📘 Найден файл: {EPUB_FILENAME}")

   title, author = get_metadata(EPUB_FILENAME)

   print(f"📖 Название: {title}")

   print(f"✍️ Автор: {author}")

   # Безопасное имя файла

   safe_title = "".join(c for c in title if c.isalnum() or c in (' ', '-', '_')).strip().replace(" ", "_")

   output_file = f"{safe_title}.m4b"

   os.makedirs("audio", exist_ok=True)

   chapters = extract_chapters(EPUB_FILENAME)

   for idx, (chapter_title, text) in enumerate(chapters):

     print(f"▶️ Синтез главы {idx + 1}/{len(chapters)}: {chapter_title}")

     filename = f"audio/chapter_{idx+1:03}.mp3"

     if not os.path.exists(filename):

       synthesize(text[:5000], filename)

     time.sleep(0.5)

   build_m4b("audio", output_file, title, author)

   print(f"✅ Готово: {output_file}")

  • Сохрани: Ctrl+O, Enter, Ctrl+X
  • Активируй среду (если нужно):
source venv/bin/activate

  • Запусти:
python epub_to_m4b_with_meta.py

🧪 Пример вывода

-2

📲 Как слушать на iPhone

  1. Скопируй .m4b на iPhone через Termius или AirDrop
  2. Открой в приложении BookPlayer, Voice Dream или Apple Books
  3. Наслаждайся качественной мужской озвучкой своей книги 🎧