Felo API PlatformFelo API Platform

Content

Ein Motion-Graphics-Video mit HTML und Opus 5.5 erstellen

Schreibe ein Beat-Sheet, lass Opus 5.5 über die Felo API eine deterministische HTML-Szene schreiben, erfasse die Frames mit Playwright und kodiere ein MP4 mit ffmpeg. Läuft in WorkBuddy, ChatGPT mit Codeausführung, Codex, Pi Agent oder Claude Code.

Dauer45 MinutenLevelFortgeschrittenAktualisiert2026-10-30
Für wenCreatorMotion-DesignerIndie-Entwickler

Prompt kopieren

Ersetze die Felder in eckigen Klammern und füge den Prompt in Claude Code, Codex oder eine KI mit Terminalzugriff ein. Sie installiert den Felo-Skill, fragt vor Credits und führt den Workflow aus.

Erstelle ein [Dauer]-Sekunden-[Hochformat / Querformat]-Video über [Idee].
Stil: [Stil]. Zielgruppe: [Zielgruppe]. Audio: [keins / lizenzierter Track unter ./audio.mp3 / TTS].

Du läufst in einem Ordner mit Terminal und [WorkBuddy / ChatGPT mit Codeausführung / Codex / Pi Agent / Claude Code]. Wenn du Node und einen Headless-Browser nicht ausführen kannst, stoppe und sag es mir, statt Rendering vorzutäuschen.

Arbeite in dieser Reihenfolge:
1. Schreibe ein Storyboard mit 3–6 Beats und exakten Start- und Endsekunden.
2. HTML-Schritt: Rufe Claude Opus 5.5 über die Felo API auf. Nutze die Modell-ID claude-opus-5-5 und meinen FELO_API_KEY. Verlange kein Claude-Abo und keinen anderen Anthropic-Schlüssel.
3. Lass Opus eine einzelne, in sich geschlossene HTML-Datei liefern: setze window.DURATION und exponiere async window.seek(t). Keine externen Assets, CDNs, Date.now(), requestAnimationFrame(), CSS-Übergänge oder Timer. Seede alle Zufallswerte, damit dasselbe t immer denselben Frame zeichnet.
4. Prüfe bei t = 0, 25 %, 50 %, 75 % und im letzten Frame. Prüfe vor dem vollständigen Rendern Überlauf, Abschneiden, Schriften und Safe Areas.
5. Rendere jeden Frame mit Playwright, kodiere mit ffmpeg nach H.264 und mische die Audiospur bei, falls vorhanden.
6. Zeige ersten Frame, letzten Frame und den finalen Dateipfad. Veröffentliche nichts.

Regeln:
- Zeige vor dem Verbrauch von Credits die Felo-API-Aufrufe und die geschätzten Token.
- Nutze nur den Text, den ich gebe, oder kennzeichne erfundenen Platzhaltertext klar.
- Verwende kein urheberrechtlich geschütztes Material, keine Musik, Logos oder Schriften. Nur Systemschriften und generierte Formen.
- Halte das finale Video unter 30 Sekunden, unless ich ausdrücklich ein längeres verlange.
- Schreibe alles nach ./video/ und fasse die ausgeführten Befehle zusammen.

Die Kopie enthält auch die Installationsschritte und Sicherheitsregeln.

Das bekommst du

Beispielausgabe eines Laufs. Keine Live-Generierung.

Beispiel-Renderbericht (Auszug)

Renderbericht

Szene: video/scene.html (18 KB) Dauer: 12 s · 1080x1920 · 30fps · 360 Frames Checks: window.DURATION = 12 · seek(t) vorhanden · kein Date.now / rAF / Timer

Vorschau: preview-0ms.png · preview-3000ms.png · preview-6000ms.png · preview-9000ms.png Encoding: video/video.mp4 (H.264, 360 Frames) Audio: video/final.mp4 (AAC, 12,0 s)

Die konkreten Aufrufe

Für Entwickler: derselbe Workflow als kopierbarer Code in Ausführungsreihenfolge.

Konkrete API-Aufrufe zeigen
  1. Zuerst das Beat-Sheet schreiben

    Lege Dauer und 3–6 Beats fest, jeweils mit Start, Ende, Text auf dem Bildschirm und zentraler visueller Änderung.

  2. HTML-Szene mit Opus 5.5 erzeugen

    Richte das Anthropic SDK auf die Felo-Base-URL, nutze das Modell claude-opus-5-5 und verlange nur HTML mit window.DURATION und 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`);

    Beispielausgabe

    scene.html: 18432 bytes
  3. Determinismus prüfen und Keyframes ansehen

    Mache Screenshots bei t=0, 25%, 50%, 75% und im letzten Frame und prüfe Textüberlauf, Schriften und Safe Areas.

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

    Beispielausgabe

    duration 12s
    video/preview-0ms.png
    video/preview-3000ms.png
    video/preview-6000ms.png
    video/preview-9000ms.png
  4. Alle Frames rendern und kodieren

    Rufe seek(t) mit t = frame / fps auf, mache Screenshots und kodiere H.264 mit 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`);

    Beispielausgabe

    360 frames -> video/video.mp4
  5. Audio mischen und komplett ansehen

    Füge die lizenzierte Spur mit -c:v copy hinzu, prüfe Dauer und Lautstärke und schau das Video ganz an.

    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

    Beispielausgabe

    12.000000
  6. Mit demselben Modell iterieren

    Beschreibe nur den fehlerhaften Frame und die gewünschte Änderung, gib das aktuelle HTML an Opus und starte zuerst die Vorschau neu.

Enthalten

  • Vorab geschriebenes Storyboard und Timeline
  • Deterministische HTML-Szene von Opus 5.5
  • Playwright-Frame-Render-Skript und ffmpeg-Kodierung
  • Finales MP4 mit optionaler Audiospur
  • Frame-für-Frame-Review und Korrekturschleife

Was es nicht macht

  • Opus 5.5 liefert Code, keine Videoframes; der Browser-Renderer erfasst die Frames
  • Kein Claude-Abo nötig, aber die Felo-Nutzung wird verbrauchsbasiert abgerechnet
  • Node, Playwright Chromium und ffmpeg werden weiterhin benötigt
  • Keine externen Assets oder CDNs; nur HTML/CSS/SVG/Canvas oder lokale Dateien
  • Lange Videos brauchen Szenenteilung; das ist keine Echtzeit-Bildschirmaufnahme
  • Narration und Musik sind separate Schritte; der Workflow mischt nur bereitgestelltes Audio

Fragen

Erzeugt Opus 5.5 direkt Video?

Nein. Es liefert Text und Code und schreibt die HTML-Szene; Browser und ffmpeg machen daraus Frames und MP4.

Brauche ich ein Claude-Abo?

Nein. Rufe `claude-opus-5-5` mit dem Felo-Key über die Felo API auf und zahle nutzungsbasiert; ein separates Claude-Abo ist nicht nötig.

In welchen Agents läuft das?

WorkBuddy, ChatGPT mit Codeausführung, Codex, Pi Agent, Claude Code oder jeder Agent, der Node und einen Headless-Browser ausführen kann.

Warum braucht die Szene seek(t)?

Frame-Erfassung läuft nicht in Echtzeit: Frame 400 kann viel später als 399 entstehen, daher muss jeder Frame eine reine Funktion von t sein.

Kann ich HyperFrames oder Remotion nutzen?

Ja, für lange Kompositionen und strukturierte Projekte. Dieses Rezept behält eine einzelne HTML-Datei, damit Modellaufruf und Render-Loop prüfbar bleiben.

Was kostet ein 12-Sekunden-Video?

Es hängt von Prompt, Ausgabetokens und Iterationen ab. Das Felo-Modell rechnet pro Token ab; prüfe die aktuellen Preise vor einem langen Render.

Kann ich eigene Musik und Narration nutzen?

Ja, wenn du die Rechte hast. Rendere zuerst das Video und mische dann die lizenzierte Spur oder dein TTS mit ffmpeg. Der Workflow erzeugt keine Narration.

Referenzen

Tutorials und Projekte, auf denen dieser Workflow basiert.

Verwandte Workflows

Mach es zu deinem

Dasselbe Rezept, angepasst an deinen tatsächlichen Ablauf.

HyperFrames- oder Remotion-Projekt

Für lange Kompositionen diese Frameworks nutzen; der Modellaufruf bleibt gleich, nur der Render-Befehl ändert sich.

Quadratische Social-Version

Beat-Sheet behalten, auf 1080x1080 wechseln und Typografie sowie Safe Areas anpassen.

Drei Varianten aus einem Briefing

Erzeuge drei Szenen mit anderen Farben und Rhythmen, prüfe die Vorschauen und rendere nur die beste.

Die Referenzseiten hinter diesem Rezept und die nächsten Schritte.