Files
AE_Anons/README.md

23 KiB
Raw Permalink Blame History

AE Anons - Автономный генератор спортивных анонсов в After Effects

AE Anons Logo

License: MIT Rust Status

AE Anons — полностью автономная (standalone) система для создания спортивных анонсов с использованием шаблонов After Effects через Nexrender. Все данные берутся из электронных таблиц Synology Office, рендеринг выполняется локально, управление заданиями происходит через встроенный веб-интерфейс с мгновенными обновлениями. Система не требует доступа в интернет — все ресурсы (иконки, стили, шрифты) встроены в бинарный файл.

Новое в версии v0.3.0

  • WebSocket — мгновенные обновления списка заданий (без устаревшего polling каждые 60 секунд)
  • SQLite — хранение истории заданий и статуса апрува
  • Просмотр видео прямо в веб-интерфейсе (по ссылке на готовый файл)
  • Апрув заданий с копированием видео на SMB-шару (без монтирования, с поддержкой Active Directory)
  • Уведомления в реальном времени о старте/завершении генерации, ошибках
  • Улучшенный веб-интерфейс с кнопками апрува и иконками превью
  • Оптимизация памяти — строки таблицы обрабатываются потоково, неиспользуемые логотипы и ассеты удаляются после генерации. Пиковое потребление памяти достигается только в момент загрузки и парсинга Excel, после чего память освобождается. Это позволяет работать с таблицами большого объёма (десятки тысяч строк) и обеспечивает стабильную работу в режиме долгоживущего сервиса.
  • Полная автономность — все статические ресурсы (HTML, CSS, Font Awesome, логотип, favicon) встроены в бинарный файл.

Обзор

AE Anons — это CLI-утилита и веб-сервер на Rust, которая выступает как интеллектуальный генератор заданий для Nexrender — опенсорсного оркестратора рендеринга After Effects.

Режимы работы

  1. Однократная обработка (--once или без флагов):

    • Подключение к NAS Synology
    • Парсинг Excel данных
    • Генерация и отправка заданий Nexrender
    • Мониторинг завершения и выход
  2. Веб-сервер (--web):

    • Запуск веб-интерфейса на порту :3000 (настраивается)
    • Управление заданиями через браузер с WebSocket-обновлениями
    • Просмотр видео и апрув готовых роликов

Особенности

  • Полная автономность — не требует выхода в интернет, все ресурсы встроены в бинарник
  • Интеграция с Synology — аутентификация и загрузка файлов с NAS Synology (локальные и AD-учётные записи)
  • Экспорт офисных таблиц — автоматическое преобразование .osheet в Excel
  • Гибкий парсинг данных — динамический парсинг листов с обнаружением заголовков
  • Множественная генерация вариантов — "Сегодня", "Завтра" и датированные версии
  • Умное управление логотипами — автоматическое разрешение и масштабирование
  • Веб-интерфейс с WebSocket — мгновенные обновления, просмотр видео, апрув
  • REST API — программное управление заданиями
  • SQLite — хранение истории и статуса апрува
  • Поддержка SMB — копирование утверждённых видео на сетевую шару (с AD-аутентификацией)
  • Профессиональное логирование — структурированный журнал с настройкой уровня
  • Эффективная работа с памятью — потоковая обработка строк, своевременное удаление неиспользуемых данных (логотипы, ассеты) позволяет обрабатывать таблицы с десятками тысяч строк без утечек памяти

Предварительные требования

  • Rust 1.70 или выше
  • Доступ к NAS Synology с пакетами File Station и Office (локальный или доменный пользователь)
  • Экземпляр server и worker (не менее одного) Nexrender
  • Шаблоны After Effects (формат .aep или .aepx, совместимые с версией AE на worker)
  • (Для апрува) Доступ к SMB-шаре с правами на запись

Установка

git clone https://git.example.com/team/ae_anons.git
cd ae_anons
cargo build --release
cp .env.example .env
# отредактируйте .env согласно вашей инфраструктуре

Конфигурация

Все настройки задаются через переменные окружения в файле .env.

Основные переменные

Переменная Обязательна Описание
NAS_FQDN Да URL Synology NAS (*)
NAS_USER Да Имя пользователя (локального или доменного, например DOMAIN\username)
NAS_PASS Да Пароль
NAS_FILE Да Путь к .osheet файлу на NAS (например, /Team Folder/schedule.osheet)
NEXRENDER_API_URL Да API Nexrender (например, http://nexrender:3050/api/v1/jobs)
OUTPUT_FOLDER Да Папка, куда Nexrender сохраняет готовые видео (локальный путь)
TEMPLATE_DOUBLE_SRC Да Путь к AEP-шаблону для двух команд (например, file:///templates/double.aepx)
TEMPLATE_SINGLE_SRC Да Путь к AEP-шаблону для одной команды
TEMPLATE_COMPOSITION Да Имя композиции в проекте AE
TEMPLATE_OUTPUT_MODULE Да Имя модуля вывода в AE
TEMPLATE_OUTPUT_EXT Да Расширение выходного файла (например, mp4)
WEB_PORT Нет Порт веб-сервера (по умолчанию 3000)
RUST_LOG Нет Уровень логирования (info, debug, trace)
SMB_UPLOAD_URL Да(**) SMB-URL для апрува (например, smb://storage/approved)
SMB_USERNAME Да(**) Имя пользователя для SMB (локальный или DOMAIN\user)
SMB_PASSWORD Да(**) Пароль для SMB
DATABASE_URL Нет Путь к SQLite БД (по умолчанию sqlite:ae_anons.db)

(*) — для NAS_FQDN можно указывать протокол http:// или https://. Безопаснее https, хотя для локальной сети допустим и http. Если NAS доступен по стандартному HTTPS-порту 443, протокол можно опустить (например, nas.company.local). Иначе указывайте полный URL с портом: https://nas.company.local:5001 или http://nas.local:5000.

(**) — обязательно, если используется функция апрува (веб-режим). В режиме --once апрув не требуется.

Пример файла .env

# Synology NAS
NAS_FQDN="https://nas.company.local:5001"
NAS_USER="DOMAIN\\service_account"
NAS_PASS="strongpassword"
NAS_FILE="/Team Folder/Anonsy/sport.osheet"

# Nexrender
NEXRENDER_API_URL="http://render-01:3050/api/v1/jobs"
OUTPUT_FOLDER="/mnt/nexrender/output"

# After Effects Templates
TEMPLATE_DOUBLE_SRC="file:///mnt/templates/double_team.aepx"
TEMPLATE_SINGLE_SRC="file:///mnt/templates/single_team.aepx"
TEMPLATE_COMPOSITION="main"
TEMPLATE_OUTPUT_MODULE="h264"
TEMPLATE_OUTPUT_EXT="mp4"

# Web server
WEB_PORT="3000"
RUST_LOG="info"

# SMB для апрува (AD-совместимо)
SMB_UPLOAD_URL="smb://storage.company.local/approved_videos"
SMB_USERNAME="DOMAIN\\service_account"
SMB_PASSWORD="strongpassword"

# Database
DATABASE_URL="sqlite:/var/lib/ae_anons/ae_anons.db"

Примечание об аутентификации:
Synology API и SMB-библиотека smb поддерживают как локальных пользователей NAS, так и доменных (Active Directory). Для доменных пользователей используйте формат DOMAIN\username (обратный слеш необходимо экранировать в .env как \\). Проверено на Synology DSM 7.x и Samba AD.

Использование

Однократная обработка (cron или ручной запуск)

./target/release/ae_anons --once

Веб-сервер (интерактивный режим)

./target/release/ae_anons --web

После запуска откройте браузер: http://localhost:3000

Веб-интерфейс

  • Главная страница — таблица всех заданий с полями: UID, имя файла, статус, превью (иконка видео), кнопка апрува, дата создания.
  • Обновления в реальном времени через WebSocket — статусы заданий меняются мгновенно без перезагрузки страницы.
  • Кнопка «Generate» — запускает парсинг таблицы Synology и создание новых заданий. Во время генерации кнопка блокируется, при завершении приходит уведомление.
  • Кнопка «Cleanup» — удаляет из Nexrender задания со статусом finished/error.
  • Кнопка «Stop all» — останавливает все активные (queued/started/processing) задания.
  • Просмотр видео — клик по иконке видео открывает готовый файл в новой вкладке (поддерживается любой браузерный просмотр MP4).
  • Апрув — клик по копирует видео на SMB-шару (путь из SMB_UPLOAD_URL) и помечает задание как approved. Повторный апрув невозможен.

API эндпоинты

  • GET /api/jobs — список всех заданий (из SQLite)
  • POST /api/generate — запуск генерации
  • POST /api/cleanup — очистка завершённых
  • POST /api/jobs/stop-all — остановка активных
  • GET /api/status — статус сервера
  • GET /api/video/:uid — просмотр видеофайла
  • POST /api/approve/:uid — апрув (копирование на SMB)
  • WS /ws — WebSocket для получения событий (JobUpdated, GenerationStarted, GenerationFinished, Error)

Уровни логирования

RUST_LOG=debug ./ae_anons --web

  • error — только критические ошибки
  • warn — предупреждения
  • info — стандартная информация (по умолчанию)
  • debug — детали API-вызовов, парсинга, SMB-операций
  • trace — максимальная детализация

Структура электронной таблицы

Файл Excel должен содержать следующие листы со специфичными структурами:

Лист "SPORT"

Связывает названия видов спорта с соответствующими видео пакетами.

SPORT LINK
Без оформления \server\share\path\to\null.mov
Футбол \server\share\path\to\football_pack.mov
Волейбол \server\share\path\to\volleyball_pack.mov

Лист "TEAMS"

Сопоставляет имена команд с их видами спорта и логотипами. Колонка SPORT заполняется из выпадающего списка (заполнена из листа SPORT).

Если несколько команд в одном виде спорта имеют одинаковые названия, но разные логотипы, используется разделитель хеш # для уникальной идентификации.

TEAM SPORT LINK
Галатасарай#Turki Футбол \server\share\path\to\galatasaray_football.png
Галатасарай Волейбол \server\share\path\to\galatasaray_volleyball.png
Галатасарай#UCL Волейбол \server\share\path\to\galatasaray_ucl.png
Сомбатей##400 Футбол \server\share\path\to\szombathely.png

Лист "CHANELL"

Сопоставляет названия каналов с их логотипами. Поля заполняются вручную без выпадающих списков.

CHANELL LINK
КАНАЛ \server\share\path\to\channel_logo.png
TRIUMPH \server\share\path\to\triumph_logo.png

Лист "Start"

Основной источник данных для генерации анонсов. Большинство полей заполняются из выпадающих списков, основанных на других листах.

Обязательные колонки: DATA, TIME, CHANELL, SPORT, LEAGUE, TEAM A, TEAM B

Примечания:

  • Колонка LEAGUE обязательна для заполнения, но не имеет выпадающего списка. Проверка орфографии и опечаток отсутствует!
  • Колонка DATA должна содержать дату в формате ДД.ММ.ГГГГ (например, 28.2.2026).
STATE TRIPPLE DATA TIME SPORT LEAGUE CHANELL TEAM A TEAM B
TRUE TRUE 27.2.2026 23:40 Футбол Чемпионат Португалии START Спортинг#ll#550 Эшторил#ll#550
FALSE TRUE 28.2.2026 12:55 Волейбол Чемпионат Турции. Женщины TRIUMPH Бешикташ Галатасарай#Turki

Формат имен команд

Имена команд поддерживают два типа разделителей хэш #:

  1. Первый хеш: Уникальный идентификатор для команд с одинаковыми названиями в одном виде спорта, или одинаковым названием в разных видах спорта.
  2. Второй хеш: Целевой размер в пикселях для масштабирования логотипа

Формат: DisplayName#UniqueID#TargetSize

Примеры:

  • Галатасарай#Turki - только уникальный идентификатор
  • Сомбатей##400 - только целевой размер (обратите внимание на двойной хеш)
  • Спортинг#ll#550 - оба идентификатор и целевой размер

Выходные файлы

Рендеренные видео сохраняются в OUTPUT_FOLDER по шаблону: YYYYMMDD_Sport_League_TeamA_TeamB_Channel[_Variant].mp4

При апруве файл копируется в SMB-шару с тем же именем.

Рабочий процесс (веб-режим)

  1. Пользователь заполняет таблицу Synology Office.
  2. Нажимает «Generate» в веб-интерфейсе.
  3. Сервер аутентифицируется на NAS, скачивает и парсит Excel.
  4. Генерирует задания Nexrender, сохраняет их в SQLite и отправляет в Nexrender.
  5. WebSocket уведомляет клиент о новых заданиях.
  6. Nexrender рендерит видео, статус задания обновляется (периодический опрос или webhook).
  7. Когда видео готово, пользователь видит иконку превью, может посмотреть видео и нажать апрув.
  8. При апруве видео копируется на SMB-шару, задание помечается как approved.

Требования к шаблонам After Effects

Не изменились — все слои DATA, TIME_H, TIME_M, LEAGUE, SPORT, TEAMS, TEAM_A_LOGO, TEAM_B_LOGO, CHANELL, TOP должны присутствовать согласно типу шаблона (DOUBLE/SINGLE). Поддержка масштабирования логотипов через выражения After Effects — осталась.

Устранение неисправностей

WebSocket не работает

  • Проверьте, что браузер поддерживает WebSocket (все современные поддерживают).
  • При использовании прокси (nginx) необходимо настроить Upgrade заголовки.

Ошибка аутентификации на NAS для доменного пользователя

  • Убедитесь, что в .env указано DOMAIN\\username (двойной обратный слеш).
  • Проверьте, что NAS настроен на приём доменных учётных записей (DSM → Домен/LDAP).

Ошибка SMB подключения

  • Проверьте доступность шары: smbclient -U DOMAIN/username -L //storage/
  • Убедитесь, что в URL используется smb:// протокол, путь без лишних слешей.
  • Время на сервере и клиенте должно быть синхронизировано (SMB требует этого).

БД SQLite блокирована

  • При конкурентных запросах SQLite может выдавать database is locked. Для веб-сервера с одним процессом это маловероятно. Если возникает — используйте sqlite://:memory: для тестов или настройте WAL-режим.

Высокое потребление памяти

  • Система спроектирована так, чтобы минимизировать удержание данных. Если вы наблюдаете рост памяти, убедитесь, что вы используете последнюю версию. При работе с очень большими таблицами (сотни тысяч строк) может потребоваться увеличить лимит строк в processor.rs (константа 10000).

Разработка

Все статические ресурсы (HTML, CSS, шрифты Font Awesome, логотип, favicon) встроены в бинарник с помощью include_str! и include_bytes!. Для разработки можно редактировать файлы в src/static/, но при сборке они компилируются внутрь исполняемого файла.

Сборка для production

cargo build --release
strip target/release/ae_anons   # уменьшает размер

Итоговый бинарник можно переносить на любой Linux-сервер без дополнительных зависимостей (кроме libc и openssl, если не используется статическая сборка).

Лицензия

AE Anons — MIT
Nexrender — MIT
Font Awesome Free — CC BY 4.0 (иконки) и SIL OFL 1.1 (шрифты)


Made with 🦀 Rust and coffee