Files
remotion_service/docs/consults/video-features-roadmap_v1_ru.md
2026-03-22 22:42:35 +03:00

31 KiB
Raw Permalink Blame History

Дорожная карта видеофич — Техническая консультация v1

Дата: 22 марта 2026 Консультанты: ML/AI-инженер, Backend-архитектор, Remotion-инженер, Frontend-архитектор, DevOps-инженер, Инженер по производительности


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

Четыре фичи. От простого к безумному. Вот что получается, если разложить всё по полочкам:

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

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


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

Статус: Спецификация и план реализации уже написаны. Бери и делай.

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

Что делаем: Расширяем 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 на фронте.

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


Фича 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 (models, schemas, repository, service, router) — хранит найденные клипы со связями 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-воркера — отдельный сервис не нужен.

Интеграция с LLM:

  • Прямой HTTP-вызов из актора с retry + exponential backoff на 429
  • Промпты хранятся в cpv3/infrastructure/prompts/viral_detection_v1.txt
  • Активная версия контролируется через env-переменную LLM_VIRAL_PROMPT_VERSION
  • Новые настройки: LLM_API_URL, LLM_API_KEY, LLM_MODEL_NAME

Фронтенд

  • Новый ViralClipsStep в визарде проекта (features/project/)
  • Список клипов с превьюшками, скорами, заголовками, кнопками принять/отклонить
  • Модалка редактирования клипа с видео-превью (воспроизведение ограничено диапазоном start/end)
  • Новый тип джоба VIRAL_DETECT в обработке нотификаций (через существующую WebSocket-инфраструктуру)

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

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

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

Риски

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

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

  • MVP: Только текстовый анализ через LLM, без аудио-энергии. Возвращает клипы со скорами. Пользователь ревьюит и принимает/отклоняет.
  • Полная: Добавляем librosa-анализ энергии, few-shot примеры из принятых пользователем клипов, пакетную обработку, прямой экспорт клипов в 9:16.

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

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

Архитектура

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

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

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

  • Фаза 1: Эвристика по временнОй корреляции — сопоставляем треки лиц с сегментами спикеров по максимальному пересечению во времени. 70-85% точности для видео с двумя спикерами. Ноль дополнительных зависимостей. Около 100 строк Python.
  • Фаза 2: TalkNet-ASD (Active Speaker Detection) — совместный анализ движения губ и аудио для определения, кто говорит. 92.3% точности. Требует torchvision + веса модели (~50МБ). Нужен GPU (2-5 FPS на CPU vs 15-25 FPS на GPU).

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

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

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

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

Все композиции разделяют компонент <Captions> и хук useCaptions.

Формат данных кропа (ключевые кадры):

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

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

Remotion interpolate() между ключевыми кадрами для плавного панорамирования/зума. spring() используется только для жёстких переключений между спикерами.

Бэкенд

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

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

  • Фаза 1: Оставляем в Dramatiq-воркерах (тот же образ). MediaPipe + pyannote добавляют только ~280МБ к образу.
  • Фаза 2: Отдельный Docker-контейнер ml-worker на выделенных очередях Dramatiq (ml_head_tracking, ml_diarization). Тот же код, другой образ, другие лимиты ресурсов.

Изменения в Remotion-сервисе: POST /api/render нужен параметр compositionId для выбора композиции. Props расширяются полями crop, outputWidth, outputHeight.

Время обработки (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 мин

Детекция лиц и диаризация могут работать параллельно — у них разные входные данные (видеокадры vs аудиодорожка).

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

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

Фронтенд

  • Превью трекинга лица: видеоплеер с наложением bounding box через canvas
  • Трек спикеров в TimelinePanel (расширяет существующую систему из 4 треков)
  • Контролы: слайдер уровня зума, скорость перехода, выбор спикера
  • Переключатель сравнения «до/после»
  • UX-флоу: загрузка подкаста -> запуск анализа (ProcessingStep) -> ревью назначений спикеров -> корректировка -> экспорт

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

Метрика Значение
Точность детекции лиц ~90% (MediaPipe на talking-head контенте)
DER диаризации ~10% (pyannote 3.1)
Точность маппинга лицо-спикер (Фаза 1) 70-85%
Точность маппинга лицо-спикер (Фаза 2, TalkNet) ~92%
Новые зависимости ~280МБ (mediapipe + pyannote + torchaudio)
GPU обязателен? Нет для Фазы 1; рекомендуется для Фазы 2

Риски

  • Маппинг лицо-спикер — главная нерешённая подзадача. Точность 70-85% означает, что каждое пятое назначение может быть неверным. Пользователь должен иметь возможность поправить вручную.
  • Диаризация на CPU — бутылочное горлышко. 15-30 минут на 30-минутное видео. GPU сокращает до 1-2 минут.
  • Конфликты версий PyTorch между Whisper и pyannote — обязательно тестировать uv sync перед коммитом.
  • Потеря качества видео при кропе 16:9 -> 9:16 — остаётся только ~31.6% ширины кадра. Исходник должен быть минимум 1080p.
  • Скачивание моделей при первом запуске — модели pyannote (~100МБ) требуют принятия лицензии на Hugging Face. Обрабатывать в Dockerfile, не в рантайме.

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

  • MVP (12-15 дней): Детекция лиц на сэмплированных кадрах. Пользователь вручную выбирает, за каким лицом следить. Статический кроп на выбранное лицо. Без переключения спикеров, без диаризации. Работает для одного спикера.
  • Полная (30-45 дней): Диаризация + маппинг лицо-спикер. Динамический кроп, следующий за активным спикером. Плавные spring()-переходы при смене спикеров. Сплит-скрин для реакций. Поддержка нескольких спикеров.

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

Архитектура

Пайплайн: Сначала кроп, потом субтитры — всегда. Один проход рендеринга в Remotion через новую композицию ShortsVideo. Композиция рендерит в целевых размерах 9:16, применяет CSS-кроп к <Video> и накладывает субтитры поверх.

Позиционирование субтитров: Новые поля в схеме не нужны. Бэкенд корректирует font_size, padding_px, max_width_pct в styleConfig под соотношение 9:16. Remotion — это «глупый рендерер»: логика о том, что выглядит хорошо в 9:16, живёт в пресетах.

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

type CropConfig = {
  mode: "static" | "keyframe";
  staticCrop?: { x: number; y: number; zoom: number };  // 0-1 нормализовано
  keyframes?: Array<{ time: number; x: number; y: number; zoom: number }>;
  interpolation?: "linear" | "ease" | "smooth";
};

Статический кроп — вырожденный случай ключевого кропа (один ключевой кадр).

Бэкенд

Новый тип джоба: ASPECT_CONVERT в JobTypeEnum. Новая функция crop_to_vertical() в media/service.py через FFmpeg crop+scale фильтр.

Новый тип артефакта: VERTICAL_VIDEO в ArtifactTypeEnum.

Пайплайн:

  1. Обрезка исходного видео до временного диапазона клипа (если из вирусной детекции)
  2. Применение кропа (статический центральный кроп или face-tracking кроп из Фичи 3)
  3. Загрузка в S3 по пути {folder}/vertical/{filename}
  4. Webhook + нотификация

Фронтенд

  • Превью кропа: перетаскиваемый прямоугольник 9:16 поверх видеоплеера (CSS object-fit: cover + object-position)
  • Переключатель 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 дней): Ручной выбор региона кропа с превью. Пользователь перетаскивает прямоугольник 9:16 поверх видео. Новая ShortsVideo Remotion-композиция рендерит кроп + субтитры.
  • Полная (+3-4 дня после Фичи 3): Авто-кроп на основе данных детекции лица. Конвертация в один клик. Пакетная конвертация вирусных клипов.

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

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

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

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

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

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

Уровень Состав Вычисления LLM API Итого Время ожидания
Только CPU Всё на CPU $0.05 $0.06 $0.11 35-80 мин
GPU (T4) ML на GPU, FFmpeg на CPU $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 (g4dn.xlarge 24/7) ~$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%

Маржинальность 60-85%. При масштабировании — только растёт.


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

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

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

Фаза 2: Отдельный Docker-контейнер ml-worker на выделенных очередях. Тот же код, другой образ (Dockerfile.ml), другие лимиты ресурсов. Docker Compose profiles:

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

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

Немедленные оптимизации (до начала работы над новыми фичами)

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

Четыре задачи. Суммарно полдня. Экономия: 800МБ, один баг, и страховка от того, что ML-джоб сожрёт всю память и уронит API.


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

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

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

Новые бэкенд-модули

Модуль Назначение Фича
clips CRUD клипов, воркфлоу ревью 2

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

Композиция Назначение Фича
ShortsVideo Статический/ключевой кроп + субтитры в 9:16 4
AutoEditVideo Динамический кроп с трекингом лица + субтитры 3

Новые типы джобов

Тип джоба Назначение Фича
VIRAL_DETECT LLM-анализ транскрипции 2
ASPECT_CONVERT 9:16 кроп + пере-кодирование 4
FACE_DETECT Детекция bounding box лиц 3
SPEAKER_DIARIZE Диаризация спикеров 3

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

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

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

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

Полные выводы специалистов доступны в стенограмме сессии. Ключевые файлы, которые изучал каждый:

  • ML-инженер: cpv3/modules/transcription/service.py, cpv3/modules/tasks/service.py, pyproject.toml
  • Backend-архитектор: cpv3/modules/tasks/service.py, cpv3/modules/jobs/schemas.py, cpv3/modules/media/service.py, cpv3/modules/captions/service.py, docker-compose.yml
  • Remotion-инженер: remotion_service/src/components/Composition.tsx, Captions.tsx, Root.tsx, useCaptions.ts, useVideoMeta.ts, все определения типов
  • Frontend-архитектор: src/widgets/TimelinePanel/, src/features/project/FragmentsStep/, src/shared/context/WizardContext.tsx, src/shared/store/notifications/
  • DevOps-инженер: docker-compose.yml, Dockerfile, pyproject.toml, uv.lock
  • Инженер по производительности: cpv3/modules/tasks/service.py, cpv3/modules/media/service.py, cpv3/modules/transcription/service.py, docker-compose.yml