399 lines
22 KiB
Markdown
399 lines
22 KiB
Markdown
# AE Anons - Автоматизированный генератор спортивных анонсов в After Effects
|
||
|
||
<div align="left">
|
||
<img src="assets/logo.png" alt="AE Anons Logo" width="200"/>
|
||
|
||
|
||
</div>
|
||
|
||
[](https://opensource.org/licenses/MIT) [](https://www.rust-lang.org/) [](https://git.tvstart.ru/lexx/AE_Anons)
|
||
|
||
Автоматизированная система для создания спортивных анонсов с использованием шаблонов After Effects через Nexrender, с данными из электронных таблиц Synology Office.
|
||
|
||
## Обзор
|
||
|
||
AE Anons — это CLI-утилита на Rust, которая выступает как **интеллектуальный генератор заданий**
|
||
для [Nexrender](https://github.com/inlife/nexrender) — опенсорсного оркестратора рендеринга
|
||
After Effects (лицензия MIT).
|
||
|
||
1. Подключения к NAS Synology для получения данных расписания из файлов офисных таблиц (.osheet)
|
||
2. Парсинга Excel данных, содержащих информацию о спортивных событиях, командах, каналах и временных интервалах
|
||
3. Генерации заданий Nexrender с соответствующими шаблонами и ресурсами
|
||
4. Мониторинга завершения рендеринга и управления выходными файлами
|
||
|
||
## Особенности
|
||
|
||
- **Интеграция с Synology**: Аутентификация и загрузка файлов с NAS Synology
|
||
- **Экспорт офисных таблиц**: Автоматическое преобразование файлов .osheet в формат Excel
|
||
- **Гибкий парсинг данных**: Динамический парсинг листов с обнаружением заголовков
|
||
- **Множественная генерация вариантов**: Создание "Сегодня", "Завтра" и датированных версий для каждого анонса
|
||
- **Умное управление логотипами**: Автоматическое разрешение и масштабирование логотипов на основе хэштегов `#` в имени команды
|
||
- **Оркестрация заданий Nexrender**: Автоматическая отправка, мониторинг и очистка заданий
|
||
- **Профессиональное логирование**: Структурированный журнал с возможностью настройки уровня детализации
|
||
- **Конфигурация через переменные окружения**: Все параметры управляются через файл `.env`
|
||
|
||
## Предварительные требования
|
||
|
||
- Rust 1.70 или выше
|
||
- Доступ к NAS Synology с установленными и включенными пакетами File Station и Office
|
||
- Экземпляр _server_ и _worker_(не менее одного) Nexrender
|
||
- Шаблоны After Effects, настроенные на _worker_ (формат Adobe After Effects 2024 .aepx)
|
||
|
||
## Установка
|
||
|
||
### 1. Клонирование репозитория
|
||
|
||
```bash
|
||
git clone https://git.tvstart.ru/lexx/AE_Anons.git
|
||
cd ae_anons
|
||
```
|
||
|
||
### 2. Сборка проекта
|
||
|
||
```bash
|
||
cargo build --release
|
||
```
|
||
|
||
Бинарный файл будет доступен по пути `target/release/ae_anons`
|
||
|
||
### 3. Настройка окружения
|
||
|
||
Скопируйте пример конфигурации и заполните своими данными:
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
```
|
||
|
||
Затем отредактируйте файл .env:
|
||
|
||
```env
|
||
# Synology NAS
|
||
NAS_FQDN=https://your-nas.domain.com
|
||
NAS_USER=your_username
|
||
NAS_PASS=your_password
|
||
NAS_FILE=/team-folders/path/to/your/file.osheet
|
||
|
||
# Nexrender
|
||
NEXRENDER_API_URL=http://your-nexrender-server:3000/api/v1/jobs
|
||
OUTPUT_FOLDER=//your-storage/path/to/output
|
||
|
||
# Logging
|
||
RUST_LOG=info
|
||
```
|
||
|
||
См. раздел Конфигурация для подробной информации.
|
||
|
||
## Использование
|
||
|
||
### Базовое выполнение
|
||
|
||
```bash
|
||
# Запуск с настройками по умолчанию
|
||
./target/release/ae_anons
|
||
|
||
# Запуск с пользовательским уровнем логирования
|
||
RUST_LOG=debug ./target/release/ae_anons
|
||
```
|
||
|
||
## Уровни логирования
|
||
|
||
Управляйте детализацией вывода через переменную окружения `RUST_LOG`:
|
||
|
||
- **error** - Только критические ошибки
|
||
- **warn** - Предупреждения и ошибки
|
||
- **info** - Общие операционные сообщения (по умолчанию)
|
||
- **debug** - Детальная информация о процессе обработки
|
||
- **trace** - Полное отладочное логирование с деталями API вызовов
|
||
|
||
```bash
|
||
RUST_LOG=debug cargo run
|
||
```
|
||
|
||
## Конфигурация
|
||
|
||
### Переменные окружения
|
||
|
||
| Переменная | Обязательна | Описание |
|
||
|---------------------|-------------|------------------------------------------------------|
|
||
| `NAS_FQDN` | Да | URL NAS Synology с протоколом и портом |
|
||
| `NAS_USER` | Да | Имя пользователя учетной записи Synology |
|
||
| `NAS_PASS` | Да | Пароль учетной записи Synology |
|
||
| `NAS_FILE` | Да | Полный путь к файлу .osheet на NAS |
|
||
| `NEXRENDER_API_URL` | Да | Конечная точка API сервера Nexrender |
|
||
| `OUTPUT_FOLDER` | Да | Сетевой путь для рендеренных видео |
|
||
| `RUST_LOG` | Нет | Уровень детализации логирования (по умолчанию: info) |
|
||
|
||
## Структура электронной таблицы
|
||
|
||
Файл 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"
|
||
|
||
Сопоставляет названия каналов с их логотипами. Поля заполняются вручную без выпадающих списков.
|
||
|
||
| CHANEL | LINK |
|
||
|---------|-----------------------------------------|
|
||
| КАНАЛ | \\server\share\path\to\channel_logo.png |
|
||
| TRIUMPH | \\server\share\path\to\triumph_logo.png |
|
||
|
||
### Лист "Start"
|
||
|
||
Основной источник данных для генерации анонсов. Большинство полей заполняются из выпадающих списков, основанных на других листах.
|
||
|
||
Обязательные колонки: DATA, TIME, CHANEL, SPORT, LEAGUE, TEAM A, TEAM B
|
||
|
||
**Примечание**: Колонка LEAGUE обязательна для заполнения, но не имеет выпадающего списка. Проверка орфографии и опечаток отсутствует!
|
||
|
||
| STATE | TRIPPLE | DATA | TIME | SPORT | LEAGUE | CHANEL | 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. **Первый хеш**: Уникальный идентификатор для команд с одинаковыми названиями в одном виде спорта, или одинаковым названием в разных видах спорта.
|
||
Примеры:
|
||
|
||
- `Динамо#Футбол`, `Динамо#Волейбол` - Одно название разный вид спорта
|
||
- `Спартак#ЖенскийФ`, `Спартак#МужскойФ` Одно название _разный_ вид спорта
|
||
|
||
1. **Второй хеш**: Целевой размер в пикселях для масштабирования логотипа
|
||
|
||
Формат: `DisplayName#UniqueID#TargetSize`
|
||
|
||
Примеры:
|
||
|
||
- `Галатасарай#Turki` - только уникальный идентификатор
|
||
- `Сомбатей##400` - только целевой размер (обратите внимание на двойной хеш)
|
||
- `Спортинг#ll#550` - оба идентификатор и целевой размер
|
||
|
||
**Важно**: Обрабатывается **только второй хеш** для масштабирования логотипа. Если уникальный идентификатор не требуется, используйте двойной хеш ## перед целевым размером.
|
||
|
||
## Выходные файлы
|
||
|
||
### Экспорт JSON
|
||
|
||
Во время обработки сохраняются представления таблицы в формате JSON:
|
||
|
||
- `{filename}_workbook.json` - Полная структура книги
|
||
- `{filename}_{SheetName}.json` - Данные отдельного листа
|
||
|
||
### Рендеренные видео
|
||
|
||
Рендерные видео сохраняются в `OUTPUT_FOLDER` по следующему шаблону именования:
|
||
|
||
```shell
|
||
YYYYMMDD_Sport_League_TeamA_TeamB_Channel[_Variant].mp4
|
||
```
|
||
|
||
Имена файлов транслитерируются в латиницу. Примеры:
|
||
|
||
- `20260228_Volleyball_Championship-Turkey-Women_Beşiktaş_Galatasaray_TRIUMPH.mp4`
|
||
- `20260228_Volleyball_Championship-Turkey-Women_Beşiktaş_Galatasaray_TRIUMPH_Today.mp4`
|
||
- `20260228_Volleyball_Championship-Turkey-Women_Beşiktaş_Galatasaray_TRIUMPH_Tomorrow.mp4`
|
||
|
||
## Рабочий процесс
|
||
|
||
1. **Аутентификация**: Подключение к NAS Synology с использованием предоставленных учетных данных
|
||
2. **Получение файла**: Поиск и экспорт указанного файла .osheet в Excel
|
||
3. **Парсинг данных**: Чтение всех листов и структурирование данных
|
||
4. **Разрешение ресурсов**: Сопоставление видов спорта, команд и каналов с визуальными элементами
|
||
5. **Генерация заданий**: Создание заданий Nexrender для каждой активной строки с вариантами
|
||
6. **Очистка**: Удаление завершенных/неудачных заданий из предыдущих запусков
|
||
7. **Отправка**: Отправка заданий на API Nexrender
|
||
8. **Мониторинг**: Слежение за прогрессом выполнения до завершения
|
||
9. **Завершение сеанса**: Закрытие сессии Synology
|
||
|
||
## Требования к шаблонам After Effects
|
||
|
||
Шаблоны должны быть предварительно настроены на узлах рендеринга со следующими именами слоев:
|
||
|
||
### Типы шаблонов
|
||
|
||
| Файл шаблона | Назначение |
|
||
|------------------------|---------------------------------|
|
||
| `PackShot_DOUBLE.aepx` | Сопоставление с двумя командами |
|
||
| `PackShot_SINGLE.aepx` | Анонсы для одной команды |
|
||
|
||
### Обязательные слои
|
||
|
||
| Имя слоя | Тип | Описание |
|
||
|------------------------|-------|-------------------------------------------------|
|
||
| DATA | Text | Отображение даты (автоматически подстраивается) |
|
||
| TIME / TIME_H / TIME_M | Text | Отображение времени |
|
||
| LEAGUE | Text | Название лиги |
|
||
| SPORT | Text | Категория спорта |
|
||
| TEAMS | Text | Скомбинированные имена команд |
|
||
| TEAM_A_LOGO | Image | Логотип домашней команды |
|
||
| TEAM_B_LOGO | Image | Логотип гостевой команды |
|
||
| CHANEL | Image | Логотип канала |
|
||
| TOP | Video | Наложение видео оформления |
|
||
|
||
### Настройки композиции
|
||
|
||
- Имя композиции: `pack`
|
||
- Выходной модуль: `Start_h264`
|
||
- Формат вывода: `mp4`
|
||
- Формат проекта: Adobe After Effects 2024 .aepx
|
||
|
||
## Устранение неисправностей
|
||
|
||
### Частые проблемы
|
||
|
||
#### Ошибка подключения к NAS
|
||
|
||
- Проверьте, что `NAS_FQDN` включает протокол и порт (например, `https://nas.example.com:5001`)
|
||
- Проверьте сетевую связность с NAS
|
||
- Убедитесь, что сервисы File Station и Office включены
|
||
|
||
#### Файл не найден
|
||
|
||
- Убедитесь, что путь в `NAS_FILE` точно соответствует пути в Synology Drive
|
||
- Путь должен начинаться с `/Team Folder/` для рабочих папок
|
||
- Проверьте права доступа к файлу для учетной записи сервиса
|
||
|
||
#### Ошибка отправки задания Nexrender
|
||
|
||
- Подтвердите доступность сервера Nexrender
|
||
- Убедитесь, что `NEXRENDER_API_URL` правильный
|
||
- Проверьте существование файлов шаблонов на узлах рендеринга
|
||
|
||
### Режим отладки
|
||
|
||
Включите подробное логирование для детального анализа:
|
||
|
||
```bash
|
||
RUST_LOG=debug ./target/release/ae_anons
|
||
```
|
||
|
||
Это выведет:
|
||
|
||
- Детали API запросов/ответов
|
||
- Информацию о парсинге листов
|
||
- Детали создания заданий
|
||
- Процесс разрешения ресурсов
|
||
|
||
## Возможные ограничения по производительности
|
||
|
||
- **Большие таблицы**: Ограничение обработки до 10,000 строк на лист
|
||
- **Задержка сети**: Загрузка файлов с NAS может занимать время для больших файлов
|
||
- **Параллельные задания**: Nexrender управляет очередью заданий внутренне
|
||
- **Использование памяти**: Парсинг Excel сохраняет всю книгу в памяти
|
||
|
||
## Примечания по безопасности
|
||
|
||
- Храните учетные данные только в файле `.env` (исключен из git)
|
||
- Используйте специальные аккаунты с минимально необходимыми правами
|
||
- Сессии Synology завершаются после выполнения
|
||
- HTTPS рекомендуется для подключений NAS в продакшене
|
||
|
||
## Разработка
|
||
|
||
### Структура кода
|
||
|
||
```shell
|
||
ae_anons/
|
||
├── Cargo.toml
|
||
├── LICENSE
|
||
├── README.md
|
||
├── .env.example
|
||
└── src/
|
||
├── main.rs # Точка входа и оркестрация приложения
|
||
├── config.rs # Управление конфигурацией
|
||
├── nexrender.rs # Генерация заданий Nexrender и структура данных
|
||
└── synology.rs # Клиент API Synology
|
||
```
|
||
|
||
## Зависимости
|
||
|
||
| Crate | Версия | Назначение |
|
||
|--------------------|--------|-----------------------------------------|
|
||
| reqwest | 0.12 | HTTP клиент для коммуникации API |
|
||
| serde / serde_json | 1.0 | Сериализация JSON |
|
||
| calamine | 0.26 | Парсинг файлов Excel |
|
||
| chrono | 0.4 | Обработка дат и времени |
|
||
| tokio | 1.0 | Асинхронная среда выполнения |
|
||
| dotenv | 0.15 | Конфигурация через переменные окружения |
|
||
| log / env_logger | 0.11 | Инфраструктура логирования |
|
||
| thiserror | 2.0 | Определение типов ошибок |
|
||
| anyhow | 1.0 | Обработка ошибок |
|
||
|
||
### Планируемые новые возможности
|
||
|
||
1. Расширить `JobData` в `nexrender.rs` для новых полей данных
|
||
2. Обновить логику парсинга листов при необходимости добавления новых колонок
|
||
3. Добавить соответствующие слои After Effects в шаблоны
|
||
4. Обновите метод `to_nexrender_job()` с новыми сопоставлениями ресурсов
|
||
|
||
## 🙏 Благодарности
|
||
|
||
Особая благодарность проекту **[Nexrender](https://github.com/inlife/nexrender)**
|
||
([@inlife](https://github.com/inlife) и контрибьюторам) за создание надёжной платформы
|
||
для автоматизации After Effects.
|
||
|
||
## Лицензия
|
||
|
||
**AE Anons** — [MIT License](LICENSE)
|
||
**Nexrender** — [MIT License](https://github.com/inlife/nexrender/blob/master/LICENSE)
|
||
|
||
Обе лицензии MIT обеспечивают полную свободу использования и модификации кода.
|
||
|
||
**Разрешается:**
|
||
|
||
- ✅ Использовать в коммерческих целях
|
||
- ✅ Изменять исходный код
|
||
- ✅ Распространять копии
|
||
- ✅ Использовать приватно
|
||
|
||
**Требуется:**
|
||
|
||
- Сохранять копирайт и текст лицензии
|
||
|
||
## Поддержка
|
||
|
||
Для вопросов и запросов функций обращайтесь:
|
||
|
||
- <a.barabanov@tvstart.ru>
|
||
- [README.md](https://git.tvstart.ru/lexx/AE_Anons)
|
||
|
||
## История изменений
|
||
|
||
### v0.1.0
|
||
|
||
- Первый выпуск
|
||
- Интеграция с Synology Office
|
||
- Базовая генерация заданий Nexrender
|
||
- Парсинг Excel с динамическим обнаружением листов
|
||
- Создание множественных вариантов
|
||
- Автоматические настройки размера шрифта и позиции
|
||
- Умное масштабирование логотипов по целевому размеру
|
||
|
||
---
|
||
|
||
Made with 🦀 Rust and ☕ coffee
|