Felo API PlatformFelo API Platform

Контент

Создайте моушн-видео на HTML с Opus 5.5

Напишите бит-лист, попросите Opus 5.5 через Felo API создать детерминированную HTML-сцену, затем снимите кадры через Playwright и закодируйте MP4 в ffmpeg. Запускается в WorkBuddy, ChatGPT с исполнением кода, Codex, Pi Agent или Claude Code.

Время45 минутУровеньСреднийОбновлено2026-10-30
Для когоАвторыМоушн-дизайнерыНезависимые разработчики

Скопировать промпт

Замените поля в квадратных скобках и вставьте в Claude Code, Codex или любой AI с доступом к терминалу. Он установит навык Felo, спросит перед списанием кредитов и выполнит процесс.

Создай видео на [длительность] секунд, формат [вертикальный / горизонтальный], по идее [идея].
Стиль: [стиль]. Аудитория: [аудитория]. Аудио: [нет / лицензированный трек в ./audio.mp3 / TTS].

Ты работаешь в папке с терминалом и [WorkBuddy / ChatGPT с выполнением кода / Codex / Pi Agent / Claude Code]. Если не можешь запустить Node и headless-браузер, остановись и скажи мне, а не делай вид, что отрендерил.

Действуй по порядку:
1. Напиши раскадровку из 3–6 битов с точными секундами начала и конца.
2. Шаг HTML: вызови Claude Opus 5.5 через Felo API. Используй ID модели claude-opus-5-5 и мой FELO_API_KEY. Не проси у меня подписку Claude или другой ключ Anthropic.
3. Попроси Opus сделать один самодостаточный HTML-файл: задать window.DURATION и открыть async window.seek(t). Никаких внешних ресурсов, CDN, Date.now(), requestAnimationFrame(), CSS-переходов и таймеров. Задай seed всем случайным значениям, чтобы один и тот же t всегда рисовал один и тот же кадр.
4. Проверь предпросмотр при t = 0, 25%, 50%, 75% и на последнем кадре. До полного рендера проверь переполнение, обрезку, шрифты и безопасные зоны.
5. Отрендерь каждый кадр через Playwright, закодируй в H.264 через ffmpeg и склей аудиодорожку, если она есть.
6. Покажи первый кадр, последний и итоговый путь к файлу. Ничего не публикуй.

Правила:
- Перед расходом кредитов покажи вызовы Felo API и оценку токенов.
- Используй только текст, который дал я, или явно помечай выдуманный текст-заглушку.
- Не используй защищённые авторским правом материалы, музыку, логотипы и шрифты. Только системные шрифты и сгенерированные фигуры.
- Держи итоговое видео короче 30 секунд, если я явно не попросил длинное.
- Запиши всё в ./video/ и кратко изложи выполненные команды.

В копию также входят шаги установки и правила безопасности.

Что получится

Пример вывода одного запуска. Не живая генерация.

Пример отчёта рендера (фрагмент)

Отчёт рендера

Сцена: video/scene.html (18 КБ) Длительность: 12 с · 1080x1920 · 30 fps · 360 кадров Проверки: window.DURATION = 12 · seek(t) есть · без Date.now / rAF / таймеров

Предпросмотр: preview-0ms.png · preview-3000ms.png · preview-6000ms.png · preview-9000ms.png Кодирование: video/video.mp4 (H.264, 360 кадров) Аудио: video/final.mp4 (AAC, 12,0 с)

Реальные вызовы

Для разработчиков: тот же процесс в виде кода в порядке выполнения.

Показать реальные вызовы API
  1. Сначала напишите бит-лист

    Сначала зафиксируйте длительность и 3–6 битов: время начала и конца, текст на экране и главное визуальное изменение.

  2. Создайте HTML-сцену через Opus 5.5

    Направьте Anthropic SDK на base URL Felo, используйте модель claude-opus-5-5 и попросите вернуть только HTML с window.DURATION и async seek(t).

    generate-scene.ts
    import { mkdir, writeFile } from "node:fs/promises";
    import Anthropic from "@anthropic-ai/sdk";
    
    const SYSTEM = `You write a single, self-contained HTML video scene.
    Requirements:
    - 1080x1920 (or 1920x1080), no external assets, system fonts only.
    - set window.DURATION = <seconds>.
    - expose async window.seek(t) that draws the frame for time t.
    - no Date.now(), no requestAnimationFrame(), no CSS transitions, no timers.
    - seed every random value; the same t must always produce the same frame.
    - return only the HTML file, no markdown fences.`;
    
    const brief = `12-second vertical motion graphic about [idea].
    Beats: [0-3s hook], [3-7s point], [7-10s proof], [10-12s CTA].
    Palette: [colors]. Type: system sans. Keep text inside a 64px safe area.`;
    
    const anthropic = new Anthropic({
      apiKey: process.env.FELO_API_KEY,
      baseURL: "https://openapi.felo.ai/api",
    });
    
    const message = await anthropic.messages.create({
      model: "claude-opus-5-5",
      max_tokens: 32000,
      system: SYSTEM,
      messages: [{ role: "user", content: brief }],
    });
    
    const raw = message.content
      .filter((block) => block.type === "text")
      .map((block) => block.text)
      .join("");
    
    const html = raw.replace(/^```(?:html)?\s*/i, "").replace(/```\s*$/, "").trim();
    await mkdir("video", { recursive: true });
    await writeFile("video/scene.html", html);
    console.log(`scene.html: ${html.length} bytes`);

    Пример вывода

    scene.html: 18432 bytes
  3. Проверьте детерминизм и превью ключевых кадров

    Сделайте скриншоты в t=0, 25%, 50%, 75% и на последнем кадре; проверьте переполнение текста, шрифты и безопасные зоны.

    preview.ts
    import { chromium } from "playwright";
    import { pathToFileURL } from "node:url";
    
    const browser = await chromium.launch();
    const page = await browser.newPage({
      viewport: { width: 1080, height: 1920 },
      deviceScaleFactor: 1,
    });
    
    await page.goto(pathToFileURL("video/scene.html").href);
    await page.waitForFunction(() => typeof (window as any).seek === "function");
    
    const duration = await page.evaluate(() => (window as any).DURATION as number);
    for (const t of [0, duration * 0.25, duration * 0.5, duration * 0.75]) {
      await page.evaluate(async (time) => {
        await (window as any).seek(time);
      }, t);
      await page.screenshot({ path: `video/preview-${Math.round(t * 1000)}ms.png` });
    }
    
    await browser.close();
    console.log(`duration ${duration}s`);

    Пример вывода

    duration 12s
    video/preview-0ms.png
    video/preview-3000ms.png
    video/preview-6000ms.png
    video/preview-9000ms.png
  4. Отрендерьте все кадры и закодируйте

    Вызывайте seek(t) при t = frame / fps, делайте скриншоты и кодируйте H.264 через ffmpeg.

    render.ts
    import { spawn } from "node:child_process";
    import { mkdir, rm } from "node:fs/promises";
    import { pathToFileURL } from "node:url";
    import { chromium } from "playwright";
    
    const FPS = 30;
    
    const browser = await chromium.launch();
    const page = await browser.newPage({
      viewport: { width: 1080, height: 1920 },
      deviceScaleFactor: 1,
    });
    await page.goto(pathToFileURL("video/scene.html").href);
    await page.waitForFunction(() => typeof (window as any).seek === "function");
    
    const duration = await page.evaluate(() => (window as any).DURATION as number);
    const frames = Math.ceil(duration * FPS);
    
    await rm("video/frames", { recursive: true, force: true });
    await mkdir("video/frames", { recursive: true });
    
    for (let frame = 0; frame < frames; frame++) {
      await page.evaluate(async (time) => {
        await (window as any).seek(time);
      }, frame / FPS);
      await page.screenshot({
        path: `video/frames/${String(frame).padStart(5, "0")}.png`,
      });
    }
    await browser.close();
    
    const ffmpeg = spawn("ffmpeg", [
      "-y",
      "-framerate", String(FPS),
      "-i", "video/frames/%05d.png",
      "-c:v", "libx264",
      "-pix_fmt", "yuv420p",
      "-movflags", "+faststart",
      "video/video.mp4",
    ], { stdio: "inherit" });
    
    await new Promise<void>((resolve, reject) => {
      ffmpeg.on("exit", (code) => {
        if (code === 0) resolve();
        else reject(new Error(`ffmpeg exited with ${code}`));
      });
    });
    
    console.log(`${frames} frames -> video/video.mp4`);

    Пример вывода

    360 frames -> video/video.mp4
  5. Добавьте аудио и просмотрите целиком

    Добавьте лицензированную дорожку с -c:v copy, проверьте длительность и громкость, затем посмотрите видео целиком.

    mux.sh
    ffmpeg -i video/video.mp4 -i video/audio.wav \
      -c:v copy -c:a aac -b:a 192k -shortest \
      video/final.mp4
    
    ffprobe -v error -show_entries format=duration \
      -of default=nw=1:nk=1 video/final.mp4

    Пример вывода

    12.000000
  6. Итерируйте с той же моделью

    Опишите только проблемный кадр и желаемое изменение, передайте текущий HTML Opus, сначала перезапустите превью, затем полный рендер.

Что входит

  • Заранее написанный раскадровка и таймлайн
  • Детерминированная HTML-сцена от Opus 5.5
  • Скрипт покадрового рендера Playwright и кодирование ffmpeg
  • Итоговый MP4 с опциональной аудиодорожкой
  • Цикл проверки и правок по кадрам

Чего не делает

  • Opus 5.5 выдаёт код, а не видеокадры; кадры снимает браузерный рендерер
  • Подписка Claude не нужна, но модель Felo оплачивается по факту использования
  • Нужны Node, Playwright Chromium и ffmpeg
  • Внешние материалы и CDN запрещены: только HTML/CSS/SVG/Canvas или локальные файлы
  • Длинные видео требуют разбиения на сцены; это не запись экрана в реальном времени
  • Озвучка и музыка — отдельные шаги; процесс только добавляет ваш аудиофайл

Вопросы

Opus 5.5 сам создаёт видео?

Нет. Он выдаёт текст и код, создавая HTML-сцену; браузер и ffmpeg превращают сцену в кадры и MP4.

Нужна подписка Claude?

Нет. Через ключ Felo вызывайте `claude-opus-5-5` по Felo API с оплатой по факту использования; отдельная подписка Claude не нужна.

В каких agent это работает?

WorkBuddy, ChatGPT с исполнением кода, Codex, Pi Agent, Claude Code или любой agent с Node и headless-браузером.

Зачем сцене seek(t)?

Захват кадров не идёт в реальном времени: между кадром 399 и 400 может пройти время, поэтому каждый кадр должен быть чистой функцией от t.

Можно использовать HyperFrames или Remotion?

Да, для длинных композиций и структурированных проектов. Этот рецепт оставляет один HTML-файл, чтобы вызов модели и цикл рендера было легко проверить.

Сколько стоит 12-секундное видео?

Зависит от промпта, выходных токенов и числа итераций. Модель Felo тарифицируется по токенам; проверьте актуальные цены перед длинным рендером.

Можно использовать свою музыку и озвучку?

Да, если у вас есть права. Сначала отрендерьте видео, затем добавьте лицензированную дорожку или свой TTS через ffmpeg. Процесс не создаёт озвучку.

Источники

Учебники и проекты, на которых основан процесс.

Связанные процессы

Адаптируйте под себя

Тот же рецепт, подстроенный под ваш реальный процесс.

Проект HyperFrames или Remotion

Для длинных композиций используйте эти фреймворки; вызов модели тот же, меняется команда рендера.

Квадратная версия для соцсетей

Сохраните бит-лист, сделайте 1080x1080, настройте размер шрифта и безопасные зоны.

Три варианта из одного брифа

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

Справочные страницы этого рецепта и куда двигаться дальше.