# Видеоконвейер канала «Энергия | Квинтэссенция»
Визуальная версия: energy-editorial-v1. Утверждена владельцем 1 октября 2026.
Этот формат закреплен за YouTube-каналом энергии
UCPVtwV3NNypUqkPF8cBWJbg. Другие четыре канала не получают этот шаблон
и его очередь автоматически. Все даты и расписание — по Москве.
## Что фиксируем
Белый фон #ffffff, графит #181916, оранжевый #f77e36.
Manrope, заголовки 92 px / 800, неподвижное выравнивание слева.
Один и тот же женский персонаж: согласованный PNG с прозрачностью.
Согласованные предметы: хромированный секундомер и смартфон.
Сцены: персонаж, крупный кроп персонажа, секундомер, сообщения на телефоне,
два вопроса, бесконечность. Оранжевое выделение раскрывается один раз.
Нет английского названия проекта, нижних служебных блоков, скачущих аватаров.
Нельзя автоматически заменять персонажа, ассеты, палитру или анимационную основу.
Контрольные SHA-256 защищают утвержденные файлы от случайной замены.
## Кто что делает
1. Владелец один раз утверждает сценарный промпт и дает команду запуска.
В дальнейшем обновляет карточку проекта/промпт, количество и окно публикаций.
2. systemd на VDS запускает проверку каждые 30 минут, в том числе после
перезагрузки сервера. Чат, Mac и работающий Codex для этого не нужны.
3. Планировщик смотрит очередь, а не количество файлов в папке.
Поддерживает запас на три дня: при цели 2 ролика/сутки это до шести задач.
Время выбирается один раз и сохраняется: 10:00–21:30 МСК, разные минуты
и секунды, минимум три часа между выходами. Перезапуск время не меняет.
4. Сценарист — существующий OpenAI API, модель gpt-4o-mini.
За один запрос создаются до двух сценариев с названием, описанием,
конкретной ситуацией, выводом и 8–10 сценами. Перед каждым пакетом читаются
текущая карточка проекта, сценарный промпт и недавние темы из памяти.
В историю запроса помещается ограниченный объем, а сравнение дублей
проводится со всем сохраненным архивом этой ветки.
5. Редактор — серверные проверки: структура, длина, отсутствие служебного
текста/показателей платформы, ширина строк, допустимые сообщения,
разнообразие сцен и сходство с прошлыми сценариями. Отбракованный сценарий
не озвучивается и не рендерится. До четырех попыток с увеличением пауз.
6. Озвучка — существующий Яндекс SpeechKit: marina, friendly, speed=0.9.
Один запрос на весь ролик, без оплаты за каждую сцену отдельно.
Ответ разбирается как поток JSON. Аудио сохраняется в WAV 48 кГц;
словесные тайминги определяют точные границы сцен. Без совпадающих
таймингов ролик блокируется, приблизительная синхронизация не подставляется.
Словарь произношения хранится отдельно. Автоматическая проверка не
гарантирует правильность всех русских ударений: спорные слова добавляются
в словарь по результатам прослушивания.
7. Кэш голоса — SHA-256 текста, произношения, голоса, роли и скорости.
Повторная сборка с тем же звуком не вызывает новый платный запрос.
8. Визуальная сборка — Remotion на VDS. Сценарий выбирает готовые композиции,
подставляет короткие титры и сообщения. Ассеты переиспользуются.
ImageGen был нужен для создания персонажа и предметов один раз.
HeroUI — библиотека интерфейсов, для каждого рендера не вызывается.
PictureBooks/сторонние генераторы и новая генерация картинки на каждый ролик
в этом утвержденном формате не нужны.
Шаблон компилируется один раз в отдельный renderer-bundle этой ветки.
Следующие ролики используют эту сборку: повторная компиляция не расходует
CPU/RAM на каждый выпуск. Качество и разрешение не снижаются.
9. Финальный файл — FFmpeg: MP4/H.264, 1080×1920, 30 fps, yuv420p,
цвет BT.709, звук AAC, faststart. Нагрузка ограничена, рендерится один ролик.
10. Проверка — полное декодирование MP4, параметры видео/аудио, длительность,
слышимость, кадр каждой сцены, горизонтальные границы заголовков,
непустой визуал и смена сцен. Получаются master.mp4, preview.jpg,
contact.jpg, script.json, props.json и qa.json.
Эти проверки отсеивают технический брак, но не заменяют человеческую
оценку юмора, аргументов, эстетики и произношения.
11. Только прошедший проверку ролик получает статус «Готов к публикации».
На этом производство может работать при выключенном постинге.
12. Публикатор — официальный YouTube API, отдельный OAuth-токен энергии.
Перед загрузкой проверяются канал, контрольная сумма MP4 и QA.
Загрузка возобновляемая: URL сессии сохраняется в закрытой базе.
После сетевого сбоя проверяется та же сессия, а не создается новое видео.
Неоднозначный ответ без сохраненной сессии требует сверки, слепой повтор
запрещен. «Опубликовано» ставится после проверки правильного канала,
public-видимости и завершенной обработки YouTube.
13. Дашборд показывает реальные состояния, ближайшую очередь, готовые файлы,
ошибки, дату обновления и включение производства/постинга отдельно.
14. Через пять суток после подтвержденной публикации удаляются тяжелые
файлы данного выпуска. Неопубликованные ролики, ассеты и голосовой кэш
защищены. Сценарии, отчеты, хэши, темы и выводы остаются в SQLite навсегда.
## Очередь и защита от повторов
Состояния: planned → script_ready → rendering → ready → uploading →
uploaded → published. Ошибки имеют счетчик попыток и retry_at.
Процесс защищен файловой блокировкой: два worker одновременно не работают.
SQLite сохраняет состояние транзакционно. Прерванный рендер возобновляется
после перезапуска; сценарий и кэш голоса переиспользуются.
Память содержит нормализованный текст, SHA-256, ситуацию, вывод и SHA-256 MP4.
Сравниваются точные совпадения, лексическое сходство текста, темы и вывода.
Также импортируется имеющаяся память контент-завода по проекту q-energy.
Похожие по смыслу, но полностью перефразированные тексты алгоритм может
пропустить: это практическая защита, а не математическая гарантия уникальности.
Одинаковый персонаж и оформление не считаются дублем: это утвержденный стиль.
## Папки на сервере
Реестр `config/video/profiles.json` хранит привязку проект → канал → профиль.
Диспетчер запускает утвержденные профили последовательно каждые 30 минут.
Другие каналы зарегистрированы как `waiting_visual_selection`: они не получают
персонажа энергии и не запускают генерацию. После согласования для каждого
создаются собственные config.json, assets.lock.json, сценарный промпт и словарь
произношения. Очередь, файлы и кэш лежат раздельно в
`data/projects/<project>/video/<channel>/<profile>` и
`storage/projects/<project>/video/<channel>/<profile>`.
Старый путь энергии сохранен без переноса. Новый профиль использует контракт
`editorial-scenes-v1`; другой тип монтажа подключается отдельным адаптером,
а не автоматической подменой утвержденной композиции. Проверяются ID канала
и OAuth token_id, подставлять токен одного канала в другой запрещено.
```text
/opt/content-factory/
config/video/energy-editorial-v1/
config.json # Два выключателя, частота, голос, лимиты
assets.lock.json # Хэши утвержденного шаблона и ассетов
pronunciation.json # Словарь спорных ударений
config/prompts/energy_editorial_v1/script.md
src/content_factory/energy_video_factory.py
data/projects/q-energy/video/energy-editorial-v1/
factory.sqlite # Очередь и постоянная память
worker.lock
storage/projects/q-energy/video/energy-editorial-v1/
voice-cache/<hash>/voice.wav
voice-cache/<hash>/timings.json
episodes/<id>/master.mp4
episodes/<id>/script.json
episodes/<id>/props.json
episodes/<id>/qa.json
episodes/<id>/preview.jpg
episodes/<id>/contact.jpg
video-renderer/remotion-v13/src/QEnergyEditorial.tsx
video-renderer/remotion-v13/src/editorial-ref/Design.tsx
video-renderer/remotion-v13/public/q-editorial-*.png
data/energy_video_factory_status.json
```
Не создаются новые модели на 5–10 ГБ и не требуется GPU.
Рендер: одна задача, CPU 75%, память максимум 850 МБ, запуск при
доступной памяти >=850 МБ и диске >=4 ГБ. Кодирование ограничено одним
потоком; процесс имеет повышенный OOMScoreAdjust=800, чтобы при аварийной
нехватке памяти ядро предпочитало остановить его. Ограничения не резервируют
память и не гарантируют изоляцию при любой внешней нагрузке. При нехватке
ресурсов worker откладывает производство, не исчерпывая попытки сценария;
проверка/публикация уже готовых роликов остается отдельным этапом.
## Экономия и лимиты
LLM: максимум 16 000 зарезервированных токенов за сутки; резерв считается
консервативно до запроса и включает потенциальный ответ. Это защитный лимит,
не фактическая стоимость. Ошибки и повторные запросы также учитываются.
Яндекс: максимум 5000 символов нового синтеза/сутки. Запросы с кэшем бесплатны.
Новых платных сервисов не подключено. Яндекс-озвучка и генерация сценариев
через существующие API оплачиваются по их тарифам; подписка на чат их не покрывает.
## Как запускать после сценарного апгрейда
Текущий режим: visual_approved=true, scripts_approved=false,
production_enabled=false, publishing_enabled=false.
systemd timer включен и проверяет состояние, но не делает платных запросов,
не создает очередь производства и не загружает ролики при этих настройках.
После внедрения нового сценарного ТЗ устанавливается scripts_approved=true.
Команда владельца «начнем производство» включает только производство:
```sh
cd /opt/content-factory
PYTHONPATH=src python3 -m content_factory.energy_video_factory enable-production
systemctl start content-factory-energy-video.service
```
Постинг включается отдельной командой владельца. Текущий OAuth имеет только
youtube.upload. Для проверки выбранного канала и результата нужно добавить
youtube.readonly, открыть ссылку и выбрать канал энергии:
https://content.myquintessence.ru/oauth/youtube/start?token_id=q-energy-youtube-main&project_id=q-energy&channel_key=youtube&verify=1
Проекты Google API без необходимого аудита могут принудительно оставлять
видео приватными; при этом система не покажет ложный статус публикации.
Фактическая загрузка не тестируется до разрешения владельца.
Официальные источники:
https://developers.google.com/youtube/v3/docs/videos/insert
https://developers.google.com/youtube/v3/guides/using_resumable_upload_protocol
https://aistudio.yandex.ru/en/docs/speechkit/tts-v3/api-ref/Synthesizer/utteranceSynthesis
```sh
PYTHONPATH=src python3 -m content_factory.energy_video_factory enable-publishing
```
Остановить только эту ветку:
```sh
PYTHONPATH=src python3 -m content_factory.energy_video_factory pause
```
Instagram, TikTok и другие YouTube-каналы не включаются этой командой.
Дублирование энергии во ВК подготовлено в общей инфраструктуре, но в новой
ветке выключено и не заявлено как работающая публикация в VK Clips.