Skill #10 · Post-production QA

video-reviewer

AI пост-продакшен супервайзер. «Смотрит» готовое видео через extract-frames + Vision LLM, выдаёт структурированный review-отчёт со score, проблемами и точечными фиксами. Драйвит render-review-fix loop.

Путь
~/.claude/skills/video-reviewer/
Триггеры
review video, ревью видео, проверь видео, оцени видео, посмотри что получилось, видео ревью
Зависит от
ffprobe, extract_frames.py из analyzer, Vision LLM
Пэйрится с

Что делает простыми словами

Это «худрук на сдаче». Получает готовый .mp4 и за пару минут выдаёт вердикт — публиковать или переделывать. Работает так:

  1. Достаёт из видео 15-25 кадров через uniform-sampling (для 30-секундного ролика это примерно кадр каждые 2 секунды — хватает чтобы увидеть каждую сцену)
  2. Дёргает ffprobe для метаданных: resolution, fps, длительность, наличие аудио, битрейт
  3. Vision LLM смотрит на кадры и оценивает по 5 измерениям (визуал / пейсинг / синк / субтитры / платформа)
  4. Формирует структурированный отчёт: score 1-10, что работает, что сломано, конкретные фиксы
  5. Возвращает JSON {score, issues, suggested_fixes} + читабельный текстовый report
Это quality gate перед доставкой. Reviewer не правит видео сам — он диагностирует. Фиксы прокидываются обратно в director (другие клипы, другая длительность сегментов) либо в captions (стиль/размер). Дальше — пересборка, повторное ревью. Loop крутится пока score не станет ≥ 8.

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-10Publish-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

Из вывода смотрим:

Главный воркхорс: 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:

  1. Список конкретных фиксов в порядке приоритета
  2. Спросить юзера — применять?
  3. Если да — возвращаемся в director для пересборки с правками: другие клипы, скорректированная длительность сегментов, изменённый transition, перезаписанная озвучка (если аудио-проблема)
  4. После пересборки — снова reviewer
  5. Цикл до score 8+
assemble review fix assemble review

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.pyvideo-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

Reviewer не «смотрит» видео целиком — он смотрит срезы. 15-25 кадров покрывают сцены, но не покажут проблему длиной в 0.5с между фреймами. Для критичных проектов поднимать --frames до 30-40 (это медленнее и дороже, но точнее).
Чёрные кадры между клипами — самая частая критичная проблема. Возникает когда FFmpeg склейка имеет gap 1-2 фрейма. Если reviewer ругается — смотреть в assemble.py на overlap/crossfade параметры.
Frames-кадры остаются в thumbnails/review/ после ревью — можно посмотреть глазами, что именно увидел LLM. Полезно для отладки когда score кажется заниженным.
Score 8 — practical ceiling для большинства проектов. 9-10 требует premium-съёмки, идеальной цветокоррекции, безупречного звука. Для performance-ad'ов 7-8 хватает — главное чтобы не было critical issues.
Reviewer полезен и для chcompare-режима — когда нужно выбрать между 2-3 готовыми вариантами для запуска в Meta Ads. Прогнать каждый → сравнить score → отдать в продакшен лучший.

Место в пайплайне

director captions reviewer deliver

Reviewer = последний quality gate перед доставкой. Вход: captioned.mp4. Выход: review.json + вердикт APPROVED / NEEDS REVISION / MAJOR REVISION.

В авто-режиме video-orchestrator может запускать reviewer автоматически и крутить loop пока score ≥ 8. В ручном режиме reviewer вызывают точечно когда юзер просит «оцени что получилось».