ПРОМЕТЕЙ: Хроники цифрового суверенитета и победа над медленной озвучкой

Этот материал — не просто очередная инструкция. Это история победы над системным ограничением, которое годами мешало мне потреблять информацию так, как я этого хочу. Это технический отчет о создании «Прометея» — инструмента, который делает создание аудиокниг промышленным процессом.

Предыстория: Почему стандартные решения — это боль

Каждый, кто пробовал превратить электронную книгу в аудио, сталкивался с тремя стенами:

  • Балаболка и её аналоги: Замечательный софт, но в 2026 году он безнадежно медленный для больших объемов. Когда программа показывает «1% прогресса в час», а твой компьютер превращается в жужжащую печку — это не работа, это мазохизм. Интерфейс Windows накладывает свои ограничения на скорость обращения к API, и этот барьер невозможно пробить.
  • Облачные сервисы: Они предлагают отличное качество, но душат тебя лимитами. «Первые 5000 символов бесплатно», «Подписка за 20 долларов в месяц», «Ограничение на размер файла». Это полная противоположность цифровому суверенитету. Ты становишься зависимым от чужого биллинга.
  • Мобильные читалки: Удобно, но они не создают файл. Ты привязан к приложению. Если оно упадет или ты сменишь телефон, твоя «озвучка» исчезнет.

Мне нужен был инструмент, который работает на моем «железе», использует лучшие нейросети мира (Microsoft Neural TTS), но делает это со скоростью боевого истребителя. Так появился «Прометей».

Архитектурная логика: Почему это работает быстро

«Прометей» — это не программа. Это конвейер. Я обосновал выбор каждого компонента, исходя из физики процессов:

1. Многопоточность как основа (xargs -P)

Microsoft ограничивает скорость генерации аудио на один поток. Если ты просишь озвучить книгу целиком, сервер будет отдавать данные со скоростью чуть быстрее человеческой речи. Это узкое горлышко. «Прометей» рубит книгу на десятки чанков и запрашивает их одновременно. 12-16 потоков заставляют сервера Microsoft работать на нас в полную силу. Мы утилизируем канал сервера, а не ждем своей очереди.

2. Стабильность данных (fold -s и Disk-First)

Стандартные скрипты часто падают на кириллице. Русская буква в UTF-8 весит 2 байта. Обычный разрез файла может пройти ровно между этими байтами, и Python-декодер вылетит с критической ошибкой. Использование fold -s гарантирует, что разрез пройдет по пробелу. А перенос рабочего каталога из RAM на SSD (Disk-First) позволяет перемалывать книги любого объема, не боясь заполнения оперативной памяти.

3. Пандок и парсинг метаданных

Я не хочу видеть в плеере файлы с именами типа 12345.mp3. Использование pandoc позволяет извлекать из FB2-структуры чистый текст, а самописный парсер вытягивает ФИО автора и название книги. На выходе — идеальный порядок в библиотеке.

Инструкция для тех, кто готов созидать

Я даю вам базу. Она работает. Как вы её развернете и что будете озвучивать — ваше личное дело. Саппорта не будет, потому что админ должен уметь читать логи сам.

Что нужно поставить на сервер (Debian/Ubuntu)

  • Python 3.10+: Среда для работы движка.
  • edge-tts: Библиотека для прямого доступа к нейросетям Microsoft.
  • FFmpeg: Инструмент для «сшивания» аудио-кусков в монолитный MP3 без потери качества.
  • Pandoc: Универсальный конвертер для FB2 и других текстовых форматов.
# Установка за одну минуту:
apt update && apt install -y python3-pip ffmpeg pandoc
pip install edge-tts --break-system-packages
mkdir -p /root/books/{text,audio,tmp}

После этого создай файл prometheus.sh в папке /root/ и вставь туда код ниже.

ОТКРЫТЬ ИСХОДНЫЙ КОД ПРОМЕТЕЯ v7.2.1
#!/bin/bash
# ======================================================
# PROJECT PROMETHEUS v7.2.1 | MASTER EDITION
# Technical Assistant: Phoenix901
# ======================================================

# КОНФИГУРАЦИЯ
THREADS=12                # Оптимально для 1 ядра
VOICE="ru-RU-DmitryNeural"
RATE="+15%"               # Темп речи (схлопывает паузы)
OUTPUT_BASE="/root/books/audio"
TEMP_BASE="/root/books/tmp"

# ЦВЕТОВАЯ ПАЛИТРА PHOENIX901
ORANGE='\033[0;31m'
COPPER='\033[0;33m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m'

clear
echo -e "${ORANGE}======================================================${NC}"
echo -e "${COPPER}   PROJECT PROMETHEUS v7.2.1 | MASTER EDITION         ${NC}"
echo -e "${ORANGE}======================================================${NC}"

# 1. ПРОВЕРКА ЗАВИСИМОСТЕЙ
for cmd in edge-tts ffmpeg pandoc; do
    if ! command -v $cmd &> /dev/null; then echo -e "${ORANGE}ERR: $cmd не установлен!${NC}"; exit 1; fi
done

# 2. ВВОД ДАННЫХ
read -e -p "Введи путь к файлу (txt/fb2): " INPUT_PATH
INPUT_PATH=$(echo "$INPUT_PATH" | sed -e 's/^"//' -e 's/"$//' -e "s/^'//" -e "s/'$//")

if [ ! -f "$INPUT_PATH" ]; then echo -e "${ORANGE}ERR: Файл не найден!${NC}"; exit 1; fi

# 3. ПОДГОТОВКА СРЕДЫ
WORKDIR="${TEMP_BASE}/work_$(date +%s)"
mkdir -p "$WORKDIR" "$OUTPUT_BASE"

# 4. ОБРАБОТКА МЕТАДАННЫХ И КОНВЕРТАЦИЯ
FILE_EXT="${INPUT_PATH##*.}"
ORIG_NAME=$(basename "$INPUT_PATH" ."$FILE_EXT")

if [[ "$FILE_EXT" == "fb2" ]]; then
    echo -e "${GREEN}>>> Формат: FB2. Парсинг структуры...${NC}"
    F_NAME=$(grep -i -oP '(?<=<first-name>).*?(?=</first-name>)' "$INPUT_PATH" | head -1)
    M_NAME=$(grep -i -oP '(?<=<middle-name>).*?(?=</middle-name>)' "$INPUT_PATH" | head -1)
    L_NAME=$(grep -i -oP '(?<=<last-name>).*?(?=</last-name>)' "$INPUT_PATH" | head -1)
    TITLE=$(grep -i -oP '(?<=<book-title>).*?(?=</book-title>)' "$INPUT_PATH" | head -1)
    META_NAME="${L_NAME}_${F_NAME}${M_NAME:+_$M_NAME}__${TITLE}"
    if [ ${#META_NAME} -lt 10 ]; then BOOK_NAME="$ORIG_NAME"; else BOOK_NAME="$META_NAME"; fi
    pandoc -f fb2 -t plain "$INPUT_PATH" -o "$WORKDIR/raw.txt"
else
    echo -e "${GREEN}>>> Формат: TXT. Наследование имени...${NC}"
    BOOK_NAME="$ORIG_NAME"
    cp "$INPUT_PATH" "$WORKDIR/raw.txt"
fi

BOOK_NAME=$(echo "$BOOK_NAME" | sed 's/[[:space:]]/_/g' | sed 's/[\\/:"*?<>|]//g')
FINAL_FILE="$OUTPUT_BASE/${BOOK_NAME}.mp3"

echo -e "${COPPER}>>> КНИГА: ${BLUE}${BOOK_NAME}.mp3${NC}"

# 5. ОПТИМИЗАЦИЯ ТЕКСТА (SILENCE KILLER)
sed '/^$/d' "$WORKDIR/raw.txt" > "$WORKDIR/source.txt"

# 6. НАРЕЗКА (UTF-8 SAFE)
echo -e "${GREEN}>>> Нарезка безопасных чанков...${NC}"
fold -s -w 2000 "$WORKDIR/source.txt" | tr -d '\r' > "$WORKDIR/formatted.txt"
split -l 100 -d -a 4 "$WORKDIR/formatted.txt" "$WORKDIR/part_"

TOTAL_PARTS=$(ls "$WORKDIR"/part_[0-9]* | wc -l)

# 7. МНОГОПОТОЧНАЯ ОЗВУЧКА
export VOICE WORKDIR RATE
do_tts() {
    local file=$1
    edge-tts --rate="$RATE" --voice "$VOICE" --file "$file" --write-media "$file.mp3" > /dev/null 2>&1
}
export -f do_tts

(
    while true; do
        DONE_PARTS=$(ls "$WORKDIR"/part_*.mp3 2>/dev/null | wc -l)
        if [ "$TOTAL_PARTS" -gt 0 ]; then PERCENT=$(( DONE_PARTS * 100 / TOTAL_PARTS )); else PERCENT=0; fi
        printf "\r${ORANGE}Прогресс: [${COPPER}%-40s${ORANGE}] %d%% (%d/%d)${NC}" $(printf '#%.0s' $(seq 1 $((PERCENT * 40 / 100)) 2>/dev/null)) "$PERCENT" "$DONE_PARTS" "$TOTAL_PARTS"
        [ "$DONE_PARTS" -ge "$TOTAL_PARTS" ] && break
        sleep 2
    done
) &
PROGRESS_PID=$!

ls "$WORKDIR"/part_[0-9]* | xargs -P $THREADS -I {} bash -c 'do_tts "{}"'
wait $PROGRESS_PID

# 8. СКЛЕЙКА (FFMPEG)
echo -e "\n${GREEN}>>> Склеиваю финальный монолит...${NC}"
ls "$WORKDIR"/part_*.mp3 | sort | xargs -I {} echo "file '{}'" > "$WORKDIR/list.txt"
ffmpeg -f concat -safe 0 -i "$WORKDIR/list.txt" -c copy -y "$FINAL_FILE" &> /dev/null

# 9. ЧИСТКА
rm -rf "$WORKDIR"
echo -e "${ORANGE}======================================================${NC}"
echo -e "${GREEN}ГОТОВО!${NC} Файл: ${BLUE}$FINAL_FILE${NC}"
echo -e "${ORANGE}======================================================${NC}"

Технические нюансы и ответы на вопросы

  • Проблема пауз: Нейронки Microsoft имеют «врожденную» особенность — они делают длинные паузы между абзацами, имитируя дыхание диктора. На текущий момент в библиотеке нет штатного способа управлять этим параметром. Решение: Я выставил в скрипте RATE="+15%", что немного ускоряет темп и сжимает задержки. Для идеального комфорта используйте в плеере функцию «Skip Silence» и скорость 1.2x.
  • Блокировки IP (Error 429): Если вы решите озвучить сразу 50 книг, Microsoft может временно заблокировать ваш сервер. 12 потоков (THREADS) — это проверенный безопасный предел для личного использования.
  • Качество звука: Мы получаем чистый моно-поток, который идеально подходит для речи. Битрейт оптимизирован так, чтобы 15-часовая книга весила около 300-400 МБ. Это экономит место на вашем устройстве.
  • Кириллица в именах: Скрипт полностью поддерживает русские названия файлов и корректно передает их в файловую систему Linux.

Манифест «Не жалко»

Я делюсь этой технологией, потому что ресурс не должен гнить на складе. Если код написан и он приносит пользу — он должен быть в обороте. Я потратил время на борьбу с кодировками, лимитами и структурой FB2, чтобы вы могли просто запустить скрипт и получить результат.

Этот инструмент для свободных людей. Для тех, кто не хочет платить корпорациям за право слушать книги. Берите, пользуйтесь, ломайте, переписывайте. Но делайте это сами.

👁️ 49

ПРОМЕТЕЙ: Хроники цифрового суверенитета и победа над медленной озвучкой: 4 комментария

  1. классная штука! Я недавно задумался о чём-то подобном. Спасибо за исполнение на линуксе, Наверное я переделаю это под себя для использования на винде, и потом поделюсь версией для винды, тут впринципе переделать sh на bat наверное и делов то…





    1. Там же вся суть «Прометея» не в расширении файла, а в менеджменте процессов через xargs -P, который 16 потоков в параллели держит и выжимает из канала максимум. В обычном виндовом батнике ты такую многопоточность не реализуешь, он просто захлебнётся или будет по одной главе мурыжить вечность, сводя всю затею к нулю. Плюс в винде физически нет нативных split и fold, чтобы текст на чанки безопасно резать — батник тебе гарантированно русскую букву в UTF-8 пополам порвёт и питоновский движок сразу вылетит с критической ошибкой декодирования. Если реально хочешь под виндой это завести, то единственный вменяемый путь это WSL, там мой скрипт заведётся вообще без правок. А на чистых батниках ты только время убьёшь и в итоге получишь медленного инвалида. Попробуй конечно, если секса с консолью не хватает, но я бы на твоём месте не питал иллюзий про лёгкий перенос.





      1. спасибо за разъяснение. Действительно лучше так пользоваться, чем сношаться. А на чистом python это можно реализовать, как думаешь?





        1. На чистом питоне это сделать не просто можно, а технически это будет даже «роднее» для движка, так как сама библиотека edge-tts написана на Python и асинхронности (asyncio). Чтобы реализовать логику «Прометея» без баша, тебе придётся воспроизвести весь мой конвейер внутри кода: сначала использовать модуль textwrap для имитации работы fold -s (чтобы не рвать кириллицу), потом через генераторы разбивать текст на блоки, и самое главное — вместо xargs -P использовать asyncio.gather или Semaphore для контроля потоков, чтобы разом отправлять пачку запросов в облако Microsoft. Плюс такого подхода в том, что скрипт станет кроссплатформенным и заведётся на той же винде без костылей WSL, но минус в том, что баш на сервере управляет процессами более жёстко и прозрачно на уровне ядра системы. Если есть желание сношаться с обработкой исключений внутри асинхронных циклов и писать свою обвязку для склейки через ffmpeg-python, то питон даст тебе полный контроль, но по скорости генерации выигрыша не будет, так как всё равно всё упирается в лимиты API Майкрософта. Короче, на питоне это будет элегантный монолитный код вместо моего модульного конструктора, но для админа баш-скрипт всегда остаётся более «честным» инструментом, который видно насквозь в логах процесса.





Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

четыре × три =

root@phoenix901:~# connect
[×]

Получай дайджест раз в неделю.
Без спама.