Добавлены скомпилированные релизы
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,7 +1,6 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
*.xlsx
|
*.xlsx
|
||||||
*.txt
|
*.txt
|
||||||
makefile
|
|
||||||
# Файлы окружения
|
# Файлы окружения
|
||||||
.env
|
.env
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ name = "ae_anons"
|
|||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
license-file = "LICENSE"
|
|
||||||
authors = ["Alexey Barabanov <a.barabanov@tvstart.ru>"]
|
authors = ["Alexey Barabanov <a.barabanov@tvstart.ru>"]
|
||||||
description = "Automated Nexrender job generator from Synology Office spreadsheets"
|
description = "Automated Nexrender job generator from Synology Office spreadsheets"
|
||||||
repository = "https://git.tvstart.ru/lexx/AE_Anons"
|
repository = "https://git.tvstart.ru/lexx/AE_Anons"
|
||||||
|
|||||||
BIN
ae_anons-v0.2.3-all.tar.gz
Normal file
BIN
ae_anons-v0.2.3-all.tar.gz
Normal file
Binary file not shown.
250
makefile
Normal file
250
makefile
Normal file
@@ -0,0 +1,250 @@
|
|||||||
|
.PHONY: all clean build-mac build-windows build-linux build-linux-musl package help quick package-single
|
||||||
|
|
||||||
|
# Название проекта
|
||||||
|
PROJECT_NAME := ae_anons
|
||||||
|
RELEASE_DIR := target/release
|
||||||
|
BINARIES_DIR := releases
|
||||||
|
VERSION := $(shell grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/')
|
||||||
|
|
||||||
|
# Определение текущей ОС
|
||||||
|
UNAME_S := $(shell uname -s)
|
||||||
|
UNAME_M := $(shell uname -m)
|
||||||
|
|
||||||
|
# Цвета для вывода
|
||||||
|
GREEN := \033[0;32m
|
||||||
|
RED := \033[0;31m
|
||||||
|
YELLOW := \033[1;33m
|
||||||
|
BLUE := \033[0;34m
|
||||||
|
CYAN := \033[0;36m
|
||||||
|
MAGENTA := \033[0;35m
|
||||||
|
BOLD := \033[1m
|
||||||
|
NC := \033[0m # No Color
|
||||||
|
|
||||||
|
# Файл для хранения времени сборки
|
||||||
|
TIMING_FILE := .build_timing
|
||||||
|
|
||||||
|
help:
|
||||||
|
@echo "$(BOLD)$(CYAN)AE Anons - Makefile команды$(NC)"
|
||||||
|
@echo ""
|
||||||
|
@echo "$(GREEN)Сборка под конкретную платформу:$(NC)"
|
||||||
|
@echo " make build-mac - Собрать для macOS (Apple Silicon)"
|
||||||
|
@echo " make build-windows - Собрать для Windows x86_64"
|
||||||
|
@echo " make build-linux - Собрать для Linux x86_64 (GNU)"
|
||||||
|
@echo " make build-linux-musl - Собрать для Linux x86_64 (musl static)"
|
||||||
|
@echo ""
|
||||||
|
@echo "$(GREEN)Быстрая сборка:$(NC)"
|
||||||
|
@echo " make quick - Собрать под текущую платформу с упаковкой"
|
||||||
|
@echo " make quick-release - Собрать под текущую платформу (release, без упаковки)"
|
||||||
|
@echo ""
|
||||||
|
@echo "$(GREEN)Полная сборка:$(NC)"
|
||||||
|
@echo " make build-all - Собрать для всех платформ"
|
||||||
|
@echo " make package - Создать пакеты для всех платформ"
|
||||||
|
@echo " make package-single - Создать пакет для текущей платформы"
|
||||||
|
@echo ""
|
||||||
|
@echo "$(GREEN)Очистка:$(NC)"
|
||||||
|
@echo " make clean - Очистить все сборки"
|
||||||
|
@echo " make clean-timing - Очистить файл с временами сборки"
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
# Копирование общих файлов в пакет
|
||||||
|
define copy_common_files
|
||||||
|
@cp .env.example $(1)/ 2>/dev/null || true
|
||||||
|
@cp README.md $(1)/ 2>/dev/null || true
|
||||||
|
@if [ -f LICENSE ]; then cp LICENSE $(1)/; else echo "$(YELLOW)⚠️ LICENSE не найден, пропускаем$(NC)"; fi
|
||||||
|
endef
|
||||||
|
|
||||||
|
# Функция для замера времени
|
||||||
|
define measure_time
|
||||||
|
@start=$$(date +%s); \
|
||||||
|
$(2); \
|
||||||
|
end=$$(date +%s); \
|
||||||
|
duration=$$((end - start)); \
|
||||||
|
echo "$(1): $$duration сек" >> $(TIMING_FILE); \
|
||||||
|
echo "$(GREEN)✓ $(1) завершён за $$duration сек$(NC)"
|
||||||
|
endef
|
||||||
|
|
||||||
|
# Функция для вывода итоговой таблицы
|
||||||
|
define print_timing_summary
|
||||||
|
@echo ""
|
||||||
|
@echo "$(BOLD)$(CYAN)═══════════════════════════════════════════════════════════════$(NC)"
|
||||||
|
@echo "$(BOLD)$(CYAN) ВРЕМЯ СБОРКИ $(NC)"
|
||||||
|
@echo "$(BOLD)$(CYAN)═══════════════════════════════════════════════════════════════$(NC)"
|
||||||
|
@if [ -f $(TIMING_FILE) ]; then \
|
||||||
|
total=0; \
|
||||||
|
while IFS=':' read -r platform duration; do \
|
||||||
|
sec=$$(echo $$duration | sed 's/ сек//'); \
|
||||||
|
total=$$((total + sec)); \
|
||||||
|
printf "$(YELLOW)%-20s$(NC) : $(GREEN)%5d сек$(NC)\n" "$$platform" "$$sec"; \
|
||||||
|
done < $(TIMING_FILE); \
|
||||||
|
echo "$(BOLD)$(CYAN)───────────────────────────────────────────────────────────────$(NC)"; \
|
||||||
|
printf "$(BOLD)$(MAGENTA)%-20s$(NC) : $(BOLD)$(GREEN)%5d сек$(NC) (%.2f мин)\n" "ВСЕГО" "$$total" "$$(echo "scale=2; $$total/60" | bc 2>/dev/null || echo "$$total/60" | awk '{printf "%.2f", $$1/60}')"; \
|
||||||
|
else \
|
||||||
|
echo "$(YELLOW)Нет данных о времени сборки$(NC)"; \
|
||||||
|
fi
|
||||||
|
@echo "$(BOLD)$(CYAN)═══════════════════════════════════════════════════════════════$(NC)"
|
||||||
|
@rm -f $(TIMING_FILE)
|
||||||
|
endef
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# ОПРЕДЕЛЕНИЕ ПЛАТФОРМЫ
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
detect-platform:
|
||||||
|
ifeq ($(UNAME_S),Darwin)
|
||||||
|
@echo "$(BLUE)🍎 macOS $(UNAME_M)$(NC)"
|
||||||
|
@$(MAKE) quick-mac
|
||||||
|
else ifeq ($(UNAME_S),Linux)
|
||||||
|
@echo "$(BLUE)🐧 Linux $(UNAME_M)$(NC)"
|
||||||
|
@$(MAKE) quick-linux
|
||||||
|
else ifeq ($(OS),Windows_NT)
|
||||||
|
@echo "$(BLUE)🪟 Windows$(NC)"
|
||||||
|
@$(MAKE) quick-windows
|
||||||
|
else
|
||||||
|
@echo "$(RED)❌ Неизвестная платформа: $(UNAME_S)$(NC)"
|
||||||
|
@exit 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# БЫСТРАЯ СБОРКА (ТЕКУЩАЯ ПЛАТФОРМА)
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
quick: detect-platform
|
||||||
|
|
||||||
|
# Быстрая сборка без упаковки (только бинарник)
|
||||||
|
quick-release:
|
||||||
|
ifeq ($(UNAME_S),Darwin)
|
||||||
|
@echo "$(GREEN)🍎 Сборка для macOS...$(NC)"
|
||||||
|
@time cargo build --release
|
||||||
|
else ifeq ($(UNAME_S),Linux)
|
||||||
|
@echo "$(GREEN)🐧 Сборка для Linux (musl)...$(NC)"
|
||||||
|
@time cargo build --target x86_64-unknown-linux-musl --release
|
||||||
|
else ifeq ($(OS),Windows_NT)
|
||||||
|
@echo "$(GREEN)🪟 Сборка для Windows...$(NC)"
|
||||||
|
@time cargo build --release
|
||||||
|
else
|
||||||
|
@echo "$(RED)❌ Неизвестная платформа$(NC)"
|
||||||
|
@exit 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
quick-mac:
|
||||||
|
@rm -f $(TIMING_FILE)
|
||||||
|
@$(call measure_time,"🍎 macOS $(UNAME_M)",cargo build --release)
|
||||||
|
@mkdir -p $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-macos-$(UNAME_M)
|
||||||
|
@cp $(RELEASE_DIR)/$(PROJECT_NAME) $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-macos-$(UNAME_M)/
|
||||||
|
$(call copy_common_files,$(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-macos-$(UNAME_M))
|
||||||
|
@echo "$(GREEN)✅ Пакет: $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-macos-$(UNAME_M)/$(NC)"
|
||||||
|
@$(call print_timing_summary)
|
||||||
|
|
||||||
|
quick-linux:
|
||||||
|
@rm -f $(TIMING_FILE)
|
||||||
|
@$(call measure_time,"🐧 Linux $(UNAME_M)",cargo build --target x86_64-unknown-linux-musl --release)
|
||||||
|
@mkdir -p $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-linux-$(UNAME_M)
|
||||||
|
@cp target/x86_64-unknown-linux-musl/release/$(PROJECT_NAME) $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-linux-$(UNAME_M)/
|
||||||
|
$(call copy_common_files,$(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-linux-$(UNAME_M))
|
||||||
|
@echo "$(GREEN)✅ Пакет: $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-linux-$(UNAME_M)/$(NC)"
|
||||||
|
@$(call print_timing_summary)
|
||||||
|
|
||||||
|
quick-windows:
|
||||||
|
@rm -f $(TIMING_FILE)
|
||||||
|
@if command -v x86_64-w64-mingw32-gcc >/dev/null 2>&1; then \
|
||||||
|
$(call measure_time,"🪟 Windows x64",cargo build --target x86_64-pc-windows-gnu --release); \
|
||||||
|
mkdir -p $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-windows-x64; \
|
||||||
|
cp target/x86_64-pc-windows-gnu/release/$(PROJECT_NAME).exe $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-windows-x64/; \
|
||||||
|
$(call copy_common_files,$(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-windows-x64); \
|
||||||
|
echo "$(GREEN)✅ Пакет: $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-windows-x64/$(NC)"; \
|
||||||
|
$(call print_timing_summary); \
|
||||||
|
else \
|
||||||
|
echo "$(RED)❌ Для кросс-компиляции Windows установите mingw-w64:$(NC)"; \
|
||||||
|
echo " brew install mingw-w64"; \
|
||||||
|
exit 1; \
|
||||||
|
fi
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# СБОРКА ПОД КОНКРЕТНЫЕ ПЛАТФОРМЫ
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
build-mac:
|
||||||
|
@echo "$(GREEN)🍎 Сборка для macOS...$(NC)"
|
||||||
|
@time cargo build --release
|
||||||
|
|
||||||
|
build-windows:
|
||||||
|
@echo "$(GREEN)🪟 Сборка для Windows x86_64...$(NC)"
|
||||||
|
@time cargo build --target x86_64-pc-windows-gnu --release
|
||||||
|
|
||||||
|
build-linux:
|
||||||
|
@echo "$(GREEN)🐧 Сборка для Linux x86_64 (GNU)...$(NC)"
|
||||||
|
@time cargo build --target x86_64-unknown-linux-gnu --release
|
||||||
|
|
||||||
|
build-linux-musl:
|
||||||
|
@echo "$(GREEN)🐧 Сборка для Linux x86_64 (musl static)...$(NC)"
|
||||||
|
@time cargo build --target x86_64-unknown-linux-musl --release
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# СБОРКА ВСЕХ ПЛАТФОРМ С ТАЙМИНГОМ
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
build-all:
|
||||||
|
@rm -f $(TIMING_FILE)
|
||||||
|
@echo "$(BOLD)$(CYAN)🚀 Сборка для всех платформ...$(NC)"
|
||||||
|
@echo ""
|
||||||
|
@$(call measure_time,"🍎 macOS",cargo build --release)
|
||||||
|
@echo ""
|
||||||
|
@$(call measure_time,"🐧 Linux GNU",cargo build --target x86_64-unknown-linux-gnu --release)
|
||||||
|
@echo ""
|
||||||
|
@$(call measure_time,"🐧 Linux Musl",cargo build --target x86_64-unknown-linux-musl --release)
|
||||||
|
@echo ""
|
||||||
|
@-$(call measure_time,"🪟 Windows",cargo build --target x86_64-pc-windows-gnu --release)
|
||||||
|
@echo ""
|
||||||
|
@$(call print_timing_summary)
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# УПАКОВКА РЕЛИЗОВ
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
define create_release_package
|
||||||
|
@echo "$(YELLOW)📦 Упаковка для $(1)...$(NC)"
|
||||||
|
@mkdir -p $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-$(1)
|
||||||
|
@cp $(2) $(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-$(1)/$(3) 2>/dev/null || true
|
||||||
|
$(call copy_common_files,$(BINARIES_DIR)/$(PROJECT_NAME)-v$(VERSION)-$(1))
|
||||||
|
@echo "$(GREEN) ✓ $(PROJECT_NAME)-v$(VERSION)-$(1)$(NC)"
|
||||||
|
endef
|
||||||
|
|
||||||
|
package: build-all
|
||||||
|
@echo ""
|
||||||
|
@echo "$(BOLD)$(CYAN)📦 Создание пакетов...$(NC)"
|
||||||
|
@mkdir -p $(BINARIES_DIR)
|
||||||
|
|
||||||
|
@$(call create_release_package,macos-arm64,$(RELEASE_DIR)/$(PROJECT_NAME),$(PROJECT_NAME))
|
||||||
|
@$(call create_release_package,windows-x64,target/x86_64-pc-windows-gnu/release/$(PROJECT_NAME).exe,$(PROJECT_NAME).exe)
|
||||||
|
@$(call create_release_package,linux-gnu,target/x86_64-unknown-linux-gnu/release/$(PROJECT_NAME),$(PROJECT_NAME))
|
||||||
|
@$(call create_release_package,linux-musl,target/x86_64-unknown-linux-musl/release/$(PROJECT_NAME),$(PROJECT_NAME))
|
||||||
|
|
||||||
|
@echo ""
|
||||||
|
@echo "$(GREEN)🗜️ Создание общего архива...$(NC)"
|
||||||
|
@tar -czf $(PROJECT_NAME)-v$(VERSION)-all.tar.gz -C $(BINARIES_DIR) .
|
||||||
|
@echo "$(GREEN)✅ Архив: $(PROJECT_NAME)-v$(VERSION)-all.tar.gz$(NC)"
|
||||||
|
@echo ""
|
||||||
|
@echo "$(BOLD)$(GREEN)🎉 Релиз v$(VERSION) готов!$(NC)"
|
||||||
|
@echo "$(BOLD)📁 Папка: $(BINARIES_DIR)/$(NC)"
|
||||||
|
@ls -lh $(BINARIES_DIR)/ | grep "^d"
|
||||||
|
|
||||||
|
package-single: detect-platform
|
||||||
|
|
||||||
|
# ============================================
|
||||||
|
# ОЧИСТКА
|
||||||
|
# ============================================
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@echo "$(RED)🧹 Очистка...$(NC)"
|
||||||
|
cargo clean
|
||||||
|
@rm -rf $(BINARIES_DIR)
|
||||||
|
@rm -f *.tar.gz
|
||||||
|
@rm -f $(TIMING_FILE)
|
||||||
|
@echo "$(GREEN)✅ Очищено$(NC)"
|
||||||
|
|
||||||
|
clean-timing:
|
||||||
|
@rm -f $(TIMING_FILE)
|
||||||
|
@echo "$(GREEN)✅ Файл с временами сборки удалён$(NC)"
|
||||||
22
releases/ae_anons-v0.2.3-linux-gnu/.env.example
Normal file
22
releases/ae_anons-v0.2.3-linux-gnu/.env.example
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Synology NAS
|
||||||
|
NAS_FQDN="https://your-nas.example.com"
|
||||||
|
NAS_USER="your_username"
|
||||||
|
NAS_PASS="your_password"
|
||||||
|
NAS_FILE="/Team Folder/path/to/file.osheet"
|
||||||
|
|
||||||
|
# Logging (optional, defaults to info)
|
||||||
|
RUST_LOG="info"
|
||||||
|
|
||||||
|
# Web Server (optional, defaults to 3000)
|
||||||
|
WEB_PORT="3000"
|
||||||
|
|
||||||
|
# Nexrender
|
||||||
|
NEXRENDER_API_URL="http://nexrender-server:3050/api/v1/jobs"
|
||||||
|
OUTPUT_FOLDER="/path/to/output"
|
||||||
|
|
||||||
|
# After Effects Templates
|
||||||
|
TEMPLATE_DOUBLE_SRC="file:///path/to/double_team_template.aep"
|
||||||
|
TEMPLATE_SINGLE_SRC="file:///path/to/single_team_template.aep"
|
||||||
|
TEMPLATE_COMPOSITION="main"
|
||||||
|
TEMPLATE_OUTPUT_MODULE="h264"
|
||||||
|
TEMPLATE_OUTPUT_EXT="mp4"
|
||||||
21
releases/ae_anons-v0.2.3-linux-gnu/LICENSE
Normal file
21
releases/ae_anons-v0.2.3-linux-gnu/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 [Your Name or Company]
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
656
releases/ae_anons-v0.2.3-linux-gnu/README.md
Normal file
656
releases/ae_anons-v0.2.3-linux-gnu/README.md
Normal file
@@ -0,0 +1,656 @@
|
|||||||
|
# AE Anons - Автоматизированный генератор спортивных анонсов в After Effects
|
||||||
|
|
||||||
|
<!-- markdownlint-disable MD033 -->
|
||||||
|
<p align="left">
|
||||||
|
<img src="assets/logo.png" alt="AE Anons Logo" width="250"/>
|
||||||
|
</p>
|
||||||
|
<!-- markdownlint-enable MD033 -->
|
||||||
|
|
||||||
|
[](https://opensource.org/licenses/MIT)
|
||||||
|
[](https://www.rust-lang.org/)
|
||||||
|
[](https://git.tvstart.ru/lexx/AE_Anons)
|
||||||
|
|
||||||
|
Автоматизированная система для создания спортивных анонсов с использованием шаблонов After Effects через Nexrender, с данными из электронных таблиц Synology Office.
|
||||||
|
|
||||||
|
## Новое в версии 0.2.3
|
||||||
|
|
||||||
|
- Веб-интерфейс с настраиваемым портом (WEB_PORT)
|
||||||
|
- Тёмная/светлая тема с автоопределением ОС
|
||||||
|
- Сортировка по всем колонкам
|
||||||
|
- Фильтрация по имени файла/UID
|
||||||
|
- Остановка всех активных заданий
|
||||||
|
- Автообновление каждые 60 секунд
|
||||||
|
- Улучшенное debug-логирование
|
||||||
|
- Исправлена обработка UNC/SMB путей
|
||||||
|
- Нормализация множественных пробелов в именах файлов"
|
||||||
|
|
||||||
|
## Обзор
|
||||||
|
|
||||||
|
AE Anons — это CLI-утилита и веб-сервер на Rust, которая выступает как **интеллектуальный генератор заданий**
|
||||||
|
для [Nexrender](https://github.com/inlife/nexrender) — опенсорсного оркестратора рендеринга
|
||||||
|
After Effects (лицензия MIT).
|
||||||
|
|
||||||
|
### Режимы работы
|
||||||
|
|
||||||
|
1. **Однократная обработка** (`--once` или без флагов):
|
||||||
|
- Подключение к NAS Synology
|
||||||
|
- Парсинг Excel данных
|
||||||
|
- Генерация и отправка заданий Nexrender
|
||||||
|
- Мониторинг завершения и выход
|
||||||
|
|
||||||
|
2. **Веб-сервер** (`--web`):
|
||||||
|
- Запуск веб-интерфейса на порту `:3000`
|
||||||
|
- Управление заданиями через браузер
|
||||||
|
- Автообновление статуса каждую минуту
|
||||||
|
|
||||||
|
## Особенности
|
||||||
|
|
||||||
|
- **Интеграция с Synology**: Аутентификация и загрузка файлов с NAS Synology
|
||||||
|
- **Экспорт офисных таблиц**: Автоматическое преобразование файлов .osheet в формат Excel
|
||||||
|
- **Гибкий парсинг данных**: Динамический парсинг листов с обнаружением заголовков
|
||||||
|
- **Множественная генерация вариантов**: Создание "Сегодня", "Завтра" и датированных версий
|
||||||
|
- **Умное управление логотипами**: Автоматическое разрешение и масштабирование логотипов
|
||||||
|
- **Веб-интерфейс**: Удобное управление и мониторинг заданий
|
||||||
|
- **REST API**: Программный доступ к управлению заданиями
|
||||||
|
- **Профессиональное логирование**: Структурированный журнал с настройкой уровня
|
||||||
|
|
||||||
|
## Предварительные требования
|
||||||
|
|
||||||
|
- Rust 1.70 или выше
|
||||||
|
- Доступ к NAS Synology с пакетами File Station и Office
|
||||||
|
- Экземпляр _server_ и _worker_(не менее одного) Nexrender
|
||||||
|
- Шаблоны After Effects (формат 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
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Настройка окружения
|
||||||
|
|
||||||
|
Скопируйте пример конфигурации и заполните своими данными:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
Затем отредактируйте файл .env:
|
||||||
|
|
||||||
|
См. раздел Конфигурация для подробной информации.
|
||||||
|
|
||||||
|
## Использование
|
||||||
|
|
||||||
|
### Однократная обработка
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запуск с настройками по умолчанию
|
||||||
|
./target/release/ae_anons
|
||||||
|
|
||||||
|
# Явно указать однократный режим
|
||||||
|
./target/release/ae_anons --once
|
||||||
|
|
||||||
|
# С отладочным логированием
|
||||||
|
RUST_LOG=debug ./target/release/ae_anons
|
||||||
|
```
|
||||||
|
|
||||||
|
### Веб-сервер
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запуск веб-интерфейса на порту по умолчанию (3000)
|
||||||
|
./target/release/ae_anons --web
|
||||||
|
|
||||||
|
# Или с указанием другого порта через .env файл
|
||||||
|
# WEB_PORT=8080 ./target/release/ae_anons --web
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Веб-интерфейс
|
||||||
|
|
||||||
|
После запуска веб-сервера откройте браузер:
|
||||||
|
|
||||||
|
- Главная страница: <http://localhost:3000>
|
||||||
|
|
||||||
|
- API эндпоинты:
|
||||||
|
- `GET /api/jobs` - список всех заданий
|
||||||
|
- `POST /api/generate` - запуск генерации
|
||||||
|
- `POST /api/cleanup` - очистка завершённых
|
||||||
|
- `POST /api/jobs/stop-all` - остановка активных
|
||||||
|
- `GET /api/status` - статус сервера
|
||||||
|
|
||||||
|
## Уровни логирования
|
||||||
|
|
||||||
|
Управляйте детализацией вывода через переменную окружения `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` | Да | Сетевой путь для рендеренных видео |
|
||||||
|
| `TEMPLATE_DOUBLE_SRC` | Да | Путь к AEP-шаблону для двух команд |
|
||||||
|
| `TEMPLATE_SINGLE_SRC` | Да | Путь к AEP-шаблону для одной команды |
|
||||||
|
| `TEMPLATE_COMPOSITION` | Да | Имя композиции в проекте AE (например, `main`) |
|
||||||
|
| `TEMPLATE_OUTPUT_MODULE`| Да | Имя модуля вывода в AE (например, `h264`) |
|
||||||
|
| `TEMPLATE_OUTPUT_EXT` | Да | Расширение выходного файла (например, `mp4`) |
|
||||||
|
| `WEB_PORT` | Нет | Порт для веб-сервера (по умолчанию: 3000) |
|
||||||
|
| `RUST_LOG` | Нет | Уровень детализации логирования (по умолчанию: info) |
|
||||||
|
|
||||||
|
### Пример файла `.env`
|
||||||
|
|
||||||
|
```env
|
||||||
|
# Synology NAS
|
||||||
|
NAS_FQDN="https://your-nas.example.com"
|
||||||
|
NAS_USER="your_username"
|
||||||
|
NAS_PASS="your_password"
|
||||||
|
NAS_FILE="/Team Folder/path/to/file.osheet"
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
RUST_LOG="info"
|
||||||
|
|
||||||
|
# Web Server
|
||||||
|
WEB_PORT="3000"
|
||||||
|
|
||||||
|
# Nexrender
|
||||||
|
NEXRENDER_API_URL="http://nexrender-server:3050/api/v1/jobs"
|
||||||
|
OUTPUT_FOLDER="/path/to/output"
|
||||||
|
|
||||||
|
# After Effects Templates
|
||||||
|
TEMPLATE_DOUBLE_SRC="file:///path/to/double_team_template.aepx"
|
||||||
|
TEMPLATE_SINGLE_SRC="file:///path/to/single_team_template.aepx"
|
||||||
|
TEMPLATE_COMPOSITION="main"
|
||||||
|
TEMPLATE_OUTPUT_MODULE="h264"
|
||||||
|
TEMPLATE_OUTPUT_EXT="mp4"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Структура электронной таблицы
|
||||||
|
|
||||||
|
Файл 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. **Первый хеш**: Уникальный идентификатор для команд с одинаковыми названиями в одном виде спорта, или одинаковым названием в разных видах спорта.
|
||||||
|
Примеры:
|
||||||
|
|
||||||
|
- `Динамо#Футбол`, `Динамо#Волейбол` - Одно название разный вид спорта
|
||||||
|
- `Спартак#ЖенскийФ`, `Спартак#МужскойФ` Одно название _разный_ вид спорта
|
||||||
|
|
||||||
|
1. **Второй хеш**: Целевой размер в пикселях для масштабирования логотипа
|
||||||
|
|
||||||
|
Формат: `DisplayName#UniqueID#TargetSize`
|
||||||
|
|
||||||
|
Примеры:
|
||||||
|
|
||||||
|
- `Галатасарай#Turki` - только уникальный идентификатор
|
||||||
|
- `Сомбатей##400` - только целевой размер (обратите внимание на двойной хеш)
|
||||||
|
- `Спортинг#ll#550` - оба идентификатор и целевой размер
|
||||||
|
|
||||||
|
**Важно**: Обрабатывается **только второй хеш** для масштабирования логотипа. Если уникальный идентификатор не требуется, используйте двойной хеш ## перед целевым размером.
|
||||||
|
|
||||||
|
## Выходные файлы
|
||||||
|
|
||||||
|
### Рендеренные видео
|
||||||
|
|
||||||
|
Рендерные видео сохраняются в `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
|
||||||
|
|
||||||
|
Шаблоны должны быть предварительно настроены на узлах рендеринга со следующими именами слоёв.
|
||||||
|
|
||||||
|
### Файлы шаблонов
|
||||||
|
|
||||||
|
Настраиваются через переменные окружения:
|
||||||
|
|
||||||
|
| Переменная | Назначение | Пример значения |
|
||||||
|
|-------------------------|-------------------------------------|------------------------------------|
|
||||||
|
| `TEMPLATE_DOUBLE_SRC` | Шаблон для матчей с двумя командами | `file:///path/to/double.aepx` |
|
||||||
|
| `TEMPLATE_SINGLE_SRC` | Шаблон для анонсов с одной командой | `file:///path/to/single.aepx` |
|
||||||
|
| `TEMPLATE_COMPOSITION` | Имя главной композиции | `main` |
|
||||||
|
| `TEMPLATE_OUTPUT_MODULE`| Имя модуля вывода | `h264` |
|
||||||
|
| `TEMPLATE_OUTPUT_EXT` | Расширение выходного файла | `mp4` |
|
||||||
|
|
||||||
|
### Обязательные слои в шаблонах
|
||||||
|
|
||||||
|
#### Текстовые слои
|
||||||
|
|
||||||
|
| Имя слоя | Шаблон DOUBLE | Шаблон SINGLE | Описание |
|
||||||
|
|-----------|:-------------:|:-------------:|-------------------------------------------------|
|
||||||
|
| `DATA` | ✅ | ✅ | Отображение даты (автоматически подстраивается) |
|
||||||
|
| `TIME_H` | ✅ | ❌ | Часы (отдельный слой) |
|
||||||
|
| `TIME_M` | ✅ | ❌ | Минуты (отдельный слой) |
|
||||||
|
| `TIME` | ❌ | ✅ | Полное время (единый слой) |
|
||||||
|
| `LEAGUE` | ✅ | ✅ | Название лиги/турнира |
|
||||||
|
| `SPORT` | ✅ | ✅ | Категория спорта |
|
||||||
|
| `TEAMS` | ✅ | ✅ | Скомбинированные имена команд |
|
||||||
|
|
||||||
|
#### Слои с изображениями
|
||||||
|
|
||||||
|
| Имя слоя | Шаблон DOUBLE | Шаблон SINGLE | Описание |
|
||||||
|
|----------------|:-------------:|:-------------:|-----------------------------|
|
||||||
|
| `TEAM_A_LOGO` | ✅ | ✅ | Логотип команды A |
|
||||||
|
| `TEAM_B_LOGO` | ✅ | ❌ | Логотип команды B |
|
||||||
|
| `CHANELL` | ✅ | ✅ | Логотип канала (две буквы L)|
|
||||||
|
|
||||||
|
#### Видео слои
|
||||||
|
|
||||||
|
| Имя слоя | Шаблон DOUBLE | Шаблон SINGLE | Описание |
|
||||||
|
|-----------|:-------------:|:-------------:|----------------------------|
|
||||||
|
| `TOP` | ✅ | ✅ | Наложение видео оформления |
|
||||||
|
|
||||||
|
### Особенности шаблонов
|
||||||
|
|
||||||
|
#### Шаблон DOUBLE (две команды)
|
||||||
|
|
||||||
|
Используется когда в строке Excel заполнены оба поля `TEAM A` и `TEAM B`.
|
||||||
|
|
||||||
|
Обязательные слои:
|
||||||
|
|
||||||
|
- Все текстовые слои с `TIME_H` и `TIME_M` вместо `TIME`
|
||||||
|
- Оба логотипа команд: `TEAM_A_LOGO` и `TEAM_B_LOGO`
|
||||||
|
|
||||||
|
#### Шаблон SINGLE (одна команда)
|
||||||
|
|
||||||
|
Используется когда заполнено только одно поле команды.
|
||||||
|
|
||||||
|
Обязательные слои:
|
||||||
|
|
||||||
|
- Текстовый слой `TIME` вместо `TIME_H` и `TIME_M`
|
||||||
|
- Только логотип `TEAM_A_LOGO`
|
||||||
|
|
||||||
|
### Автоматические корректировки
|
||||||
|
|
||||||
|
AE Anons автоматически применяет следующие настройки к слоям:
|
||||||
|
|
||||||
|
#### Слой DATA
|
||||||
|
|
||||||
|
В зависимости от отображаемого текста и типа шаблона:
|
||||||
|
|
||||||
|
| Текст | Шаблон | Font Size | Anchor Point |
|
||||||
|
|------------|----------|-----------|--------------|
|
||||||
|
| "сегодня" | DOUBLE | 105 | [0, 5] |
|
||||||
|
| "завтра" | DOUBLE | 115 | [0, 25] |
|
||||||
|
| дата (<6) | DOUBLE | 120 | [0, 20] |
|
||||||
|
|
||||||
|
#### Слои TIME_H, TIME_M, TIME
|
||||||
|
|
||||||
|
Корректировка Anchor Point в зависимости от длины текста:
|
||||||
|
|
||||||
|
| Условие | Anchor Point |
|
||||||
|
|-------------------|--------------|
|
||||||
|
| 1 символ | [60, 0] |
|
||||||
|
| 2 символа, <20 | [20, 0] |
|
||||||
|
|
||||||
|
#### Слой LEAGUE
|
||||||
|
|
||||||
|
Если длина текста превышает 16 символов, размер шрифта уменьшается до 73.
|
||||||
|
|
||||||
|
#### Слой TEAMS
|
||||||
|
|
||||||
|
Если суммарная длина имён команд ≥ 32 символов, размер шрифта уменьшается до 55.
|
||||||
|
|
||||||
|
#### Логотипы (TEAM_A_LOGO, TEAM_B_LOGO)
|
||||||
|
|
||||||
|
Если в имени команды указан целевой размер через `#` (например, `Спортинг##550`), применяется выражение масштабирования:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
if (width > height) {
|
||||||
|
max_size = width;
|
||||||
|
} else {
|
||||||
|
max_size = height;
|
||||||
|
}
|
||||||
|
var real_size = 550 / max_size * 100;
|
||||||
|
[real_size, real_size]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример структуры слоёв в After Effects
|
||||||
|
|
||||||
|
Ниже представлен рекомендуемый порядок слоёв в композиции. Порядок важен для правильного наложения элементов.
|
||||||
|
|
||||||
|
```text
|
||||||
|
📁 main (композиция)
|
||||||
|
├── 🎬 TOP (видео слой) # Видео-оверлей (обязательный)
|
||||||
|
├── 📝 TEAMS (текстовый слой) # Имена команд (обязательный)
|
||||||
|
├── 📝 LEAGUE (текстовый слой) # Название лиги (обязательный)
|
||||||
|
├── 📝 SPORT (текстовый слой) # Вид спорта (обязательный)
|
||||||
|
├── 📝 DATA (текстовый слой) # Дата (обязательный)
|
||||||
|
├── 📝 TIME (текстовый слой) # Время (только SINGLE)
|
||||||
|
├── 📝 TIME_H (текстовый слой) # Часы (только DOUBLE)
|
||||||
|
├── 📝 TIME_M (текстовый слой) # Минуты (только DOUBLE)
|
||||||
|
├── 🖼️ CHANELL (слой изображения) # Логотип канала (обязательный)
|
||||||
|
├── 🖼️ TEAM_A_LOGO (слой изображения) # Логотип команды A (обязательный)
|
||||||
|
├── 🖼️ TEAM_B_LOGO (слой изображения) # Логотип команды B (только DOUBLE)
|
||||||
|
└── 🖼️ BOTTOM (слой изображения) # Фоновый слой (опционально)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Формат проекта и совместимость с After Effects
|
||||||
|
|
||||||
|
**Поддерживаемые форматы проектов:**
|
||||||
|
|
||||||
|
- `.aep` — стандартный бинарный формат After Effects (рекомендуется)
|
||||||
|
- `.aepx` — XML-формат проекта (поддерживается с AE CC 2015)
|
||||||
|
|
||||||
|
**Совместимость версий After Effects:**
|
||||||
|
|
||||||
|
| Версия After Effects | Поддерживаемые форматы | Особенности |
|
||||||
|
|----------------------|------------------------|-------------------------------------------------|
|
||||||
|
| CS 5.5 | `.aep` | Базовая поддержка |
|
||||||
|
| CC / CC 2014 | `.aep` | Полная поддержка |
|
||||||
|
| CC 2015 - CC 2019 | `.aep`, `.aepx` | Добавлена поддержка XML формата `.aepx` |
|
||||||
|
| CC 2020 - CC 2022 | `.aep`, `.aepx` | Рекомендуется использовать `.aep` |
|
||||||
|
| CC 2023 и новее | `.aep`, `.aepx` | **Требуется настройка Output Module** (см. ниже)|
|
||||||
|
|
||||||
|
> **⚠️ Важно для After Effects 2023+:**
|
||||||
|
>
|
||||||
|
> В версиях After Effects 2023 и новее критически важно настроить **Output Module** в шаблоне проекта. Бинарный файл рендеринга (`aerender`) не будет обрабатывать композицию без явно указанного модуля вывода, даже если в проекте используется модуль по умолчанию.
|
||||||
|
>
|
||||||
|
> AE Anons автоматически решает эту проблему, используя параметры `TEMPLATE_OUTPUT_MODULE` и `TEMPLATE_OUTPUT_EXT` из `.env` файла. Убедитесь, что эти значения соответствуют настройкам вашего шаблона.
|
||||||
|
|
||||||
|
### Настройки композиции
|
||||||
|
|
||||||
|
| Параметр | Переменная окружения | Пример значения | Описание |
|
||||||
|
|---------------------------|--------------------------|-----------------|---------------------------------------------|
|
||||||
|
| Имя композиции | `TEMPLATE_COMPOSITION` | `main` | Имя главной композиции в проекте AE |
|
||||||
|
| Выходной модуль | `TEMPLATE_OUTPUT_MODULE` | `h264` | Имя модуля вывода в AE |
|
||||||
|
| Расширение выходного файла| `TEMPLATE_OUTPUT_EXT` | `mp4` | Расширение выходного файла |
|
||||||
|
|
||||||
|
**Рекомендации по выбору формата:**
|
||||||
|
|
||||||
|
1. Используйте `.aep` для максимальной совместимости со всеми версиями AE
|
||||||
|
2. Версия After Effects на worker-машине должна быть не ниже версии, в которой создан проект
|
||||||
|
3. Для AE 2023+ убедитесь, что в шаблоне настроен Output Module с именем, указанным в `TEMPLATE_OUTPUT_MODULE`
|
||||||
|
|
||||||
|
**Источники:**
|
||||||
|
|
||||||
|
- [Nexrender - Tested with After Effects versions](https://github.com/inlife/nexrender#tested-with)
|
||||||
|
- [Adobe Aerender documentation](https://helpx.adobe.com/after-effects/using/automated-rendering-network-rendering.html)
|
||||||
|
|
||||||
|
## Устранение неисправностей
|
||||||
|
|
||||||
|
### Частые проблемы
|
||||||
|
|
||||||
|
#### Ошибка подключения к 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 управляет очередью заданий внутренне
|
||||||
|
|
||||||
|
## Примечания по безопасности
|
||||||
|
|
||||||
|
- Храните учетные данные только в файле `.env` (исключен из git)
|
||||||
|
- Используйте специальные аккаунты с минимально необходимыми правами
|
||||||
|
- Сессии Synology завершаются после выполнения
|
||||||
|
- HTTPS рекомендуется для подключений NAS в продакшене
|
||||||
|
|
||||||
|
## Разработка
|
||||||
|
|
||||||
|
### Структура кода
|
||||||
|
|
||||||
|
```shell
|
||||||
|
ae_anons/
|
||||||
|
├── .gitignore
|
||||||
|
├── .env.example
|
||||||
|
├── Cargo.toml
|
||||||
|
├── LICENSE
|
||||||
|
├── README.md
|
||||||
|
├── assets/
|
||||||
|
│ └── logo.png
|
||||||
|
└── src/
|
||||||
|
├── main.rs # Точка входа, CLI
|
||||||
|
├── config.rs # Конфигурация из .env
|
||||||
|
├── nexrender.rs # Модели заданий Nexrender
|
||||||
|
├── synology.rs # Клиент Synology API
|
||||||
|
├── processor.rs # Логика обработки
|
||||||
|
├── web.rs # Веб-сервер и API
|
||||||
|
└── static/
|
||||||
|
├── index.html # Веб-интерфейс
|
||||||
|
└── style.css # Стили
|
||||||
|
```
|
||||||
|
|
||||||
|
## Зависимости
|
||||||
|
|
||||||
|
### Основные зависимости
|
||||||
|
|
||||||
|
| Crate | Версия | Назначение |
|
||||||
|
|--------------------|---------|-----------------------------------------|
|
||||||
|
| reqwest | 0.12 | HTTP клиент для коммуникации с API |
|
||||||
|
| serde / serde_json | 1.0 | Сериализация и десериализация JSON |
|
||||||
|
| calamine | 0.26 | Парсинг файлов Excel (.xlsx, .xls) |
|
||||||
|
| chrono | 0.4 | Обработка дат и времени |
|
||||||
|
| tokio | 1.0 | Асинхронная среда выполнения |
|
||||||
|
| dotenv | 0.15 | Загрузка конфигурации из .env файла |
|
||||||
|
| log / env_logger | 0.4/0.11| Система логирования с уровнями |
|
||||||
|
| thiserror | 2.0 | Эргономичные определения типов ошибок |
|
||||||
|
| anyhow | 1.0 | Упрощённая обработка ошибок |
|
||||||
|
| regex | 1.11 | Регулярные выражения |
|
||||||
|
| urlencoding | 2.1 | Кодирование URL для API запросов |
|
||||||
|
| bytes | 1.9 | Работа с байтовыми данными |
|
||||||
|
| futures | 0.3 | Асинхронные примитивы |
|
||||||
|
|
||||||
|
### Веб-сервер и CLI
|
||||||
|
|
||||||
|
| Crate | Версия | Назначение |
|
||||||
|
|--------------------|--------|-----------------------------------------|
|
||||||
|
| axum | 0.8 | Веб-фреймворк для REST API |
|
||||||
|
| tower | 0.5 | Промежуточное ПО для веб-сервера |
|
||||||
|
| tower-http | 0.6 |HTTP утилиты (CORS, статика, трассировка)|
|
||||||
|
| askama | 0.15 | Шаблонизация (опционально) |
|
||||||
|
| clap | 4.5 | Парсинг аргументов командной строки |
|
||||||
|
|
||||||
|
### Платформозависимые зависимости
|
||||||
|
|
||||||
|
| Crate | Версия | Платформа | Назначение |
|
||||||
|
|--------------------|--------|-----------|----------------------------------|
|
||||||
|
| openssl | 0.10 | Linux | Криптография для HTTPS (vendored)|
|
||||||
|
|
||||||
|
## 🙏 Благодарности
|
||||||
|
|
||||||
|
Особая благодарность проекту **[Nexrender](https://github.com/inlife/nexrender)**
|
||||||
|
([@inlife](https://github.com/inlife) и контрибьюторам) за создание надёжной платформы
|
||||||
|
для автоматизации After Effects.
|
||||||
|
|
||||||
|
## Лицензия
|
||||||
|
|
||||||
|
**AE Anons** — [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.2.3 (текущая)
|
||||||
|
|
||||||
|
- Веб-интерфейс с настраиваемым портом (WEB_PORT)
|
||||||
|
- Улучшенное debug-логирование
|
||||||
|
- Исправлена обработка UNC/SMB путей
|
||||||
|
- Нормализация множественных пробелов в именах файлов"
|
||||||
|
|
||||||
|
### v0.2.2
|
||||||
|
|
||||||
|
- Исправлено отображение имён выходных файлов в веб-интерфейсе
|
||||||
|
|
||||||
|
- Улучшена цветовая схема
|
||||||
|
|
||||||
|
- Добавлена сортировка по всем колонкам
|
||||||
|
|
||||||
|
- Вынесены стили в отдельный CSS файл
|
||||||
|
|
||||||
|
### v0.2.0
|
||||||
|
|
||||||
|
- Добавлен веб-интерфейс для управления заданиями
|
||||||
|
|
||||||
|
- Реализован REST API
|
||||||
|
|
||||||
|
- Добавлена поддержка тёмной/светлой темы
|
||||||
|
|
||||||
|
- Автообновление статуса заданий
|
||||||
|
|
||||||
|
- Возможность остановки всех активных заданий
|
||||||
|
|
||||||
|
### v0.1.1
|
||||||
|
|
||||||
|
- Оптимизирована работа с памятью
|
||||||
|
|
||||||
|
- Убрана функция создания .json
|
||||||
|
|
||||||
|
### v0.1.0
|
||||||
|
|
||||||
|
- Первый выпуск
|
||||||
|
|
||||||
|
- Интеграция с Synology Office
|
||||||
|
|
||||||
|
- Базовая генерация заданий Nexrender
|
||||||
|
|
||||||
|
- Парсинг Excel с динамическим обнаружением листов
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Made with 🦀 Rust and ☕ coffee
|
||||||
BIN
releases/ae_anons-v0.2.3-linux-gnu/ae_anons
Executable file
BIN
releases/ae_anons-v0.2.3-linux-gnu/ae_anons
Executable file
Binary file not shown.
22
releases/ae_anons-v0.2.3-linux-musl/.env.example
Normal file
22
releases/ae_anons-v0.2.3-linux-musl/.env.example
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Synology NAS
|
||||||
|
NAS_FQDN="https://your-nas.example.com"
|
||||||
|
NAS_USER="your_username"
|
||||||
|
NAS_PASS="your_password"
|
||||||
|
NAS_FILE="/Team Folder/path/to/file.osheet"
|
||||||
|
|
||||||
|
# Logging (optional, defaults to info)
|
||||||
|
RUST_LOG="info"
|
||||||
|
|
||||||
|
# Web Server (optional, defaults to 3000)
|
||||||
|
WEB_PORT="3000"
|
||||||
|
|
||||||
|
# Nexrender
|
||||||
|
NEXRENDER_API_URL="http://nexrender-server:3050/api/v1/jobs"
|
||||||
|
OUTPUT_FOLDER="/path/to/output"
|
||||||
|
|
||||||
|
# After Effects Templates
|
||||||
|
TEMPLATE_DOUBLE_SRC="file:///path/to/double_team_template.aep"
|
||||||
|
TEMPLATE_SINGLE_SRC="file:///path/to/single_team_template.aep"
|
||||||
|
TEMPLATE_COMPOSITION="main"
|
||||||
|
TEMPLATE_OUTPUT_MODULE="h264"
|
||||||
|
TEMPLATE_OUTPUT_EXT="mp4"
|
||||||
21
releases/ae_anons-v0.2.3-linux-musl/LICENSE
Normal file
21
releases/ae_anons-v0.2.3-linux-musl/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 [Your Name or Company]
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
656
releases/ae_anons-v0.2.3-linux-musl/README.md
Normal file
656
releases/ae_anons-v0.2.3-linux-musl/README.md
Normal file
@@ -0,0 +1,656 @@
|
|||||||
|
# AE Anons - Автоматизированный генератор спортивных анонсов в After Effects
|
||||||
|
|
||||||
|
<!-- markdownlint-disable MD033 -->
|
||||||
|
<p align="left">
|
||||||
|
<img src="assets/logo.png" alt="AE Anons Logo" width="250"/>
|
||||||
|
</p>
|
||||||
|
<!-- markdownlint-enable MD033 -->
|
||||||
|
|
||||||
|
[](https://opensource.org/licenses/MIT)
|
||||||
|
[](https://www.rust-lang.org/)
|
||||||
|
[](https://git.tvstart.ru/lexx/AE_Anons)
|
||||||
|
|
||||||
|
Автоматизированная система для создания спортивных анонсов с использованием шаблонов After Effects через Nexrender, с данными из электронных таблиц Synology Office.
|
||||||
|
|
||||||
|
## Новое в версии 0.2.3
|
||||||
|
|
||||||
|
- Веб-интерфейс с настраиваемым портом (WEB_PORT)
|
||||||
|
- Тёмная/светлая тема с автоопределением ОС
|
||||||
|
- Сортировка по всем колонкам
|
||||||
|
- Фильтрация по имени файла/UID
|
||||||
|
- Остановка всех активных заданий
|
||||||
|
- Автообновление каждые 60 секунд
|
||||||
|
- Улучшенное debug-логирование
|
||||||
|
- Исправлена обработка UNC/SMB путей
|
||||||
|
- Нормализация множественных пробелов в именах файлов"
|
||||||
|
|
||||||
|
## Обзор
|
||||||
|
|
||||||
|
AE Anons — это CLI-утилита и веб-сервер на Rust, которая выступает как **интеллектуальный генератор заданий**
|
||||||
|
для [Nexrender](https://github.com/inlife/nexrender) — опенсорсного оркестратора рендеринга
|
||||||
|
After Effects (лицензия MIT).
|
||||||
|
|
||||||
|
### Режимы работы
|
||||||
|
|
||||||
|
1. **Однократная обработка** (`--once` или без флагов):
|
||||||
|
- Подключение к NAS Synology
|
||||||
|
- Парсинг Excel данных
|
||||||
|
- Генерация и отправка заданий Nexrender
|
||||||
|
- Мониторинг завершения и выход
|
||||||
|
|
||||||
|
2. **Веб-сервер** (`--web`):
|
||||||
|
- Запуск веб-интерфейса на порту `:3000`
|
||||||
|
- Управление заданиями через браузер
|
||||||
|
- Автообновление статуса каждую минуту
|
||||||
|
|
||||||
|
## Особенности
|
||||||
|
|
||||||
|
- **Интеграция с Synology**: Аутентификация и загрузка файлов с NAS Synology
|
||||||
|
- **Экспорт офисных таблиц**: Автоматическое преобразование файлов .osheet в формат Excel
|
||||||
|
- **Гибкий парсинг данных**: Динамический парсинг листов с обнаружением заголовков
|
||||||
|
- **Множественная генерация вариантов**: Создание "Сегодня", "Завтра" и датированных версий
|
||||||
|
- **Умное управление логотипами**: Автоматическое разрешение и масштабирование логотипов
|
||||||
|
- **Веб-интерфейс**: Удобное управление и мониторинг заданий
|
||||||
|
- **REST API**: Программный доступ к управлению заданиями
|
||||||
|
- **Профессиональное логирование**: Структурированный журнал с настройкой уровня
|
||||||
|
|
||||||
|
## Предварительные требования
|
||||||
|
|
||||||
|
- Rust 1.70 или выше
|
||||||
|
- Доступ к NAS Synology с пакетами File Station и Office
|
||||||
|
- Экземпляр _server_ и _worker_(не менее одного) Nexrender
|
||||||
|
- Шаблоны After Effects (формат 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
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Настройка окружения
|
||||||
|
|
||||||
|
Скопируйте пример конфигурации и заполните своими данными:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
Затем отредактируйте файл .env:
|
||||||
|
|
||||||
|
См. раздел Конфигурация для подробной информации.
|
||||||
|
|
||||||
|
## Использование
|
||||||
|
|
||||||
|
### Однократная обработка
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запуск с настройками по умолчанию
|
||||||
|
./target/release/ae_anons
|
||||||
|
|
||||||
|
# Явно указать однократный режим
|
||||||
|
./target/release/ae_anons --once
|
||||||
|
|
||||||
|
# С отладочным логированием
|
||||||
|
RUST_LOG=debug ./target/release/ae_anons
|
||||||
|
```
|
||||||
|
|
||||||
|
### Веб-сервер
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запуск веб-интерфейса на порту по умолчанию (3000)
|
||||||
|
./target/release/ae_anons --web
|
||||||
|
|
||||||
|
# Или с указанием другого порта через .env файл
|
||||||
|
# WEB_PORT=8080 ./target/release/ae_anons --web
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Веб-интерфейс
|
||||||
|
|
||||||
|
После запуска веб-сервера откройте браузер:
|
||||||
|
|
||||||
|
- Главная страница: <http://localhost:3000>
|
||||||
|
|
||||||
|
- API эндпоинты:
|
||||||
|
- `GET /api/jobs` - список всех заданий
|
||||||
|
- `POST /api/generate` - запуск генерации
|
||||||
|
- `POST /api/cleanup` - очистка завершённых
|
||||||
|
- `POST /api/jobs/stop-all` - остановка активных
|
||||||
|
- `GET /api/status` - статус сервера
|
||||||
|
|
||||||
|
## Уровни логирования
|
||||||
|
|
||||||
|
Управляйте детализацией вывода через переменную окружения `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` | Да | Сетевой путь для рендеренных видео |
|
||||||
|
| `TEMPLATE_DOUBLE_SRC` | Да | Путь к AEP-шаблону для двух команд |
|
||||||
|
| `TEMPLATE_SINGLE_SRC` | Да | Путь к AEP-шаблону для одной команды |
|
||||||
|
| `TEMPLATE_COMPOSITION` | Да | Имя композиции в проекте AE (например, `main`) |
|
||||||
|
| `TEMPLATE_OUTPUT_MODULE`| Да | Имя модуля вывода в AE (например, `h264`) |
|
||||||
|
| `TEMPLATE_OUTPUT_EXT` | Да | Расширение выходного файла (например, `mp4`) |
|
||||||
|
| `WEB_PORT` | Нет | Порт для веб-сервера (по умолчанию: 3000) |
|
||||||
|
| `RUST_LOG` | Нет | Уровень детализации логирования (по умолчанию: info) |
|
||||||
|
|
||||||
|
### Пример файла `.env`
|
||||||
|
|
||||||
|
```env
|
||||||
|
# Synology NAS
|
||||||
|
NAS_FQDN="https://your-nas.example.com"
|
||||||
|
NAS_USER="your_username"
|
||||||
|
NAS_PASS="your_password"
|
||||||
|
NAS_FILE="/Team Folder/path/to/file.osheet"
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
RUST_LOG="info"
|
||||||
|
|
||||||
|
# Web Server
|
||||||
|
WEB_PORT="3000"
|
||||||
|
|
||||||
|
# Nexrender
|
||||||
|
NEXRENDER_API_URL="http://nexrender-server:3050/api/v1/jobs"
|
||||||
|
OUTPUT_FOLDER="/path/to/output"
|
||||||
|
|
||||||
|
# After Effects Templates
|
||||||
|
TEMPLATE_DOUBLE_SRC="file:///path/to/double_team_template.aepx"
|
||||||
|
TEMPLATE_SINGLE_SRC="file:///path/to/single_team_template.aepx"
|
||||||
|
TEMPLATE_COMPOSITION="main"
|
||||||
|
TEMPLATE_OUTPUT_MODULE="h264"
|
||||||
|
TEMPLATE_OUTPUT_EXT="mp4"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Структура электронной таблицы
|
||||||
|
|
||||||
|
Файл 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. **Первый хеш**: Уникальный идентификатор для команд с одинаковыми названиями в одном виде спорта, или одинаковым названием в разных видах спорта.
|
||||||
|
Примеры:
|
||||||
|
|
||||||
|
- `Динамо#Футбол`, `Динамо#Волейбол` - Одно название разный вид спорта
|
||||||
|
- `Спартак#ЖенскийФ`, `Спартак#МужскойФ` Одно название _разный_ вид спорта
|
||||||
|
|
||||||
|
1. **Второй хеш**: Целевой размер в пикселях для масштабирования логотипа
|
||||||
|
|
||||||
|
Формат: `DisplayName#UniqueID#TargetSize`
|
||||||
|
|
||||||
|
Примеры:
|
||||||
|
|
||||||
|
- `Галатасарай#Turki` - только уникальный идентификатор
|
||||||
|
- `Сомбатей##400` - только целевой размер (обратите внимание на двойной хеш)
|
||||||
|
- `Спортинг#ll#550` - оба идентификатор и целевой размер
|
||||||
|
|
||||||
|
**Важно**: Обрабатывается **только второй хеш** для масштабирования логотипа. Если уникальный идентификатор не требуется, используйте двойной хеш ## перед целевым размером.
|
||||||
|
|
||||||
|
## Выходные файлы
|
||||||
|
|
||||||
|
### Рендеренные видео
|
||||||
|
|
||||||
|
Рендерные видео сохраняются в `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
|
||||||
|
|
||||||
|
Шаблоны должны быть предварительно настроены на узлах рендеринга со следующими именами слоёв.
|
||||||
|
|
||||||
|
### Файлы шаблонов
|
||||||
|
|
||||||
|
Настраиваются через переменные окружения:
|
||||||
|
|
||||||
|
| Переменная | Назначение | Пример значения |
|
||||||
|
|-------------------------|-------------------------------------|------------------------------------|
|
||||||
|
| `TEMPLATE_DOUBLE_SRC` | Шаблон для матчей с двумя командами | `file:///path/to/double.aepx` |
|
||||||
|
| `TEMPLATE_SINGLE_SRC` | Шаблон для анонсов с одной командой | `file:///path/to/single.aepx` |
|
||||||
|
| `TEMPLATE_COMPOSITION` | Имя главной композиции | `main` |
|
||||||
|
| `TEMPLATE_OUTPUT_MODULE`| Имя модуля вывода | `h264` |
|
||||||
|
| `TEMPLATE_OUTPUT_EXT` | Расширение выходного файла | `mp4` |
|
||||||
|
|
||||||
|
### Обязательные слои в шаблонах
|
||||||
|
|
||||||
|
#### Текстовые слои
|
||||||
|
|
||||||
|
| Имя слоя | Шаблон DOUBLE | Шаблон SINGLE | Описание |
|
||||||
|
|-----------|:-------------:|:-------------:|-------------------------------------------------|
|
||||||
|
| `DATA` | ✅ | ✅ | Отображение даты (автоматически подстраивается) |
|
||||||
|
| `TIME_H` | ✅ | ❌ | Часы (отдельный слой) |
|
||||||
|
| `TIME_M` | ✅ | ❌ | Минуты (отдельный слой) |
|
||||||
|
| `TIME` | ❌ | ✅ | Полное время (единый слой) |
|
||||||
|
| `LEAGUE` | ✅ | ✅ | Название лиги/турнира |
|
||||||
|
| `SPORT` | ✅ | ✅ | Категория спорта |
|
||||||
|
| `TEAMS` | ✅ | ✅ | Скомбинированные имена команд |
|
||||||
|
|
||||||
|
#### Слои с изображениями
|
||||||
|
|
||||||
|
| Имя слоя | Шаблон DOUBLE | Шаблон SINGLE | Описание |
|
||||||
|
|----------------|:-------------:|:-------------:|-----------------------------|
|
||||||
|
| `TEAM_A_LOGO` | ✅ | ✅ | Логотип команды A |
|
||||||
|
| `TEAM_B_LOGO` | ✅ | ❌ | Логотип команды B |
|
||||||
|
| `CHANELL` | ✅ | ✅ | Логотип канала (две буквы L)|
|
||||||
|
|
||||||
|
#### Видео слои
|
||||||
|
|
||||||
|
| Имя слоя | Шаблон DOUBLE | Шаблон SINGLE | Описание |
|
||||||
|
|-----------|:-------------:|:-------------:|----------------------------|
|
||||||
|
| `TOP` | ✅ | ✅ | Наложение видео оформления |
|
||||||
|
|
||||||
|
### Особенности шаблонов
|
||||||
|
|
||||||
|
#### Шаблон DOUBLE (две команды)
|
||||||
|
|
||||||
|
Используется когда в строке Excel заполнены оба поля `TEAM A` и `TEAM B`.
|
||||||
|
|
||||||
|
Обязательные слои:
|
||||||
|
|
||||||
|
- Все текстовые слои с `TIME_H` и `TIME_M` вместо `TIME`
|
||||||
|
- Оба логотипа команд: `TEAM_A_LOGO` и `TEAM_B_LOGO`
|
||||||
|
|
||||||
|
#### Шаблон SINGLE (одна команда)
|
||||||
|
|
||||||
|
Используется когда заполнено только одно поле команды.
|
||||||
|
|
||||||
|
Обязательные слои:
|
||||||
|
|
||||||
|
- Текстовый слой `TIME` вместо `TIME_H` и `TIME_M`
|
||||||
|
- Только логотип `TEAM_A_LOGO`
|
||||||
|
|
||||||
|
### Автоматические корректировки
|
||||||
|
|
||||||
|
AE Anons автоматически применяет следующие настройки к слоям:
|
||||||
|
|
||||||
|
#### Слой DATA
|
||||||
|
|
||||||
|
В зависимости от отображаемого текста и типа шаблона:
|
||||||
|
|
||||||
|
| Текст | Шаблон | Font Size | Anchor Point |
|
||||||
|
|------------|----------|-----------|--------------|
|
||||||
|
| "сегодня" | DOUBLE | 105 | [0, 5] |
|
||||||
|
| "завтра" | DOUBLE | 115 | [0, 25] |
|
||||||
|
| дата (<6) | DOUBLE | 120 | [0, 20] |
|
||||||
|
|
||||||
|
#### Слои TIME_H, TIME_M, TIME
|
||||||
|
|
||||||
|
Корректировка Anchor Point в зависимости от длины текста:
|
||||||
|
|
||||||
|
| Условие | Anchor Point |
|
||||||
|
|-------------------|--------------|
|
||||||
|
| 1 символ | [60, 0] |
|
||||||
|
| 2 символа, <20 | [20, 0] |
|
||||||
|
|
||||||
|
#### Слой LEAGUE
|
||||||
|
|
||||||
|
Если длина текста превышает 16 символов, размер шрифта уменьшается до 73.
|
||||||
|
|
||||||
|
#### Слой TEAMS
|
||||||
|
|
||||||
|
Если суммарная длина имён команд ≥ 32 символов, размер шрифта уменьшается до 55.
|
||||||
|
|
||||||
|
#### Логотипы (TEAM_A_LOGO, TEAM_B_LOGO)
|
||||||
|
|
||||||
|
Если в имени команды указан целевой размер через `#` (например, `Спортинг##550`), применяется выражение масштабирования:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
if (width > height) {
|
||||||
|
max_size = width;
|
||||||
|
} else {
|
||||||
|
max_size = height;
|
||||||
|
}
|
||||||
|
var real_size = 550 / max_size * 100;
|
||||||
|
[real_size, real_size]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример структуры слоёв в After Effects
|
||||||
|
|
||||||
|
Ниже представлен рекомендуемый порядок слоёв в композиции. Порядок важен для правильного наложения элементов.
|
||||||
|
|
||||||
|
```text
|
||||||
|
📁 main (композиция)
|
||||||
|
├── 🎬 TOP (видео слой) # Видео-оверлей (обязательный)
|
||||||
|
├── 📝 TEAMS (текстовый слой) # Имена команд (обязательный)
|
||||||
|
├── 📝 LEAGUE (текстовый слой) # Название лиги (обязательный)
|
||||||
|
├── 📝 SPORT (текстовый слой) # Вид спорта (обязательный)
|
||||||
|
├── 📝 DATA (текстовый слой) # Дата (обязательный)
|
||||||
|
├── 📝 TIME (текстовый слой) # Время (только SINGLE)
|
||||||
|
├── 📝 TIME_H (текстовый слой) # Часы (только DOUBLE)
|
||||||
|
├── 📝 TIME_M (текстовый слой) # Минуты (только DOUBLE)
|
||||||
|
├── 🖼️ CHANELL (слой изображения) # Логотип канала (обязательный)
|
||||||
|
├── 🖼️ TEAM_A_LOGO (слой изображения) # Логотип команды A (обязательный)
|
||||||
|
├── 🖼️ TEAM_B_LOGO (слой изображения) # Логотип команды B (только DOUBLE)
|
||||||
|
└── 🖼️ BOTTOM (слой изображения) # Фоновый слой (опционально)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Формат проекта и совместимость с After Effects
|
||||||
|
|
||||||
|
**Поддерживаемые форматы проектов:**
|
||||||
|
|
||||||
|
- `.aep` — стандартный бинарный формат After Effects (рекомендуется)
|
||||||
|
- `.aepx` — XML-формат проекта (поддерживается с AE CC 2015)
|
||||||
|
|
||||||
|
**Совместимость версий After Effects:**
|
||||||
|
|
||||||
|
| Версия After Effects | Поддерживаемые форматы | Особенности |
|
||||||
|
|----------------------|------------------------|-------------------------------------------------|
|
||||||
|
| CS 5.5 | `.aep` | Базовая поддержка |
|
||||||
|
| CC / CC 2014 | `.aep` | Полная поддержка |
|
||||||
|
| CC 2015 - CC 2019 | `.aep`, `.aepx` | Добавлена поддержка XML формата `.aepx` |
|
||||||
|
| CC 2020 - CC 2022 | `.aep`, `.aepx` | Рекомендуется использовать `.aep` |
|
||||||
|
| CC 2023 и новее | `.aep`, `.aepx` | **Требуется настройка Output Module** (см. ниже)|
|
||||||
|
|
||||||
|
> **⚠️ Важно для After Effects 2023+:**
|
||||||
|
>
|
||||||
|
> В версиях After Effects 2023 и новее критически важно настроить **Output Module** в шаблоне проекта. Бинарный файл рендеринга (`aerender`) не будет обрабатывать композицию без явно указанного модуля вывода, даже если в проекте используется модуль по умолчанию.
|
||||||
|
>
|
||||||
|
> AE Anons автоматически решает эту проблему, используя параметры `TEMPLATE_OUTPUT_MODULE` и `TEMPLATE_OUTPUT_EXT` из `.env` файла. Убедитесь, что эти значения соответствуют настройкам вашего шаблона.
|
||||||
|
|
||||||
|
### Настройки композиции
|
||||||
|
|
||||||
|
| Параметр | Переменная окружения | Пример значения | Описание |
|
||||||
|
|---------------------------|--------------------------|-----------------|---------------------------------------------|
|
||||||
|
| Имя композиции | `TEMPLATE_COMPOSITION` | `main` | Имя главной композиции в проекте AE |
|
||||||
|
| Выходной модуль | `TEMPLATE_OUTPUT_MODULE` | `h264` | Имя модуля вывода в AE |
|
||||||
|
| Расширение выходного файла| `TEMPLATE_OUTPUT_EXT` | `mp4` | Расширение выходного файла |
|
||||||
|
|
||||||
|
**Рекомендации по выбору формата:**
|
||||||
|
|
||||||
|
1. Используйте `.aep` для максимальной совместимости со всеми версиями AE
|
||||||
|
2. Версия After Effects на worker-машине должна быть не ниже версии, в которой создан проект
|
||||||
|
3. Для AE 2023+ убедитесь, что в шаблоне настроен Output Module с именем, указанным в `TEMPLATE_OUTPUT_MODULE`
|
||||||
|
|
||||||
|
**Источники:**
|
||||||
|
|
||||||
|
- [Nexrender - Tested with After Effects versions](https://github.com/inlife/nexrender#tested-with)
|
||||||
|
- [Adobe Aerender documentation](https://helpx.adobe.com/after-effects/using/automated-rendering-network-rendering.html)
|
||||||
|
|
||||||
|
## Устранение неисправностей
|
||||||
|
|
||||||
|
### Частые проблемы
|
||||||
|
|
||||||
|
#### Ошибка подключения к 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 управляет очередью заданий внутренне
|
||||||
|
|
||||||
|
## Примечания по безопасности
|
||||||
|
|
||||||
|
- Храните учетные данные только в файле `.env` (исключен из git)
|
||||||
|
- Используйте специальные аккаунты с минимально необходимыми правами
|
||||||
|
- Сессии Synology завершаются после выполнения
|
||||||
|
- HTTPS рекомендуется для подключений NAS в продакшене
|
||||||
|
|
||||||
|
## Разработка
|
||||||
|
|
||||||
|
### Структура кода
|
||||||
|
|
||||||
|
```shell
|
||||||
|
ae_anons/
|
||||||
|
├── .gitignore
|
||||||
|
├── .env.example
|
||||||
|
├── Cargo.toml
|
||||||
|
├── LICENSE
|
||||||
|
├── README.md
|
||||||
|
├── assets/
|
||||||
|
│ └── logo.png
|
||||||
|
└── src/
|
||||||
|
├── main.rs # Точка входа, CLI
|
||||||
|
├── config.rs # Конфигурация из .env
|
||||||
|
├── nexrender.rs # Модели заданий Nexrender
|
||||||
|
├── synology.rs # Клиент Synology API
|
||||||
|
├── processor.rs # Логика обработки
|
||||||
|
├── web.rs # Веб-сервер и API
|
||||||
|
└── static/
|
||||||
|
├── index.html # Веб-интерфейс
|
||||||
|
└── style.css # Стили
|
||||||
|
```
|
||||||
|
|
||||||
|
## Зависимости
|
||||||
|
|
||||||
|
### Основные зависимости
|
||||||
|
|
||||||
|
| Crate | Версия | Назначение |
|
||||||
|
|--------------------|---------|-----------------------------------------|
|
||||||
|
| reqwest | 0.12 | HTTP клиент для коммуникации с API |
|
||||||
|
| serde / serde_json | 1.0 | Сериализация и десериализация JSON |
|
||||||
|
| calamine | 0.26 | Парсинг файлов Excel (.xlsx, .xls) |
|
||||||
|
| chrono | 0.4 | Обработка дат и времени |
|
||||||
|
| tokio | 1.0 | Асинхронная среда выполнения |
|
||||||
|
| dotenv | 0.15 | Загрузка конфигурации из .env файла |
|
||||||
|
| log / env_logger | 0.4/0.11| Система логирования с уровнями |
|
||||||
|
| thiserror | 2.0 | Эргономичные определения типов ошибок |
|
||||||
|
| anyhow | 1.0 | Упрощённая обработка ошибок |
|
||||||
|
| regex | 1.11 | Регулярные выражения |
|
||||||
|
| urlencoding | 2.1 | Кодирование URL для API запросов |
|
||||||
|
| bytes | 1.9 | Работа с байтовыми данными |
|
||||||
|
| futures | 0.3 | Асинхронные примитивы |
|
||||||
|
|
||||||
|
### Веб-сервер и CLI
|
||||||
|
|
||||||
|
| Crate | Версия | Назначение |
|
||||||
|
|--------------------|--------|-----------------------------------------|
|
||||||
|
| axum | 0.8 | Веб-фреймворк для REST API |
|
||||||
|
| tower | 0.5 | Промежуточное ПО для веб-сервера |
|
||||||
|
| tower-http | 0.6 |HTTP утилиты (CORS, статика, трассировка)|
|
||||||
|
| askama | 0.15 | Шаблонизация (опционально) |
|
||||||
|
| clap | 4.5 | Парсинг аргументов командной строки |
|
||||||
|
|
||||||
|
### Платформозависимые зависимости
|
||||||
|
|
||||||
|
| Crate | Версия | Платформа | Назначение |
|
||||||
|
|--------------------|--------|-----------|----------------------------------|
|
||||||
|
| openssl | 0.10 | Linux | Криптография для HTTPS (vendored)|
|
||||||
|
|
||||||
|
## 🙏 Благодарности
|
||||||
|
|
||||||
|
Особая благодарность проекту **[Nexrender](https://github.com/inlife/nexrender)**
|
||||||
|
([@inlife](https://github.com/inlife) и контрибьюторам) за создание надёжной платформы
|
||||||
|
для автоматизации After Effects.
|
||||||
|
|
||||||
|
## Лицензия
|
||||||
|
|
||||||
|
**AE Anons** — [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.2.3 (текущая)
|
||||||
|
|
||||||
|
- Веб-интерфейс с настраиваемым портом (WEB_PORT)
|
||||||
|
- Улучшенное debug-логирование
|
||||||
|
- Исправлена обработка UNC/SMB путей
|
||||||
|
- Нормализация множественных пробелов в именах файлов"
|
||||||
|
|
||||||
|
### v0.2.2
|
||||||
|
|
||||||
|
- Исправлено отображение имён выходных файлов в веб-интерфейсе
|
||||||
|
|
||||||
|
- Улучшена цветовая схема
|
||||||
|
|
||||||
|
- Добавлена сортировка по всем колонкам
|
||||||
|
|
||||||
|
- Вынесены стили в отдельный CSS файл
|
||||||
|
|
||||||
|
### v0.2.0
|
||||||
|
|
||||||
|
- Добавлен веб-интерфейс для управления заданиями
|
||||||
|
|
||||||
|
- Реализован REST API
|
||||||
|
|
||||||
|
- Добавлена поддержка тёмной/светлой темы
|
||||||
|
|
||||||
|
- Автообновление статуса заданий
|
||||||
|
|
||||||
|
- Возможность остановки всех активных заданий
|
||||||
|
|
||||||
|
### v0.1.1
|
||||||
|
|
||||||
|
- Оптимизирована работа с памятью
|
||||||
|
|
||||||
|
- Убрана функция создания .json
|
||||||
|
|
||||||
|
### v0.1.0
|
||||||
|
|
||||||
|
- Первый выпуск
|
||||||
|
|
||||||
|
- Интеграция с Synology Office
|
||||||
|
|
||||||
|
- Базовая генерация заданий Nexrender
|
||||||
|
|
||||||
|
- Парсинг Excel с динамическим обнаружением листов
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Made with 🦀 Rust and ☕ coffee
|
||||||
BIN
releases/ae_anons-v0.2.3-linux-musl/ae_anons
Executable file
BIN
releases/ae_anons-v0.2.3-linux-musl/ae_anons
Executable file
Binary file not shown.
22
releases/ae_anons-v0.2.3-macos-arm64/.env.example
Normal file
22
releases/ae_anons-v0.2.3-macos-arm64/.env.example
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Synology NAS
|
||||||
|
NAS_FQDN="https://your-nas.example.com"
|
||||||
|
NAS_USER="your_username"
|
||||||
|
NAS_PASS="your_password"
|
||||||
|
NAS_FILE="/Team Folder/path/to/file.osheet"
|
||||||
|
|
||||||
|
# Logging (optional, defaults to info)
|
||||||
|
RUST_LOG="info"
|
||||||
|
|
||||||
|
# Web Server (optional, defaults to 3000)
|
||||||
|
WEB_PORT="3000"
|
||||||
|
|
||||||
|
# Nexrender
|
||||||
|
NEXRENDER_API_URL="http://nexrender-server:3050/api/v1/jobs"
|
||||||
|
OUTPUT_FOLDER="/path/to/output"
|
||||||
|
|
||||||
|
# After Effects Templates
|
||||||
|
TEMPLATE_DOUBLE_SRC="file:///path/to/double_team_template.aep"
|
||||||
|
TEMPLATE_SINGLE_SRC="file:///path/to/single_team_template.aep"
|
||||||
|
TEMPLATE_COMPOSITION="main"
|
||||||
|
TEMPLATE_OUTPUT_MODULE="h264"
|
||||||
|
TEMPLATE_OUTPUT_EXT="mp4"
|
||||||
21
releases/ae_anons-v0.2.3-macos-arm64/LICENSE
Normal file
21
releases/ae_anons-v0.2.3-macos-arm64/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 [Your Name or Company]
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
656
releases/ae_anons-v0.2.3-macos-arm64/README.md
Normal file
656
releases/ae_anons-v0.2.3-macos-arm64/README.md
Normal file
@@ -0,0 +1,656 @@
|
|||||||
|
# AE Anons - Автоматизированный генератор спортивных анонсов в After Effects
|
||||||
|
|
||||||
|
<!-- markdownlint-disable MD033 -->
|
||||||
|
<p align="left">
|
||||||
|
<img src="assets/logo.png" alt="AE Anons Logo" width="250"/>
|
||||||
|
</p>
|
||||||
|
<!-- markdownlint-enable MD033 -->
|
||||||
|
|
||||||
|
[](https://opensource.org/licenses/MIT)
|
||||||
|
[](https://www.rust-lang.org/)
|
||||||
|
[](https://git.tvstart.ru/lexx/AE_Anons)
|
||||||
|
|
||||||
|
Автоматизированная система для создания спортивных анонсов с использованием шаблонов After Effects через Nexrender, с данными из электронных таблиц Synology Office.
|
||||||
|
|
||||||
|
## Новое в версии 0.2.3
|
||||||
|
|
||||||
|
- Веб-интерфейс с настраиваемым портом (WEB_PORT)
|
||||||
|
- Тёмная/светлая тема с автоопределением ОС
|
||||||
|
- Сортировка по всем колонкам
|
||||||
|
- Фильтрация по имени файла/UID
|
||||||
|
- Остановка всех активных заданий
|
||||||
|
- Автообновление каждые 60 секунд
|
||||||
|
- Улучшенное debug-логирование
|
||||||
|
- Исправлена обработка UNC/SMB путей
|
||||||
|
- Нормализация множественных пробелов в именах файлов"
|
||||||
|
|
||||||
|
## Обзор
|
||||||
|
|
||||||
|
AE Anons — это CLI-утилита и веб-сервер на Rust, которая выступает как **интеллектуальный генератор заданий**
|
||||||
|
для [Nexrender](https://github.com/inlife/nexrender) — опенсорсного оркестратора рендеринга
|
||||||
|
After Effects (лицензия MIT).
|
||||||
|
|
||||||
|
### Режимы работы
|
||||||
|
|
||||||
|
1. **Однократная обработка** (`--once` или без флагов):
|
||||||
|
- Подключение к NAS Synology
|
||||||
|
- Парсинг Excel данных
|
||||||
|
- Генерация и отправка заданий Nexrender
|
||||||
|
- Мониторинг завершения и выход
|
||||||
|
|
||||||
|
2. **Веб-сервер** (`--web`):
|
||||||
|
- Запуск веб-интерфейса на порту `:3000`
|
||||||
|
- Управление заданиями через браузер
|
||||||
|
- Автообновление статуса каждую минуту
|
||||||
|
|
||||||
|
## Особенности
|
||||||
|
|
||||||
|
- **Интеграция с Synology**: Аутентификация и загрузка файлов с NAS Synology
|
||||||
|
- **Экспорт офисных таблиц**: Автоматическое преобразование файлов .osheet в формат Excel
|
||||||
|
- **Гибкий парсинг данных**: Динамический парсинг листов с обнаружением заголовков
|
||||||
|
- **Множественная генерация вариантов**: Создание "Сегодня", "Завтра" и датированных версий
|
||||||
|
- **Умное управление логотипами**: Автоматическое разрешение и масштабирование логотипов
|
||||||
|
- **Веб-интерфейс**: Удобное управление и мониторинг заданий
|
||||||
|
- **REST API**: Программный доступ к управлению заданиями
|
||||||
|
- **Профессиональное логирование**: Структурированный журнал с настройкой уровня
|
||||||
|
|
||||||
|
## Предварительные требования
|
||||||
|
|
||||||
|
- Rust 1.70 или выше
|
||||||
|
- Доступ к NAS Synology с пакетами File Station и Office
|
||||||
|
- Экземпляр _server_ и _worker_(не менее одного) Nexrender
|
||||||
|
- Шаблоны After Effects (формат 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
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Настройка окружения
|
||||||
|
|
||||||
|
Скопируйте пример конфигурации и заполните своими данными:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
Затем отредактируйте файл .env:
|
||||||
|
|
||||||
|
См. раздел Конфигурация для подробной информации.
|
||||||
|
|
||||||
|
## Использование
|
||||||
|
|
||||||
|
### Однократная обработка
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запуск с настройками по умолчанию
|
||||||
|
./target/release/ae_anons
|
||||||
|
|
||||||
|
# Явно указать однократный режим
|
||||||
|
./target/release/ae_anons --once
|
||||||
|
|
||||||
|
# С отладочным логированием
|
||||||
|
RUST_LOG=debug ./target/release/ae_anons
|
||||||
|
```
|
||||||
|
|
||||||
|
### Веб-сервер
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запуск веб-интерфейса на порту по умолчанию (3000)
|
||||||
|
./target/release/ae_anons --web
|
||||||
|
|
||||||
|
# Или с указанием другого порта через .env файл
|
||||||
|
# WEB_PORT=8080 ./target/release/ae_anons --web
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Веб-интерфейс
|
||||||
|
|
||||||
|
После запуска веб-сервера откройте браузер:
|
||||||
|
|
||||||
|
- Главная страница: <http://localhost:3000>
|
||||||
|
|
||||||
|
- API эндпоинты:
|
||||||
|
- `GET /api/jobs` - список всех заданий
|
||||||
|
- `POST /api/generate` - запуск генерации
|
||||||
|
- `POST /api/cleanup` - очистка завершённых
|
||||||
|
- `POST /api/jobs/stop-all` - остановка активных
|
||||||
|
- `GET /api/status` - статус сервера
|
||||||
|
|
||||||
|
## Уровни логирования
|
||||||
|
|
||||||
|
Управляйте детализацией вывода через переменную окружения `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` | Да | Сетевой путь для рендеренных видео |
|
||||||
|
| `TEMPLATE_DOUBLE_SRC` | Да | Путь к AEP-шаблону для двух команд |
|
||||||
|
| `TEMPLATE_SINGLE_SRC` | Да | Путь к AEP-шаблону для одной команды |
|
||||||
|
| `TEMPLATE_COMPOSITION` | Да | Имя композиции в проекте AE (например, `main`) |
|
||||||
|
| `TEMPLATE_OUTPUT_MODULE`| Да | Имя модуля вывода в AE (например, `h264`) |
|
||||||
|
| `TEMPLATE_OUTPUT_EXT` | Да | Расширение выходного файла (например, `mp4`) |
|
||||||
|
| `WEB_PORT` | Нет | Порт для веб-сервера (по умолчанию: 3000) |
|
||||||
|
| `RUST_LOG` | Нет | Уровень детализации логирования (по умолчанию: info) |
|
||||||
|
|
||||||
|
### Пример файла `.env`
|
||||||
|
|
||||||
|
```env
|
||||||
|
# Synology NAS
|
||||||
|
NAS_FQDN="https://your-nas.example.com"
|
||||||
|
NAS_USER="your_username"
|
||||||
|
NAS_PASS="your_password"
|
||||||
|
NAS_FILE="/Team Folder/path/to/file.osheet"
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
RUST_LOG="info"
|
||||||
|
|
||||||
|
# Web Server
|
||||||
|
WEB_PORT="3000"
|
||||||
|
|
||||||
|
# Nexrender
|
||||||
|
NEXRENDER_API_URL="http://nexrender-server:3050/api/v1/jobs"
|
||||||
|
OUTPUT_FOLDER="/path/to/output"
|
||||||
|
|
||||||
|
# After Effects Templates
|
||||||
|
TEMPLATE_DOUBLE_SRC="file:///path/to/double_team_template.aepx"
|
||||||
|
TEMPLATE_SINGLE_SRC="file:///path/to/single_team_template.aepx"
|
||||||
|
TEMPLATE_COMPOSITION="main"
|
||||||
|
TEMPLATE_OUTPUT_MODULE="h264"
|
||||||
|
TEMPLATE_OUTPUT_EXT="mp4"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Структура электронной таблицы
|
||||||
|
|
||||||
|
Файл 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. **Первый хеш**: Уникальный идентификатор для команд с одинаковыми названиями в одном виде спорта, или одинаковым названием в разных видах спорта.
|
||||||
|
Примеры:
|
||||||
|
|
||||||
|
- `Динамо#Футбол`, `Динамо#Волейбол` - Одно название разный вид спорта
|
||||||
|
- `Спартак#ЖенскийФ`, `Спартак#МужскойФ` Одно название _разный_ вид спорта
|
||||||
|
|
||||||
|
1. **Второй хеш**: Целевой размер в пикселях для масштабирования логотипа
|
||||||
|
|
||||||
|
Формат: `DisplayName#UniqueID#TargetSize`
|
||||||
|
|
||||||
|
Примеры:
|
||||||
|
|
||||||
|
- `Галатасарай#Turki` - только уникальный идентификатор
|
||||||
|
- `Сомбатей##400` - только целевой размер (обратите внимание на двойной хеш)
|
||||||
|
- `Спортинг#ll#550` - оба идентификатор и целевой размер
|
||||||
|
|
||||||
|
**Важно**: Обрабатывается **только второй хеш** для масштабирования логотипа. Если уникальный идентификатор не требуется, используйте двойной хеш ## перед целевым размером.
|
||||||
|
|
||||||
|
## Выходные файлы
|
||||||
|
|
||||||
|
### Рендеренные видео
|
||||||
|
|
||||||
|
Рендерные видео сохраняются в `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
|
||||||
|
|
||||||
|
Шаблоны должны быть предварительно настроены на узлах рендеринга со следующими именами слоёв.
|
||||||
|
|
||||||
|
### Файлы шаблонов
|
||||||
|
|
||||||
|
Настраиваются через переменные окружения:
|
||||||
|
|
||||||
|
| Переменная | Назначение | Пример значения |
|
||||||
|
|-------------------------|-------------------------------------|------------------------------------|
|
||||||
|
| `TEMPLATE_DOUBLE_SRC` | Шаблон для матчей с двумя командами | `file:///path/to/double.aepx` |
|
||||||
|
| `TEMPLATE_SINGLE_SRC` | Шаблон для анонсов с одной командой | `file:///path/to/single.aepx` |
|
||||||
|
| `TEMPLATE_COMPOSITION` | Имя главной композиции | `main` |
|
||||||
|
| `TEMPLATE_OUTPUT_MODULE`| Имя модуля вывода | `h264` |
|
||||||
|
| `TEMPLATE_OUTPUT_EXT` | Расширение выходного файла | `mp4` |
|
||||||
|
|
||||||
|
### Обязательные слои в шаблонах
|
||||||
|
|
||||||
|
#### Текстовые слои
|
||||||
|
|
||||||
|
| Имя слоя | Шаблон DOUBLE | Шаблон SINGLE | Описание |
|
||||||
|
|-----------|:-------------:|:-------------:|-------------------------------------------------|
|
||||||
|
| `DATA` | ✅ | ✅ | Отображение даты (автоматически подстраивается) |
|
||||||
|
| `TIME_H` | ✅ | ❌ | Часы (отдельный слой) |
|
||||||
|
| `TIME_M` | ✅ | ❌ | Минуты (отдельный слой) |
|
||||||
|
| `TIME` | ❌ | ✅ | Полное время (единый слой) |
|
||||||
|
| `LEAGUE` | ✅ | ✅ | Название лиги/турнира |
|
||||||
|
| `SPORT` | ✅ | ✅ | Категория спорта |
|
||||||
|
| `TEAMS` | ✅ | ✅ | Скомбинированные имена команд |
|
||||||
|
|
||||||
|
#### Слои с изображениями
|
||||||
|
|
||||||
|
| Имя слоя | Шаблон DOUBLE | Шаблон SINGLE | Описание |
|
||||||
|
|----------------|:-------------:|:-------------:|-----------------------------|
|
||||||
|
| `TEAM_A_LOGO` | ✅ | ✅ | Логотип команды A |
|
||||||
|
| `TEAM_B_LOGO` | ✅ | ❌ | Логотип команды B |
|
||||||
|
| `CHANELL` | ✅ | ✅ | Логотип канала (две буквы L)|
|
||||||
|
|
||||||
|
#### Видео слои
|
||||||
|
|
||||||
|
| Имя слоя | Шаблон DOUBLE | Шаблон SINGLE | Описание |
|
||||||
|
|-----------|:-------------:|:-------------:|----------------------------|
|
||||||
|
| `TOP` | ✅ | ✅ | Наложение видео оформления |
|
||||||
|
|
||||||
|
### Особенности шаблонов
|
||||||
|
|
||||||
|
#### Шаблон DOUBLE (две команды)
|
||||||
|
|
||||||
|
Используется когда в строке Excel заполнены оба поля `TEAM A` и `TEAM B`.
|
||||||
|
|
||||||
|
Обязательные слои:
|
||||||
|
|
||||||
|
- Все текстовые слои с `TIME_H` и `TIME_M` вместо `TIME`
|
||||||
|
- Оба логотипа команд: `TEAM_A_LOGO` и `TEAM_B_LOGO`
|
||||||
|
|
||||||
|
#### Шаблон SINGLE (одна команда)
|
||||||
|
|
||||||
|
Используется когда заполнено только одно поле команды.
|
||||||
|
|
||||||
|
Обязательные слои:
|
||||||
|
|
||||||
|
- Текстовый слой `TIME` вместо `TIME_H` и `TIME_M`
|
||||||
|
- Только логотип `TEAM_A_LOGO`
|
||||||
|
|
||||||
|
### Автоматические корректировки
|
||||||
|
|
||||||
|
AE Anons автоматически применяет следующие настройки к слоям:
|
||||||
|
|
||||||
|
#### Слой DATA
|
||||||
|
|
||||||
|
В зависимости от отображаемого текста и типа шаблона:
|
||||||
|
|
||||||
|
| Текст | Шаблон | Font Size | Anchor Point |
|
||||||
|
|------------|----------|-----------|--------------|
|
||||||
|
| "сегодня" | DOUBLE | 105 | [0, 5] |
|
||||||
|
| "завтра" | DOUBLE | 115 | [0, 25] |
|
||||||
|
| дата (<6) | DOUBLE | 120 | [0, 20] |
|
||||||
|
|
||||||
|
#### Слои TIME_H, TIME_M, TIME
|
||||||
|
|
||||||
|
Корректировка Anchor Point в зависимости от длины текста:
|
||||||
|
|
||||||
|
| Условие | Anchor Point |
|
||||||
|
|-------------------|--------------|
|
||||||
|
| 1 символ | [60, 0] |
|
||||||
|
| 2 символа, <20 | [20, 0] |
|
||||||
|
|
||||||
|
#### Слой LEAGUE
|
||||||
|
|
||||||
|
Если длина текста превышает 16 символов, размер шрифта уменьшается до 73.
|
||||||
|
|
||||||
|
#### Слой TEAMS
|
||||||
|
|
||||||
|
Если суммарная длина имён команд ≥ 32 символов, размер шрифта уменьшается до 55.
|
||||||
|
|
||||||
|
#### Логотипы (TEAM_A_LOGO, TEAM_B_LOGO)
|
||||||
|
|
||||||
|
Если в имени команды указан целевой размер через `#` (например, `Спортинг##550`), применяется выражение масштабирования:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
if (width > height) {
|
||||||
|
max_size = width;
|
||||||
|
} else {
|
||||||
|
max_size = height;
|
||||||
|
}
|
||||||
|
var real_size = 550 / max_size * 100;
|
||||||
|
[real_size, real_size]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример структуры слоёв в After Effects
|
||||||
|
|
||||||
|
Ниже представлен рекомендуемый порядок слоёв в композиции. Порядок важен для правильного наложения элементов.
|
||||||
|
|
||||||
|
```text
|
||||||
|
📁 main (композиция)
|
||||||
|
├── 🎬 TOP (видео слой) # Видео-оверлей (обязательный)
|
||||||
|
├── 📝 TEAMS (текстовый слой) # Имена команд (обязательный)
|
||||||
|
├── 📝 LEAGUE (текстовый слой) # Название лиги (обязательный)
|
||||||
|
├── 📝 SPORT (текстовый слой) # Вид спорта (обязательный)
|
||||||
|
├── 📝 DATA (текстовый слой) # Дата (обязательный)
|
||||||
|
├── 📝 TIME (текстовый слой) # Время (только SINGLE)
|
||||||
|
├── 📝 TIME_H (текстовый слой) # Часы (только DOUBLE)
|
||||||
|
├── 📝 TIME_M (текстовый слой) # Минуты (только DOUBLE)
|
||||||
|
├── 🖼️ CHANELL (слой изображения) # Логотип канала (обязательный)
|
||||||
|
├── 🖼️ TEAM_A_LOGO (слой изображения) # Логотип команды A (обязательный)
|
||||||
|
├── 🖼️ TEAM_B_LOGO (слой изображения) # Логотип команды B (только DOUBLE)
|
||||||
|
└── 🖼️ BOTTOM (слой изображения) # Фоновый слой (опционально)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Формат проекта и совместимость с After Effects
|
||||||
|
|
||||||
|
**Поддерживаемые форматы проектов:**
|
||||||
|
|
||||||
|
- `.aep` — стандартный бинарный формат After Effects (рекомендуется)
|
||||||
|
- `.aepx` — XML-формат проекта (поддерживается с AE CC 2015)
|
||||||
|
|
||||||
|
**Совместимость версий After Effects:**
|
||||||
|
|
||||||
|
| Версия After Effects | Поддерживаемые форматы | Особенности |
|
||||||
|
|----------------------|------------------------|-------------------------------------------------|
|
||||||
|
| CS 5.5 | `.aep` | Базовая поддержка |
|
||||||
|
| CC / CC 2014 | `.aep` | Полная поддержка |
|
||||||
|
| CC 2015 - CC 2019 | `.aep`, `.aepx` | Добавлена поддержка XML формата `.aepx` |
|
||||||
|
| CC 2020 - CC 2022 | `.aep`, `.aepx` | Рекомендуется использовать `.aep` |
|
||||||
|
| CC 2023 и новее | `.aep`, `.aepx` | **Требуется настройка Output Module** (см. ниже)|
|
||||||
|
|
||||||
|
> **⚠️ Важно для After Effects 2023+:**
|
||||||
|
>
|
||||||
|
> В версиях After Effects 2023 и новее критически важно настроить **Output Module** в шаблоне проекта. Бинарный файл рендеринга (`aerender`) не будет обрабатывать композицию без явно указанного модуля вывода, даже если в проекте используется модуль по умолчанию.
|
||||||
|
>
|
||||||
|
> AE Anons автоматически решает эту проблему, используя параметры `TEMPLATE_OUTPUT_MODULE` и `TEMPLATE_OUTPUT_EXT` из `.env` файла. Убедитесь, что эти значения соответствуют настройкам вашего шаблона.
|
||||||
|
|
||||||
|
### Настройки композиции
|
||||||
|
|
||||||
|
| Параметр | Переменная окружения | Пример значения | Описание |
|
||||||
|
|---------------------------|--------------------------|-----------------|---------------------------------------------|
|
||||||
|
| Имя композиции | `TEMPLATE_COMPOSITION` | `main` | Имя главной композиции в проекте AE |
|
||||||
|
| Выходной модуль | `TEMPLATE_OUTPUT_MODULE` | `h264` | Имя модуля вывода в AE |
|
||||||
|
| Расширение выходного файла| `TEMPLATE_OUTPUT_EXT` | `mp4` | Расширение выходного файла |
|
||||||
|
|
||||||
|
**Рекомендации по выбору формата:**
|
||||||
|
|
||||||
|
1. Используйте `.aep` для максимальной совместимости со всеми версиями AE
|
||||||
|
2. Версия After Effects на worker-машине должна быть не ниже версии, в которой создан проект
|
||||||
|
3. Для AE 2023+ убедитесь, что в шаблоне настроен Output Module с именем, указанным в `TEMPLATE_OUTPUT_MODULE`
|
||||||
|
|
||||||
|
**Источники:**
|
||||||
|
|
||||||
|
- [Nexrender - Tested with After Effects versions](https://github.com/inlife/nexrender#tested-with)
|
||||||
|
- [Adobe Aerender documentation](https://helpx.adobe.com/after-effects/using/automated-rendering-network-rendering.html)
|
||||||
|
|
||||||
|
## Устранение неисправностей
|
||||||
|
|
||||||
|
### Частые проблемы
|
||||||
|
|
||||||
|
#### Ошибка подключения к 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 управляет очередью заданий внутренне
|
||||||
|
|
||||||
|
## Примечания по безопасности
|
||||||
|
|
||||||
|
- Храните учетные данные только в файле `.env` (исключен из git)
|
||||||
|
- Используйте специальные аккаунты с минимально необходимыми правами
|
||||||
|
- Сессии Synology завершаются после выполнения
|
||||||
|
- HTTPS рекомендуется для подключений NAS в продакшене
|
||||||
|
|
||||||
|
## Разработка
|
||||||
|
|
||||||
|
### Структура кода
|
||||||
|
|
||||||
|
```shell
|
||||||
|
ae_anons/
|
||||||
|
├── .gitignore
|
||||||
|
├── .env.example
|
||||||
|
├── Cargo.toml
|
||||||
|
├── LICENSE
|
||||||
|
├── README.md
|
||||||
|
├── assets/
|
||||||
|
│ └── logo.png
|
||||||
|
└── src/
|
||||||
|
├── main.rs # Точка входа, CLI
|
||||||
|
├── config.rs # Конфигурация из .env
|
||||||
|
├── nexrender.rs # Модели заданий Nexrender
|
||||||
|
├── synology.rs # Клиент Synology API
|
||||||
|
├── processor.rs # Логика обработки
|
||||||
|
├── web.rs # Веб-сервер и API
|
||||||
|
└── static/
|
||||||
|
├── index.html # Веб-интерфейс
|
||||||
|
└── style.css # Стили
|
||||||
|
```
|
||||||
|
|
||||||
|
## Зависимости
|
||||||
|
|
||||||
|
### Основные зависимости
|
||||||
|
|
||||||
|
| Crate | Версия | Назначение |
|
||||||
|
|--------------------|---------|-----------------------------------------|
|
||||||
|
| reqwest | 0.12 | HTTP клиент для коммуникации с API |
|
||||||
|
| serde / serde_json | 1.0 | Сериализация и десериализация JSON |
|
||||||
|
| calamine | 0.26 | Парсинг файлов Excel (.xlsx, .xls) |
|
||||||
|
| chrono | 0.4 | Обработка дат и времени |
|
||||||
|
| tokio | 1.0 | Асинхронная среда выполнения |
|
||||||
|
| dotenv | 0.15 | Загрузка конфигурации из .env файла |
|
||||||
|
| log / env_logger | 0.4/0.11| Система логирования с уровнями |
|
||||||
|
| thiserror | 2.0 | Эргономичные определения типов ошибок |
|
||||||
|
| anyhow | 1.0 | Упрощённая обработка ошибок |
|
||||||
|
| regex | 1.11 | Регулярные выражения |
|
||||||
|
| urlencoding | 2.1 | Кодирование URL для API запросов |
|
||||||
|
| bytes | 1.9 | Работа с байтовыми данными |
|
||||||
|
| futures | 0.3 | Асинхронные примитивы |
|
||||||
|
|
||||||
|
### Веб-сервер и CLI
|
||||||
|
|
||||||
|
| Crate | Версия | Назначение |
|
||||||
|
|--------------------|--------|-----------------------------------------|
|
||||||
|
| axum | 0.8 | Веб-фреймворк для REST API |
|
||||||
|
| tower | 0.5 | Промежуточное ПО для веб-сервера |
|
||||||
|
| tower-http | 0.6 |HTTP утилиты (CORS, статика, трассировка)|
|
||||||
|
| askama | 0.15 | Шаблонизация (опционально) |
|
||||||
|
| clap | 4.5 | Парсинг аргументов командной строки |
|
||||||
|
|
||||||
|
### Платформозависимые зависимости
|
||||||
|
|
||||||
|
| Crate | Версия | Платформа | Назначение |
|
||||||
|
|--------------------|--------|-----------|----------------------------------|
|
||||||
|
| openssl | 0.10 | Linux | Криптография для HTTPS (vendored)|
|
||||||
|
|
||||||
|
## 🙏 Благодарности
|
||||||
|
|
||||||
|
Особая благодарность проекту **[Nexrender](https://github.com/inlife/nexrender)**
|
||||||
|
([@inlife](https://github.com/inlife) и контрибьюторам) за создание надёжной платформы
|
||||||
|
для автоматизации After Effects.
|
||||||
|
|
||||||
|
## Лицензия
|
||||||
|
|
||||||
|
**AE Anons** — [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.2.3 (текущая)
|
||||||
|
|
||||||
|
- Веб-интерфейс с настраиваемым портом (WEB_PORT)
|
||||||
|
- Улучшенное debug-логирование
|
||||||
|
- Исправлена обработка UNC/SMB путей
|
||||||
|
- Нормализация множественных пробелов в именах файлов"
|
||||||
|
|
||||||
|
### v0.2.2
|
||||||
|
|
||||||
|
- Исправлено отображение имён выходных файлов в веб-интерфейсе
|
||||||
|
|
||||||
|
- Улучшена цветовая схема
|
||||||
|
|
||||||
|
- Добавлена сортировка по всем колонкам
|
||||||
|
|
||||||
|
- Вынесены стили в отдельный CSS файл
|
||||||
|
|
||||||
|
### v0.2.0
|
||||||
|
|
||||||
|
- Добавлен веб-интерфейс для управления заданиями
|
||||||
|
|
||||||
|
- Реализован REST API
|
||||||
|
|
||||||
|
- Добавлена поддержка тёмной/светлой темы
|
||||||
|
|
||||||
|
- Автообновление статуса заданий
|
||||||
|
|
||||||
|
- Возможность остановки всех активных заданий
|
||||||
|
|
||||||
|
### v0.1.1
|
||||||
|
|
||||||
|
- Оптимизирована работа с памятью
|
||||||
|
|
||||||
|
- Убрана функция создания .json
|
||||||
|
|
||||||
|
### v0.1.0
|
||||||
|
|
||||||
|
- Первый выпуск
|
||||||
|
|
||||||
|
- Интеграция с Synology Office
|
||||||
|
|
||||||
|
- Базовая генерация заданий Nexrender
|
||||||
|
|
||||||
|
- Парсинг Excel с динамическим обнаружением листов
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Made with 🦀 Rust and ☕ coffee
|
||||||
BIN
releases/ae_anons-v0.2.3-macos-arm64/ae_anons
Executable file
BIN
releases/ae_anons-v0.2.3-macos-arm64/ae_anons
Executable file
Binary file not shown.
22
releases/ae_anons-v0.2.3-windows-x64/.env.example
Normal file
22
releases/ae_anons-v0.2.3-windows-x64/.env.example
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# Synology NAS
|
||||||
|
NAS_FQDN="https://your-nas.example.com"
|
||||||
|
NAS_USER="your_username"
|
||||||
|
NAS_PASS="your_password"
|
||||||
|
NAS_FILE="/Team Folder/path/to/file.osheet"
|
||||||
|
|
||||||
|
# Logging (optional, defaults to info)
|
||||||
|
RUST_LOG="info"
|
||||||
|
|
||||||
|
# Web Server (optional, defaults to 3000)
|
||||||
|
WEB_PORT="3000"
|
||||||
|
|
||||||
|
# Nexrender
|
||||||
|
NEXRENDER_API_URL="http://nexrender-server:3050/api/v1/jobs"
|
||||||
|
OUTPUT_FOLDER="/path/to/output"
|
||||||
|
|
||||||
|
# After Effects Templates
|
||||||
|
TEMPLATE_DOUBLE_SRC="file:///path/to/double_team_template.aep"
|
||||||
|
TEMPLATE_SINGLE_SRC="file:///path/to/single_team_template.aep"
|
||||||
|
TEMPLATE_COMPOSITION="main"
|
||||||
|
TEMPLATE_OUTPUT_MODULE="h264"
|
||||||
|
TEMPLATE_OUTPUT_EXT="mp4"
|
||||||
21
releases/ae_anons-v0.2.3-windows-x64/LICENSE
Normal file
21
releases/ae_anons-v0.2.3-windows-x64/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2026 [Your Name or Company]
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
656
releases/ae_anons-v0.2.3-windows-x64/README.md
Normal file
656
releases/ae_anons-v0.2.3-windows-x64/README.md
Normal file
@@ -0,0 +1,656 @@
|
|||||||
|
# AE Anons - Автоматизированный генератор спортивных анонсов в After Effects
|
||||||
|
|
||||||
|
<!-- markdownlint-disable MD033 -->
|
||||||
|
<p align="left">
|
||||||
|
<img src="assets/logo.png" alt="AE Anons Logo" width="250"/>
|
||||||
|
</p>
|
||||||
|
<!-- markdownlint-enable MD033 -->
|
||||||
|
|
||||||
|
[](https://opensource.org/licenses/MIT)
|
||||||
|
[](https://www.rust-lang.org/)
|
||||||
|
[](https://git.tvstart.ru/lexx/AE_Anons)
|
||||||
|
|
||||||
|
Автоматизированная система для создания спортивных анонсов с использованием шаблонов After Effects через Nexrender, с данными из электронных таблиц Synology Office.
|
||||||
|
|
||||||
|
## Новое в версии 0.2.3
|
||||||
|
|
||||||
|
- Веб-интерфейс с настраиваемым портом (WEB_PORT)
|
||||||
|
- Тёмная/светлая тема с автоопределением ОС
|
||||||
|
- Сортировка по всем колонкам
|
||||||
|
- Фильтрация по имени файла/UID
|
||||||
|
- Остановка всех активных заданий
|
||||||
|
- Автообновление каждые 60 секунд
|
||||||
|
- Улучшенное debug-логирование
|
||||||
|
- Исправлена обработка UNC/SMB путей
|
||||||
|
- Нормализация множественных пробелов в именах файлов"
|
||||||
|
|
||||||
|
## Обзор
|
||||||
|
|
||||||
|
AE Anons — это CLI-утилита и веб-сервер на Rust, которая выступает как **интеллектуальный генератор заданий**
|
||||||
|
для [Nexrender](https://github.com/inlife/nexrender) — опенсорсного оркестратора рендеринга
|
||||||
|
After Effects (лицензия MIT).
|
||||||
|
|
||||||
|
### Режимы работы
|
||||||
|
|
||||||
|
1. **Однократная обработка** (`--once` или без флагов):
|
||||||
|
- Подключение к NAS Synology
|
||||||
|
- Парсинг Excel данных
|
||||||
|
- Генерация и отправка заданий Nexrender
|
||||||
|
- Мониторинг завершения и выход
|
||||||
|
|
||||||
|
2. **Веб-сервер** (`--web`):
|
||||||
|
- Запуск веб-интерфейса на порту `:3000`
|
||||||
|
- Управление заданиями через браузер
|
||||||
|
- Автообновление статуса каждую минуту
|
||||||
|
|
||||||
|
## Особенности
|
||||||
|
|
||||||
|
- **Интеграция с Synology**: Аутентификация и загрузка файлов с NAS Synology
|
||||||
|
- **Экспорт офисных таблиц**: Автоматическое преобразование файлов .osheet в формат Excel
|
||||||
|
- **Гибкий парсинг данных**: Динамический парсинг листов с обнаружением заголовков
|
||||||
|
- **Множественная генерация вариантов**: Создание "Сегодня", "Завтра" и датированных версий
|
||||||
|
- **Умное управление логотипами**: Автоматическое разрешение и масштабирование логотипов
|
||||||
|
- **Веб-интерфейс**: Удобное управление и мониторинг заданий
|
||||||
|
- **REST API**: Программный доступ к управлению заданиями
|
||||||
|
- **Профессиональное логирование**: Структурированный журнал с настройкой уровня
|
||||||
|
|
||||||
|
## Предварительные требования
|
||||||
|
|
||||||
|
- Rust 1.70 или выше
|
||||||
|
- Доступ к NAS Synology с пакетами File Station и Office
|
||||||
|
- Экземпляр _server_ и _worker_(не менее одного) Nexrender
|
||||||
|
- Шаблоны After Effects (формат 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
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Настройка окружения
|
||||||
|
|
||||||
|
Скопируйте пример конфигурации и заполните своими данными:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp .env.example .env
|
||||||
|
```
|
||||||
|
|
||||||
|
Затем отредактируйте файл .env:
|
||||||
|
|
||||||
|
См. раздел Конфигурация для подробной информации.
|
||||||
|
|
||||||
|
## Использование
|
||||||
|
|
||||||
|
### Однократная обработка
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запуск с настройками по умолчанию
|
||||||
|
./target/release/ae_anons
|
||||||
|
|
||||||
|
# Явно указать однократный режим
|
||||||
|
./target/release/ae_anons --once
|
||||||
|
|
||||||
|
# С отладочным логированием
|
||||||
|
RUST_LOG=debug ./target/release/ae_anons
|
||||||
|
```
|
||||||
|
|
||||||
|
### Веб-сервер
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Запуск веб-интерфейса на порту по умолчанию (3000)
|
||||||
|
./target/release/ae_anons --web
|
||||||
|
|
||||||
|
# Или с указанием другого порта через .env файл
|
||||||
|
# WEB_PORT=8080 ./target/release/ae_anons --web
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## Веб-интерфейс
|
||||||
|
|
||||||
|
После запуска веб-сервера откройте браузер:
|
||||||
|
|
||||||
|
- Главная страница: <http://localhost:3000>
|
||||||
|
|
||||||
|
- API эндпоинты:
|
||||||
|
- `GET /api/jobs` - список всех заданий
|
||||||
|
- `POST /api/generate` - запуск генерации
|
||||||
|
- `POST /api/cleanup` - очистка завершённых
|
||||||
|
- `POST /api/jobs/stop-all` - остановка активных
|
||||||
|
- `GET /api/status` - статус сервера
|
||||||
|
|
||||||
|
## Уровни логирования
|
||||||
|
|
||||||
|
Управляйте детализацией вывода через переменную окружения `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` | Да | Сетевой путь для рендеренных видео |
|
||||||
|
| `TEMPLATE_DOUBLE_SRC` | Да | Путь к AEP-шаблону для двух команд |
|
||||||
|
| `TEMPLATE_SINGLE_SRC` | Да | Путь к AEP-шаблону для одной команды |
|
||||||
|
| `TEMPLATE_COMPOSITION` | Да | Имя композиции в проекте AE (например, `main`) |
|
||||||
|
| `TEMPLATE_OUTPUT_MODULE`| Да | Имя модуля вывода в AE (например, `h264`) |
|
||||||
|
| `TEMPLATE_OUTPUT_EXT` | Да | Расширение выходного файла (например, `mp4`) |
|
||||||
|
| `WEB_PORT` | Нет | Порт для веб-сервера (по умолчанию: 3000) |
|
||||||
|
| `RUST_LOG` | Нет | Уровень детализации логирования (по умолчанию: info) |
|
||||||
|
|
||||||
|
### Пример файла `.env`
|
||||||
|
|
||||||
|
```env
|
||||||
|
# Synology NAS
|
||||||
|
NAS_FQDN="https://your-nas.example.com"
|
||||||
|
NAS_USER="your_username"
|
||||||
|
NAS_PASS="your_password"
|
||||||
|
NAS_FILE="/Team Folder/path/to/file.osheet"
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
RUST_LOG="info"
|
||||||
|
|
||||||
|
# Web Server
|
||||||
|
WEB_PORT="3000"
|
||||||
|
|
||||||
|
# Nexrender
|
||||||
|
NEXRENDER_API_URL="http://nexrender-server:3050/api/v1/jobs"
|
||||||
|
OUTPUT_FOLDER="/path/to/output"
|
||||||
|
|
||||||
|
# After Effects Templates
|
||||||
|
TEMPLATE_DOUBLE_SRC="file:///path/to/double_team_template.aepx"
|
||||||
|
TEMPLATE_SINGLE_SRC="file:///path/to/single_team_template.aepx"
|
||||||
|
TEMPLATE_COMPOSITION="main"
|
||||||
|
TEMPLATE_OUTPUT_MODULE="h264"
|
||||||
|
TEMPLATE_OUTPUT_EXT="mp4"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Структура электронной таблицы
|
||||||
|
|
||||||
|
Файл 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. **Первый хеш**: Уникальный идентификатор для команд с одинаковыми названиями в одном виде спорта, или одинаковым названием в разных видах спорта.
|
||||||
|
Примеры:
|
||||||
|
|
||||||
|
- `Динамо#Футбол`, `Динамо#Волейбол` - Одно название разный вид спорта
|
||||||
|
- `Спартак#ЖенскийФ`, `Спартак#МужскойФ` Одно название _разный_ вид спорта
|
||||||
|
|
||||||
|
1. **Второй хеш**: Целевой размер в пикселях для масштабирования логотипа
|
||||||
|
|
||||||
|
Формат: `DisplayName#UniqueID#TargetSize`
|
||||||
|
|
||||||
|
Примеры:
|
||||||
|
|
||||||
|
- `Галатасарай#Turki` - только уникальный идентификатор
|
||||||
|
- `Сомбатей##400` - только целевой размер (обратите внимание на двойной хеш)
|
||||||
|
- `Спортинг#ll#550` - оба идентификатор и целевой размер
|
||||||
|
|
||||||
|
**Важно**: Обрабатывается **только второй хеш** для масштабирования логотипа. Если уникальный идентификатор не требуется, используйте двойной хеш ## перед целевым размером.
|
||||||
|
|
||||||
|
## Выходные файлы
|
||||||
|
|
||||||
|
### Рендеренные видео
|
||||||
|
|
||||||
|
Рендерные видео сохраняются в `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
|
||||||
|
|
||||||
|
Шаблоны должны быть предварительно настроены на узлах рендеринга со следующими именами слоёв.
|
||||||
|
|
||||||
|
### Файлы шаблонов
|
||||||
|
|
||||||
|
Настраиваются через переменные окружения:
|
||||||
|
|
||||||
|
| Переменная | Назначение | Пример значения |
|
||||||
|
|-------------------------|-------------------------------------|------------------------------------|
|
||||||
|
| `TEMPLATE_DOUBLE_SRC` | Шаблон для матчей с двумя командами | `file:///path/to/double.aepx` |
|
||||||
|
| `TEMPLATE_SINGLE_SRC` | Шаблон для анонсов с одной командой | `file:///path/to/single.aepx` |
|
||||||
|
| `TEMPLATE_COMPOSITION` | Имя главной композиции | `main` |
|
||||||
|
| `TEMPLATE_OUTPUT_MODULE`| Имя модуля вывода | `h264` |
|
||||||
|
| `TEMPLATE_OUTPUT_EXT` | Расширение выходного файла | `mp4` |
|
||||||
|
|
||||||
|
### Обязательные слои в шаблонах
|
||||||
|
|
||||||
|
#### Текстовые слои
|
||||||
|
|
||||||
|
| Имя слоя | Шаблон DOUBLE | Шаблон SINGLE | Описание |
|
||||||
|
|-----------|:-------------:|:-------------:|-------------------------------------------------|
|
||||||
|
| `DATA` | ✅ | ✅ | Отображение даты (автоматически подстраивается) |
|
||||||
|
| `TIME_H` | ✅ | ❌ | Часы (отдельный слой) |
|
||||||
|
| `TIME_M` | ✅ | ❌ | Минуты (отдельный слой) |
|
||||||
|
| `TIME` | ❌ | ✅ | Полное время (единый слой) |
|
||||||
|
| `LEAGUE` | ✅ | ✅ | Название лиги/турнира |
|
||||||
|
| `SPORT` | ✅ | ✅ | Категория спорта |
|
||||||
|
| `TEAMS` | ✅ | ✅ | Скомбинированные имена команд |
|
||||||
|
|
||||||
|
#### Слои с изображениями
|
||||||
|
|
||||||
|
| Имя слоя | Шаблон DOUBLE | Шаблон SINGLE | Описание |
|
||||||
|
|----------------|:-------------:|:-------------:|-----------------------------|
|
||||||
|
| `TEAM_A_LOGO` | ✅ | ✅ | Логотип команды A |
|
||||||
|
| `TEAM_B_LOGO` | ✅ | ❌ | Логотип команды B |
|
||||||
|
| `CHANELL` | ✅ | ✅ | Логотип канала (две буквы L)|
|
||||||
|
|
||||||
|
#### Видео слои
|
||||||
|
|
||||||
|
| Имя слоя | Шаблон DOUBLE | Шаблон SINGLE | Описание |
|
||||||
|
|-----------|:-------------:|:-------------:|----------------------------|
|
||||||
|
| `TOP` | ✅ | ✅ | Наложение видео оформления |
|
||||||
|
|
||||||
|
### Особенности шаблонов
|
||||||
|
|
||||||
|
#### Шаблон DOUBLE (две команды)
|
||||||
|
|
||||||
|
Используется когда в строке Excel заполнены оба поля `TEAM A` и `TEAM B`.
|
||||||
|
|
||||||
|
Обязательные слои:
|
||||||
|
|
||||||
|
- Все текстовые слои с `TIME_H` и `TIME_M` вместо `TIME`
|
||||||
|
- Оба логотипа команд: `TEAM_A_LOGO` и `TEAM_B_LOGO`
|
||||||
|
|
||||||
|
#### Шаблон SINGLE (одна команда)
|
||||||
|
|
||||||
|
Используется когда заполнено только одно поле команды.
|
||||||
|
|
||||||
|
Обязательные слои:
|
||||||
|
|
||||||
|
- Текстовый слой `TIME` вместо `TIME_H` и `TIME_M`
|
||||||
|
- Только логотип `TEAM_A_LOGO`
|
||||||
|
|
||||||
|
### Автоматические корректировки
|
||||||
|
|
||||||
|
AE Anons автоматически применяет следующие настройки к слоям:
|
||||||
|
|
||||||
|
#### Слой DATA
|
||||||
|
|
||||||
|
В зависимости от отображаемого текста и типа шаблона:
|
||||||
|
|
||||||
|
| Текст | Шаблон | Font Size | Anchor Point |
|
||||||
|
|------------|----------|-----------|--------------|
|
||||||
|
| "сегодня" | DOUBLE | 105 | [0, 5] |
|
||||||
|
| "завтра" | DOUBLE | 115 | [0, 25] |
|
||||||
|
| дата (<6) | DOUBLE | 120 | [0, 20] |
|
||||||
|
|
||||||
|
#### Слои TIME_H, TIME_M, TIME
|
||||||
|
|
||||||
|
Корректировка Anchor Point в зависимости от длины текста:
|
||||||
|
|
||||||
|
| Условие | Anchor Point |
|
||||||
|
|-------------------|--------------|
|
||||||
|
| 1 символ | [60, 0] |
|
||||||
|
| 2 символа, <20 | [20, 0] |
|
||||||
|
|
||||||
|
#### Слой LEAGUE
|
||||||
|
|
||||||
|
Если длина текста превышает 16 символов, размер шрифта уменьшается до 73.
|
||||||
|
|
||||||
|
#### Слой TEAMS
|
||||||
|
|
||||||
|
Если суммарная длина имён команд ≥ 32 символов, размер шрифта уменьшается до 55.
|
||||||
|
|
||||||
|
#### Логотипы (TEAM_A_LOGO, TEAM_B_LOGO)
|
||||||
|
|
||||||
|
Если в имени команды указан целевой размер через `#` (например, `Спортинг##550`), применяется выражение масштабирования:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
if (width > height) {
|
||||||
|
max_size = width;
|
||||||
|
} else {
|
||||||
|
max_size = height;
|
||||||
|
}
|
||||||
|
var real_size = 550 / max_size * 100;
|
||||||
|
[real_size, real_size]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Пример структуры слоёв в After Effects
|
||||||
|
|
||||||
|
Ниже представлен рекомендуемый порядок слоёв в композиции. Порядок важен для правильного наложения элементов.
|
||||||
|
|
||||||
|
```text
|
||||||
|
📁 main (композиция)
|
||||||
|
├── 🎬 TOP (видео слой) # Видео-оверлей (обязательный)
|
||||||
|
├── 📝 TEAMS (текстовый слой) # Имена команд (обязательный)
|
||||||
|
├── 📝 LEAGUE (текстовый слой) # Название лиги (обязательный)
|
||||||
|
├── 📝 SPORT (текстовый слой) # Вид спорта (обязательный)
|
||||||
|
├── 📝 DATA (текстовый слой) # Дата (обязательный)
|
||||||
|
├── 📝 TIME (текстовый слой) # Время (только SINGLE)
|
||||||
|
├── 📝 TIME_H (текстовый слой) # Часы (только DOUBLE)
|
||||||
|
├── 📝 TIME_M (текстовый слой) # Минуты (только DOUBLE)
|
||||||
|
├── 🖼️ CHANELL (слой изображения) # Логотип канала (обязательный)
|
||||||
|
├── 🖼️ TEAM_A_LOGO (слой изображения) # Логотип команды A (обязательный)
|
||||||
|
├── 🖼️ TEAM_B_LOGO (слой изображения) # Логотип команды B (только DOUBLE)
|
||||||
|
└── 🖼️ BOTTOM (слой изображения) # Фоновый слой (опционально)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Формат проекта и совместимость с After Effects
|
||||||
|
|
||||||
|
**Поддерживаемые форматы проектов:**
|
||||||
|
|
||||||
|
- `.aep` — стандартный бинарный формат After Effects (рекомендуется)
|
||||||
|
- `.aepx` — XML-формат проекта (поддерживается с AE CC 2015)
|
||||||
|
|
||||||
|
**Совместимость версий After Effects:**
|
||||||
|
|
||||||
|
| Версия After Effects | Поддерживаемые форматы | Особенности |
|
||||||
|
|----------------------|------------------------|-------------------------------------------------|
|
||||||
|
| CS 5.5 | `.aep` | Базовая поддержка |
|
||||||
|
| CC / CC 2014 | `.aep` | Полная поддержка |
|
||||||
|
| CC 2015 - CC 2019 | `.aep`, `.aepx` | Добавлена поддержка XML формата `.aepx` |
|
||||||
|
| CC 2020 - CC 2022 | `.aep`, `.aepx` | Рекомендуется использовать `.aep` |
|
||||||
|
| CC 2023 и новее | `.aep`, `.aepx` | **Требуется настройка Output Module** (см. ниже)|
|
||||||
|
|
||||||
|
> **⚠️ Важно для After Effects 2023+:**
|
||||||
|
>
|
||||||
|
> В версиях After Effects 2023 и новее критически важно настроить **Output Module** в шаблоне проекта. Бинарный файл рендеринга (`aerender`) не будет обрабатывать композицию без явно указанного модуля вывода, даже если в проекте используется модуль по умолчанию.
|
||||||
|
>
|
||||||
|
> AE Anons автоматически решает эту проблему, используя параметры `TEMPLATE_OUTPUT_MODULE` и `TEMPLATE_OUTPUT_EXT` из `.env` файла. Убедитесь, что эти значения соответствуют настройкам вашего шаблона.
|
||||||
|
|
||||||
|
### Настройки композиции
|
||||||
|
|
||||||
|
| Параметр | Переменная окружения | Пример значения | Описание |
|
||||||
|
|---------------------------|--------------------------|-----------------|---------------------------------------------|
|
||||||
|
| Имя композиции | `TEMPLATE_COMPOSITION` | `main` | Имя главной композиции в проекте AE |
|
||||||
|
| Выходной модуль | `TEMPLATE_OUTPUT_MODULE` | `h264` | Имя модуля вывода в AE |
|
||||||
|
| Расширение выходного файла| `TEMPLATE_OUTPUT_EXT` | `mp4` | Расширение выходного файла |
|
||||||
|
|
||||||
|
**Рекомендации по выбору формата:**
|
||||||
|
|
||||||
|
1. Используйте `.aep` для максимальной совместимости со всеми версиями AE
|
||||||
|
2. Версия After Effects на worker-машине должна быть не ниже версии, в которой создан проект
|
||||||
|
3. Для AE 2023+ убедитесь, что в шаблоне настроен Output Module с именем, указанным в `TEMPLATE_OUTPUT_MODULE`
|
||||||
|
|
||||||
|
**Источники:**
|
||||||
|
|
||||||
|
- [Nexrender - Tested with After Effects versions](https://github.com/inlife/nexrender#tested-with)
|
||||||
|
- [Adobe Aerender documentation](https://helpx.adobe.com/after-effects/using/automated-rendering-network-rendering.html)
|
||||||
|
|
||||||
|
## Устранение неисправностей
|
||||||
|
|
||||||
|
### Частые проблемы
|
||||||
|
|
||||||
|
#### Ошибка подключения к 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 управляет очередью заданий внутренне
|
||||||
|
|
||||||
|
## Примечания по безопасности
|
||||||
|
|
||||||
|
- Храните учетные данные только в файле `.env` (исключен из git)
|
||||||
|
- Используйте специальные аккаунты с минимально необходимыми правами
|
||||||
|
- Сессии Synology завершаются после выполнения
|
||||||
|
- HTTPS рекомендуется для подключений NAS в продакшене
|
||||||
|
|
||||||
|
## Разработка
|
||||||
|
|
||||||
|
### Структура кода
|
||||||
|
|
||||||
|
```shell
|
||||||
|
ae_anons/
|
||||||
|
├── .gitignore
|
||||||
|
├── .env.example
|
||||||
|
├── Cargo.toml
|
||||||
|
├── LICENSE
|
||||||
|
├── README.md
|
||||||
|
├── assets/
|
||||||
|
│ └── logo.png
|
||||||
|
└── src/
|
||||||
|
├── main.rs # Точка входа, CLI
|
||||||
|
├── config.rs # Конфигурация из .env
|
||||||
|
├── nexrender.rs # Модели заданий Nexrender
|
||||||
|
├── synology.rs # Клиент Synology API
|
||||||
|
├── processor.rs # Логика обработки
|
||||||
|
├── web.rs # Веб-сервер и API
|
||||||
|
└── static/
|
||||||
|
├── index.html # Веб-интерфейс
|
||||||
|
└── style.css # Стили
|
||||||
|
```
|
||||||
|
|
||||||
|
## Зависимости
|
||||||
|
|
||||||
|
### Основные зависимости
|
||||||
|
|
||||||
|
| Crate | Версия | Назначение |
|
||||||
|
|--------------------|---------|-----------------------------------------|
|
||||||
|
| reqwest | 0.12 | HTTP клиент для коммуникации с API |
|
||||||
|
| serde / serde_json | 1.0 | Сериализация и десериализация JSON |
|
||||||
|
| calamine | 0.26 | Парсинг файлов Excel (.xlsx, .xls) |
|
||||||
|
| chrono | 0.4 | Обработка дат и времени |
|
||||||
|
| tokio | 1.0 | Асинхронная среда выполнения |
|
||||||
|
| dotenv | 0.15 | Загрузка конфигурации из .env файла |
|
||||||
|
| log / env_logger | 0.4/0.11| Система логирования с уровнями |
|
||||||
|
| thiserror | 2.0 | Эргономичные определения типов ошибок |
|
||||||
|
| anyhow | 1.0 | Упрощённая обработка ошибок |
|
||||||
|
| regex | 1.11 | Регулярные выражения |
|
||||||
|
| urlencoding | 2.1 | Кодирование URL для API запросов |
|
||||||
|
| bytes | 1.9 | Работа с байтовыми данными |
|
||||||
|
| futures | 0.3 | Асинхронные примитивы |
|
||||||
|
|
||||||
|
### Веб-сервер и CLI
|
||||||
|
|
||||||
|
| Crate | Версия | Назначение |
|
||||||
|
|--------------------|--------|-----------------------------------------|
|
||||||
|
| axum | 0.8 | Веб-фреймворк для REST API |
|
||||||
|
| tower | 0.5 | Промежуточное ПО для веб-сервера |
|
||||||
|
| tower-http | 0.6 |HTTP утилиты (CORS, статика, трассировка)|
|
||||||
|
| askama | 0.15 | Шаблонизация (опционально) |
|
||||||
|
| clap | 4.5 | Парсинг аргументов командной строки |
|
||||||
|
|
||||||
|
### Платформозависимые зависимости
|
||||||
|
|
||||||
|
| Crate | Версия | Платформа | Назначение |
|
||||||
|
|--------------------|--------|-----------|----------------------------------|
|
||||||
|
| openssl | 0.10 | Linux | Криптография для HTTPS (vendored)|
|
||||||
|
|
||||||
|
## 🙏 Благодарности
|
||||||
|
|
||||||
|
Особая благодарность проекту **[Nexrender](https://github.com/inlife/nexrender)**
|
||||||
|
([@inlife](https://github.com/inlife) и контрибьюторам) за создание надёжной платформы
|
||||||
|
для автоматизации After Effects.
|
||||||
|
|
||||||
|
## Лицензия
|
||||||
|
|
||||||
|
**AE Anons** — [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.2.3 (текущая)
|
||||||
|
|
||||||
|
- Веб-интерфейс с настраиваемым портом (WEB_PORT)
|
||||||
|
- Улучшенное debug-логирование
|
||||||
|
- Исправлена обработка UNC/SMB путей
|
||||||
|
- Нормализация множественных пробелов в именах файлов"
|
||||||
|
|
||||||
|
### v0.2.2
|
||||||
|
|
||||||
|
- Исправлено отображение имён выходных файлов в веб-интерфейсе
|
||||||
|
|
||||||
|
- Улучшена цветовая схема
|
||||||
|
|
||||||
|
- Добавлена сортировка по всем колонкам
|
||||||
|
|
||||||
|
- Вынесены стили в отдельный CSS файл
|
||||||
|
|
||||||
|
### v0.2.0
|
||||||
|
|
||||||
|
- Добавлен веб-интерфейс для управления заданиями
|
||||||
|
|
||||||
|
- Реализован REST API
|
||||||
|
|
||||||
|
- Добавлена поддержка тёмной/светлой темы
|
||||||
|
|
||||||
|
- Автообновление статуса заданий
|
||||||
|
|
||||||
|
- Возможность остановки всех активных заданий
|
||||||
|
|
||||||
|
### v0.1.1
|
||||||
|
|
||||||
|
- Оптимизирована работа с памятью
|
||||||
|
|
||||||
|
- Убрана функция создания .json
|
||||||
|
|
||||||
|
### v0.1.0
|
||||||
|
|
||||||
|
- Первый выпуск
|
||||||
|
|
||||||
|
- Интеграция с Synology Office
|
||||||
|
|
||||||
|
- Базовая генерация заданий Nexrender
|
||||||
|
|
||||||
|
- Парсинг Excel с динамическим обнаружением листов
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Made with 🦀 Rust and ☕ coffee
|
||||||
BIN
releases/ae_anons-v0.2.3-windows-x64/ae_anons.exe
Executable file
BIN
releases/ae_anons-v0.2.3-windows-x64/ae_anons.exe
Executable file
Binary file not shown.
Reference in New Issue
Block a user