KeiSeiKit-1.0/skills/ai-animation/skill.md
Parfii-bot 0be354a920 KeiSeiKit-public — clean state
Single-commit clean baseline after security scrub of niche-tells,
project codenames, internal jargon, and contributor-email leaks.

Contents:
- 100 Rust crates (_primitives/_rust/)
- 37 agent manifests (_manifests/) + generated specs (_generated/)
- 67 user-invocable skills (skills/)
- 33 hooks (hooks/)
- Composition blocks (_blocks/)
- Documentation (docs/, README.md)
- TS adapter packages (_ts_packages/)
- Assembler (_assembler/)
- Roles (_roles/)
- Templates (_templates/)
- Forgejo CI (.forgejo/)

Author: Denis Parfionovich <info@greendragon.info>

License: see LICENSE.
2026-05-01 12:09:03 +08:00

28 KiB
Raw Blame History

name description arguments
ai-animation Use when creating AI-powered animations and videos — nano-banana keyframes → Kling/Luma/Veo video generation via fal.ai → web-ready output. Full pipeline from concept to scroll-driven animation or video embed. Triggers on "AI animation", "animate image", "AI video", "Kling", "image to video", "анимируй", "сделай видео из картинки".
name description required
pipeline Pipeline: keyframe-to-video, image-to-video, text-to-video, video-to-web (default: keyframe-to-video) false
name description required
model Model: kling, luma, veo, ltx, pixverse (default: auto-select by use case) false
name description required
style Visual style or reference for generation false

AI Animation Pipeline

nano-banana (keyframes) → fal.ai (video gen) → FFmpeg (web-ready) → scroll/embed Prices verified 2026-03-13 [E1-fal.ai API docs]

Pipeline Overview

Concept / Prompt
  │
  ├─→ [1. Keyframes] nano-banana → reference images (poses, angles, scenes)
  │
  ├─→ [2. Animate] fal.ai → Kling / Luma / Veo → MP4 video
  │
  ├─→ [3. Process] FFmpeg → frame sequence / optimized video / GIF
  │
  └─→ [4. Integrate] scroll-animation / video embed / motion-design

Model Selection Matrix [E1-fal.ai docs]

Use Case Model Endpoint Cost/sec Duration Why
Product reveal Kling v3 Pro fal-ai/kling-video/v3/pro/image-to-video $0.112 (no audio) / $0.168 (audio) 3-15s Best motion, multi-prompt, elements
Hero loop Luma Ray 2 fal-ai/luma-dream-machine/ray-2/image-to-video $0.10/sec @540p 5s, 9s loop: true, start+end keyframes
Cinematic Veo 3 fal-ai/veo3 $0.20 (no audio) / $0.40 (audio) 4-8s Best quality + audio, 1080p
Cinematic (fast) Veo 3 Fast fal-ai/veo3/fast/image-to-video $0.10 (no audio) / $0.15 (audio) 4-8s 50% cheaper I2V
Bulk/cheap LTX 2.0 fal-ai/ltx-2/text-to-video/fast $0.04 @1080p 6-20s Cheapest, up to 4K, extend/retake
Stylized PixVerse v4.5 fal-ai/pixverse/v4.5/image-to-video $0.03-0.08/sec 5-8s anime/3d/clay/comic/cyberpunk + camera presets

Quick Decision

  • Loop for hero section? → Luma Ray 2 (loop: true)
  • Animate a product/design comp? → Kling v3 Pro
  • Maximum quality, budget OK? → Veo 3
  • Need 10+ videos cheap? → LTX 2.0
  • Specific art style? → PixVerse v4.5

Step 1: Generate Keyframes (nano-banana)

Generate reference images that will be animated into video.

Best Practices for Animation Keyframes

# Product floating in space — good for Kling rotation
nano-banana "premium wireless headphones floating on dark background, studio lighting, centered composition, clean edges" -s 2K -a 16:9 -o keyframe-product

# Scene for cinematic animation — good for Veo/Kling
nano-banana "cyberpunk street at golden hour, rain puddles, neon reflections, cinematic composition" -s 2K -a 16:9 -o keyframe-scene

# Character pose — good for Kling motion
nano-banana "3D character mascot robot waving, isometric view, white background, Pixar style" -s 1K -a 1:1 -o keyframe-character

# Hero background — good for Luma loop
nano-banana "abstract flowing liquid metal, iridescent purple and gold, macro photography" -s 2K -a 16:9 -o keyframe-hero

# Transparent asset for animation
nano-banana "floating crystal sphere with inner glow" -t -s 1K -o keyframe-crystal

nano-banana → fal.ai Upload Workflow

nano-banana outputs local PNG files. To use as input for fal.ai video models:

import fal_client

# Option A: Upload to fal CDN (recommended for large files)
image_url = fal_client.upload_file("keyframe-product.png")  # → https://fal.media/files/...

# Option B: Encode as data URI (inline, faster for small files, no CDN hop)
image_data = fal_client.encode_file("keyframe-product.png")

# Then use in any video model
result = fal_client.run("fal-ai/kling-video/v3/pro/image-to-video", arguments={
    "start_image_url": image_url,  # or image_data
    "prompt": "the headphones slowly rotate",
    "duration": "5"
})

Optimal nano-banana settings per video model:

Video Model nano-banana Size Aspect Notes
Kling v3 Pro -s 2K -a 16:9 or -a 9:16 or -a 1:1 Match aspect_ratio param
Luma Ray 2 -s 2K -a 16:9 or any of 6 ratios 540p output, 2K input still better
Veo 3 -s 2K -a 16:9 or -a 9:16 only Must be 720p+ and <8MB
LTX 2.0 -s 2K -a 16:9 Flexible, handles most inputs
PixVerse v4.5 -s 2K match target Resolution matches input

Keyframe Prompting Rules

  1. Clean edges — AI video models struggle with busy/cluttered compositions
  2. Centered subject — off-center subjects may drift during animation
  3. Consistent lighting — dramatic lighting gives video models more to work with
  4. Simple backgrounds — solid/gradient backgrounds → cleaner motion
  5. Describe potential motion — "floating", "flowing", "spinning" primes the composition
  6. 16:9 for video — match the target video aspect ratio in the keyframe
  7. High resolution — use -s 2K minimum, video models downsample better than upscale

Step 2: Animate via fal.ai

Prerequisites

pip install fal-client
export FAL_KEY="your-key"

fal_client SDK Patterns (Python)

import fal_client

# SYNC — blocks until done (simplest, for single generations)
result = fal_client.run("fal-ai/veo3", arguments={...})
video_url = result["video"]["url"]

# ASYNC — non-blocking
import asyncio
async def generate():
    result = await fal_client.run_async("fal-ai/veo3", arguments={...})
    return result["video"]["url"]

# QUEUE with progress tracking — best for long jobs
async def generate_with_progress():
    handler = await fal_client.submit_async("fal-ai/veo3", arguments={...})
    logs_index = 0
    async for event in handler.iter_events(with_logs=True):
        if isinstance(event, fal_client.Queued):
            print(f"Queue position: {event.position}")
        elif isinstance(event, (fal_client.InProgress, fal_client.Completed)):
            for log in event.logs[logs_index:]:
                print(log["message"])
            logs_index = len(event.logs)
    result = await handler.get()
    return result["video"]["url"]

# FILE UPLOAD — local file → fal CDN URL
url = fal_client.upload_file("local-image.png")  # returns https://fal.media/files/...
data_uri = fal_client.encode_file("local-image.png")  # inline data URI, no upload

REST API Pattern (curl)

# Sync (blocks until done, timeout risk for long generations)
curl -X POST "https://fal.run/{endpoint}" \
  -H "Authorization: Key $FAL_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "...", ...}'

# Queue submit (non-blocking, recommended)
REQUEST_ID=$(curl -s -X POST "https://queue.fal.run/{endpoint}" \
  -H "Authorization: Key $FAL_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "...", ...}' | jq -r '.request_id')

# Check status
curl -s "https://queue.fal.run/{endpoint}/requests/$REQUEST_ID/status" \
  -H "Authorization: Key $FAL_KEY"

# Get result
curl -s "https://queue.fal.run/{endpoint}/requests/$REQUEST_ID" \
  -H "Authorization: Key $FAL_KEY"

# Webhook (fire and forget)
curl -X POST "https://queue.fal.run/{endpoint}" \
  -H "Authorization: Key $FAL_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Fal-Webhook-Url: https://your-server.com/webhook" \
  -d '{"prompt": "..."}'

Kling v3 Pro — Image to Video [E1-verified]

Best for: product reveals, design comp animation, character motion, multi-shot sequences.

import fal_client

result = fal_client.run(
    "fal-ai/kling-video/v3/pro/image-to-video",
    arguments={
        "prompt": "the headphones slowly rotate 360 degrees, studio lighting, smooth motion",
        "start_image_url": "https://...keyframe-product.png",
        "duration": "5",           # "3" to "15" seconds (string)
        "aspect_ratio": "16:9",    # 16:9, 9:16, 1:1
        "generate_audio": False,   # True adds $0.056/sec
    }
)
video_url = result["video"]["url"]
print(f"Video: {video_url}")
// Node.js
import { fal } from "@fal-ai/client";

const result = await fal.subscribe("fal-ai/kling-video/v3/pro/image-to-video", {
  input: {
    prompt: "the headphones slowly rotate 360 degrees",
    start_image_url: "https://...keyframe.png",
    duration: "5",
    aspect_ratio: "16:9",
    generate_audio: false,
  },
  logs: true,
  onQueueUpdate: (update) => {
    if (update.status === "IN_PROGRESS") {
      update.logs.map((log) => log.message).forEach(console.log);
    }
  },
});

Parameters:

Param Values Default Notes
prompt string Describe MOTION, not scene. Mutually exclusive with multi_prompt
start_image_url URL required Source keyframe (not image_url)
end_image_url URL End frame for interpolation
duration "3"-"15" "5" String, per-second increments
aspect_ratio 16:9, 9:16, 1:1 16:9
generate_audio bool true Native audio (Chinese/English)
negative_prompt string "blur, distort, and low quality"
cfg_scale float 0.5 Prompt adherence strength
multi_prompt array Multi-shot: [{"prompt": "...", "duration": "5"}, ...]
elements array Character/object consistency via reference images

Cost [E1]:

  • No audio: $0.112/sec → 5s = $0.56, 10s = $1.12
  • With audio: $0.168/sec → 5s = $0.84, 10s = $1.68
  • With voice control: $0.196/sec

Multi-shot example:

result = fal_client.run("fal-ai/kling-video/v3/pro/image-to-video", arguments={
    "start_image_url": "https://...keyframe.png",
    "multi_prompt": [
        {"prompt": "camera orbits around the product slowly", "duration": "5"},
        {"prompt": "zoom in to the detail panel", "duration": "5"}
    ],
    "generate_audio": False,
})

curl:

curl -X POST "https://fal.run/fal-ai/kling-video/v3/pro/image-to-video" \
  -H "Authorization: Key $FAL_KEY" \
  -H "Content-Type: application/json" \
  -d '{"start_image_url": "https://...keyframe.png", "prompt": "rotate slowly", "duration": "5", "generate_audio": false}'

Prompting for motion:

  • Describe WHAT MOVES: "the camera slowly orbits around the product"
  • NOT the scene: "beautiful product on dark background"
  • Be specific: "rotate 90 degrees clockwise" > "rotate"
  • Keep it simple: one primary motion per clip

Luma Ray 2 — Looping Hero Videos [E1-verified]

Best for: hero section backgrounds, ambient loops, living textures, start→end interpolation.

result = fal_client.run(
    "fal-ai/luma-dream-machine/ray-2/image-to-video",
    arguments={
        "prompt": "gentle flowing motion, seamless loop",
        "image_url": "https://...keyframe-hero.png",
        "loop": True,           # seamless loop!
        "resolution": "540p",   # 540p, 720p (2x), 1080p (4x)
        "duration": "5s",       # "5s" or "9s"
        "aspect_ratio": "16:9",
    }
)
video_url = result["video"]["url"]

Key features:

  • loop: True → seamless loops for <video loop autoplay> hero sections
  • end_image_url → interpolate between start and end keyframes (морфинг!)

Start→End keyframe example:

result = fal_client.run("fal-ai/luma-dream-machine/ray-2/image-to-video", arguments={
    "prompt": "smooth transformation between the two states",
    "image_url": "https://...keyframe-start.png",
    "end_image_url": "https://...keyframe-end.png",
    "duration": "5s",
    "aspect_ratio": "16:9",
})

Parameters:

Param Values Default Notes
prompt string required Min 3, max 5000 chars
image_url URL required Start frame
end_image_url URL End frame (interpolation)
loop bool false End blended with beginning
duration "5s", "9s" "5s" 9s costs 2x
resolution "540p", "720p", "1080p" "540p" 720p=2x, 1080p=4x cost
aspect_ratio 16:9, 9:16, 4:3, 3:4, 21:9, 9:21 "16:9"

Cost [E1]:

Resolution 5s 9s
540p $0.50 $1.00
720p $1.00 $2.00
1080p $2.00 $4.00

curl:

curl -X POST "https://fal.run/fal-ai/luma-dream-machine/ray-2/image-to-video" \
  -H "Authorization: Key $FAL_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "gentle flowing motion, seamless loop", "image_url": "https://...hero.png", "loop": true, "resolution": "540p", "duration": "5s"}'

Veo 3 — Maximum Quality [E1-verified]

Best for: cinematic hero videos, with audio. Two variants: standard and fast.

# Standard — best quality
result = fal_client.run(
    "fal-ai/veo3",
    arguments={
        "prompt": "cinematic reveal of headphones, dramatic lighting, camera dollies in slowly",
        "image_url": "https://...keyframe.png",  # optional for text-to-video
        "duration": "8s",          # "4s", "6s", "8s"
        "resolution": "1080p",     # "720p", "1080p"
        "aspect_ratio": "16:9",    # "16:9", "9:16"
        "generate_audio": True,    # unique: audio generation
    }
)
video_url = result["video"]["url"]

# Fast I2V — 50% cheaper for image-to-video
result = fal_client.run(
    "fal-ai/veo3/fast/image-to-video",
    arguments={
        "prompt": "camera slowly orbits the product",
        "image_url": "https://...keyframe.png",
        "duration": "8s",
        "generate_audio": False,
    }
)

Unique: Veo 3 generates audio with the video. safety_tolerance 1-6 (1=strict, 6=permissive). auto_fix auto-rewrites failing prompts. seed for reproducibility.

Cost [E1]:

Variant No audio With audio
Standard $0.20/sec $0.40/sec
Fast I2V $0.10/sec $0.15/sec

8s standard with audio = $3.20. 8s fast I2V no audio = $0.80.

Image input constraints (Veo 3): Max 8MB, must be 720p+, formats: PNG/JPEG/WebP. Aspect must be 16:9 or 9:16.

curl (fast I2V):

curl -X POST "https://fal.run/fal-ai/veo3/fast/image-to-video" \
  -H "Authorization: Key $FAL_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "gentle camera movement, ambient sounds", "image_url": "https://...keyframe.png", "duration": "8s", "generate_audio": true}'

LTX 2.0 Fast — Budget Option [E1-verified]

Best for: bulk generation, prototyping, long videos up to 20s, up to 4K.

# Text-to-video
result = fal_client.run(
    "fal-ai/ltx-2/text-to-video/fast",
    arguments={
        "prompt": "flowing abstract particles, dark background",
        "duration": 6,            # 6, 8, 10, 12, 14, 16, 18, 20 seconds
        "resolution": "1080p",    # "1080p", "1440p", "2160p"
        "fps": 25,                # 25 or 50
        "generate_audio": True,
    }
)

# Image-to-video
result = fal_client.run(
    "fal-ai/ltx-2/image-to-video/fast",
    arguments={
        "prompt": "gentle camera movement revealing details",
        "image_url": "https://...keyframe.png",
        "duration": 6,
        "resolution": "1080p",
    }
)

# Extend existing video
result = fal_client.run(
    "fal-ai/ltx-2/extend-video",
    arguments={
        "video_url": "https://...existing.mp4",
        "prompt": "continue the motion smoothly",
        "duration": 5,            # max 20s total
        "mode": "end",            # "start" or "end"
    }
)

Cost [E1]: $0.04/sec @1080p, $0.08/sec @1440p, $0.16/sec @2160p 6s @1080p = $0.24. 5x cheaper than Kling (no audio).

Extra endpoints: extend-video (extend existing), retake-video (regenerate segment), audio-to-video (audio→video).

PixVerse v4.5 — Stylized [E1-verified]

Best for: 3D render, cyberpunk, anime, clay, comic styles. Has camera presets.

result = fal_client.run(
    "fal-ai/pixverse/v4.5/image-to-video",
    arguments={
        "prompt": "cyberpunk city comes alive, neon signs flicker",
        "image_url": "https://...keyframe.png",
        "style": "cyberpunk",     # anime, 3d_animation, clay, comic, cyberpunk
        "camera_movement": "smooth_zoom_in",  # see list below
        "resolution": "720p",     # 360p, 540p, 720p, 1080p
        "duration": "5",          # "5" or "8" (8s = 2x cost, 1080p = 5s only)
    }
)

Camera presets: horizontal_left, horizontal_right, vertical_up, vertical_down, zoom_in, zoom_out, crane_up, quickly_zoom_in, quickly_zoom_out, smooth_zoom_in, camera_rotation, robo_arm, super_dolly_out, whip_pan, hitchcock, left_follow, right_follow, pan_left, pan_right, fix_bg

Cost [E1]:

Resolution 5s 8s (2x)
360p/540p $0.15 $0.30
720p $0.20 $0.40
1080p $0.40 — (5s only)

Step 3: Process for Web (FFmpeg)

Download Generated Video

# Download from fal.ai URL
curl -o generated.mp4 "VIDEO_URL_FROM_FAL"

Route A: Frame Sequence (for scroll animations)

Use when the video will be played via GSAP ScrollTrigger or canvas scroll.

# Extract frames at 30fps, 1920x1080
mkdir -p frames/desktop
ffmpeg -i generated.mp4 -vf "fps=30,scale=1920:1080" frames/desktop/frame_%04d.png

# Convert to WebP
for f in frames/desktop/*.png; do
  cwebp -q 80 "$f" -o "${f%.png}.webp"
  rm "$f"
done

# Mobile version (fewer frames, smaller)
mkdir -p frames/mobile
ffmpeg -i generated.mp4 -vf "fps=15,scale=960:540" frames/mobile/frame_%04d.png
for f in frames/mobile/*.png; do
  cwebp -q 80 "$f" -o "${f%.png}.webp"
  rm "$f"
done

→ Then use scroll-animation skill for GSAP ScrollTrigger canvas playback.

Route B: Optimized Video (for autoplay/embed)

Use for hero video backgrounds, embedded players.

# Web-optimized MP4 (H.264 for max compat)
ffmpeg -i generated.mp4 \
  -c:v libx264 -preset slow -crf 23 \
  -c:a aac -b:a 128k \
  -movflags +faststart \
  -vf "scale=1920:1080" \
  hero-video.mp4

# WebM (VP9, smaller, modern browsers)
ffmpeg -i generated.mp4 \
  -c:v libvpx-vp9 -crf 30 -b:v 2M \
  -c:a libopus -b:a 128k \
  -vf "scale=1920:1080" \
  hero-video.webm

# AV1 (smallest, newer browsers)
ffmpeg -i generated.mp4 \
  -c:v libaom-av1 -crf 30 -b:v 0 \
  -c:a libopus -b:a 128k \
  -vf "scale=1920:1080" \
  hero-video.av1.mp4

Route C: Scrub-Optimized Video (for scroll-driven playback)

# Every frame is keyframe = instant seeking
ffmpeg -i generated.mp4 \
  -c:v libx264 -preset slow -crf 23 \
  -g 1 -an -movflags +faststart \
  -vf "scale=1920:1080" \
  scrub-video.mp4

Route D: Looping GIF (for social/email)

# High quality GIF with palette optimization
ffmpeg -i generated.mp4 \
  -vf "fps=15,scale=480:-1:flags=lanczos,split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" \
  -loop 0 output.gif

Step 4: Integrate into Web

Hero Video Background

<section class="hero">
  <video autoplay loop muted playsinline class="hero-video">
    <source src="hero-video.av1.mp4" type="video/mp4; codecs=av01.0.05M.08">
    <source src="hero-video.webm" type="video/webm">
    <source src="hero-video.mp4" type="video/mp4">
  </video>
  <div class="hero-content">
    <h1>Product Name</h1>
  </div>
</section>

<style>
.hero { position: relative; height: 100vh; overflow: hidden; }
.hero-video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
}
.hero-content {
  position: relative; z-index: 1;
  display: grid; place-items: center;
  height: 100%;
}
</style>

Scroll-Driven Frame Sequence

→ Invoke scroll-animation skill with the frame sequence from Step 3A.

Reduced Motion Fallback

<picture>
  <source srcset="keyframe-hero.avif" type="image/avif">
  <source srcset="keyframe-hero.webp" type="image/webp">
  <img src="keyframe-hero.jpg" alt="Hero" class="hero-fallback">
</picture>

<style>
.hero-video { display: block; }
.hero-fallback { display: none; }

@media (prefers-reduced-motion: reduce) {
  .hero-video { display: none; }
  .hero-fallback { display: block; }
}
</style>

Cost Calculator [E1-verified]

Per-Video Costs (no audio, cheapest resolution)

Model 5s 10s With keyframe ($0.07)
Kling v3 Pro (no audio) $0.56 $1.12 $0.63 / $1.19
Kling v3 Pro (audio) $0.84 $1.68 $0.91 / $1.75
Luma Ray 2 @540p $0.50 $0.57
Luma Ray 2 @1080p $2.00 $2.07
Veo 3 Standard (no audio) $1.00 $1.07
Veo 3 Fast I2V (no audio) $0.50 $0.57
LTX 2.0 @1080p $0.20 $0.40 $0.27 / $0.47
PixVerse v4.5 @720p $0.20 $0.27

Landing Page Budget Estimates

Scenario Videos Model Est. Cost
1 hero loop @540p 1 Luma ~$0.57
Product reveal 10s 1 Kling no audio ~$1.19
Product + hero 2 Kling + Luma ~$1.20
Full cinematic page 3-5 Mixed ~$2-5
Bulk content (10 clips) 10 LTX 2.0 ~$2.70
Max quality (Veo 3 audio) 3 Veo 3 Standard ~$10+

Before Running — API Cost Guard

  1. Check fal.ai dashboard balance
  2. Calculate exact cost: duration × cost_per_sec + keyframe_cost
  3. Generate ONE test clip first
  4. Review quality before batch
  5. Tell user total cost before proceeding

Full Pipeline Examples

Example 1: Apple-Style Product Scroll

# 1. Keyframe
nano-banana "premium smart watch floating on dark background, studio rim lighting, centered" -s 2K -a 16:9 -o watch-keyframe

# 2. Animate (product rotation)
python3 -c "
import fal_client
result = fal_client.run('fal-ai/kling-video/v3/pro/image-to-video', arguments={
    'prompt': 'the watch slowly rotates 360 degrees, camera orbits smoothly, dramatic lighting',
    'start_image_url': 'file://watch-keyframe.png',
    'duration': '10',
    'aspect_ratio': '16:9',
    'generate_audio': False,
})
print(result['video']['url'])
"

# 3. Download & extract frames
curl -o watch-rotation.mp4 "VIDEO_URL"
mkdir -p public/frames/watch/desktop public/frames/watch/mobile
ffmpeg -i watch-rotation.mp4 -vf "fps=30,scale=1920:1080" public/frames/watch/desktop/frame_%04d.png
ffmpeg -i watch-rotation.mp4 -vf "fps=15,scale=960:540" public/frames/watch/mobile/frame_%04d.png

# Convert to WebP
for dir in public/frames/watch/desktop public/frames/watch/mobile; do
  for f in "$dir"/*.png; do cwebp -q 80 "$f" -o "${f%.png}.webp" && rm "$f"; done
done

# 4. → Use scroll-animation skill for GSAP canvas playback

Cost: ~$0.07 (keyframe) + $1.12 (Kling 10s no audio) = $1.19

Example 2: Hero Background Loop

# 1. Keyframe
nano-banana "abstract flowing liquid metal, iridescent, macro photography, dark background" -s 2K -a 16:9 -o hero-bg

# 2. Animate (seamless loop)
python3 -c "
import fal_client
result = fal_client.run('fal-ai/luma-dream-machine/ray-2/image-to-video', arguments={
    'prompt': 'gentle flowing motion, metallic liquid ripples, seamless loop',
    'image_url': 'file://hero-bg.png',
    'loop': True,
    'aspect_ratio': '16:9'
})
print(result['video']['url'])
"

# 3. Optimize for web autoplay
curl -o hero-loop-raw.mp4 "VIDEO_URL"
ffmpeg -i hero-loop-raw.mp4 -c:v libx264 -preset slow -crf 23 -an -movflags +faststart hero-loop.mp4
ffmpeg -i hero-loop-raw.mp4 -c:v libvpx-vp9 -crf 30 -b:v 2M -an hero-loop.webm

Cost: ~$0.07 + $0.50 = $0.57

Example 3: Bulk Content Videos (Budget)

# 1. Generate 5 keyframes
for i in 1 2 3 4 5; do
  nano-banana "feature illustration $i, minimal, clean" -s 1K -a 16:9 -o "feature-$i"
done

# 2. Animate all with LTX (cheapest)
python3 << 'EOF'
import fal_client
prompts = [
    "gentle zoom in, subtle particle effects",
    "slow pan right revealing details",
    "elements float upward gently",
    "soft glow pulses outward",
    "camera slowly pulls back"
]
for i, prompt in enumerate(prompts, 1):
    result = fal_client.run("fal-ai/ltx-2/text-to-video/fast", arguments={
        "prompt": prompt,
        "image_url": f"file://feature-{i}.png",
        "duration": 5,
        "aspect_ratio": "16:9"
    })
    print(f"Feature {i}: {result['video']['url']}")
EOF

Cost: 5 × ($0.07 + $0.20) = $1.35 for 5 videos


Prompting Guide for Video Models

Motion Prompts (DO)

  • "slowly rotates 360 degrees clockwise"
  • "camera dollies in from medium to close-up"
  • "gentle floating up and down motion"
  • "particles drift outward from center"
  • "liquid flows from left to right"
  • "zoom in on the detail, rack focus"

Motion Prompts (DON'T)

  • "beautiful product" (describes scene, not motion)
  • "4K cinematic masterpiece" (quality tags don't help)
  • "the scene transforms into a different scene" (too complex)
  • "person walks, talks, and dances" (too many actions)

Rules

  1. One motion per clip — don't combine rotate + zoom + pan
  2. Describe the camera — "camera orbits", "dolly in", "static wide"
  3. Describe speed — "slowly", "gently", "dramatically fast"
  4. 5s for simple motion, 10s for complex reveals
  5. Match prompt to model — Kling handles product/object motion best, Luma handles ambient/organic best

Integration with Other Skills

Skill Role When
nano-banana Generate keyframe images Step 1
video-gen Process video → frame sequence Step 3A
scroll-animation GSAP ScrollTrigger playback Step 4 (scroll)
motion-design Page transitions + micro-interactions Step 4 (ambient)
web-assets Optimize final video/frames Step 3 (all routes)
landing-page Full page orchestration When recipe needs video
3d-scene Three.js alternative to AI video When real 3D needed

nano-banana via fal.ai API (Alternative to CLI)

If the nano-banana CLI is not available, use the fal.ai endpoint directly:

import fal_client

# Generate keyframe via fal.ai nano-banana (Gemini image gen)
result = fal_client.run("fal-ai/nano-banana", arguments={
    "prompt": "premium smart watch on dark background, studio rim lighting, centered, clean edges",
    "num_images": 1,
    "aspect_ratio": "16:9",   # 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3, 4:5, 5:4, 21:9
    "output_format": "png",   # png, jpeg, webp
    "safety_tolerance": 4,    # 1 (strict) to 6 (permissive)
})
keyframe_url = result["images"][0]["url"]
# Cost: $0.039 per image

# Now chain directly into video generation (no upload needed — already a URL!)
video_result = fal_client.run("fal-ai/kling-video/v3/pro/image-to-video", arguments={
    "start_image_url": keyframe_url,  # direct URL from nano-banana
    "prompt": "watch slowly rotates 360 degrees, studio lighting",
    "duration": "5",
    "generate_audio": False,
})
video_url = video_result["video"]["url"]

Key advantage: nano-banana output is already a fal.ai URL, so it chains directly into any video model without upload. Total cost for keyframe + 5s Kling video: $0.039 + $0.56 = $0.60.

# curl version
KEYFRAME_URL=$(curl -s -X POST "https://fal.run/fal-ai/nano-banana" \
  -H "Authorization: Key $FAL_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "premium watch on dark bg, studio lighting, centered", "aspect_ratio": "16:9"}' \
  | jq -r '.images[0].url')

curl -X POST "https://queue.fal.run/fal-ai/kling-video/v3/pro/image-to-video" \
  -H "Authorization: Key $FAL_KEY" \
  -H "Content-Type: application/json" \
  -d "{\"start_image_url\": \"$KEYFRAME_URL\", \"prompt\": \"watch rotates slowly\", \"duration\": \"5\", \"generate_audio\": false}"

Workflow Summary

  1. Define goal — what animation, where on page, what triggers it?
  2. Pick model — use selection matrix above
  3. Cost estimate — calculate and tell user BEFORE generating
  4. Generate keyframe — nano-banana with animation-friendly composition
  5. Animate — fal.ai with focused motion prompt
  6. Review — watch output, iterate prompt if needed (budget 2-3 attempts)
  7. Process — choose route: frame sequence / video / scrub / GIF
  8. Integrate — embed with scroll-animation, video tag, or motion-design
  9. Fallback — static keyframe for prefers-reduced-motion