video-reviewer
AI пост-продакшен супервайзер. «Смотрит» готовое видео через extract-frames + Vision LLM, выдаёт структурированный review-отчёт со score, проблемами и точечными фиксами. Драйвит render-review-fix loop.
Что делает простыми словами
Это «худрук на сдаче». Получает готовый .mp4 и за пару минут выдаёт вердикт — публиковать или переделывать. Работает так:
- Достаёт из видео 15-25 кадров через uniform-sampling (для 30-секундного ролика это примерно кадр каждые 2 секунды — хватает чтобы увидеть каждую сцену)
- Дёргает
ffprobeдля метаданных: resolution, fps, длительность, наличие аудио, битрейт - Vision LLM смотрит на кадры и оценивает по 5 измерениям (визуал / пейсинг / синк / субтитры / платформа)
- Формирует структурированный отчёт: score 1-10, что работает, что сломано, конкретные фиксы
- Возвращает JSON
{score, issues, suggested_fixes}+ читабельный текстовый report
5 измерений ревью
| Измерение | Что проверяется |
|---|---|
| Visual quality | Нет чёрных/пустых кадров, все клипы резкие и правильно экспонированы, нет артефактов компрессии, цветовая консистентность между клипами, правильный 9:16 кроп (без pillarbox/letterbox если не задумано) |
| Pacing & structure | Hook (0-3с) цепляет внимание? Middle — визуал совпадает с тем что говорит голос? CTA (последние 3-5с) — есть финал/призыв? Ни один клип не держится дольше 5 секунд. Ритм нарезки разнообразный. |
| Audio-visual sync | Озвучка соответствует визуалу? Голос чёткий и слышимый? Музыка не глушит голос (ducking работает)? Переходы плавные, не резкие? |
| Subtitles/captions | Текст читается на mobile-экране? Не перекрывает важные элементы кадра? Достаточный контраст (обводка/тень)? Тайминг попадает в речь? |
| Platform readiness | Правильный aspect для целевой площадки. Текст в safe zones (не перекрывается TikTok/Reels UI). Длительность подходит платформе (15-60с для shorts). Размер файла адекватен для загрузки. |
Score guide
| Score | Значение | Action |
|---|---|---|
| 9-10 | Publish-ready. Профессиональное качество. | APPROVED |
| 7-8 | Хорошо. Мелочи можно подшлифовать, но смотрибельно. | APPROVED с заметками |
| 5-6 | Нужна работа. Несколько заметных проблем. | NEEDS REVISION |
| 3-4 | Серьёзные проблемы. | MAJOR REVISION NEEDED |
| 1-2 | Фундаментально сломано. | MAJOR REVISION NEEDED |
Команды
Извлечь кадры из видео
python ~/.claude/skills/video-analyzer/scripts/extract_frames.py \ --video ~/video-projects/bas_dent/videos/variant_a.mp4 \ --output-dir ~/video-projects/bas_dent/thumbnails/review \ --count 15 \ --mode uniform # Для 30с видео → 1 кадр каждые 2с # Для 60с+ видео → --count 20 или 25
Проверить metadata
ffprobe -v quiet -print_format json -show_format -show_streams \ ~/video-projects/bas_dent/videos/variant_a.mp4
Из вывода смотрим:
- Resolution — должно быть 1080×1920 (9:16)
- Duration — совпадает с ожидаемой длиной озвучки
- FPS — 30
- Audio track — присутствует
- File size — не раздутый и не слишком сжатый (для 30с реклы — 5-25MB норма)
Главный воркхорс: review_video.py
python ~/.claude/skills/video-reviewer/scripts/review_video.py \
--video ~/video-projects/bas_dent/videos/variant_a.mp4 \
--project-dir ~/video-projects/bas_dent \
--frames 15 \
--output review.json
# → JSON {score, issues, suggested_fixes} + human-readable report
Формат финального отчёта
Reviewer выдаёт review в строгом формате — agent наверху по нему принимает решение:
VIDEO REVIEW: variant_a.mp4 Duration: 28.4s | Resolution: 1080x1920 | Size: 12.3MB QUALITY SCORE: 7/10 WHAT'S WORKING: + Сильный hook — крупный план улыбки в первые 2с + Хорошая цветовая консистентность между всеми клипами + Субтитры читаются на мобильном ISSUES FOUND: 1. [CRITICAL] Чёрный кадр на 14.2с между двумя клипами → пересобрать с overlap или crossfade 2. [MAJOR] CTA-сцена слишком тихая — голос почти не слышен → поднять voice volume +3dB или убрать музыку в последние 4с 3. [MINOR] Один клип держится 6.3с (превышение лимита) → разрезать на два сегмента 3 + 3.3с PRIORITY FIX: Убрать чёрный кадр на 14.2с — это единственное что сразу скроллится. CHECKLIST: [x] No blank/black frames ← НЕТ, есть на 14.2с [x] Subtitles readable at mobile [x] Strong opening hook (first 2-3s) [x] Correct aspect ratio (9:16) [x] Audio track present [x] Clean ending with CTA [x] Consistent visual quality [ ] Smooth transitions VERDICT: NEEDS REVISION
The improvement loop
Если видео NEEDS REVISION:
- Список конкретных фиксов в порядке приоритета
- Спросить юзера — применять?
- Если да — возвращаемся в director для пересборки с правками: другие клипы, скорректированная длительность сегментов, изменённый transition, перезаписанная озвучка (если аудио-проблема)
- После пересборки — снова reviewer
- Цикл до score 8+
Render-review-fix loop. Reviewer не правит, он диагностирует. Правит director / captions / voiceover.
Сравнение вариантов
Когда на ревью 2-3 варианта одного и того же ролика — reviewer прогоняет каждый независимо, потом сравнивает и даёт рекомендацию:
VARIANT COMPARISON: Variant A (score 7/10): + Сильный hook с крупным планом лица - Middle ощущается монотонным (3 раза одинаковый scene type) Variant B (score 8/10): + Лучшее разнообразие клипов в middle + Плавный пейсинг - Hook слабее RECOMMENDATION: Variant B сильнее в целом. Можно подменить hook Variant B на открывающий клип Variant A — получится лучший микс.
Скрипты
| Файл | Что делает |
|---|---|
scripts/review_video.py | Главный entry-point. Дергает extract_frames.py из analyzer → собирает frames + metadata → отправляет Vision LLM → парсит ответ в JSON + human report. |
Чужие скрипты, на которые опирается:
| Скрипт | Откуда | Зачем |
|---|---|---|
extract_frames.py | video-analyzer | Достаёт 15-25 кадров uniform-sampling в thumbnails/review/ |
ffprobe | системный | Метаданные видео — resolution, fps, duration, audio, codec |
Brand context из project.yaml
Reviewer читает project.yaml чтобы понимать что считать «хорошо для этого бренда»:
brand:
voice: "профессиональный, деликатный"
colors:
primary: "#0F4F8B"
accent: "#FFB400"
target_audience: "женщины 28-45, Алматы, средний+"
forbidden: ["шок-контент", "негатив о конкурентах"]
captions:
style: karaoke # стиль субтитров — проверяется на читабельность
aspect: "9:16" # целевой aspect для платформы
Reviewer не оценивает соответствие бренду напрямую, но использует brand-контекст для контекстуальной оценки: например, если voice = «премиум, деликатный», а в кадре резкий маркетинговый текст — это попадёт в ISSUES.
Gotchas и tips
--frames до 30-40 (это медленнее и дороже, но точнее).
assemble.py на overlap/crossfade параметры.
thumbnails/review/ после ревью — можно посмотреть глазами, что именно увидел LLM. Полезно для отладки когда score кажется заниженным.
Место в пайплайне
Reviewer = последний quality gate перед доставкой. Вход:
captioned.mp4. Выход: review.json + вердикт APPROVED / NEEDS REVISION / MAJOR REVISION.
В авто-режиме video-orchestrator может запускать reviewer автоматически и крутить loop пока score ≥ 8. В ручном режиме reviewer вызывают точечно когда юзер просит «оцени что получилось».