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.
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.
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
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ą.
Wygeneruj scenę HTML z Opus 5.5
Skieruj Anthropic SDK na base URL Felo, użyj
claude-opus-5-5i poproś tylko o HTML zwindow.DURATIONiasync 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
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
Wyrenderuj wszystkie klatki i zakoduj
Wywołaj
seek(t)zt = 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
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.mp4Przykładowy wynik
12.000000
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
Zamień stronę badawczą w prezentację
Wyekstrahuj stronę, zapisz jako kontekst LiveDoc, pozwól PPT Task API zbudować deck i pytaj, aż link będzie gotowy.
Otwórz workflowTreściZamień brief produktu w landing page
Zbadaj publiczność, zapisz brief w LiveDoc, utwórz z tego kontekstu zadanie Landing Page i pytaj, aż hostowana strona będzie gotowa.
Otwórz workflowTreściWypełnij miesiąc treści pytaniami odbiorców
Zmapuj tematy z Chat, znajdź pytania odbiorców na X, weź prawdziwy kąt z transkryptu wideo i złóż czterotygodniowy kalendarz, w którym każdy wiersz podaje dowód.
Otwórz workflowDostosuj
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ą.
Idź dalej
Strony referencyjne za tą recepturą i kolejne kroki.