Видео с Claude Code: от брифа до воспроизводимого рендера
Подробный процесс создания видео с Claude Code: Canvas, Playwright и FFmpeg, выбор движка, бриф, таймлайн, движение, звук, проверки и выпуск нескольких форматов.
Claude Code помогает превратить сценарий в программу: написать сцены, настроить экспорт и исправить конкретный переход. В основном маршруте этой статьи Canvas рисует кадры, Playwright сохраняет их в PNG, а FFmpeg собирает MP4. Чтобы повторить результат, нужно зафиксировать исходные данные и вычислять каждый кадр из заданного времени. Начните с короткой сцены: проверьте весь путь до файла, затем усложняйте движение и звук.
Руководство рассчитано на разработчика, который умеет запускать Node.js, читать JavaScript и работать с Git. Два полных исходных файла приведены ниже; для упражнения не нужны закрытый архив или платный генератор видео. Сначала соберём технический образец, затем разберём работу над полноценным роликом: бриф, визуальный язык, таймлайн, звук и приёмку. Remotion, HyperFrames, генеративные планы и интерактивные объяснения вынесены в отдельные разделы: выбирать все эти инструменты для первого проекта не требуется.
Учебный сюжет — вымышленный инструмент Patchwork для подготовки выпуска: изменения собираются в группы, проходят проверку и становятся готовым пакетом. Это условная история для работы с формой и временем. Она не описывает реальный продукт и не содержит показателей его эффективности.
Какую часть работы выполняет Claude Code
В кодовом видеопроекте можно отделить содержание, дизайн, таймлайн и инфраструктуру. Содержание определяет, что зритель должен понять. Дизайн задаёт объекты, шрифты и визуальную иерархию. Таймлайн связывает изменения со временем. Инфраструктура загружает файлы, получает изображения и кодирует их в видео.
Claude Code помогает менять эти части через файлы и инструменты. Модель не заменяет видеокодек и не придаёт композиции художественное качество самим фактом генерации кода. Исправление опечатки, поиск неготового шрифта и выбор выразительной паузы требуют разных способов проверки.
У программного видео есть полезное свойство: данные можно отделить от сцены. Один утверждённый шаблон затем принимает новый заголовок, язык или набор чисел. Но переиспользование имеет смысл после проверки самого шаблона. Если текст не читается в первой версии, автоматический выпуск двадцати вариантов размножит тот же дефект.
Для первого опыта выбраны 16 секунд при 30 fps: 480 кадров. Четыре состояния по четыре секунды дают место для появления объекта, действия, чтения и смены сцены. В минимальном примере реализованы простые появления и переключения; выразительные переходы предстоит спроектировать отдельно. Этот объём выбран ради короткого полного цикла проверки, а не как стандарт рекламного ролика.
Выберите один движок
Движок стоит выбирать по материалу и привычному способу описания сцены. Установка сразу нескольких систем затрудняет диагностику: у каждой свой источник времени, загрузчик ассетов и способ экспорта.
| Маршрут | Когда подходит | Как задаётся время | Что остаётся поддерживать |
|---|---|---|---|
| Canvas + Playwright + FFmpeg | Геометрия, типографика, диаграммы, небольшой собственный рендерер | Явная функция кадра от секунд | Загрузку, размещение текста, захват, проверки и экспорт |
| Remotion | React-компоненты, интерфейсные сцены, варианты из данных | Номер кадра и API композиции | Дизайн, данные, ресурсы, качество и параметры поставки |
| HyperFrames | HTML/CSS-сцены и GSAP | Контракт композиции и управляемые timelines | Соблюдение runtime-контракта, входы и визуальную приёмку |
| Монтаж исходных клипов | Интервью, демонстрация интерфейса, съёмка продукта | Монтажная шкала выбранного инструмента | Точные склейки, звук, субтитры и качество исходников |
У Canvas нет готового монтажного редактора. Зато путь от времени до пикселя хорошо виден, а минимальная сцена помещается в один файл. В этой статье такой путь выбран для обучения. При большом числе интерфейсных компонентов React-проект часто проще поддерживать в Remotion; текущий старт и ограничения описаны в официальной документации.
HyperFrames предоставляет собственный HTML-видеопроцесс и CLI. Его нельзя воспринимать как обёртку над произвольным window.seek: композиции должны соответствовать его контракту. Ниже есть отдельные команды старта для обеих альтернатив. Их не нужно выполнять для Canvas-примера.
Для нарисованных персонажей также можно изучить claude-animation-skill: это сторонний проект с Node Canvas и собственными правилами анимации. Он полезен как отдельная реализация, а не обязательная зависимость. Перед запуском изучите его код и лицензию. Публичный репозиторий и известное имя платформы сами по себе не подтверждают безопасность установки или права на все вложенные медиа.
Подготовьте окружение и границы проекта
Для основного маршрута нужны Node.js, FFmpeg, Python для локального HTTP-сервера и Chromium, который устанавливается через Playwright. Python здесь ничего не генерирует и не обращается к модели. Пример использует обычный Canvas 2D, без WebGL и внешних изображений.
На Mac с уже установленным Homebrew можно начать так:
brew install --cask claude-code
brew install node@24 ffmpeg python@3.12
export PATH="$(brew --prefix node@24)/bin:$PATH"
claude --version
claude doctor
node --version
npm --version
ffmpeg -version
ffprobe -version
python3.12 --version
Node 24 и Python 3.12 выбраны как конкретная отправная точка. При уже настроенном окружении сначала проверьте расположение и версии инструментов: переустановка может не понадобиться. Формула Homebrew node@24 требует явно добавить её каталог в PATH; приведённый export действует в текущем терминале. В новом окне проверьте node --version ещё раз. Не меняйте глобальные настройки наугад в середине проекта.
Порядок входа и доступ к моделям проверяйте в документации Claude Code. Подписка и API-биллинг имеют разные условия; бесплатный доступ к чату не следует считать подтверждением доступа к CLI. Существующий ANTHROPIC_API_KEY тоже может влиять на выбранный способ работы. Ключи не должны попадать в браузерный код, скриншоты, журнал запросов или архив для получателя.
Запускайте агента из отдельной папки с нужными материалами. Для первого прохода достаточно:
claude --model opus --effort medium
Алиас opus выбирает доступную актуальную модель семейства, поэтому для воспроизводимого отчёта сохраните фактическую модель из сессии. Проверьте /model и /status. Увеличение effort может помочь со сложным рассуждением, но не заменяет раскадровку и просмотр. Доступные настройки зависят от версии CLI и аккаунта; источник синтаксиса — конфигурация модели.
Не отключайте разрешения ради первого рендера. Папка проекта и инструкция в CLAUDE.md не создают песочницу: реальные границы задаются средствами среды. npm install, npx и плагины могут выполнять скачанный код. Перед сторонней установкой смотрите зависимости, lifecycle scripts и hooks, а после принятого запуска сохраняйте lockfile.
Linux и Windows
На поддерживаемом Linux установите FFmpeg и Python средствами своей системы, а Node — способом, который действительно даёт нужную версию. Playwright может потребовать системные библиотеки; его install --with-deps chromium способен менять системные пакеты и требует соответствующих прав. Не добавляйте --no-sandbox как универсальное исправление ошибки запуска.
На Windows выберите нативный стек либо WSL и держите файлы и инструменты в одной среде. Node из WSL, Windows Python и путь к стороннему Chrome создают три разных предположения о файловой системе. Для Python-окружения в PowerShell можно запускать .venv\Scripts\python.exe напрямую, без ослабления execution policy. Точные требования проверяйте у выбранного движка; переносимость команды ещё не доказывает одинаковый рендер на другой ОС.
Соберите первый MP4 из двух файлов
Создайте проект
Создайте чистую папку. Сетевые обращения понадобятся для установки пакета и браузера; сама сцена ниже не загружает внешние ресурсы.
mkdir patchwork-motion && cd patchwork-motion
npm init -y
npm install --save-exact playwright
npx playwright install chromium
mkdir out
Первая установка выбирает текущую версию Playwright и записывает её точно в package.json. Сохраните полученный package-lock.json; повторное развёртывание этой версии выполняйте через npm ci. По документации Playwright, версии пакета соответствуют определённые браузерные бинарники. После обновления зависимости шаг установки браузера может понадобиться снова.
Статус проверки драфта. Команды кодирования проверены на синтетических PNG, но полный путь именно этого примера от браузера до MP4 пока не подтверждён. В среде проверки не удалось установить и запустить подходящий Chromium. Визуальная проверка движения и читаемости не выполнена. Ниже описаны ожидаемые результаты и действия для проверки на рабочей машине, а не отчёт об успешном сквозном запуске.
Опишите кадр в index.html
Сохраните следующий файл как index.html. Он рисует четыре простых состояния и восстанавливает кадр по времени. Тексты на двух языках включены в пример, чтобы проверить локализацию без изменения функции рисования.
<!doctype html>
<html lang="ru">
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Patchwork motion study</title>
<style>
html,
body {
margin: 0;
overflow: hidden;
background: #eeeae1;
}
canvas {
display: block;
width: 100vw;
height: 100vh;
}
</style>
<canvas aria-label="Four stages of a fictional release workflow"></canvas>
<script>
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
if (!ctx) throw new Error("Canvas 2D is unavailable");
const params = new URLSearchParams(location.search);
const labels =
params.get("lang") === "en"
? ["Changes", "Groups", "Review", "Ready to ship"]
: ["Изменения", "Группы", "Проверка", "Готовый выпуск"];
const W = (canvas.width = innerWidth);
const H = (canvas.height = innerHeight);
const unit = Math.min(W, H);
const clamp = (x) => Math.max(0, Math.min(1, x));
const ease = (x) => {
const p = clamp(x);
return p * p * (3 - 2 * p);
};
window.seek = (seconds) => {
if (!Number.isFinite(seconds)) throw new Error("Time must be finite");
const t = Math.max(0, Math.min(16 - 1e-8, seconds));
const scene = Math.floor(t / 4);
const local = t - scene * 4;
const enter = ease(local / 0.6);
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.globalAlpha = 1;
ctx.fillStyle = "#eeeae1";
ctx.fillRect(0, 0, W, H);
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle = "#173f35";
ctx.font = `700 ${unit * 0.075}px sans-serif`;
ctx.fillText("PATCHWORK", W / 2, H * 0.17);
const cardY = H * 0.38 + (1 - enter) * unit * 0.08;
ctx.fillStyle = "#ffffff";
ctx.fillRect(W * 0.12, cardY, W * 0.76, unit * 0.42);
ctx.globalAlpha = enter;
ctx.fillStyle = "#20241f";
ctx.font = `600 ${unit * 0.065}px sans-serif`;
ctx.fillText(labels[scene], W / 2, cardY + unit * 0.12);
ctx.fillStyle = "#527465";
for (let i = 0; i <= scene; i++) {
ctx.fillRect(
W * 0.22,
cardY + unit * (0.22 + i * 0.04),
W * (0.56 - i * 0.06),
unit * 0.014,
);
}
ctx.globalAlpha = 1;
ctx.fillStyle = "#173f35";
ctx.font = `400 ${unit * 0.035}px sans-serif`;
ctx.fillText(`${scene + 1} / 4`, W / 2, H * 0.8);
};
window.ready = document.fonts.ready.then(() => window.seek(0));
if (!params.has("render")) {
window.ready.then(() => {
const start = performance.now();
const tick = (now) => {
window.seek(((now - start) / 1000) % 16);
requestAnimationFrame(tick);
};
requestAnimationFrame(tick);
});
}
</script>
</html>
В обычном браузере страница показывает зацикленное превью. Параметр render=1 отключает автономный таймер: при захвате время будет задавать только рендерер. Это важное разделение. Второй таймер может перерисовать Canvas между вызовом seek и скриншотом, даже если в интерактивном окне всё выглядит нормально.
window.seek и window.ready — договорённость внутри примера, а не встроенные API браузера. Промис ready здесь ждёт document.fonts.ready и рисует начальный кадр. Сцена использует системный sans-serif, поэтому вид букв может отличаться между операционными системами. Для поставки выберите конкретный локальный шрифт, проверьте загрузку нужного начертания и сохраните лицензию. Один document.fonts.ready не доказывает, что нужный файл шрифта загрузился успешно.
Захватывайте кадры через capture.mjs
Сохраните второй файл как capture.mjs:
import { chromium } from "playwright";
import { mkdir, writeFile } from "node:fs/promises";
import { parseArgs } from "node:util";
import assert from "node:assert/strict";
const { values } = parseArgs({
options: {
start: { type: "string", default: "0" },
end: { type: "string", default: "480" },
width: { type: "string", default: "540" },
height: { type: "string", default: "960" },
out: { type: "string", default: "out/frames" },
lang: { type: "string", default: "ru" },
},
});
const start = Number(values.start),
end = Number(values.end);
const width = Number(values.width),
height = Number(values.height);
for (const n of [start, end, width, height]) assert.ok(Number.isInteger(n));
assert.ok(start >= 0 && end > start && end <= 480);
assert.ok(width > 0 && height > 0 && width % 2 === 0 && height % 2 === 0);
assert.ok(["ru", "en"].includes(values.lang));
// A fresh directory avoids mixing frames from different revisions.
await mkdir(values.out, { recursive: false });
const browser = await chromium.launch();
const errors = [];
try {
const page = await browser.newPage({ viewport: { width, height }, deviceScaleFactor: 1 });
page.on("pageerror", (error) => errors.push(error.message));
const response = await page.goto(`http://127.0.0.1:8000/index.html?render=1&lang=${values.lang}`);
assert.equal(response?.status(), 200);
await page.evaluate(() => window.ready);
const canvas = page.locator("canvas");
const at = async (t) => {
await page.evaluate((seconds) => window.seek(seconds), t);
assert.deepEqual(errors, []);
return canvas.screenshot({ type: "png" });
};
const reference = await at(5);
await at(12);
await at(1);
assert.deepEqual(await at(5), reference, "Frame depends on seek order");
for (let frame = start; frame < end; frame++) {
const png = await at(frame / 30);
await writeFile(`${values.out}/${String(frame).padStart(5, "0")}.png`, png);
}
assert.deepEqual(errors, []);
console.log(
JSON.stringify({ start, end, frames: end - start, fps: 30, width, height, lang: values.lang }),
);
} finally {
await browser.close();
}
Скрипт проверяет размер и диапазон кадров, отказывает при существующем выходном каталоге и закрывает браузер в finally. Новая папка нужна, чтобы не смешать PNG разных версий. При неудаче оставьте её для диагностики и укажите новое имя следующему запуску. Не удаляйте чужие результаты автоматическим «очищением» общего каталога.
Проверка внутри скрипта получает кадр на пятой секунде, переходит к двенадцатой и первой, затем повторяет пятую. Байты PNG должны совпасть в том же окружении. Это узкая проверка независимости кадра от порядка вызовов. Она не оценивает дизайн, не доказывает переносимость между ОС и не проверяет ещё не добавленные загрузчики видео или шрифтов.
Проверьте первые две секунды
В первом терминале из папки проекта запустите сервер только на loopback-интерфейсе:
python3.12 -m http.server 8000 --bind 127.0.0.1
Он останется в foreground. Во втором терминале перейдите в ту же папку и выполните:
node --check capture.mjs
node capture.mjs --end 60 --out out/smoke
ffmpeg -n -framerate 30 -start_number 0 -i out/smoke/%05d.png \
-frames:v 60 -c:v libx264 -pix_fmt yuv420p -crf 18 \
-movflags +faststart out/smoke.mp4
Ожидаемый результат — две секунды вертикальной сцены 540 × 960 без звука. Откройте MP4 обычным плеером: проверьте слово PATCHWORK, карточку, первую подпись и индикатор 1 / 4. Этот короткий запуск проверяет цепочку захвата и кодирования только на первой сцене. Стыки четырёх состояний появятся в полном экспорте; пока это простые переключения без сложных переходов.
-n запрещает перезапись существующего результата. -framerate относится к входной последовательности изображений, -start_number задаёт номер первого PNG, а -frames:v ограничивает количество закодированных кадров. Параметры кодирования нужно сохранять рядом с проектом. Случайная замена входной частоты меняет длительность, даже если все изображения остались прежними.
Экспортируйте все 480 кадров
После короткой проверки запустите полный вертикальный экспорт:
node capture.mjs --width 1080 --height 1920 --out out/full
ffmpeg -n -framerate 30 -start_number 0 -i out/full/%05d.png \
-frames:v 480 -c:v libx264 -pix_fmt yuv420p -crf 18 \
-movflags +faststart out/silent.mp4
ffprobe -v error -select_streams v:0 -count_frames \
-show_entries stream=codec_name,width,height,r_frame_rate,nb_read_frames \
-show_entries format=duration -of json out/silent.mp4
Проверьте H.264, размеры 1080 × 1920, частоту 30/1 и 480 прочитанных кадров. Продолжительность изображения должна соответствовать 16 секундам. Наличие файла на диске не означает успешное завершение: проверяйте код выхода FFmpeg и декодирование готового результата. После работы остановите HTTP-сервер через Ctrl+C.
Для английской версии добавьте --lang en к захвату и выберите отдельный каталог. Текст может быть длиннее, поэтому новая локаль требует просмотра, даже когда технические параметры совпали. Минимальный layout рассчитан на вертикальную сцену; полноценную горизонтальную адаптацию будем проектировать отдельно.
Сделайте время единственным источником состояния
Кадр должен вычисляться из времени и зафиксированных входов. Вызов на 8,2 секунды обязан давать тот же результат после перехода с начала или после прыжка с конца. Такой контракт позволяет экспортировать диапазоны, запускать сцены независимо и добавлять motion blur без зависимости от порядка вычислений.
Поэтому внутри рисования нельзя бездумно накапливать x += velocity, создавать новую частицу при каждом вызове или брать очередное значение Math.random(). Случайные исходные данные создавайте один раз с записанным seed либо вычисляйте из стабильного идентификатора объекта. При повторном вызове меняется только заданное время; исходные положения, цвета и число объектов остаются прежними.
Состояние Canvas тоже необходимо восстанавливать. Трансформация, прозрачность, шрифт, выравнивание и стиль линии переживают вызовы рисования. Каждая функция должна либо выставлять всё, что использует, либо ограничивать локальные изменения парой save/restore. Нельзя полагаться на то, что предыдущая сцена оставила подходящие настройки.
У ассетов есть собственная готовность. Изображение должно закончить декодирование, шрифт — реально загрузить нужное семейство, а видео — завершить переход к заданному времени. Присваивание video.currentTime ещё не означает доступность нужного кадра. Поэтому внедрение видеоклипа в Canvas требует отдельного загрузчика и теста; минимальный пример такой функции не обещает.
Сохраняйте интервалы сцен в одной конвенции: начало включено, конец исключён. При 30 fps диапазон кадров [210, 270) содержит 60 кадров, то есть две секунды исходного фильма с 7-й секунды. Время сцены при этом остаётся глобальным. Если каждый частичный рендер начинать с нуля, переходы и музыка перестанут совпадать.
Запишите бриф, который допускает проверку
Для Patchwork можно сформулировать результат так: разработчик видит, как разрозненные изменения превращаются в понятный пакет выпуска. В ролике четыре утверждённых подписи, один основной объект и спокойный финальный экран. Длительность 16 секунд, первый формат вертикальный, внешних изображений и продуктовых обещаний нет.
Бриф должен различать обязательное и свободное. Точный текст, логотип, длительность и подтверждённые факты фиксируются. Композиция, вид карточки и характер перехода остаются предметом выбора. Если всё разрешено менять, агент будет решать задачу заново при каждой итерации. Если каждый пиксель заранее описан, пользы от поиска направления почти не остаётся.
Полезные поля брифа: аудитория, место показа, одно сообщение, нужное действие зрителя, обязательный текст, форматы, звук, разрешённые ассеты и признаки готовности. Для каждого числа или заявления о реальном продукте нужен источник. Не позволяйте модели заполнять пустые места выдуманными клиентами, метриками экономии или обещанием результата.
Первое творческое задание может быть таким:
Прочитай project-brief.md и asset-manifest.md.
Нужен 16-секундный ролик о вымышленном Patchwork.
Сообщение: изменения проходят путь от списка до готового выпуска.
Используй только четыре утверждённые подписи из брифа.
Предложи три направления, различающиеся композицией и движением.
Для каждого опиши главный объект, порядок чтения, палитру
и самый рискованный переход. Код пока не меняй.
Сохрани текущий Canvas-рендерер и общий контракт времени.
Три почти одинаковые карточки разных цветов не дают полезного выбора. Попросите различить саму идею: крупная типографика, единый превращающийся контейнер или схема движения данных. После сравнения выберите направление и переходите к статике. Обсуждение без зафиксированного решения тоже расходует время.
Свяжите проектные документы между собой
По мере роста проекта удобно разделить восемь видов информации. Это карта ответственности, а не требование завести восемь файлов для каждого короткого ролика. Существующий CSV, который читает программа, не стоит заменять Markdown только ради единообразия названий.
| Документ | За какое решение отвечает |
|---|---|
CLAUDE.md | Порядок работы, команды проверки, границы изменений |
project-brief.md | Аудитория, сообщение, факты, формат и приёмка |
style-guide.md | Сетка, шрифты, палитра, материалы и роли движения |
asset-manifest.md | Файлы, происхождение, права и допустимые преобразования |
storyboard.md | Смысл сцен и передача внимания между ними |
motion-spec.md | Время, границы сцен, геометрия и текстовые треки |
audio-cues.md | Речь, музыка, эффекты и точки событий |
review-log.md | Дефекты, версия, исправление и повторная проверка |
Документы должны ссылаться на одни и те же идентификаторы сцен. Если сцена review начинается на восьмой секунде, звуковое событие и комментарий проверяющего должны находить её однозначно. Изменение длительности отражается в зависимых данных, а не только в тексте сценария.
Числа, которые читает программа, лучше хранить в одном project.json: fps, размеры, длительность и список сцен. Остальные документы объясняют решения. Не поддерживайте вручную четыре независимые копии длительности в рендерере, звуковом скрипте, README и брифе. В минимальном примере значения пока записаны прямо в коде. Чтобы перейти к общей конфигурации, нужно изменить чтение параметров и проверить расчёты во всех зависимых командах; одного нового JSON-файла недостаточно.
В CLAUDE.md достаточно нескольких проверяемых правил: не менять утверждённый текст, не трогать стабильный захват при художественной правке, после изменения таймлайна пересчитать число кадров. Подробнее о таком подходе — правила для CLAUDE.md. Фраза «качество 10/10» не говорит агенту, как обнаружить обрезанную подпись.
Реестр ассетов полезно вести даже без внешней генерации. Для логотипа фиксируйте разрешённые масштабирование и цвет, для скриншота — допустимый crop, для референса — только анализ или ещё и включение в итог. Статусы «найден», «права проверены» и «утверждён» означают разные вещи. Замена файла под прежним именем должна быть видна по контрольной сумме.
Проверьте статичный кадр и animatic
Референс полезен, когда из него извлечено конкретное правило. «Крупная надпись занимает верхнюю треть, а объект остаётся единственным цветным акцентом» можно проверить. Просьба повторить чужой бренд оставляет слишком много неопределённого и повышает риск копирования узнаваемых элементов.
Возьмите несколько разрешённых примеров с разными функциями: композиция, типографика, движение, фактура. Для каждого запишите, что используете и что не переносите. Двадцать конфликтующих изображений без приоритета часто приводят к усреднённой сцене. Сам референс не обязательно должен входить в клиентский экспорт; доступность картинки в интернете не даёт такого разрешения.
Сначала попросите один статичный кадр. Оцените, куда зритель посмотрит первым, что прочитает вторым и где остаётся место для движения. В Patchwork это может быть тёплый фон, тёмный заголовок и одна светлая карточка с зелёным акцентом. Если иерархия не работает без анимации, добавление бликов или размытия затруднит поиск причины.
После принятой статики соберите animatic: весь фильм в грубых формах, с точными текстами и длительностями. На этом этапе допустимы прямоугольники и простые переключения. Проверяется последовательность понимания: зритель увидел изменения, понял группировку, заметил проверку и распознал результат. Декоративная фактура не нужна, чтобы обнаружить слишком короткую сцену.
Для каждого состояния укажите, когда оно начинается, что меняется, сколько времени остаётся на чтение и как внимание переходит к следующему объекту. Учтите, что появление текста ещё не означает начало чтения: внимание сначала забирает движение. Смотрите animatic целиком и на телефоне. Если приходится ставить паузу ради основной надписи, увеличьте устойчивый интервал или сократите текст по смыслу.
Типографика и адаптация
Ограничьтесь небольшим набором размеров и начертаний. Заголовок, основная короткая фраза и вспомогательная подпись должны различаться по роли. Для русского текста проверьте кириллицу, включая Ё и Й, а не только успешный HTTP-запрос шрифта. Fallback способен незаметно подменить часть знаков.
fillText не переносит строку автоматически. При переходе к реальным данным понадобятся measureText, максимальная ширина и явный межстрочный интервал. Длинное название должно либо корректно переноситься, либо давать понятную ошибку входных данных. Уменьшение размера до нечитаемого состояния маскирует проблему.
В квадратном и горизонтальном кадре изменяется композиция: карточку и заголовок можно поставить рядом, раскрытие списка — сделать горизонтальным. Пропорциональное уменьшение вертикального кадра часто оставляет пустоты и слишком мелкий текст. Для каждой версии тестируйте длиннейшую строку, реальный размер просмотра и интерфейс площадки, который может закрывать края. Безопасную область кадра проверяйте для конкретного места показа.
Сохраните объект через переход
У связного ролика внимание передаётся между состояниями. В Patchwork карточка со списком может расшириться, её линии — сгруппироваться, одна метка — стать знаком проверки. Для такого перехода нужно заранее назвать объект, который переживает стык, и определить его форму до и после.
Запишите опорную точку, размеры, допустимое изменение радиуса и направление движения. Сначала анимируйте оболочку без текста. Если движение уже непонятно, добавление содержимого не объяснит его автоматически. Проверка одного перехода дешевле полной реализации четырёх сцен с разными ошибками.
Геометрия и надписи должны иметь отдельные треки. Прежний текст может уйти до сильного изменения формы, а новый — появиться, когда область для чтения уже раскрылась. Если растягивать растровое изображение букв вместе с контейнером, исказятся и сами буквы. Пересчитайте размещение текста для новой формы, а положение и прозрачность надписи анимируйте отдельно.
Курсор уместен там, где объясняет действие. При перетаскивании ручка следует за ним по понятному правилу; после отпускания может включиться пружина. Если интерфейс постоянно запаздывает без причины, это выглядит как ошибка взаимодействия. В сцене без действия курсор добавляет ещё один конкурирующий объект.
Хорошее упражнение после первого фильма — один контейнер, проходящий состояния кнопки, поля ввода, результата и готового пакета. Сначала сохраните центр внимания и непрерывность формы, затем добавьте содержимое. Так становится видно, где переход держится на общей геометрии, а где старый объект просто исчезает под новым.
Настройте характер движения и физику
Для спокойного перехода часто достаточно easing, у которого скорость на концах равна нулю. В минимальном примере используется p²(3 − 2p) на ограниченном диапазоне. Это удобная интерполяция, а не физическая модель материала. Она помогает организовать вход, но не сообщает зрителю массу или упругость объекта сама по себе.
Пружина нужна, когда колебание действительно выражает характер движения. У неё есть масса, жёсткость и затухание. При массе 1 критический коэффициент затухания равен 2 × sqrt(k). Для k = 220 это примерно 29,66; значение 32 уже соответствует сверхкритическому режиму. Имя пресета вроде criticalText не доказывает, что формула реализует именно критический случай.
Функция движения должна восстанавливать результат из времени. Для простой пружины удобно аналитическое решение с явными начальными условиями. Если нужна численная физика, задайте фиксированный шаг расчёта, сохраните состояния и интерполируйте результат. Если шаг интеграции зависит от интервала между браузерными кадрами, нагрузка на компьютер может менять результат расчёта.
Разделяйте три дефекта. При скачке позиции объект мгновенно перемещается. При скачке скорости траектория непрерывна, но движение резко ломается. При смысловом скачке всё плавно, однако зритель теряет связь между объектами. Первые два можно изучать графиками и разностями значений; третий требует просмотра и обсуждения истории.
У персонажа двигаться должна связанная система: опора, корпус, взгляд и вторичные детали. Одна машущая кисть при неподвижном теле редко передаёт вес и намерение. Для длинного фильма сначала утвердите силуэт, пропорции и несколько поз. Общий rig — систему связанных частей персонажа — и правила внешности храните в одном месте. Так при смене сцены сохранятся пропорции, точки опоры и характер движения.
Проверьте настоящий стык цикла
Операция t % duration только возвращает время в начало. Минимальное превью использует её для удобства просмотра, но четыре состояния примера не образуют бесшовный цикл. Для цикла нужно отдельно согласовать изображение, движение и звук на границе.
Простой вариант — привести финальную композицию к начальному состоянию и успокоить движение. Периодическое вращение тоже может работать, если за длительность ролика совершается целое число оборотов и остальные свойства согласованы. Камера, фактура и маленькая подпись способны испортить стык даже при правильном движении главного объекта.
Не ограничивайтесь сравнением кадров в 0 и 16 секунд: modulo может сделать их одинаковыми по определению. Посмотрите последовательность duration − 1/fps, 0, 1/fps и короткий клип, где конец переходит в начало несколько раз. Так заметен скачок скорости, который теряется в двух неподвижных изображениях.
Звук проверяется отдельно. Разрыв волны, хвост реверберации и особенности воспроизведения AAC могут создавать щелчок или паузу. Быстрое склеивание MP4 с -c copy не доказывает sample-accurate loop. Проверяйте декодированные кадры, PCM-аудио и реальную среду показа. Если ролику нужен ясный финал, остановка с читаемым экраном может лучше соответствовать брифу.
Поставьте музыку на общую шкалу времени
Если музыка определяет монтаж, выберите её до тонкой настройки переходов. Если главная опора — речь, сначала закрепите реплики и их фактические длительности. Попытка добавить любую дорожку поверх уже законченного ритма часто приводит к случайным акцентам.
При 120 BPM один удар длится 0,5 секунды. В размере 4/4 такт занимает две секунды, а восемь тактов — 16 секунд. При первом сильном ударе в нуле начала тактов приходятся на 0, 2, 4 и далее. Переход на пятой секунде допустим как сознательное решение, но не соответствует обещанию ставить все крупные смены на начало такта.
Автоматический beat tracker оценивает точки ударов. Он может ошибиться вдвое по темпу, выбрать другую фазу или не найти устойчивый ритм. Начало такта нельзя получить просто объявлением каждого четвёртого найденного удара сильным. Размер и фазу нужно проверить на слух; затем сохранить принятые времена как данные, связанные с конкретной версией аудио.
Если хотите добавить Python-анализ, используйте отдельное виртуальное окружение, сверяйте API с выбранной версией librosa и сохраните зависимости. Для первого ролика эта библиотека необязательна. Несколько вручную проверенных опорных точек могут быть полезнее сложного детектора, качество которого никто не оценил.
Оставляйте периоды покоя. Основные переходы могут совпадать с музыкальной фразой, а небольшие детали — с отдельными ударами. Если всё двигается на каждом ударе, зрителю трудно выбрать момент для чтения. Один звуковой акцент должен подчёркивать видимое событие, а не компенсировать отсутствие ясного действия.
Добавьте звук с явной политикой длительности
Сохраняйте музыку, голос и эффекты отдельными дорожками. Тогда можно заменить язык, сделать тихую версию или изменить баланс, не пересоздавая графику. Рано сведённый MP3 ограничивает такую работу и скрывает происхождение отдельных звуков.
Чтобы объединить видео со звуком, подготовьте локальный assets/music.wav, который разрешено использовать в ролике. Создайте папку assets и положите файл в неё; звуковой файл в исходный пример не входит. Следующая команда дополняет короткую дорожку тишиной и обрезает длинную до 16 секунд. Это явная техническая политика; музыкальный финал всё равно нужно подготовить и прослушать заранее.
ffmpeg -n -i out/silent.mp4 -i assets/music.wav \
-map 0:v:0 -map 1:a:0 -c:v copy \
-af "asetpts=PTS-STARTPTS,apad=whole_dur=16,atrim=duration=16" \
-c:a aac -ar 48000 -b:a 192k -t 16 \
-movflags +faststart out/final.mp4
ffprobe -v error -show_streams -show_format \
-of json out/final.mp4 > out/final.probe.json
Здесь нет нормализации громкости. Не используйте -shortest как незаметное исправление: короткая аудиодорожка способна обрезать видео. Если нужен fade или хвост финальной ноты, внесите его в согласованную временную шкалу, а не рассчитывайте, что контейнер решит художественную задачу.
Для измерения готового закодированного файла можно использовать фильтр loudnorm:
ffmpeg -i out/final.mp4 -vn \
-af "loudnorm=I=-16:TP=-1.5:LRA=11:print_format=json" \
-f null - 2> out/loudness.log
В этом отчёте input_i и input_tp описывают измеренный вход, то есть ваш готовый файл. output_i и output_tp относятся к ещё одному проходу фильтра и не должны подменять результат измерения. Цель −16 LUFS здесь лишь пример настройки, а не универсальный норматив всех площадок.
Для двухпроходной нормализации сначала измеряют исходный mix, затем передают полученные параметры во второй проход и снова проверяют итог после AAC. Материал с короткими высокими пиками может потребовать изменения динамики, чтобы уложиться одновременно в цель по громкости и предел true peak. Сохраните измеренные integrated loudness, true peak и каналность. Разборчивость речи дополнительно проверяйте в наушниках и на телефоне: правильное число LUFS не устраняет частотный конфликт с музыкой.
Добавляйте motion blur после проверки траектории
Motion blur усредняет несколько состояний внутри интервала экспозиции. Это дополнительный проход рендера; в минимальный capture.mjs он намеренно не включён. Не добавляйте к нему придуманные флаги --sub или --shutter, пока такая функциональность не реализована и не проверена.
При четырёх подкадрах на итоговый кадр 16 секунд × 30 fps потребуют 1920 захватов вместо 480. При 60 fps их будет 3840. Прежде чем переносить размытие на весь фильм, проверьте короткий участок и оцените читаемость текста: типографике сильное размытие может мешать больше, чем помогать.
Задайте точную временную конвенцию. При четырёх равномерных подкадрах в серединах интервалов, симметричных относительно n/fps, и экспозиции в половину длительности кадра смещения составляют −0,1875, −0,0625, 0,0625 и 0,1875 длительности кадра. Первый кадр обращается к отрицательному времени. В цикле возможен wrap, в линейном фильме нужны clamp, удержание начального состояния или заранее определённый preroll.
Если усреднение выполняется через FFmpeg, учитывайте скользящий характер tmix: группировка подкадров и выбор результата должны быть явными. Проверьте алгоритм на изображениях с известными цветами, прежде чем оценивать красивую сцену. Усреднение кодированных цветовых значений также отличается от усреднения света в линейном цветовом пространстве.
Сначала устраните неверный fps, конфликт таймеров и скачки скорости. Размытие не исправляет плохую временную шкалу. Утверждённый обычный рендер остаётся контрольной версией, с которой сравнивают новый эффект.
Давайте Claude одну наблюдаемую правку
Запрос «сделай профессиональнее» не сообщает, что именно мешает ролику. Полезная правка содержит время, наблюдение, ограничение и способ повторной проверки. Предположим, после доработки Patchwork расширяющаяся карточка стала перекрывать заголовок. Это пример обратной связи для новой версии, а не обнаруженный дефект двух исходных файлов:
Исправь только переход 7.4–8.6 секунды.
При раскрытии карточка закрывает нижнюю часть заголовка.
Сохрани текст, палитру, шрифт, fps и длительность сцен.
Не меняй capture.mjs и зависимости.
До изменения назови вероятную причину.
После правки покажи кадры 7.4, 7.8, 8.0, 8.3 и 8.6.
Затем подготовь короткий клип 7–9 секунд.
Если нужен более широкий рефакторинг, объясни зависимость отдельно.
Для нового захвата нужен тот же локальный HTTP-сервер. Если вы остановили его после полного экспорта, снова выполните python3.12 -m http.server 8000 --bind 127.0.0.1 из папки проекта в отдельном терминале. Оставьте сервер работающим; следующие команды выполняйте во втором терминале из той же папки.
В приведённом рендерере диапазон 7–9 секунд выглядит так:
node capture.mjs --start 210 --end 270 --out out/transition-v2
ffmpeg -n -framerate 30 -start_number 210 \
-i out/transition-v2/%05d.png -frames:v 60 \
-c:v libx264 -pix_fmt yuv420p -crf 18 out/transition-v2.mp4
Входное время остаётся временем полного фильма, а выходной клип начинается с собственного нулевого timestamp. Нумерация PNG поэтому начинается с 210. Если забыть соответствующий -start_number, FFmpeg будет искать другие файлы.
Не смешивайте изменение стиля, обновление зависимостей и замену движка в одной итерации. Сохраните рабочую версию, проверьте минимальную гипотезу и решите, принимаете ли результат. В review-log.md достаточно номера версии, запроса, затронутых файлов, результата проверки и решения. Такой журнал объяснит через неделю, почему карточка стала медленнее.
Если модель постоянно меняет соседние части, сузьте задачу и укажите конкретные файлы. Новая сессия с актуальными брифом, стилем и списком дефектов может быть полезнее длинной истории отменённых решений. Важен согласованный текущий контракт, а не сохранение каждой реплики в одном контексте.
Проверьте готовый файл несколькими способами
Контактный лист помогает увидеть крупные состояния, повторяющиеся композиции и исчезнувший объект. Он не показывает плавность или синхронизацию музыки. Для 16-секундного фильма можно извлечь по кадру в секунду. Команды ниже используют версию со звуком; если звук не добавляли, замените out/final.mp4 на out/silent.mp4:
mkdir -p out/review
ffmpeg -n -i out/final.mp4 \
-vf "fps=1,scale=270:-1,tile=4x4" \
-frames:v 1 out/review/contact.png
ffmpeg -n -i out/final.mp4 \
-vf "trim=start=7:end=9,setpts=PTS-STARTPTS,fps=5,scale=216:-1,tile=5x2" \
-frames:v 1 out/review/transition.png
Первая сетка вмещает шестнадцать кадров. Для длинного фильма делайте несколько листов: фиксированный tile и один выходной PNG не означают, что весь материал просмотрен. Вторая команда сначала выбирает нужный временной диапазон и только потом собирает плотную сетку перехода.
Разделите приёмку на уровни:
- Математика: функции времени, границы интервалов, количество кадров и выбранные параметры движения.
- Браузер: загрузка ассетов, ошибки страницы и восстановление пикселей после перестановки
seek. - Кодирование: кодек, размер, fps, число декодированных кадров, длительность и отсутствие ошибок чтения.
- Звук: длительность, каналность, громкость, пики, стыки и разборчивость.
- Содержание и восприятие: правдивость текста, читаемость, причинность переходов и понятность результата.
Успех одного уровня не закрывает остальные. Подмена Canvas в тесте проверяет вызовы и расчёты, но не реальное отображение букв. Хеш MP4 относится ко всему закодированному файлу, включая контейнер, поэтому не заменяет сравнение изображений. Побайтовое сравнение кадров полезно в одном закреплённом окружении; между ОС и браузерами может понадобиться пороговое сравнение и визуальная проверка.
Посмотрите ролик без звука, затем послушайте звуковую дорожку отдельно и, наконец, просмотрите всё вместе в реальном темпе. Для критика задайте наблюдаемый формат: timestamp, дефект, вероятная причина, минимальная правка. Число «8 из 10» не объясняет, готова ли работа к передаче.
Если тест не запускался, в отчёте так и пишите. Успешный анализ документации не является выполненным рендером. Для этой инструкции точный технический журнал должен храниться рядом с проверенной версией примера; его выводы нельзя переносить на изменённую сцену без повторной проверки.
Превратите повторённый процесс в skill
Шаблон появляется после принятого ролика и повторной сборки. Сначала выделите действительно повторившееся: загрузку, текстовый layout, общий таймлайн, экспорт и проверки. Универсальный движок до первого законченного результата обычно добавляет больше неизвестного, чем экономит работы.
В Claude Code процесс можно оформить в skill. Например, файл .claude/skills/motion-review/SKILL.md задаёт отдельный проход проверки:
---
name: motion-review
description: Проверить черновой ролик по брифу и журналу рендера.
disable-model-invocation: true
---
Прочитай project-brief.md, motion-spec.md и последний review-log.md.
Сверь входную версию, параметры экспорта и реально выполненные проверки.
Посмотри контактный лист и доступный клип; назови непроверенные части.
Верни дефекты с timestamp и минимальной правкой.
Не меняй код, не публикуй файл и не запускай платные сервисы.
Вызов /motion-review запускает описанную процедуру. Поле disable-model-invocation оставляет запуск за пользователем; оно не ограничивает процесс на уровне ОС и не предоставляет новых разрешений.
Если позже понадобится внешний каталог ассетов или сервис озвучки, сначала проверьте его контракт отдельно от модели. Успешное соединение не доказывает корректность ответа и допустимость расхода. Локальному Canvas-примеру MCP не нужен.
Параллелите сцены после общего образца
Длинный фильм удобнее делить на самостоятельные главы с утверждённым визуальным языком. До параллельной работы создайте эталонную сцену, общие компоненты и контракт границ: положение главного объекта, состояние камеры, входной и выходной кадры, длительность и допустимые зависимости.
Один исполнитель должен владеть общим таймлайном и финальной интеграцией. Остальные меняют свои сцены. Если каждый пишет собственный рендерер, spring и копию логотипа, сборка начнётся с устранения несовместимостей. Изменение общего компонента проверяйте отдельно от художественной правки одной главы.
Субагент полезен для ограниченной задачи: сверить факты образовательной сцены или проверить несколько переходов. Команда агентов требует ещё и распределения владения файлами. Отдельный контекст разговора не означает отдельную файловую систему или автоматическую защиту от конфликтующих записей.
После интеграции проверьте начало и конец затронутых сцен и короткие клипы стыков. Изменение одной длительности может сдвинуть речь и музыку в остальном фильме. Для автономной работы заранее задайте пределы файлов, расходов и действий. Молчание пользователя не должно становиться разрешением на публикацию, новую подписку или передачу материалов.
Перенесите процесс на учебное видео с речью
Для учебного видео сначала определите проверяемый результат понимания. «Рассказать про очередь задач» слишком широко. Более точная цель: зритель объяснит, почему задача ждёт свободного исполнителя и чем очередь отличается от одновременного выполнения. Визуальная модель может показывать карточки и ограниченное число рабочих мест, но её допущения нужно назвать.
У каждой сцены должны быть учебная цель, проверяемое утверждение, источник, действие, реплика и состояние на выходе. Голос объясняет то, чего не видно напрямую: условие ожидания, ограничение модели или причину ошибки. Он не обязан перечислять каждое движение карточки.
Сначала сделайте временную начитку и animatic. Затем сохраняйте финальную речь по сценам, например queue-01-ru-v2.wav, с точным текстом, версией, языком и измеренной длительностью. Замена одной реплики не требует пересоздания всего голоса, но зависимые паузы, события и субтитры всё равно нужно пересчитать.
При темпе 135 слов в минуту 80 секунд непрерывной речи вмещают около 180 слов. Это арифметическая оценка, а не норма понятного урока. Сложные термины и время для наблюдения уменьшают полезный объём. Если текст не помещается, сократите объяснение или продлите сцену; автоматическое ускорение голоса может ухудшить понимание.
Музыка под речью требует отдельного баланса и плавного ducking, то есть снижения уровня на время реплик. Выбирайте величину по голосу и фонограмме, затем слушайте вход и восстановление уровня. Сохраняйте дорожки раздельно. Для внешнего TTS заранее проверьте разрешение на передачу сценария, условия сервиса и права на используемый голос.
Субтитры сверяются с окончательной речью: слова, числа, отрицания, термины и границы реплик. Сохраните редактируемый SRT или VTT; при необходимости сделайте отдельную версию с вшитыми подписями. Крупные кинетические слова не заменяют точные субтитры. Для вертикальной версии заново проверьте переносы и конфликт с главным объектом.
Приёмка такого фильма включает предметную проверку и пересказ зрителя из целевой аудитории. Ошибка в объясняемой причинной связи не исчезает от удачного цвета или плавного движения. Числовая самооценка модели не подтверждает, что человек понял объяснение.
Используйте генеративные планы как отдельный вход
Для отражений, сложного материала или движения камеры вокруг продукта можно добавить генерацию видеопланов. Тогда Claude помогает составить shot list и собрать монтаж, а пиксели плана создаёт другой сервис. Принятые клипы сохраняются локально, точные цены, подписи и логотипы остаются контролируемыми графическими слоями.
Один из таких инструментов — Boreal-H3 от Creatify. Эта ветка необязательна для кодового ролика. Перед платным запуском откройте актуальную документацию выбранного режима, тариф и условия передачи материалов. Не выводите наличие локальных весов или точность бренда из демонстрационной страницы.
Подготовьте согласованные виды одного продукта и список признаков, которые менять нельзя. Для каждого плана задайте цель, длительность, крупность, движение камеры, свет, референсы и состояние на выходе. Критерии брака должны быть предметными: лишняя кнопка, меняющийся порт, неверная надпись, деформированный логотип или скачок цвета.
Начните с одного короткого плана и ограниченного числа попыток. Проверяйте весь клип, включая промежуточные кадры. Красивая миниатюра не подтверждает сохранение товара при вращении. Сохраняйте принятый файл, параметры, идентификатор задания и фактический расход. Повторный запрос к генератору не равен повторному детерминированному рендеру.
При сетевом тайм-ауте сначала выясните судьбу уже созданного задания, прежде чем повторять платный POST. API-ключи держите в защищённом локальном или серверном процессе. Размещение исходника по URL, доступному поставщику, уже является передачей данных; нельзя делать конфиденциальный ассет публичным ради удобства.
После приёмки проверьте реальные размеры, fps, длительность и звук клипа. Выбранный инструмент сборки сцены должен уметь точно выбирать кадры исходного видео. Наш минимальный Canvas-захват этого не реализует: внедрение генеративного материала требует отдельного медиаэтапа и проверок seek.
Отделите интерактивное объяснение от линейного фильма
Интерактивный эксперимент добавляет действия пользователя к исходным параметрам. Например, зритель меняет число исполнителей и наблюдает длину очереди. Сначала нужно определить модель: правила поступления задач, время обработки, пределы параметров и величины, которые показываются на графике. Декоративный счётчик не должен жить отдельно от расчёта.
Разделите вычисление, визуализацию, команды пользователя и запись опыта. Кнопки Play, Pause и Reset обязаны согласованно управлять моделью и её измерениями. Для первого варианта проще применять новые параметры после Reset. Если изменения разрешены во время работы, явно опишите, действуют ли они с текущего момента или пересчитывают весь опыт.
Для повтора сохраняйте версию модели, начальные параметры, seed и события со временем. Аналитический расчёт подходит не всегда; численная симуляция может потребовать фиксированного шага и контрольных снимков состояния. Добавление функции seek не делает произвольный доступ корректным автоматически.
Если нужен MP4 одного опыта, сначала зафиксируйте этот опыт и способ восстановления его состояния, затем применяйте покадровый экспорт. FPS экрана и шаг расчёта модели — разные величины. Проверяйте контрольные случаи, края диапазонов, повтор после Reset и возврат из фоновой вкладки.
Интерактив требует дополнительных проверок: клавиатура, видимый фокус, подписи с единицами, сравнение без опоры только на цвет и вариант с уменьшенным движением. Цель вроде 60 fps проверяется на конкретных устройствах. Для первого моушн-проекта эта ветка может подождать; у неё другой продуктовый результат и отдельная приёмка.
Если удобнее Remotion или HyperFrames
Альтернативный движок создавайте в отдельном проекте. Сохраните бриф, стиль и критерии качества, но используйте его собственный контракт времени. Копирование Canvas-рендерера поверх чужого runtime создаёт конкурирующие механизмы управления кадром.
Remotion
Текущий официальный маршрут старта:
npx create-video@latest --yes --blank --no-tailwind patchwork-remotion
cd patchwork-remotion
npm install
npx remotion skills add
npm run dev
В другом терминале из этой папки запустите Claude Code и создайте композицию с явными ID, fps, размерами и длительностью. После этого проверьте фактический список:
npx remotion compositions
npx remotion render Main out/launch.mp4 \
--codec h264 --pixel-format yuv420p --crf 18
Вторая команда предполагает, что композиция действительно называется Main и entry point найден автоматически. Подставьте ID из списка; при необходимости укажите настоящий entry point согласно render CLI. В Remotion длительность композиции задаётся кадрами. Анимацию вычисляйте через frame-driven API, а не таймер, начавшийся при mount компонента.
Проверьте системные требования и лицензию Remotion до коммерческой работы. У проекта собственные условия, а не универсальная MIT-лицензия. Размер команды и сценарий использования влияют на необходимое разрешение; условия могут меняться между версиями.
HyperFrames
Для отдельного CLI-проекта:
npx hyperframes init patchwork-hyperframes --non-interactive
cd patchwork-hyperframes
npx hyperframes skills update
npx hyperframes doctor
npx hyperframes lint
npx hyperframes check --snapshots
npx hyperframes snapshot --at 0,1,2 --no-end --describe false
npx hyperframes render --output out/video.mp4
Следуйте документации CLI установленной версии. Корневая композиция, атрибуты времени и зарегистрированные GSAP-таймлайны в состоянии паузы должны соответствовать контракту движка. Здесь не следует добавлять свой window.seek вместо предусмотренного движком механизма.
Флаги последней проверки снимков выбраны осознанно: --no-end не добавляет отдельный финальный кадр, а --describe false отключает необязательное описание через модель. Иначе при наличии соответствующего API-ключа инструмент может выполнить внешний анализ. Локальный экспорт и команда публикации — разные действия; для сохранения MP4 публикация не нужна.
Репозиторий HyperFrames использует Apache 2.0. Условия медиа, шрифтов, музыки и подключённых сервисов проверяются отдельно. Эти же обязанности сохраняются при любом другом движке, даже если его код разрешён для коммерческого использования.
Соберите версии и пакет передачи
Формат, язык и вариант текста должны быть входными данными. Для каждого экспортируйте отдельный файл с понятным именем, например patchwork_release_en_9x16_v003.mp4. Один timeline можно использовать повторно, но layout и читаемость проверяются для каждой версии.
Для пакетного экспорта сначала запускайте варианты последовательно. Он должен останавливаться при ошибке и сохранять лог конкретного варианта. Несколько Chromium быстро увеличивают расход памяти, а параллельные encoder-процессы конкурируют за CPU. Оптимизация имеет смысл после измерения узкого места и проверки независимости кадров.
Различайте review, master и delivery. Черновик можно уменьшить ради быстрой обратной связи. Master сохраняет качество для производных версий. Delivery соответствует требованиям получателя. H.264 с yuv420p — практичный формат широкого воспроизведения, но он не подходит для прозрачного фона. Alpha нужно согласовать отдельным форматом и проверить у получателя.
В манифесте поставки сохраните commit, версии входных данных, команды, окружение, список файлов и контрольные суммы. В README должны быть понятные шаги восстановления зависимостей и рендера. Включите исходники, разрешённые ассеты, лицензии и известные ограничения; исключите секреты, node_modules, browser cache и случайные рабочие материалы.
Перед передачей распакуйте пакет в новую папку и повторите сборку по README. Так обнаруживаются забытый шрифт, абсолютный путь и файл, который существовал только на авторской машине. Успешный повтор в одном окружении не доказывает идентичную картинку на любой системе, поэтому укажите, где именно выполнена проверка.
Измеряйте стоимость на законченном варианте
В бюджете разделяйте работу модели, платные генерации, локальный рендер, хранение и ручные правки. Лимит попыток генерации относится ко всем дублям, а не только к принятому. Подписка, налоги и подготовка материалов могут лежать вне цены выходной секунды.
Полезные показатели собственного проекта: время до первого превью, число содержательных итераций, длительность захвата и кодирования, число подкадров, фактический API-расход и время человека. Сравнивайте одинаковые разрешение, fps и участок. Один холодный запуск с установкой Chromium и один повторный рендер измеряют разные вещи.
Если процесс медленный, сначала уменьшите разрешение черновика, длину диапазона и число подкадров. Измерьте захват и кодирование отдельно. Большая тень, процедурная фактура или программная отрисовка WebGL могут занимать больше времени, чем остальная сцена. Увеличение параллелизма до диагностики способно только сделать сбой сложнее.
Шаблон окупается, когда второй ролик использует проверенную инфраструктуру и требует меньше повторной настройки. Это можно установить по своим проектам. Обещать универсальное время производства или экономию без таких данных не стоит.
Что проверить при сбое
- Команда не найдена: проверьте PATH, текущую папку и фактическую версию. Не заменяйте имя недоступной модели только в тексте запроса.
- Chromium не запускается: сверяйте установку браузера с версией Playwright и читайте сообщение о библиотеках или поддержке ОС. Не обходите изоляцию вслепую.
- Кадр пустой: проверьте HTTP-ответ, ошибки страницы и готовность конкретного ассета. Сервер должен раздавать только нужную папку.
- Превью плавное, экспорт дёргается: ищите второй таймер, накопление состояния, ошибку fps или неверный seek.
- FFmpeg оставил повреждённый файл: проверьте stderr, код выхода, наличие всех PNG и начальный номер последовательности.
- Звук расходится постепенно: проверьте темп и общую временную шкалу. Постоянный сдвиг чаще указывает на offset, нарастающий — на длительность или темп.
- Текст обрезан в одной версии: проверяйте layout, реальные метрики шрифта и длинные строки. Не принимайте нечитаемый мелкий текст как нормальную адаптацию.
- После правки стало хуже в другом месте: сравните diff и повторите затронутые сцены, прежде чем менять ещё один параметр.
Первый проект закончен, когда вы можете воспроизвести MP4 из чистой папки, объяснить его временную шкалу и показать результаты технических и визуальных проверок. После этого замените бриф и соберите второй ролик тем же способом. Именно повторённый выпуск показывает, какие части действительно стали вашей рабочей системой.