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
لمنالمنشئونمصممو الموشنالمطورون المستقلون

انسخ الموجّه

استبدل الحقول بين الأقواس المربعة وألصق في Claude Code أو Codex أو أي ذكاء اصطناعي يملك وصولًا إلى الطرفية. يثبّت مهارة Felo ويسأل قبل إنفاق الرصيد وينفّذ سير العمل.

أنشئ فيديو مدته [المدة] ثانية، بصيغة [عمودية / أفقية]، عن [الفكرة].
النمط: [النمط]. الجمهور: [الجمهور]. الصوت: [بدون / مقطع مرخّص في ./audio.mp3 / TTS].

أنت تعمل في مجلد به طرفية و[WorkBuddy / ChatGPT مع تنفيذ الكود / Codex / Pi Agent / Claude Code]. إذا لم تستطع تشغيل Node ومتصفح headless، توقف وأخبرني، ولا تتظاهر بأنك أنجزت العرض.

اتبع هذا الترتيب:
1. اكتب لوحة قصص من 3–6 نبضات بثواني بداية ونهاية دقيقة.
2. خطوة HTML: استدعِ Claude Opus 5.5 عبر Felo API. استخدم معرّف النموذج claude-opus-5-5 ومفتاح FELO_API_KEY الخاص بي. لا تطلب مني اشتراك Claude أو مفتاح Anthropic آخر.
3. اطلب من Opus ملف HTML واحدًا مكتفيًا بذاته: يضبط window.DURATION ويعرض async window.seek(t). بلا أصول خارجية أو CDN أو Date.now() أو requestAnimationFrame() أو انتقالات CSS أو مؤقتات. اضبط بذرة لكل قيمة عشوائية حتى يرسم نفس 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 / مؤقتات

المعاينة: 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. ادمج الصوت وشاهد كاملًا

    أضف المسار المرخص بـ-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 وأعد المعاينة قبل العرض الكامل.

ما يتضمنه

  • Storyboard وخط زمني مكتوبان أولًا
  • مشهد 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 منفصل.

في أي وكلاء يعمل؟

WorkBuddy وChatGPT مع تنفيذ الكود وCodex وPi Agent وClaude Code أو أي وكيل يشغّل Node ومتصفحًا بلا واجهة.

لماذا seek(t)?

التقاط الإطارات ليس آنيًا: قد يُلتقط الإطار 400 بعد 399 بكثير لذا يجب أن يكون كل إطار دالة خالصة لـt.

هل يمكن استخدام HyperFrames أو Remotion؟

نعم للتركيبات الطويلة والمشاريع المنظمة. تحفظ هذه الوصفة ملف HTML واحدًا ليظل استدعاء النموذج وحلقة العرض قابلين للتحقق.

كم تكلفة فيديو 12 ثانية؟

يعتمد على الموجّه وتوكنات الخرج والتكرارات. يحسب نموذج Felo لكل توكن؛ راجع الأسعار قبل عرض طويل.

هل يمكن استخدام موسيقاي وتعليقي الصوتي؟

نعم إن كنت تملك الحقوق. اعرض الفيديو أولًا ثم ادمج المسار المرخص أو TTS بـffmpeg. سير العمل لا ينتج تعليقًا صوتيًا.

المراجع

الدروس والمشاريع التي تقوم عليها هذه الوصفة.

سير عمل مرتبط

اجعله مناسبًا لك

الوصفة نفسها، معدّلة بحسب طريقة تسليمك الفعلية.

مشروع HyperFrames أو Remotion

للتركيبات الطويلة استخدم هذه الأطر؛ استدعاء النموذج نفسه ويتغير أمر العرض فقط.

نسخة مربعة للتواصل

أبقِ beat sheet وانتقل إلى 1080x1080 واضبط الخطوط والمناطق الآمنة.

ثلاث نسخ من موجز واحد

أنشئ ثلاثة مشاهد بألوان وإيقاعات مختلفة وراجع المعاينات واعرض الأفضل فقط.

صفحات المراجع خلف هذه الوصفة والخطوات التالية.