# Дорожная карта видеофич

Техническая консультация v1
22 марта 2026
ML/AI-инженер · Backend-архитектор · Remotion-инженер
Frontend-архитектор · DevOps-инженер · Инженер по производительности

## Общая картина

Всего фич
4
MVP все фичи
26–34 дня
Полные версии
44–65 дней
Один разработчик
6–8 недель

# | Фича | Сложность | MVP | Полная версия | Доп. инфраструктура
--- | --- | --- | --- | --- | ---
1 | Продвинутые шаблоны Remotion | Легко | 3–4 дня | 3–4 дня | Ничего
2 | Детекция вирусных моментов | Средне | 5–7 дней | 8–12 дней | API-ключ для LLM
3 | Авто-монтаж и трекинг лица | Сложно | 12–15 дней | 30–45 дней | Фаза 2: GPU-воркер
4 | Конвертация в Shorts (9:16) | Средне | 6–8 дней | +3–4 дня | Ничего

Реалистичный прогноз для одного разработчика: 6–8 недель (все MVP) или 3–4 месяца (полные версии).

## 1 Продвинутые шаблоны Remotion

Спецификация и план готовы

Что делаем: Расширяем `CaptionStyleSchema` четырьмя новыми стилями подсветки слов (`pop_in`, `karaoke`, `bounce`, `glow_pulse`), двумя переходами (`zoom_in`, `drop_in`), тремя полями (`word_entrance`, `highlight_rotation_deg`, `text_transform`). Добавляем два системных пресета: «Shorts» и «Podcast».

Где трогаем код: Расширение схемы в Remotion + бэкенде, логика рендеринга в `Captions.tsx`, Alembic-миграция для пресетов, контролы в StyleEditor на фронте.

Особый интерес специалистов не требуется — всё спроектировано, новой инфраструктуры нет. Самая безрисковая фича в этом списке.

Спецификация: `docs/superpowers/specs/2026-03-21-advanced-remotion-templates-design.md`
План: `docs/superpowers/plans/2026-03-21-advanced-remotion-templates.md`

## 2 Детекция вирусных моментов

За $0.005 за видео мы можем автоматически находить самые цепляющие фрагменты в подкастах и интервью. Пять копеек — и AI выкладывает тебе на блюдце моменты, которые зрители пересылают друг другу.

### Архитектура

LLM API: Gemini 2.5 Flash — лучшая поддержка русского языка, $0.15/$0.60 за 1М токенов. Альтернатива: GPT-4o-mini. Стоимость анализа одного 30-минутного видео: ~$0.005.

Аудио-подкрепление: `librosa` для кривых RMS-энергии — уточняет границы клипов до естественных пауз, повышает скор для энергичных сегментов. ~20МБ, обработка 30 мин аудио <10 секунд.

### Пайплайн

1. Берём транскрипцию из БД
2. `librosa` считает огибающую энергии (разрешение 100мс)
3. LLM анализирует текст через промпт со structured JSON output
4. Постобработка: привязка границ к точкам низкой энергии, расчёт energy-скоров
5. Сохраняем клипы в новую таблицу `clips`

### Бэкенд

Новый модуль: `clips` — хранит найденные клипы со связями project / file / job.

Модель клипа:

    Clip {
      project_id: UUID (FK projects)
      source_file_id: UUID (FK files)
      job_id: UUID? (FK jobs)
      title: str
      start_ms: int
      end_ms: int
      score: float
      source_type: "viral_detected" | "user_created" | "auto_generated"
      status: "pending" | "approved" | "rejected" | "exported"
      meta: JSON? (рассуждения LLM, теги, хэштеги)
    }

Новый тип джоба: `VIRAL_DETECT` в `JobTypeEnum`. Актор вызывает LLM API через `httpx` из Dramatiq-воркера.

### Фронтенд

- Новый `ViralClipsStep` в визарде проекта
- Список клипов с превьюшками, скорами, кнопками принять/отклонить
- Модалка редактирования клипа с видео-превью
- Новый тип джоба `VIRAL_DETECT` в обработке нотификаций

### Ключевые цифры

Метрика | Значение
--- | ---
Точность (precision) | 50–70%
Полнота (recall) | 60–80%
Время обработки | 10–20 секунд
Стоимость за видео | ~$0.005
1 000 видео/месяц | ~$5
Новые зависимости | ~30 МБ

10–20 секунд и пять долларов за тысячу видео. Вдумайтесь в эти цифры.

### Риски

!
Качество промпт-инжиниринга определяет ценность фичи — придётся итерировать по фидбеку
!
Визуальные моменты (мимика, физическая комедия) из текста не ловятся — ~20–30% проходят мимо
!
Качество транскрипции критично — Whisper `tiny` даёт ~25% WER; для вирусной детекции минимум `small`
!
LLM галлюцинирует таймстемпы — обязательно валидировать метки времени

### MVP vs Полная версия

#### MVP (5–7 дней)

Только текстовый анализ через LLM, без аудио-энергии. Возвращает клипы со скорами. Пользователь ревьюит и принимает/отклоняет.

#### Полная (8–12 дней)

Добавляем librosa-анализ энергии, few-shot примеры из принятых клипов, пакетную обработку, прямой экспорт в 9:16.

## 3 Авто-монтаж и трекинг лица

Самая амбициозная фича. Самая сложная. Загружаете подкаст с двумя спикерами — на выходе динамичное вертикальное видео, где камера сама «следит» за говорящим.

### Архитектура

Детекция лиц: MediaPipe BlazeFace (Apache 2.0, ~2МБ модель, 30–60 FPS на CPU). Сэмплируем на 3 FPS. Зависимость: `mediapipe` (~30МБ).

Диаризация спикеров: pyannote.audio 3.1 (MIT, ~10% DER, self-hosted). CPU: 0.17–0.33x реального времени. GPU: 1–2 мин на 30 мин аудио. Зависимости: `pyannote-audio` (~200МБ) + `torchaudio` (~50–80МБ).

Маппинг лицо-спикер:

- Фаза 1: Эвристика по временной корреляции. 70–85% точности для двух спикеров. ~100 строк Python.
- Фаза 2: TalkNet-ASD — анализ губ + аудио. 92.3% точности. Нужен GPU.

### Видео-композитинг (Remotion)

Динамический кроп через CSS `transform: scale() translate()` на `<Video>` внутри контейнера с `overflow: hidden`. GPU-ускоренная браузерная операция — бесплатная по производительности.

### Новые Remotion-композиции

Композиция | Назначение | Фаза
--- | --- | ---
`CaptionedVideo` | Наложение субтитров (существует) | Текущая
`ShortsVideo` | Статический кроп + субтитры в 9:16 | Фича 4
`AutoEditVideo` | Кроп с трекингом лица + монтаж + субтитры | Фича 3

### Формат данных кропа

    type FaceKeyframe = {
      time: number;       // секунды
      x: number;          // центр лица, 0.0–1.0
      y: number;          // центр лица, 0.0–1.0
      width: number;      // ширина bbox, 0.0–1.0
      height: number;     // высота bbox, 0.0–1.0
      speakerId?: string;
    };

    type CropTrack = {
      keyframes: FaceKeyframe[];
      interpolation: "linear" | "ease" | "smooth";
      zoom: number;       // базовый множитель зума
      safeMargin: number; // отступ вокруг лица (0.1 = 10%)
    };

### Бэкенд

Новые типы джобов: `FACE_DETECT`, `SPEAKER_DIARIZE`. Результаты хранятся в `Job.output_data` (JSON).

Отделение ML-сервиса:

- Фаза 1: В Dramatiq-воркерах. MediaPipe + pyannote добавляют ~280МБ к образу.
- Фаза 2: Отдельный контейнер `ml-worker` на выделенных очередях Dramatiq.

### Время обработки (30-мин 1080p видео)

Шаг | CPU | GPU
--- | --- | ---
Извлечение аудио (FFmpeg) | 10–20 сек | 10–20 сек
Детекция лиц (MediaPipe, 3 FPS) | 1–2 мин | 10–15 сек
Диаризация спикеров (pyannote) | 15–30 мин | 1–2 мин
Маппинг лицо-спикер | < 1 сек | < 1 сек
Рендер Remotion | 10–30 мин | 10–30 мин
Итого | 35–80 мин | 16–40 мин

### Требования к памяти

Конфигурация | Пиковое потребление RAM
--- | ---
Whisper base + pyannote (параллельно) | 8–12 ГБ
Whisper medium + pyannote (параллельно) | 12–16 ГБ
Рекомендуемый лимит ML-воркера | 16 ГБ, `--threads 1`

### Фронтенд

- Превью трекинга лица: видеоплеер с наложением bounding box через canvas
- Трек спикеров в TimelinePanel
- Контролы: слайдер зума, скорость перехода, выбор спикера
- Переключатель «до/после»

### Ключевые цифры

Метрика | Значение
--- | ---
Точность детекции лиц | ~90%
DER диаризации | ~10%
Маппинг Фаза 1 | 70–85%
Маппинг Фаза 2 (TalkNet) | ~92%
Новые зависимости | ~280 МБ
GPU обязателен? | Нет для Фазы 1

### Риски

!
Маппинг лицо-спикер — каждое пятое назначение может быть неверным. Нужна ручная корректировка.
!
Диаризация на CPU — бутылочное горлышко. 15–30 мин на 30-мин видео.
!
Конфликты PyTorch между Whisper и pyannote.
!
Потеря качества при кропе 16:9 → 9:16 — остаётся ~31.6% ширины. Минимум 1080p.
!
Скачивание моделей pyannote (~100МБ) требует принятия лицензии HF. Обрабатывать в Dockerfile.

### MVP vs Полная версия

#### MVP (12–15 дней)

Детекция лиц. Пользователь выбирает лицо вручную. Статический кроп. Без диаризации. Один спикер.

#### Полная (30–45 дней)

Диаризация + маппинг. Динамический кроп за активным спикером. Spring()-переходы. Сплит-скрин. Несколько спикеров.

## 4 Конвертация в вертикальные Shorts (9:16)

### Архитектура

Сначала кроп, потом субтитры — всегда. Один проход рендеринга через новую композицию `ShortsVideo`.

Спецификация кропа:

    type CropConfig = {
      mode: "static" | "keyframe";
      staticCrop?: { x: number; y: number; zoom: number };
      keyframes?: Array<{ time: number; x: number; y: number; zoom: number }>;
      interpolation?: "linear" | "ease" | "smooth";
    };

### Бэкенд

- Новый тип джоба: `ASPECT_CONVERT`
- Новый тип артефакта: `VERTICAL_VIDEO`
- Функция `crop_to_vertical()` в `media/service.py`

### Фронтенд

- Превью кропа: перетаскиваемый прямоугольник 9:16 поверх видеоплеера
- Side-by-side: оригинал 16:9 vs обрезанное 9:16
- Интеграция с Фичей 2: кнопка «Конвертировать в Short» на каждом клипе
- Интеграция с Фичей 3: авто-кроп из данных детекции лица

### Время обработки

Подход | 30-мин видео
--- | ---
FFmpeg кроп (без субтитров) | 12–36 мин
Remotion кроп + субтитры | 11–45 мин
FFmpeg с NVENC | 3–5 мин

### MVP vs Полная версия

#### MVP (6–8 дней)

Ручной выбор кропа. Перетаскиваемый прямоугольник. `ShortsVideo` рендерит кроп + субтитры.

#### Полная (+3–4 дня)

Авто-кроп из трекинга лица. Конвертация в один клик. Пакетная обработка.

## Рекомендуемый порядок разработки

Неделя 1–2
Шаблоны
Неделя 2–4
Вирусная детекция
Неделя 4–6
9:16 кроп MVP
Неделя 6–14
Трекинг лица
Неделя 14–15
9:16 апгрейд

### Почему именно так

1. Шаблоны первыми — готовы к реализации, нулевой риск, моментальная польза
2. Вирусная детекция второй — лучшее соотношение пользы к трудозатратам ($0.005/видео)
3. 9:16 MVP третьим — создаёт `ShortsVideo`, которую расширит Фича 3
4. Трекинг лица последним — самая сложная; к этому моменту спрос уже валидирован
5. Апгрейд 9:16 — тривиален, когда трекинг лица уже даёт позиции

## Анализ стоимости

### Стоимость обработки одного видео

Уровень | Состав | Вычисления | LLM API | Итого | Время
--- | --- | --- | --- | --- | ---
Только CPU | Всё на CPU | $0.05 | $0.06 | $0.11 | 35–80 мин
GPU (T4) | ML на GPU | $0.11 | $0.06 | $0.17 | 16–40 мин
GPU + NVENC | Всё на GPU | $0.13 | $0.06 | $0.19 | 10–15 мин

Одиннадцать центов на CPU. Девятнадцать с GPU. Меньше двадцати центов за полный пайплайн с AI-анализом, трекингом лица и кодированием видео.

### Месячная стоимость инфраструктуры (100 видео/мес)

Сценарий | Стоимость
--- | ---
Только CPU (текущая инфра) | ~$11 + сервер
Modal serverless GPU | ~$21/мес
Spot GPU (g4dn.xlarge) | ~$115/мес
Постоянный GPU | ~$380/мес

Рекомендация: Начинаем на CPU. Переходим на Modal serverless GPU, когда время ожидания в очереди превышает 15 минут. При 500+ видео/день — смотрим на spot-инстансы.

### Предлагаемые тарифы SaaS

Тариф | Цена | Ограничения | Себестоимость | Маржа
--- | --- | --- | --- | ---
Free | $0 | Видео до 10 мин, низкий приоритет | ~$0.04/видео | Маркетинг
Pro | $15–30/мес | Видео до 30 мин, GPU ML | ~$0.17 при 50 видео | 60–80%
Business | $50–100/мес | Видео до 60 мин, приоритет, NVENC | ~$0.38/видео | 70–85%

## Инфраструктурные решения

### Отделение ML-сервиса

#### Фаза 1

ML в Dramatiq-воркерах. MediaPipe + pyannote добавляют ~280МБ. PyTorch уже установлен через Whisper.

#### Фаза 2

Отдельный `ml-worker` контейнер. Тот же код, другой образ (`Dockerfile.ml`), другие лимиты ресурсов.

    docker-compose up                    # По умолчанию: без ML-воркера
    docker-compose --profile ml up       # С ML-воркером

НЕ строить отдельный HTTP-микросервис. Dramatiq уже обеспечивает очередь джобов, ретраи, прогресс и отмену. HTTP service discovery — оверхед с нулевой пользой для асинхронных нагрузок.

### Немедленные оптимизации

Действие | Эффект | Трудозатраты
--- | --- | ---
PyTorch на CPU-only индекс | -800МБ образ | 1 час
Исправить `REMOTION_SERVICE_URL` | Баг-фикс | 5 мин
Лимиты ресурсов docker-compose | Предотвращение каскадных OOM | 30 мин
Пулы очередей Dramatiq | Предотвращение голодания воркеров | 2–3 часа

Четыре задачи. Суммарно полдня. Экономия: 800МБ, один баг, и страховка от OOM.

## Сводка по технологическому стеку

### Новые зависимости

Пакет | Размер | Назначение | Фича
--- | --- | --- | ---
`google-generativeai` / `openai` | ~10 МБ | LLM API клиент | 2
`librosa` | ~20 МБ | Анализ энергии аудио | 2
`mediapipe` | ~30 МБ | Детекция лиц | 3
`pyannote-audio` | ~200 МБ | Диаризация спикеров | 3
`torchaudio` | ~50–80 МБ | Обработка аудио | 3
Итого | ~310–340 МБ |  |

### Новые модули, композиции, типы джобов

Элемент | Назначение | Фича
--- | --- | ---
Модуль `clips` | CRUD клипов, ревью | 2
Композиция `ShortsVideo` | Статический кроп + субтитры 9:16 | 4
Композиция `AutoEditVideo` | Динамический кроп + субтитры | 3
Джоб `VIRAL_DETECT` | LLM-анализ транскрипции | 2
Джоб `ASPECT_CONVERT` | 9:16 кроп | 4
Джоб `FACE_DETECT` | Детекция лиц | 3
Джоб `SPEAKER_DIARIZE` | Диаризация | 3

## Сквозные проблемы

Шесть специалистов — шесть взглядов на одну кодовую базу.

Проблема | Кто | Приоритет | Действие
--- | --- | --- | ---
PyTorch тащит CUDA (+800МБ) | DevOps | Высокий | CPU-only PyTorch индекс
Воркер упадёт по OOM на ML-джобах | Performance | Высокий | Пулы очередей, `--threads 1`
`_get_job_status_sync()` течёт соединениями | Performance | Высокий | Починить до новых акторов
Нет очистки `/tmp` при OOM | Performance | Средний | Периодическая очистка / cron
`tasks/service.py` — 1 674 строки | Backend | Средний | Декоратор/контекст-менеджер
`REMOTION_SERVICE_URL` неверный | DevOps | Средний | Исправить на `http://remotion:3001`
Нет лимитов ресурсов Docker | DevOps | Средний | Добавить memory/CPU лимиты
Whisper в ML-сервис | Backend | Низкий | Запланировать при Фазе 2
`isCurrent` в Captions.tsx | Remotion | Низкий | Сравнивать по индексу

## Отчёты специалистов

Ключевые файлы, которые изучал каждый:

- ML-инженер: `transcription/service.py`, `tasks/service.py`, `pyproject.toml`
- Backend-архитектор: `tasks/service.py`, `jobs/schemas.py`, `media/service.py`, `captions/service.py`, `docker-compose.yml`
- Remotion-инженер: `Composition.tsx`, `Captions.tsx`, `Root.tsx`, `useCaptions.ts`, все типы
- Frontend-архитектор: `TimelinePanel/`, `FragmentsStep/`, `WizardContext.tsx`, `notifications/`
- DevOps-инженер: `docker-compose.yml`, `Dockerfile`, `pyproject.toml`, `uv.lock`
- Инженер по производительности: `tasks/service.py`, `media/service.py`, `transcription/service.py`, `docker-compose.yml`