Felo API PlatformFelo API Platform

Treści

Zbuduj wideo motion graphics z HTML i Opus 5.5

Napisz beat sheet, poproś Opus 5.5 o deterministyczną scenę HTML przez Felo API, uchwyć klatki Playwrightem i zakoduj MP4 ffmpegiem. Działa w WorkBuddy, ChatGPT z wykonywaniem kodu, Codex, Pi Agent lub Claude Code.

Czas45 minutPoziomŚredniZaktualizowano2026-10-30
Dla kogoTwórcyMotion designerzyNiezależni deweloperzy

Skopiuj prompt

Podmień pola w nawiasach kwadratowych i wklej do Claude Code, Codex albo AI z dostępem do terminala. Instaluje skill Felo, pyta przed wydaniem kredytów i uruchamia workflow.

Zrób wideo [czas] sekund, format [pionowy / poziomy], o [pomysł].
Styl: [styl]. Odbiorcy: [odbiorcy]. Audio: [brak / licencjonowany utwór w ./audio.mp3 / TTS].

Działasz w folderze z terminalem i [WorkBuddy / ChatGPT z wykonywaniem kodu / Codex / Pi Agent / Claude Code]. Jeśli nie możesz uruchomić Node i przeglądarki headless, zatrzymaj się i powiedz mi, nie udawaj, że wyrenderowałeś.

Postępuj w tej kolejności:
1. Napisz storyboard 3–6 beatów z dokładnymi sekundami startu i końca.
2. Krok HTML: wywołaj Claude Opus 5.5 przez Felo API. Użyj ID modelu claude-opus-5-5 i mojego FELO_API_KEY. Nie proś mnie o subskrypcję Claude ani inny klucz Anthropic.
3. Poproś Opus o jeden samodzielny plik HTML: ustaw window.DURATION i udostępnij async window.seek(t). Bez zewnętrznych zasobów, CDN, Date.now(), requestAnimationFrame(), przejść CSS i timerów. Ustaw seed wszystkich losowych wartości, aby to samo t zawsze rysowało tę samą klatkę.
4. Podejrzyj przy t = 0, 25%, 50%, 75% i na ostatniej klatce. Sprawdź przepełnienia, przycięcia, fonty i strefy bezpieczne przed renderowaniem całości.
5. Wyrenderuj każdą klatkę przez Playwright, zakoduj H.264 przez ffmpeg i zmiksuj ścieżkę audio, jeśli istnieje.
6. Pokaż pierwszą klatkę, ostatnią i ścieżkę pliku. Nie publikuj.

Zasady:
- Przed zużyciem kredytów pokaż wywołania Felo API i szacowane tokeny.
- Używaj tylko tekstu, który podam, albo wyraźnie oznacz wymyślony tekst zastępczy.
- Nie używaj materiałów, muzyki, logo ani fontów chronionych prawem autorskim. Tylko fonty systemowe i wygenerowane kształty.
- Trzymaj finalne wideo poniżej 30 sekund, chyba że wyraźnie poproszę o dłuższe.
- Zapisz wszystko w ./video/ i podsumuj wykonane polecenia.

Kopia zawiera też kroki instalacji i zasady bezpieczeństwa.

Co otrzymujesz

Przykładowy wynik jednego uruchomienia. Nie generowanie na żywo.

Przykładowy raport renderu (fragment)

Raport renderu

Scena: video/scene.html (18 KB) Czas: 12 s · 1080x1920 · 30 fps · 360 klatek Kontrole: window.DURATION = 12 · seek(t) obecne · brak Date.now / rAF / timerów

Podgląd: preview-0ms.png · preview-3000ms.png · preview-6000ms.png · preview-9000ms.png Kodowanie: video/video.mp4 (H.264, 360 klatek) Audio: video/final.mp4 (AAC, 12,0 s)

Dokładne wywołania

Dla deweloperów: ten sam workflow jako kod, w kolejności wykonania.

Pokaż rzeczywiste wywołania API
  1. Napisz najpierw beat sheet

    Ustal czas trwania i 3–6 beatów, każdy z początkiem, końcem, tekstem na ekranie i główną zmianą wizualną.

  2. Wygeneruj scenę HTML z Opus 5.5

    Skieruj Anthropic SDK na base URL Felo, użyj claude-opus-5-5 i poproś tylko o HTML z window.DURATION i 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`);

    Przykładowy wynik

    scene.html: 18432 bytes
  3. Sprawdź determinizm i podgląd

    Zrób zrzuty przy t=0, 25%, 50%, 75% i ostatniej klatce, sprawdzając przepełnienie tekstu, fonty i strefy bezpieczne.

    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`);

    Przykładowy wynik

    duration 12s
    video/preview-0ms.png
    video/preview-3000ms.png
    video/preview-6000ms.png
    video/preview-9000ms.png
  4. Wyrenderuj wszystkie klatki i zakoduj

    Wywołaj seek(t) z t = frame / fps, uchwyć klatki i zakoduj H.264 ffmpegiem.

    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`);

    Przykładowy wynik

    360 frames -> video/video.mp4
  5. Miksuj audio i obejrzyj całość

    Dodaj licencjonowaną ścieżkę przez -c:v copy, sprawdź czas i głośność, obejrzyj od początku do końca.

    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

    Przykładowy wynik

    12.000000
  6. Iteruj z tym samym modelem

    Opisz tylko błędną klatkę i pożądaną zmianę, przekaż bieżący HTML Opusowi i uruchom podgląd przed pełnym renderem.

Co zawiera

  • Najpierw napisany storyboard i timeline
  • Deterministyczna scena HTML od Opus 5.5
  • Skrypt renderowania Playwright i kodowanie ffmpeg
  • Finalny MP4 z opcjonalną ścieżką audio
  • Pętla przeglądu i korekty klatka po klatce

Czego nie robi

  • Opus 5.5 daje kod, nie klatki; renderer przeglądarki przechwytuje klatki
  • Bez subskrypcji Claude, ale użycie modelu Felo jest rozliczane według użycia
  • Node, Playwright Chromium i ffmpeg nadal są potrzebne
  • Bez zewnętrznych assetów i CDN; tylko HTML/CSS/SVG/Canvas lub pliki lokalne
  • Długie wideo wymaga podziału scen; to nie nagranie ekranu w czasie rzeczywistym
  • Narracja i muzyka to osobne kroki; workflow tylko miksuje dostarczone audio

Pytania

Czy Opus 5.5 tworzy wideo bezpośrednio?

Nie. Tworzy tekst i kod, pisząc scenę HTML; przeglądarka i ffmpeg zamieniają ją w klatki i MP4.

Czy potrzebna jest subskrypcja Claude?

Nie. Użyj klucza Felo do wywołania `claude-opus-5-5` przez Felo API, rozliczanego według użycia; osobna subskrypcja Claude nie jest potrzebna.

W jakich agentach działa?

WorkBuddy, ChatGPT z wykonywaniem kodu, Codex, Pi Agent, Claude Code lub dowolny agent uruchamiający Node i przeglądarkę headless.

Po co seek(t)?

Przechwytywanie klatek nie jest w czasie rzeczywistym: klatka 400 może powstać znacznie później niż 399, więc każda klatka musi być czystą funkcją t.

Czy można użyć HyperFrames lub Remotion?

Tak, do długich kompozycji i ustrukturyzowanych projektów. Ta receptura trzyma jeden HTML, by wywołanie modelu i pętla renderowania były weryfikowalne.

Ile kosztuje wideo 12 sekund?

Zależy od promptu, tokenów wyjściowych i iteracji. Model Felo rozlicza za token; sprawdź ceny przed długim renderem.

Czy można użyć własnej muzyki i narracji?

Tak, jeśli masz prawa. Najpierw wyrenderuj wideo, potem zmiksuj licencjonowaną ścieżkę lub swoje TTS ffmpegiem. Workflow nie generuje narracji.

Referencje

Samouczki i projekty, na których opiera się ten workflow.

Powiązane workflowy

Dostosuj

Ta sama receptura, dopasowana do tego, jak naprawdę dostarczasz.

Projekt HyperFrames lub Remotion

Do długich kompozycji użyj tych frameworków; wywołanie modelu jest takie samo, zmienia się tylko polecenie renderowania.

Wersja kwadratowa do social

Zachowaj beat sheet, przejdź na 1080x1080 i dostosuj typografię oraz strefy bezpieczne.

Trzy warianty z jednego briefu

Wygeneruj trzy sceny w różnych kolorach i rytmach, obejrzyj podglądy i renderuj tylko najlepszą.

Strony referencyjne za tą recepturą i kolejne kroki.