---
name: subs
description: Добавление анимированных субтитров на вертикальное видео через Remotion. Стиль TikTok/Reels — слова появляются по одному, акцентное слово жёлтым курсивом.
---

# Добавление субтитров на вертикальное видео через Remotion

## Роль

Ты — AI-агент, который добавляет стильные субтитры на вертикальные видео (Shorts/Reels) с помощью **Remotion**. macOS.

## Контекст

Русскоязычный YouTube-блогер. Вертикальные видео. Субтитры в стиле TikTok: слова появляются по одному, стекаясь вертикально. Последнее значимое слово в группе — акцентное (жёлтый, курсивный шрифт Great Vibes).

## Зависимости

Node.js пакеты (уже установлены):
- `remotion`, `@remotion/cli`, `@remotion/captions`, `@remotion/media`
- `@remotion/renderer`, `@remotion/bundler`, `@remotion/google-fonts`

## Структура файлов

```
remotion/
├── index.ts           # registerRoot(RemotionRoot)
├── Root.tsx            # <Composition> 30fps, calculateMetadata (размер из видео)
├── Subtitles.tsx       # <OffthreadVideo> + субтитры, загрузка шрифтов
├── SubtitlePage.tsx    # Группа из 4 слов, центрированная
├── SubtitleWord.tsx    # Одно слово: мгновенное появление
├── srt-utils.ts        # SRT → word-level, склейка предлогов, группировка, выбор акцента
└── styles.ts           # Константы стилей

scripts/
└── render_subtitles.mjs  # Скрипт рендеринга (programmatic API)
```

## Команда рендеринга

```bash
node scripts/render_subtitles.mjs \
  --input <видео.mp4> \
  --srt <субтитры.srt> \
  --output <результат.mp4>
```

Скрипт: hard link видео в `public/` → bundle → renderMedia (h264, CRF 18) → cleanup.

## Визуальный стиль

| Параметр | Значение |
|----------|----------|
| **Основной шрифт** | Roboto 900 |
| **Акцентный шрифт** | Great Vibes 400, italic |
| **Размер основной** | 52px |
| **Размер акцентный** | 90px (Great Vibes визуально меньше) |
| **Цвет текста** | white |
| **Цвет акцента** | #FFD700 (жёлтый) |
| **Тень** | 4-сторонний чёрный outline + drop shadow |
| **Регистр** | lowercase |
| **Позиция** | top 55% (нижняя часть экрана) |
| **Выравнивание** | по центру |
| **Анимация** | нет (мгновенное появление) |
| **Слов в группе** | 4 |

## Ключевые особенности

### Склейка предлогов
Короткие предлоги (в, на, с, не, что, вот, это и т.д.) склеиваются со следующим словом: "в Google" → одна строка.

### Умный выбор акцентного слова
Акцентным выбирается последнее **значимое** слово в группе — не предлог, не местоимение, не частица. Если все слова незначимые → fallback на последнее.

### Пропорциональные тайминги
Время внутри SRT-фразы распределяется пропорционально длине слова (не равномерно). Длинные слова получают больше времени.

### Автоподстройка размера
Размер композиции подстраивается под исходное видео (videoWidth/videoHeight из ffprobe).

## Параметры (remotion/styles.ts)

| Константа | Назначение | Значение |
|---|---|---|
| `FONT_SIZE` | Размер основного шрифта | `52` |
| `FONT_SIZE_ACCENT` | Размер акцентного | `90` |
| `COLOR_DEFAULT` | Цвет обычных слов | `'white'` |
| `COLOR_ACCENT` | Цвет акцентного | `'#FFD700'` |
| `TOP_PERCENT` | Позиция от верха | `55` |
| `WORDS_PER_PAGE` | Слов в группе | `4` |
| `PREPOSITIONS` | Список склеиваемых предлогов | Set |

## Типовые запросы

**«Добавь субтитры»** → `node scripts/render_subtitles.mjs --input video.mp4 --srt transcript.srt --output output.mp4`

**«Измени цвет акцента»** → `COLOR_ACCENT` в styles.ts

**«Больше/меньше слов на экране»** → `WORDS_PER_PAGE` в styles.ts

**«Сдвинь субтитры выше/ниже»** → `TOP_PERCENT` в styles.ts

## Ограничения

- Покадровый рендеринг — длинные видео (>10 мин) рендерятся долго
- Word-level тайминги приблизительные (пропорциональные по символам, не Whisper word-level)
- Remotion сервер отклоняет symlinks — используем hard links
