Перейти к основному содержанию

Генерация видео в Claude Opus 5.5: от кода сцены до MP4

Opus 5.5 не выдаёт видеофайл: он пишет код сцены, а MP4 собирают браузер и ffmpeg. Для моушн-графики этого хватает, для живой съёмки нужна видеомодель.

LaoZhang AI TeamОпубликовано13 мин чтения
Содержание
Видео в Opus 5.5 от кода до MP4: модель пишет код сцены, браузер без окна снимает кадры, ffmpeg собирает ролик

Claude Opus 5.5 не возвращает видеофайл. Он пишет программу, которая рисует каждый кадр, а MP4 появляется позже: браузер без окна (headless) открывает сцену, делает снимок на каждый кадр, и ffmpeg склеивает снимки в ролик. Ролики «сделано Opus 5.5», которые расходятся по YouTube, X и Telegram с 22 сентября 2026 года, в большинстве своём получены именно так.

Из этого следует и граница. Всё, что можно нарисовать кодом, — моушн-графика, анимированные схемы, объясняющие ролики, промо продукта, титры под музыку — получается хорошо и воспроизводимо. Фотореалистичные люди, естественная мимика и фактура живой съёмки кодом не рисуются: для них нужна модель генерации видео, а Opus 5.5 в такой связке пишет сценарий, вызывает её и монтирует результат.

Повторить это можно на обычном ноутбуке: нужны Node.js, установленный Chrome, ffmpeg и скрипт рендера примерно на полсотни строк. Ниже — такой скрипт, замер на 12-секундной сцене и случай, когда рендер тихо выдаёт испорченный ролик.

Что на самом деле выдаёт модель

В обзоре моделей Anthropic сказано прямо: все текущие модели Claude принимают текст и изображения, а отдают текст (обзор моделей). Видео и изображений среди выходных форматов нет. Код — это тоже текст, поэтому «видео от Opus 5.5» всегда означает файл с программой: HTML-страницу с Canvas, проект на React, скрипт на Python.

В анонсе Opus 5.5 нет ни слова про видео, анимацию или моушн-графику. Это не объявленная функция, а способ использования, который нашли сами пользователи. Справка Claude описывает ту же логику для картинок: Claude не создаёт фотографии и иллюстрации так, как это делают генераторы изображений, зато строит диаграммы, графики и интерактивные визуализации из HTML и SVG (справочный центр Claude). Подробнее об этой стороне — в разборе «Может ли Claude генерировать изображения?».

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

  • качество картинки определяется тем, насколько хорошо написана сцена, а не «разрешением модели»: размер кадра задают сама сцена и окно рендера;
  • исправление — это правка кода, а не новая попытка вслепую: можно попросить сдвинуть заголовок на полсекунды, и остальное не изменится;
  • сама модель ролик не видит, пока ей не показать кадры. В Claude Code она может запустить рендер, вытащить несколько кадров и посмотреть на них, в обычном чате такой проверки нет.

Модальности одинаковы у всех текущих моделей Claude, так что принцип не привязан к Opus 5.5: любая из них может выдать только код сцены. Насколько сложную сцену каждая напишет с первого раза — другой вопрос; общий выбор между двумя моделями линейки разобран в материале «Claude Sonnet 5.5 или Opus 5.5».

Какой ролик получится кодом, а какому нужна видеомодель

Правило простое: если кадр можно описать как фигуры, текст, линии, графики и движение между ними, его можно нарисовать кодом. Если в кадре должен быть убедительный живой человек или съёмочная фактура, код не поможет.

ЗадачаЧем делатьПочему
Промо продукта, анимация интерфейса, титрыОтрисовка кодомТекст, формы и переходы задаются точно и правятся построчно
Объясняющий ролик, анимированная схема, формулыОтрисовка кодомСцена строится из данных, цифры в кадре всегда верные
Рисованная, контурная, «тушевая» анимация, клип с текстом песниОтрисовка кодомСтиль задаётся алгоритмом кисти, движение привязывается к времени трека
Фотореалистичные люди, липсинк, «снято на камеру»Модель генерации видеоТакую фактуру процедурно не нарисовать
Реалистичные вставки внутри графического роликаОба подходаВидеомодель даёт фрагменты, Opus 5.5 пишет монтаж, титры и переходы

Перечень сильных и слабых сторон взят из подборки публичных примеров и промптов за первые дни после релиза: её составитель относит к удачным жанрам моушн-графику, рисованную анимацию, объясняющие ролики, промо и клипы, а для реалистичных кадров описывает обычную практику — модель вызывает Seedance, Runway или Higgsfield и сама занимается компоновкой и монтажом. Это оценка составителя по увиденным работам, а не замер качества.

Картину подтверждает и более крупная выборка. В каталоге роликов из X, собранном до 26 сентября 2026 года, из 1 401 видеофайла классификатор отнёс 1 119 к сделанным с участием Opus 5.5; у 350 из них основной стиль — моушн-графика и интерфейсы, у 324 — 3D-рендер, вместе 60,2 %. Медианная длина превью — 39,2 секунды. У этих цифр есть оговорка самих авторов каталога: метки ставила другая модель по тексту поста и девяти кадрам, и участие Opus 5.5 они не доказывают. Но о том, что люди делают этим способом, выборка говорит ясно: короткие графические ролики, а не игровое кино.

Если ваш замысел попал в строку про живую съёмку, вам нужны другие инструменты: вызов настоящей видеомодели из кода показан в руководстве «Seedance 2.5 API: ID модели, Python и Node.js без путаницы маршрутов», а порядок цен — в материале «Сколько стоит генерация видео нейросетью: цена секунды и ролика».

Первый MP4 на своей машине

Минимальная схема состоит из трёх частей: файл сцены, скрипт рендера и ffmpeg. Устанавливается всё одной командой и пакетом из системного менеджера:

bash
npm i playwright-core
# ffmpeg — из Homebrew, apt или winget; Chrome должен быть установлен в системе

playwright-core управляет уже установленным Chrome и не скачивает отдельный браузер.

Четыре шага рендера: сцена scene.html, захват кадров в браузере без окна, сборка ролика в ffmpeg и проверка файла

Сцена: договор между моделью и рендером

Сцена должна уметь одно: по запросу нарисовать кадр для любого момента времени. Для этого у неё два обязательных элемента — длительность window.DURATION и функция window.seek(t), которая рисует картинку для секунды t с чистого листа.

html
<!doctype html>
<meta charset="utf-8">
<canvas id="c" width="1920" height="1080"></canvas>
<script>
window.DURATION = 12;                      // длительность ролика в секундах
const ctx = document.getElementById("c").getContext("2d");
// генератор с фиксированным зерном: «случайные» значения одинаковы при каждом рендере
function rng(seed) { return () => { seed = (seed * 1664525 + 1013904223) >>> 0; return seed / 4294967296; }; }
window.seek = async (t) => {
  ctx.clearRect(0, 0, 1920, 1080);
  // всё, что рисуется ниже, вычисляется только из t
};
</script>

Запрос к модели должен включать этот договор целиком, иначе она напишет обычную веб-анимацию, которая хорошо выглядит в браузере и ломается при рендере:

Напиши scene.html — один HTML-файл с Canvas 2D размером 1920×1080, без внешних файлов и библиотек.
Содержание: 12 секунд; заголовок появляется и уходит к 4-й секунде, затем по очереди четыре блока схемы, в конце счётчик кадров и полоса прогресса.
Требования к рендеру:
- window.DURATION — длительность в секундах;
- window.seek(t) рисует кадр для времени t с нуля, картинка зависит только от t;
- не использовать requestAnimationFrame, performance.now, Date, таймеры и CSS-переходы;
- случайные значения брать только из генератора с фиксированным зерном;
- шрифты только системные.

Счётчик кадров в углу — не украшение: по нему потом проверяется синхронность. В готовом ролике его можно убрать одной правкой.

Противоположный подход — одна строка без технических условий. Самый короткий пример приведён в той же подборке промптов: Диди Дас (@deedydas) написал «make a modern slick and punchy video for a modern startup that works on inference», а инструменты модель выбрала сама. Так работает только среда, где модель может сама запускать команды и смотреть на результат; составитель подборки советует Claude Code с Opus 5.5 на effort high или xhigh и локально установленные Node.js, Chrome и FFmpeg.

Скрипт рендера

Скрипт открывает сцену, для каждого кадра вызывает seek, делает снимок окна и по трубе отправляет его в ffmpeg. В конце он печатает число кадров, время захвата, размер файла и хеш всех снимков.

js
// node render.mjs scene.html out.mp4 [fps] [png|jpeg]
import { chromium } from "playwright-core";
import { spawn } from "node:child_process";
import { once } from "node:events";
import { createHash } from "node:crypto";
import { statSync } from "node:fs";
import path from "node:path";
import { pathToFileURL } from "node:url";

const [scene, out, fpsArg = "30", type = "png"] = process.argv.slice(2);
if (!scene || !out) throw new Error("Usage: node render.mjs scene.html out.mp4 [fps] [png|jpeg]");
const fps = Number(fpsArg);
const started = Date.now();
const browser = await chromium.launch({ channel: "chrome", headless: true });
const page = await browser.newPage({ viewport: { width: 1920, height: 1080 }, deviceScaleFactor: 1 });
await page.goto(pathToFileURL(path.resolve(scene)).href);
await page.waitForFunction(() => typeof window.seek === "function");
await page.evaluate(() => document.fonts.ready);
const total = Math.round((await page.evaluate(() => window.DURATION)) * fps);

const ff = spawn("ffmpeg", ["-y", "-loglevel", "error", "-f", "image2pipe", "-framerate", String(fps), "-i", "-",
  "-c:v", "libx264", "-pix_fmt", "yuv420p", "-crf", "18", "-movflags", "+faststart", out],
  { stdio: ["pipe", "inherit", "inherit"] });
const hash = createHash("sha256");
const shotOpts = type === "jpeg" ? { type: "jpeg", quality: 92 } : { type: "png" };
const captureStart = Date.now();
for (let i = 0; i < total; i++) {
  await page.evaluate((t) => window.seek(t), i / fps);   // кадр i соответствует времени i / fps
  const buf = await page.screenshot(shotOpts);
  hash.update(buf);
  if (!ff.stdin.write(buf)) await once(ff.stdin, "drain");
}
const captureMs = Date.now() - captureStart;
ff.stdin.end();
const [code] = await once(ff, "close");
await browser.close();
if (code !== 0) throw new Error(`ffmpeg exited with ${code}`);
console.log(JSON.stringify({
  scene, out, fps, frames: total, shot: type,
  capture_seconds: +(captureMs / 1000).toFixed(2),
  total_seconds: +((Date.now() - started) / 1000).toFixed(2),
  ms_per_frame: +(captureMs / total).toFixed(1),
  mp4_bytes: statSync(out).size,
  frames_sha256: hash.digest("hex").slice(0, 16),
}));

Запуск:

bash
node render.mjs scene.html out.mp4 30 png

Проверка готового файла

Ролик, который открылся в плеере, ещё не проверен. Три короткие проверки показывают, совпадает ли файл с тем, что задумано в сцене.

bash
# 1. Кодек, размер, частота кадров, число кадров и длительность
ffprobe -v error -select_streams v:0 -count_frames \
  -show_entries stream=codec_name,width,height,r_frame_rate,nb_read_frames:format=duration out.mp4

# 2. Кадр из известного момента — сравнить с тем, что сцена должна показывать
ffmpeg -ss 9.5 -i out.mp4 -frames:v 1 frame-9500.png

# 3. Покадровые контрольные суммы — сравнить у двух рендеров одной сцены
ffmpeg -i out.mp4 -f framemd5 -

Первая проверка должна показать число кадров, равное длительности, умноженной на частоту: 12 секунд при 30 кадрах в секунду — это 360 кадров. Вторая — что кадр на отметке 9,5 секунды показывает номер 285, потому что 9,5 × 30 = 285. Третья — что два рендера одной и той же сцены совпадают кадр в кадр. Если не совпадают, сцена зависит от чего-то кроме t, и об этом следующий раздел.

Что показал тестовый рендер

Сцена для замера — 12-секундная анимация на Canvas 2D: заголовок, четыре блока схемы, фон из 140 частиц с фиксированным зерном, счётчик кадров. Её написал Opus 5.5 в сессии Claude Code за один проход, без ручных правок. Рендер выполнен 1 октября 2026 года на Apple M4 (10 ядер, 16 ГБ, macOS 26.1) с Node 24.11.0, playwright-core 1.63.0, Chrome 154 и ffmpeg 8.0.1 — скриптом, приведённым выше.

ВариантКадровЗахватНа кадрК длине роликаРазмер MP4
Снимки PNG, первый запуск36025,93 с72 мспримерно 2,2×915 183 байта
Снимки PNG, второй запуск36025,80 с71,7 мспримерно 2,2×915 183 байта
Снимки JPEG, качество 9236011,51 с32 мспримерно 0,96×1 093 045 байт

Весь процесс вместе с запуском браузера и кодированием занял 33,46 и 27,24 секунды для PNG. ffprobe подтвердил параметры файла: H.264, 1920×1080, 30 кадров в секунду, 360 кадров, 12,000 секунды. Кадр, извлечённый на отметке 9,5 секунды, показывает надпись «frame 285 / 360, t = 9.500 s» — счётчик в кадре совпал с положением в файле.

Из таблицы видны три вещи.

Рендер идёт не в реальном времени, и это нормально. При 30 кадрах в секунду на кадр отводится 33,3 мс, а снимок PNG занимал 72 мс. Сцена этого не замечает: ей говорят «покажи секунду 4,2», и она показывает секунду 4,2, сколько бы времени ни прошло снаружи.

Формат снимка меняет скорость сильнее, чем можно ожидать. JPEG сократил захват с 26 до 11,5 секунды, то есть рендер пошёл почти со скоростью воспроизведения. Плата — файл на 19 % больше и промежуточное сжатие с потерями перед кодированием. Для черновиков удобнее JPEG, для финальной версии с тонкими градиентами и мелким текстом — PNG.

Два рендера одной сцены совпали полностью. Хеши снимков одинаковы, размеры файлов совпали до байта, покадровые контрольные суммы после декодирования MP4 тоже. Это и есть детерминированность: одинаковая сцена даёт одинаковые кадры. На практике это означает, что правку одной надписи можно проверить сравнением, а не пересмотром всего ролика.

Замер относится к одной машине и одной простой двумерной сцене без звука. Тяжёлая 3D-сцена, загрузка шрифтов или другой рендерер дадут другие числа.

Почему сцена должна зависеть только от времени кадра

Обычная веб-анимация устроена иначе: она спрашивает у браузера, сколько времени прошло с начала, и рисует соответствующее состояние. В окне браузера это работает безупречно. При покадровом захвате такая сцена продолжает жить по настоящим часам, пока рендерер тратит время на снимки, и кадры перестают соответствовать своим местам в ролике.

Контрольный пример — трёхсекундная сцена на requestAnimationFrame и performance.now() с обычным Math.random(), которая игнорирует seek. Тем же скриптом на той же машине она была отрендерена дважды:

Что сравниваетсяСцена через seek(t)Сцена на настоящих часах
Хеши кадров двух рендеровсовпадаютразные
Размер файла двух рендеров915 183 и 915 183 байта115 816 и 131 033 байта
Время, которое показывает кадр9,500 с на отметке 9,5 с1,572 с на отметке 1,5 с

Сравнение двух сцен: у сцены через seek(t) хеши и размеры файлов совпадают, у сцены на настоящих часах они разные, а кадр сдвинут на 72 мс

Самое неприятное в этом отказе — он не выглядит как ошибка. Скрипт завершился без сообщений, MP4 открылся, движение на глаз было почти правильным. Причина в совпадении: захват кадра у этой лёгкой сцены занимал 33,6–38 мс, то есть почти столько же, сколько длится кадр при 30 кадрах в секунду. Расхождение в 72 мс на середине ролика заметно только по надписи со временем.

Стоит сцене стать тяжелее, и совпадение исчезнет. Если бы захват занимал 72 мс на кадр, как у первой сцены с PNG, за время одного кадра ролика сцена успевала бы прожить больше двух кадров, и движение в файле шло бы примерно в 2,2 раза быстрее задуманного (72 ÷ 33,3). Это расчёт по измеренным числам, отдельно такой рендер не записывался.

Отсюда список того, чего в сцене быть не должно, если рендерер просто вызывает seek: requestAnimationFrame как источник времени, performance.now() и Date, таймеры, CSS-переходы, Math.random() без зерна, элементы video и audio, внешние картинки и шрифты, которые могут не успеть загрузиться. Часть этого списка — video, audio, iframe, CSS-переходы, Math.random и внешние картинки — запрещена и в сценах проекта LaunchVideo, хотя часы страницы там подменяет сам рендерер; в его README причина названа прямо: рендер должен оставаться детерминированным.

Чем рендерить: свой скрипт, HyperFrames или Remotion

Скрипт из этого руководства — самый короткий путь, но не единственный. Остальные варианты решают ту же задачу — заставить сцену показать нужный кадр — другими средствами.

СпособКак пишется сценаУсловияКогда выбирать
Свой скрипт: Playwright и ffmpegОдин HTML-файл с seek(t)Node.js, Chrome, ffmpeg; контракт сцены на васПервый ролик, короткие сцены, полный контроль
Виртуальные часы, как в LaunchVideoОбычный HTML с CSS-анимациями или циклом requestAnimationFrameРендерер подменяет часы страницы и сам управляет временемСервис, где сцену пишет агент без участия человека
HyperFramesHTML с атрибутами времени и дорожекNode.js 22+, FFmpeg; лицензия Apache 2.0; есть плагин для Claude CodeДлинные композиции, готовые анимации на GSAP, Lottie, Three.js
RemotionКомпоненты ReactБесплатно для частных лиц, компаний до 3 сотрудников и некоммерческих организаций; остальным нужна Company LicenseКоманда уже пишет на React и хочет ролики как часть кодовой базы

LaunchVideo (репозиторий diggerhq/shipvideo) показывает, как выглядит тот же конвейер в виде сервиса. По описанию в README проекта, Opus 5.5 пишет фильм как один HTML-документ 1920×1080, шаг check_scene загружает его под виртуальными часами и сообщает об ошибках JavaScript и видимом тексте в нескольких точках по времени, и только после исправлений запускается рендер. Часы страницы подменены целиком — кадры анимации, таймеры, Date, CSS-анимации, — поэтому сцена может быть написана привычным способом. На выходе ролик на 20–40 секунд; авторы пишут, что рендер идёт примерно в реальном времени: 30-секундный фильм занимает 30–40 секунд на их инфраструктуре. Идея предварительной проверки стоит того, чтобы её перенять: дешевле попросить модель посмотреть на пять кадров, чем рендерить весь ролик с опечаткой.

HyperFrames описывает себя как открытый фреймворк, превращающий HTML, CSS, медиа и анимации с перемоткой в детерминированные MP4: рендерер выставляет каждый кадр в Chrome без окна и кодирует результат через FFmpeg (README). Лицензия Apache 2.0, без платы за рендер и без порогов для коммерческого использования. Плагин для Claude Code ставится двумя командами:

bash
claude plugin marketplace add heygen-com/hyperframes
claude plugin install hyperframes@hyperframes

После установки он вызывается командой /hyperframes:hyperframes.

Remotion — выбор для тех, кто пишет на React. Здесь важнее всего лицензия: по тексту лицензии, бесплатно им могут пользоваться частные лица, коммерческие организации до трёх сотрудников и некоммерческие организации, в том числе для коммерческих роликов. Компании крупнее обязаны купить Company License. Если ролик делается для работодателя, сначала выясните, под какое условие попадает организация.

Для математических и научных объяснений в публичных примерах встречается ещё Manim — библиотека на Python для математической анимации.

Сведения о LaunchVideo, HyperFrames и Remotion взяты из их собственных README и лицензии; числа из раздела с замером относятся только к скрипту на Playwright.

Сколько стоит ролик

Сам рендер на своей машине бесплатен. Платить приходится за токены, которые модель тратит на написание и правку сцены. Цена Opus 5.5 в API по состоянию на 1 октября 2026 года — $4 за миллион входных и $20 за миллион выходных токенов, идентификатор модели claude-opus-5-5.

стоимость = входные токены × $4 / 1 000 000 + выходные токены × $20 / 1 000 000

Измеренного «типичного» расхода на ролик не существует: в открытом доступе есть только цифры, которые называют сами авторы.

Чьи данныеРоликЧто заявлено
Авторы LaunchVideo, в пересказе статьи сообщества на Hugging FaceПромо на 20–40 секундОколо 4 минут, примерно 90 000 входных и 15 000 выходных токенов
Диди Дас, по записи в подборке промптовПромо стартапа из однострочного запросаОколо минуты и около $2
Пользователь Linux.do, по записи в той же подборкеКлип на p5.js, effort xhigh, с правками персонажа по замечаниямПервая версия за 45 минут, около $200

Первая строка подставляется в формулу:

90 000 × $4 / 1 000 000  = $0,36
15 000 × $20 / 1 000 000 = $0,30
итого                      $0,66 за один проход

Это расчёт по стороннему заявленному бюджету, а не замер: в README самого проекта этих чисел нет, они известны только в пересказе. Разброс между строками таблицы — от десятков центов до сотен долларов — и есть главный вывод. Стоимость определяет не длина ролика, а то, сколько раз сцена переписывается и как долго модель думает:

  • каждая правка и каждая повторная попытка оплачиваются заново, причём с ростом сессии растёт и входной контекст;
  • токены размышления считаются как выходные, поэтому переход со стандартного medium на high или xhigh увеличивает счёт;
  • чтение из кэша стоит $0,20 за миллион токенов, и в длинной агентной сессии это снижает цену повторно отправляемого контекста;
  • озвучка, музыка и кадры от видеомодели оплачиваются отдельно и в эту формулу не входят.

Чтобы оценить собственный ролик, сделайте один короткий прогон на 10–15 секунд, посмотрите фактический расход токенов в статистике использования и умножьте по формуле на ожидаемое число итераций.

На подписке Claude счёта за токены нет: расход отражается в лимитах использования. В той же подборке есть пример такого учёта — автор клипа длиной 156,6 секунды (около 3 760 кадров, два прогона) сообщил, что потратил 10 % недельного лимита тарифа Max 5x. Как устроены эти лимиты и цена API, разобрано в материале «Claude Opus 5.5: цена API и как сбросить лимит подписки».

Частые вопросы

Может ли Opus 5.5 сгенерировать видео прямо в чате?

Нет, видеофайл модель не возвращает: на выходе у неё только текст. В чате она может написать сцену и показать её как интерактивную страницу, а чтобы получить MP4, эту сцену нужно отрендерить — локально скриптом или в среде, где модель сама запускает команды, например в Claude Code.

Почему ролик идёт слишком быстро или дёргается, хотя в браузере всё было плавно?

Почти всегда сцена берёт время из настоящих часов, а не из аргумента seek(t). Захват кадра длится дольше или короче, чем сам кадр, и движение расходится с роликом. Проверка простая: отрендерите сцену дважды и сравните покадровые контрольные суммы. Если они различаются, попросите модель переписать сцену так, чтобы всё вычислялось из t, а случайные значения брались из генератора с зерном.

Можно ли добавить звук?

Да, но это отдельный этап. В публичных примерах музыку синтезируют через Web Audio или на Python, закадровый голос делают синтезом речи, а затем ffmpeg сводит дорожку с видео. В замере выше звука не было, поэтому время рендера и размер файла относятся к немому ролику.

Что выбрать, если нужен ролик с живым человеком в кадре?

Модель генерации видео. Кодом рисуются графика и схемы, а реалистичные лица и съёмочная фактура — нет. Opus 5.5 в таком проекте полезен как режиссёр монтажа: он пишет сценарий, вызывает видеомодель через API и собирает фрагменты с титрами. С чего начать без оплаты, описано в обзоре «Бесплатный API генерации видео: что доступно без оплаты».

Уведомление Temporarily unable to authenticate в Claude и три ветки диагностики: инцидент у Anthropic — ждать, логин и окружение — чинить, аккаунт и регион — не сбой
Claude и Anthropic

Temporarily unable to authenticate в Claude: ждать или чинить

Фраза приходит от Anthropic, а не из вашего клиента. Есть инцидент на status.claude.com — не выходите из аккаунта и ждите; нет — ищите другую строку в /status.

12 мин
Первые действия при внутренней ошибке сервера Claude
Claude и Anthropic

Внутренняя ошибка сервера Claude: сначала статус, затем владелец сбоя

Не удаляйте настройки и не повторяйте запрос по кругу. Сначала статус, затем интерфейс, провайдер, уже выполненные попытки и частичный результат; после одного безопасного повтора — остановка и сбор доказательств.

13 мин