Felo API PlatformFelo API Platform

เนื้อหา

สร้างวิดีโอ motion graphics ด้วย HTML และ Opus 5.5

เขียน beat sheet ให้ Opus 5.5 เขียนฉาก HTML แบบกำหนดได้ผ่าน Felo API จับภาพด้วย Playwright และเข้ารหัส MP4 ด้วย ffmpeg ทำงานใน WorkBuddy, ChatGPT ที่รันโค้ด, Codex, Pi Agent หรือ Claude Code

เวลา45 นาทีระดับระดับกลางอัปเดต2026-10-30
สำหรับใครครีเอเตอร์Motion designerนักพัฒนาอิสระ

คัดลอกพรอมป์ต์

แทนช่องในวงเล็บเหลี่ยมแล้ววางใน 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) ห้ามใช้ asset ภายนอก CDN, Date.now(), requestAnimationFrame(), CSS transition หรือ timer ใส่ seed ให้ค่าสุ่มทั้งหมด เพื่อให้ t เดียวกันวาดเฟรมเดิมเสมอ
4. ดูตัวอย่างที่ t = 0, 25%, 50%, 75% และเฟรมสุดท้าย ตรวจการล้น การตัด ฟอนต์ และพื้นที่ปลอดภัยก่อนเรนเดอร์ทั้งหมด
5. เรนเดอร์ทุกเฟรมด้วย Playwright เข้ารหัส H.264 ด้วย ffmpeg และรวมแทร็กเสียงถ้ามี
6. แสดงเฟรมแรก เฟรมสุดท้าย และพาธไฟล์สุดท้าย ห้ามเผยแพร่

กฎ:
- ก่อนใช้เครดิต ให้แสดงการเรียก Felo API และประมาณการโทเคน
- ใช้เฉพาะข้อความที่ฉันให้ หรือติดป้ายข้อความตัวอย่างที่แต่งขึ้นให้ชัดเจน
- ห้ามใช้วัสดุ เพลง โลโก้ หรือฟอนต์ที่มีลิขสิทธิ์ ใช้เฉพาะฟอนต์ระบบและรูปทรงที่สร้างขึ้น
- ให้วิดีโอสุดท้ายต่ำกว่า 30 วินาที เว้นแต่ฉันขอแบบยาว
- เขียนทุกอย่างลง ./video/ และสรุปคำสั่งที่รัน

สำเนายังรวมขั้นตอนติดตั้งและกฎความปลอดภัย

สิ่งที่คุณได้รับ

ตัวอย่างผลลัพธ์จากการรันหนึ่งครั้ง ไม่ใช่การสร้างสด

ตัวอย่างรายงานเรนเดอร์ (ตัดตอน)

รายงานเรนเดอร์

ฉาก: video/scene.html (18 KB) ความยาว: 12 วินาที · 1080x1920 · 30fps · 360 เฟรม ตรวจ: window.DURATION = 12 · มี seek(t) · ไม่มี Date.now / rAF / timer

พรีวิว: 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. เขียน beat sheet ก่อน

    กำหนดความยาวและ 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. mux เสียงและดูทั้งเรื่อง

    เพิ่มแทร็กที่มีลิขสิทธิ์ด้วย -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 หรือไฟล์ในเครื่อง
  • วิดีโอยาวต้องแบ่งฉาก ไม่ใช่บันทึกหน้าจอเรียลไทม์
  • เสียงบรรยายและดนตรีเป็นขั้นแยก เวิร์กโฟลว์เพียง mux เสียงที่ให้มา

คำถาม

Opus 5.5 สร้างวิดีโอโดยตรงไหม?

ไม่ มันสร้างข้อความและโค้ดโดยเขียนฉาก HTML เบราว์เซอร์และ ffmpeg เปลี่ยนเป็นเฟรมและ MP4

ต้องสมัคร Claude ไหม?

ไม่ ใช้คีย์ Felo เรียก `claude-opus-5-5` ผ่าน Felo API คิดตามการใช้งาน ไม่ต้องสมัคร Claude แยก

ทำงานในเอเจนต์ใด?

WorkBuddy, ChatGPT ที่รันโค้ด, Codex, Pi Agent, Claude Code หรือเอเจนต์ที่รัน Node และเบราว์เซอร์ headless

ทำไมต้อง seek(t)?

การจับเฟรมไม่เรียลไทม์ เฟรม 400 อาจจับหลัง 399 มาก ทุกเฟรมจึงต้องเป็นฟังก์ชันบริสุทธิ์ของ t

ใช้ HyperFrames หรือ Remotion ได้ไหม?

ได้สำหรับคอมโพสิชันยาวหรือโปรเจกต์มีโครงสร้าง สูตรนี้เก็บ HTML ไฟล์เดียวเพื่อตรวจการเรียกโมเดลและลูปเรนเดอร์

วิดีโอ 12 วินาทีมีค่าใช้จ่ายเท่าไร?

ขึ้นกับพรอมป์ต์ โทเคนเอาต์พุต และจำนวนรอบ โมเดล Felo คิดต่อโทเคน ตรวจราคาก่อนเรนเดอร์ยาว

ใช้ดนตรีและเสียงบรรยายเองได้ไหม?

ได้หากมีสิทธิ์ เรนเดอร์วิดีโอก่อนแล้ว mux แทร็กที่มีลิขสิทธิ์หรือ TTS ด้วย ffmpeg เวิร์กโฟลว์ไม่สร้างเสียงบรรยาย

อ้างอิง

บทช่วยสอนและโปรเจกต์ที่สูตรนี้อ้างอิง

เวิร์กโฟลว์ที่เกี่ยวข้อง

ปรับให้เป็นของคุณ

สูตรเดิม ปรับตามวิธีที่คุณส่งมอบจริง

โปรเจกต์ HyperFrames หรือ Remotion

สำหรับคอมโพสิชันยาวใช้เฟรมเวิร์กเหล่านี้ การเรียกโมเดลเหมือนเดิม เปลี่ยนเฉพาะคำสั่งเรนเดอร์

เวอร์ชันจัตุรัสสำหรับโซเชียล

คง beat sheet เปลี่ยนเป็น 1080x1080 และปรับตัวอักษรกับพื้นที่ปลอดภัย

สามแบบจากบรีฟเดียว

สร้างสามฉากด้วยสีและจังหวะต่างกัน ดูตัวอย่างและเรนเดอร์เฉพาะที่ดีที่สุด

หน้าเอกสารอ้างอิงเบื้องหลังสูตรนี้และก้าวต่อไป