vargai 0.4.0-alpha4 → 0.4.0-alpha40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +6 -0
- package/README.md +483 -61
- package/assets/fonts/TikTokSans-Bold.ttf +0 -0
- package/examples/grok-imagine-test.tsx +155 -0
- package/launch-videos/06-kawaii-fruits.tsx +93 -0
- package/launch-videos/07-ugc-weight-loss.tsx +132 -0
- package/launch-videos/08-talking-head-varg.tsx +107 -0
- package/launch-videos/09-girl.tsx +160 -0
- package/launch-videos/README.md +42 -0
- package/package.json +10 -4
- package/pipeline/cookbooks/round-video-character.md +1 -1
- package/skills/varg-video-generation/SKILL.md +224 -0
- package/skills/varg-video-generation/references/templates.md +380 -0
- package/skills/varg-video-generation/scripts/setup.ts +265 -0
- package/src/ai-sdk/cache.ts +1 -3
- package/src/ai-sdk/examples/google-image.ts +62 -0
- package/src/ai-sdk/index.ts +10 -0
- package/src/ai-sdk/middleware/wrap-image-model.ts +4 -21
- package/src/ai-sdk/middleware/wrap-music-model.ts +4 -16
- package/src/ai-sdk/middleware/wrap-video-model.ts +5 -17
- package/src/ai-sdk/providers/CONTRIBUTING.md +457 -0
- package/src/ai-sdk/providers/editly/backends/index.ts +8 -0
- package/src/ai-sdk/providers/editly/backends/local.ts +94 -0
- package/src/ai-sdk/providers/editly/backends/types.ts +74 -0
- package/src/ai-sdk/providers/editly/editly.test.ts +49 -1
- package/src/ai-sdk/providers/editly/index.ts +164 -80
- package/src/ai-sdk/providers/editly/layers.ts +58 -6
- package/src/ai-sdk/providers/editly/rendi/editly-with-rendi-backend.test.ts +335 -0
- package/src/ai-sdk/providers/editly/rendi/index.ts +289 -0
- package/src/ai-sdk/providers/editly/rendi/rendi.test.ts +35 -0
- package/src/ai-sdk/providers/editly/types.ts +30 -0
- package/src/ai-sdk/providers/elevenlabs.ts +10 -2
- package/src/ai-sdk/providers/fal.test.ts +214 -0
- package/src/ai-sdk/providers/fal.ts +435 -40
- package/src/ai-sdk/providers/google.ts +423 -0
- package/src/ai-sdk/providers/together.ts +191 -0
- package/src/cli/commands/find.tsx +1 -0
- package/src/cli/commands/frame.tsx +616 -0
- package/src/cli/commands/hello.ts +85 -0
- package/src/cli/commands/help.tsx +18 -30
- package/src/cli/commands/index.ts +11 -2
- package/src/cli/commands/init.tsx +570 -0
- package/src/cli/commands/list.tsx +1 -0
- package/src/cli/commands/render.tsx +322 -76
- package/src/cli/commands/run.tsx +1 -0
- package/src/cli/commands/storyboard.tsx +1714 -0
- package/src/cli/commands/which.tsx +1 -0
- package/src/cli/index.ts +23 -4
- package/src/cli/ui/components/Badge.tsx +1 -0
- package/src/cli/ui/components/DataTable.tsx +1 -0
- package/src/cli/ui/components/Header.tsx +1 -0
- package/src/cli/ui/components/HelpBlock.tsx +1 -0
- package/src/cli/ui/components/KeyValue.tsx +1 -0
- package/src/cli/ui/components/OptionRow.tsx +1 -0
- package/src/cli/ui/components/Separator.tsx +1 -0
- package/src/cli/ui/components/StatusBox.tsx +1 -0
- package/src/cli/ui/components/VargBox.tsx +1 -0
- package/src/cli/ui/components/VargProgress.tsx +1 -0
- package/src/cli/ui/components/VargSpinner.tsx +1 -0
- package/src/cli/ui/components/VargText.tsx +1 -0
- package/src/definitions/actions/grok-edit.ts +133 -0
- package/src/definitions/actions/index.ts +16 -0
- package/src/definitions/actions/qwen-angles.ts +218 -0
- package/src/index.ts +1 -0
- package/src/providers/fal.ts +196 -0
- package/src/react/assets.ts +9 -0
- package/src/react/elements.ts +0 -5
- package/src/react/examples/branching.tsx +6 -4
- package/src/react/examples/character-video.tsx +13 -10
- package/src/react/examples/local-files-test.tsx +19 -0
- package/src/react/examples/ltx2-test.tsx +25 -0
- package/src/react/examples/madi.tsx +13 -10
- package/src/react/examples/mcmeows.tsx +40 -0
- package/src/react/examples/music-defaults.tsx +24 -0
- package/src/react/examples/quickstart-test.tsx +101 -0
- package/src/react/examples/qwen-angles-test.tsx +72 -0
- package/src/react/index.ts +3 -3
- package/src/react/layouts/grid.tsx +1 -1
- package/src/react/layouts/index.ts +2 -1
- package/src/react/layouts/slot.tsx +85 -0
- package/src/react/layouts/split.tsx +18 -0
- package/src/react/react.test.ts +60 -11
- package/src/react/renderers/burn-captions.ts +95 -0
- package/src/react/renderers/cache.test.ts +182 -0
- package/src/react/renderers/captions.ts +25 -6
- package/src/react/renderers/clip.ts +56 -25
- package/src/react/renderers/context.ts +5 -2
- package/src/react/renderers/image.ts +5 -2
- package/src/react/renderers/index.ts +0 -1
- package/src/react/renderers/music.ts +8 -3
- package/src/react/renderers/packshot/blinking-button.ts +413 -0
- package/src/react/renderers/packshot.ts +170 -8
- package/src/react/renderers/progress.ts +4 -3
- package/src/react/renderers/render.ts +127 -71
- package/src/react/renderers/speech.ts +2 -2
- package/src/react/renderers/split.ts +34 -13
- package/src/react/renderers/utils.test.ts +80 -0
- package/src/react/renderers/utils.ts +37 -1
- package/src/react/renderers/video.ts +47 -9
- package/src/react/types.ts +70 -17
- package/src/studio/stages.ts +40 -39
- package/src/studio/step-renderer.ts +14 -24
- package/src/studio/ui/index.html +2 -2
- package/src/tests/all.test.ts +4 -4
- package/src/tests/index.ts +1 -1
- package/test-slot-grid.tsx +19 -0
- package/test-slot-userland.tsx +30 -0
- package/test-sync-v2.ts +30 -0
- package/test-sync-v2.tsx +29 -0
- package/tsconfig.json +1 -1
- package/video.tsx +7 -0
- package/src/ai-sdk/providers/editly/ffmpeg.ts +0 -60
- package/src/react/renderers/animate.ts +0 -59
- /package/src/cli/commands/{studio.tsx → studio.ts} +0 -0
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"module": "src/index.ts",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
|
-
"
|
|
6
|
+
"vargai": "./src/cli/index.ts"
|
|
7
7
|
},
|
|
8
8
|
"scripts": {
|
|
9
9
|
"check": "biome check . && tsc --noEmit",
|
|
@@ -34,14 +34,18 @@
|
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"typescript": "^5",
|
|
37
|
-
"ai": "^6.0.0"
|
|
37
|
+
"ai": "^6.0.0",
|
|
38
|
+
"zod": "^3.25.76 || ^4.1.8"
|
|
38
39
|
},
|
|
39
40
|
"dependencies": {
|
|
40
41
|
"@ai-sdk/fal": "^1.0.23",
|
|
41
42
|
"@ai-sdk/fireworks": "^2.0.16",
|
|
42
43
|
"@ai-sdk/groq": "^3.0.12",
|
|
44
|
+
"@ai-sdk/google": "^3.0.13",
|
|
43
45
|
"@ai-sdk/openai": "^3.0.9",
|
|
46
|
+
"@google/genai": "^1.0.0",
|
|
44
47
|
"@ai-sdk/provider": "^3.0.2",
|
|
48
|
+
"@ai-sdk/provider-utils": "^4.0.4",
|
|
45
49
|
"@ai-sdk/replicate": "^2.0.5",
|
|
46
50
|
"@aws-sdk/client-s3": "^3.937.0",
|
|
47
51
|
"@aws-sdk/s3-request-presigner": "^3.937.0",
|
|
@@ -61,9 +65,10 @@
|
|
|
61
65
|
"react-dom": "^19.2.0",
|
|
62
66
|
"remotion": "^4.0.377",
|
|
63
67
|
"replicate": "^1.4.0",
|
|
68
|
+
"sharp": "^0.34.5",
|
|
64
69
|
"zod": "^4.2.1"
|
|
65
70
|
},
|
|
66
|
-
"version": "0.4.0-
|
|
71
|
+
"version": "0.4.0-alpha40",
|
|
67
72
|
"exports": {
|
|
68
73
|
".": "./src/index.ts",
|
|
69
74
|
"./ai": "./src/ai-sdk/index.ts",
|
|
@@ -73,6 +78,7 @@
|
|
|
73
78
|
"./react": "./src/react/index.ts",
|
|
74
79
|
"./studio": "./src/studio/index.ts",
|
|
75
80
|
"./jsx-runtime": "./src/react/runtime/jsx-runtime.ts",
|
|
76
|
-
"./jsx-dev-runtime": "./src/react/runtime/jsx-dev-runtime.ts"
|
|
81
|
+
"./jsx-dev-runtime": "./src/react/runtime/jsx-dev-runtime.ts",
|
|
82
|
+
"./editly": "./src/ai-sdk/providers/editly/index.ts"
|
|
77
83
|
}
|
|
78
84
|
}
|
|
@@ -321,7 +321,7 @@ see all voices: `bun run lib/elevenlabs.ts voices`
|
|
|
321
321
|
```bash
|
|
322
322
|
# required api keys
|
|
323
323
|
export ELEVENLABS_API_KEY="your_key"
|
|
324
|
-
export
|
|
324
|
+
export FAL_API_KEY="your_key" # for wan-25 and image generation (or set FAL_KEY)
|
|
325
325
|
```
|
|
326
326
|
|
|
327
327
|
## changelog
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: varg-video-generation
|
|
3
|
+
description: Generate AI videos using varg SDK React engine. Use when creating videos, animations, talking characters, slideshows, or social media content.
|
|
4
|
+
license: MIT
|
|
5
|
+
metadata:
|
|
6
|
+
author: vargHQ
|
|
7
|
+
version: "1.0.0"
|
|
8
|
+
compatibility: Requires bun runtime. FAL_KEY required. Optional ELEVENLABS_API_KEY, REPLICATE_API_TOKEN, GROQ_API_KEY
|
|
9
|
+
allowed-tools: Bash(bun:*) Bash(cat:*) Read Write Edit
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Video Generation with varg React Engine
|
|
13
|
+
|
|
14
|
+
Generate AI videos using declarative JSX syntax with automatic caching and parallel generation.
|
|
15
|
+
|
|
16
|
+
## Quick Setup
|
|
17
|
+
|
|
18
|
+
Initialize a new project:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
bunx vargai init
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Or just create hello.tsx starter:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
bunx vargai hello
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Check existing API keys:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
cat .env 2>/dev/null | grep -E "^(FAL_KEY|ELEVENLABS_API_KEY)=" || echo "No API keys found"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Required API Keys
|
|
37
|
+
|
|
38
|
+
### FAL_KEY (Required)
|
|
39
|
+
|
|
40
|
+
| Detail | Value |
|
|
41
|
+
|--------|-------|
|
|
42
|
+
| Provider | Fal.ai |
|
|
43
|
+
| Get it | https://fal.ai/dashboard/keys |
|
|
44
|
+
| Free tier | Yes (limited credits) |
|
|
45
|
+
| Used for | Image generation (Flux), Video generation (Wan 2.5, Kling) |
|
|
46
|
+
|
|
47
|
+
If user doesn't have `FAL_KEY`:
|
|
48
|
+
1. Direct them to https://fal.ai/dashboard/keys
|
|
49
|
+
2. Create account and generate API key
|
|
50
|
+
3. Add to `.env` file: `FAL_KEY=fal_xxxxx`
|
|
51
|
+
|
|
52
|
+
### Optional Keys
|
|
53
|
+
|
|
54
|
+
| Feature | Key | Provider | URL |
|
|
55
|
+
|---------|-----|----------|-----|
|
|
56
|
+
| Music/Voice | `ELEVENLABS_API_KEY` | ElevenLabs | https://elevenlabs.io/app/settings/api-keys |
|
|
57
|
+
| Lipsync | `REPLICATE_API_TOKEN` | Replicate | https://replicate.com/account/api-tokens |
|
|
58
|
+
| Transcription | `GROQ_API_KEY` | Groq | https://console.groq.com/keys |
|
|
59
|
+
|
|
60
|
+
**Warn user about missing optional keys but continue with available features.**
|
|
61
|
+
|
|
62
|
+
## Available Features by API Key
|
|
63
|
+
|
|
64
|
+
**FAL_API_KEY only:**
|
|
65
|
+
- Image generation (Flux models)
|
|
66
|
+
- Image-to-video animation (Wan 2.5, Kling)
|
|
67
|
+
- Text-to-video generation
|
|
68
|
+
- Slideshows with transitions
|
|
69
|
+
- Ken Burns zoom effects
|
|
70
|
+
|
|
71
|
+
**FAL + ELEVENLABS:**
|
|
72
|
+
- All above, plus:
|
|
73
|
+
- AI-generated background music
|
|
74
|
+
- Text-to-speech voiceovers
|
|
75
|
+
- Talking character videos
|
|
76
|
+
|
|
77
|
+
**All keys:**
|
|
78
|
+
- Full production pipeline with lipsync and auto-captions
|
|
79
|
+
|
|
80
|
+
## Quick Templates
|
|
81
|
+
|
|
82
|
+
### Simple Slideshow (FAL only)
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
/** @jsxImportSource vargai */
|
|
86
|
+
import { Render, Clip, Image } from "vargai/react";
|
|
87
|
+
|
|
88
|
+
const SCENES = ["sunset over ocean", "mountain peaks", "city at night"];
|
|
89
|
+
|
|
90
|
+
export default (
|
|
91
|
+
<Render width={1080} height={1920}>
|
|
92
|
+
{SCENES.map((prompt, i) => (
|
|
93
|
+
<Clip key={i} duration={3} transition={{ name: "fade", duration: 0.5 }}>
|
|
94
|
+
<Image prompt={prompt} zoom="in" />
|
|
95
|
+
</Clip>
|
|
96
|
+
))}
|
|
97
|
+
</Render>
|
|
98
|
+
);
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Animated Video (FAL + ElevenLabs)
|
|
102
|
+
|
|
103
|
+
```tsx
|
|
104
|
+
/** @jsxImportSource vargai */
|
|
105
|
+
import { Render, Clip, Image, Video, Music } from "vargai/react";
|
|
106
|
+
import { fal, elevenlabs } from "vargai/ai";
|
|
107
|
+
|
|
108
|
+
const cat = Image({ prompt: "cute cat on windowsill" });
|
|
109
|
+
|
|
110
|
+
export default (
|
|
111
|
+
<Render width={1080} height={1920}>
|
|
112
|
+
<Music prompt="upbeat electronic" model={elevenlabs.musicModel()} />
|
|
113
|
+
<Clip duration={5}>
|
|
114
|
+
<Video
|
|
115
|
+
prompt={{ text: "cat turns head, blinks slowly", images: [cat] }}
|
|
116
|
+
model={fal.videoModel("wan-2.5")}
|
|
117
|
+
/>
|
|
118
|
+
</Clip>
|
|
119
|
+
</Render>
|
|
120
|
+
);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Talking Character
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
/** @jsxImportSource vargai */
|
|
127
|
+
import { Render, Clip, Image, Video, Speech, Captions } from "vargai/react";
|
|
128
|
+
import { fal, elevenlabs } from "vargai/ai";
|
|
129
|
+
|
|
130
|
+
const robot = Image({ prompt: "friendly robot, blue metallic", aspectRatio: "9:16" });
|
|
131
|
+
|
|
132
|
+
const voiceover = Speech({
|
|
133
|
+
model: elevenlabs.speechModel("eleven_multilingual_v2"),
|
|
134
|
+
voice: "adam",
|
|
135
|
+
children: "Hello! I'm your AI assistant. Let's create something amazing!",
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
export default (
|
|
139
|
+
<Render width={1080} height={1920}>
|
|
140
|
+
<Clip duration={5}>
|
|
141
|
+
<Video
|
|
142
|
+
prompt={{ text: "robot talking, subtle head movements", images: [robot] }}
|
|
143
|
+
model={fal.videoModel("wan-2.5")}
|
|
144
|
+
/>
|
|
145
|
+
</Clip>
|
|
146
|
+
<Captions src={voiceover} style="tiktok" />
|
|
147
|
+
</Render>
|
|
148
|
+
);
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
## Running Videos
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
bunx vargai render your-video.tsx
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Key Components
|
|
160
|
+
|
|
161
|
+
| Component | Purpose | Required Key |
|
|
162
|
+
|-----------|---------|--------------|
|
|
163
|
+
| `<Render>` | Root container | - |
|
|
164
|
+
| `<Clip>` | Sequential segment | - |
|
|
165
|
+
| `<Image>` | AI image | FAL |
|
|
166
|
+
| `<Animate>` | Image-to-video | FAL |
|
|
167
|
+
| `<Music>` | Background music | ElevenLabs |
|
|
168
|
+
| `<Speech>` | Text-to-speech | ElevenLabs |
|
|
169
|
+
|
|
170
|
+
## Common Patterns
|
|
171
|
+
|
|
172
|
+
### Character Consistency
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
const character = Image({ prompt: "blue robot" });
|
|
176
|
+
// Reuse same reference = same generated image
|
|
177
|
+
<Animate image={character} motion="waving" />
|
|
178
|
+
<Animate image={character} motion="dancing" />
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Transitions
|
|
182
|
+
|
|
183
|
+
```tsx
|
|
184
|
+
<Clip transition={{ name: "fade", duration: 0.5 }}>
|
|
185
|
+
// Options: fade, crossfade, wipeleft, cube, slideup, etc.
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Aspect Ratios
|
|
189
|
+
|
|
190
|
+
- `9:16` - TikTok, Reels, Shorts (vertical)
|
|
191
|
+
- `16:9` - YouTube (horizontal)
|
|
192
|
+
- `1:1` - Instagram (square)
|
|
193
|
+
|
|
194
|
+
### Zoom Effects
|
|
195
|
+
|
|
196
|
+
```tsx
|
|
197
|
+
<Image prompt="landscape" zoom="in" /> // Zoom in
|
|
198
|
+
<Image prompt="landscape" zoom="out" /> // Zoom out
|
|
199
|
+
<Image prompt="landscape" zoom="left" /> // Pan left
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Troubleshooting
|
|
203
|
+
|
|
204
|
+
### "FAL_KEY not found"
|
|
205
|
+
- Check `.env` file exists in project root
|
|
206
|
+
- Ensure no spaces around `=` sign
|
|
207
|
+
- Restart terminal after adding keys
|
|
208
|
+
|
|
209
|
+
### "Rate limit exceeded"
|
|
210
|
+
- Free tier has limited credits
|
|
211
|
+
- Wait or upgrade plan
|
|
212
|
+
- Use caching to avoid regenerating
|
|
213
|
+
|
|
214
|
+
### "Video generation failed"
|
|
215
|
+
- Check prompt doesn't violate content policy
|
|
216
|
+
- Try simpler motion descriptions
|
|
217
|
+
- Reduce video duration
|
|
218
|
+
|
|
219
|
+
## Next Steps
|
|
220
|
+
|
|
221
|
+
1. Run `bunx vargai init` to initialize project
|
|
222
|
+
2. Add your FAL_KEY to `.env`
|
|
223
|
+
3. Run `bunx vargai render hello.tsx`
|
|
224
|
+
4. Or ask the agent: "create a 10 second tiktok video about cats"
|
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
# Video Generation Templates
|
|
2
|
+
|
|
3
|
+
Complete code templates for common video generation patterns.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
1. [Simple Slideshow](#simple-slideshow)
|
|
8
|
+
2. [Animated Video with Music](#animated-video-with-music)
|
|
9
|
+
3. [Talking Character](#talking-character)
|
|
10
|
+
4. [TikTok Multi-Clip](#tiktok-multi-clip)
|
|
11
|
+
5. [Character with Consistent Style](#character-with-consistent-style)
|
|
12
|
+
6. [Split Screen Comparison](#split-screen-comparison)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Simple Slideshow
|
|
17
|
+
|
|
18
|
+
**Requirements:** FAL_API_KEY only
|
|
19
|
+
|
|
20
|
+
Basic image slideshow with transitions and zoom effects.
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
// slideshow.tsx
|
|
24
|
+
import { render, Render, Clip, Image } from "vargai/react";
|
|
25
|
+
|
|
26
|
+
const SCENES = [
|
|
27
|
+
"sunset over ocean, cinematic golden hour",
|
|
28
|
+
"mountain peaks at dawn, misty atmosphere",
|
|
29
|
+
"city skyline at night, neon lights",
|
|
30
|
+
"forest path in autumn, fallen leaves",
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
async function main() {
|
|
34
|
+
await render(
|
|
35
|
+
<Render width={1080} height={1920}>
|
|
36
|
+
{SCENES.map((prompt, i) => (
|
|
37
|
+
<Clip
|
|
38
|
+
key={i}
|
|
39
|
+
duration={3}
|
|
40
|
+
transition={{ name: "fade", duration: 0.5 }}
|
|
41
|
+
>
|
|
42
|
+
<Image prompt={prompt} zoom="in" />
|
|
43
|
+
</Clip>
|
|
44
|
+
))}
|
|
45
|
+
</Render>,
|
|
46
|
+
{ output: "output/slideshow.mp4" }
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
console.log("Done! output/slideshow.mp4");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
main();
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Run: `bun run slideshow.tsx`
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Animated Video with Music
|
|
60
|
+
|
|
61
|
+
**Requirements:** FAL_API_KEY + ELEVENLABS_API_KEY
|
|
62
|
+
|
|
63
|
+
Video with AI-generated animation and background music.
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
// animated-video.tsx
|
|
67
|
+
import { render, Render, Clip, Image, Animate, Music } from "vargai/react";
|
|
68
|
+
import { fal, elevenlabs } from "vargai/ai";
|
|
69
|
+
|
|
70
|
+
async function main() {
|
|
71
|
+
await render(
|
|
72
|
+
<Render width={1080} height={1920}>
|
|
73
|
+
<Music
|
|
74
|
+
prompt="upbeat electronic pop, energetic, modern tiktok vibe"
|
|
75
|
+
model={elevenlabs.musicModel()}
|
|
76
|
+
duration={10}
|
|
77
|
+
volume={0.7}
|
|
78
|
+
/>
|
|
79
|
+
|
|
80
|
+
<Clip duration={5}>
|
|
81
|
+
<Animate
|
|
82
|
+
image={Image({
|
|
83
|
+
prompt: "cute cat sitting on windowsill, golden hour lighting",
|
|
84
|
+
model: fal.imageModel("flux-schnell")
|
|
85
|
+
})}
|
|
86
|
+
motion="cat slowly turns head, blinks, tail swishes gently"
|
|
87
|
+
model={fal.videoModel("wan-2.5")}
|
|
88
|
+
duration={5}
|
|
89
|
+
/>
|
|
90
|
+
</Clip>
|
|
91
|
+
|
|
92
|
+
<Clip duration={5} transition={{ name: "fade", duration: 0.5 }}>
|
|
93
|
+
<Animate
|
|
94
|
+
image={Image({
|
|
95
|
+
prompt: "same cat stretching on windowsill, yawning"
|
|
96
|
+
})}
|
|
97
|
+
motion="cat stretches, yawns widely, settles back down"
|
|
98
|
+
model={fal.videoModel("wan-2.5")}
|
|
99
|
+
duration={5}
|
|
100
|
+
/>
|
|
101
|
+
</Clip>
|
|
102
|
+
</Render>,
|
|
103
|
+
{ output: "output/cat-video.mp4" }
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
main();
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Talking Character
|
|
113
|
+
|
|
114
|
+
**Requirements:** FAL_API_KEY + ELEVENLABS_API_KEY
|
|
115
|
+
|
|
116
|
+
Character that speaks with animated movement.
|
|
117
|
+
|
|
118
|
+
```tsx
|
|
119
|
+
// talking-character.tsx
|
|
120
|
+
import { render, Render, Clip, Image, Animate, Speech } from "vargai/react";
|
|
121
|
+
import { fal, elevenlabs } from "vargai/ai";
|
|
122
|
+
|
|
123
|
+
const CHARACTER = "friendly cartoon robot, blue metallic body, expressive LED eyes, studio background";
|
|
124
|
+
|
|
125
|
+
const SCRIPT = `
|
|
126
|
+
Hello! I'm your AI assistant.
|
|
127
|
+
Today I'm going to show you something amazing.
|
|
128
|
+
Let's create some videos together!
|
|
129
|
+
`;
|
|
130
|
+
|
|
131
|
+
async function main() {
|
|
132
|
+
await render(
|
|
133
|
+
<Render width={1080} height={1920}>
|
|
134
|
+
<Clip duration="auto">
|
|
135
|
+
<Animate
|
|
136
|
+
image={Image({
|
|
137
|
+
prompt: CHARACTER,
|
|
138
|
+
aspectRatio: "9:16",
|
|
139
|
+
model: fal.imageModel("flux-schnell")
|
|
140
|
+
})}
|
|
141
|
+
motion="robot talking naturally, subtle head movements, eyes blink occasionally, friendly gestures"
|
|
142
|
+
model={fal.videoModel("wan-2.5")}
|
|
143
|
+
/>
|
|
144
|
+
<Speech
|
|
145
|
+
voice="adam"
|
|
146
|
+
model={elevenlabs.speechModel("turbo")}
|
|
147
|
+
>
|
|
148
|
+
{SCRIPT}
|
|
149
|
+
</Speech>
|
|
150
|
+
</Clip>
|
|
151
|
+
</Render>,
|
|
152
|
+
{ output: "output/talking-robot.mp4" }
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
main();
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Available voices:** `adam`, `rachel`, `bella`, `sam`, `josh`
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## TikTok Multi-Clip
|
|
164
|
+
|
|
165
|
+
**Requirements:** FAL_API_KEY + ELEVENLABS_API_KEY
|
|
166
|
+
|
|
167
|
+
Multi-scene TikTok-style video with varied camera angles.
|
|
168
|
+
|
|
169
|
+
```tsx
|
|
170
|
+
// tiktok-video.tsx
|
|
171
|
+
import { render, Render, Clip, Image, Animate, Music, Title } from "vargai/react";
|
|
172
|
+
import { fal, elevenlabs } from "vargai/ai";
|
|
173
|
+
|
|
174
|
+
const CHARACTER = "confident young woman, casual style, bright smile, modern apartment";
|
|
175
|
+
|
|
176
|
+
const SCENES = [
|
|
177
|
+
{
|
|
178
|
+
prompt: "extreme close-up face, surprised expression, wide eyes",
|
|
179
|
+
motion: "eyes widen in surprise, eyebrows raise, subtle gasp"
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
prompt: "medium shot, laughing genuinely, hand on chest",
|
|
183
|
+
motion: "head tilts back slightly, genuine laugh, shoulders shake"
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
prompt: "close-up, knowing smirk, raised eyebrow",
|
|
187
|
+
motion: "slow smile forms, eyebrow raises, subtle head nod"
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
prompt: "medium shot, waving at camera, bright smile",
|
|
191
|
+
motion: "waves energetically at camera, bright smile, slight bounce"
|
|
192
|
+
},
|
|
193
|
+
];
|
|
194
|
+
|
|
195
|
+
async function main() {
|
|
196
|
+
await render(
|
|
197
|
+
<Render width={1080} height={1920}>
|
|
198
|
+
<Music
|
|
199
|
+
prompt="trendy tiktok music, upbeat, catchy hook, viral sound"
|
|
200
|
+
model={elevenlabs.musicModel()}
|
|
201
|
+
duration={8}
|
|
202
|
+
volume={0.6}
|
|
203
|
+
/>
|
|
204
|
+
|
|
205
|
+
{SCENES.map((scene, i) => (
|
|
206
|
+
<Clip
|
|
207
|
+
key={i}
|
|
208
|
+
duration={2}
|
|
209
|
+
transition={{ name: "fade", duration: 0.3 }}
|
|
210
|
+
>
|
|
211
|
+
<Animate
|
|
212
|
+
image={Image({
|
|
213
|
+
prompt: `${CHARACTER}, ${scene.prompt}`,
|
|
214
|
+
aspectRatio: "9:16",
|
|
215
|
+
model: fal.imageModel("flux-schnell")
|
|
216
|
+
})}
|
|
217
|
+
motion={scene.motion}
|
|
218
|
+
model={fal.videoModel("wan-2.5")}
|
|
219
|
+
duration={5}
|
|
220
|
+
/>
|
|
221
|
+
{i === 0 && (
|
|
222
|
+
<Title position="bottom">POV: When it actually works</Title>
|
|
223
|
+
)}
|
|
224
|
+
</Clip>
|
|
225
|
+
))}
|
|
226
|
+
</Render>,
|
|
227
|
+
{ output: "output/tiktok-video.mp4" }
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
main();
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Character with Consistent Style
|
|
237
|
+
|
|
238
|
+
**Requirements:** FAL_API_KEY
|
|
239
|
+
|
|
240
|
+
Reuse the same character reference for visual consistency across clips.
|
|
241
|
+
|
|
242
|
+
```tsx
|
|
243
|
+
// consistent-character.tsx
|
|
244
|
+
import { render, Render, Clip, Image, Animate } from "vargai/react";
|
|
245
|
+
import { fal } from "vargai/ai";
|
|
246
|
+
|
|
247
|
+
async function main() {
|
|
248
|
+
// Define character once - same reference = same generated image
|
|
249
|
+
const character = Image({
|
|
250
|
+
prompt: "cute cartoon fox, orange fur, big eyes, friendly expression",
|
|
251
|
+
model: fal.imageModel("flux-schnell"),
|
|
252
|
+
aspectRatio: "9:16"
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
await render(
|
|
256
|
+
<Render width={1080} height={1920}>
|
|
257
|
+
<Clip duration={3}>
|
|
258
|
+
<Animate
|
|
259
|
+
image={character}
|
|
260
|
+
motion="fox waves hello, tail wagging"
|
|
261
|
+
model={fal.videoModel("wan-2.5")}
|
|
262
|
+
duration={3}
|
|
263
|
+
/>
|
|
264
|
+
</Clip>
|
|
265
|
+
|
|
266
|
+
<Clip duration={3} transition={{ name: "fade", duration: 0.5 }}>
|
|
267
|
+
<Animate
|
|
268
|
+
image={character}
|
|
269
|
+
motion="fox dances happily, spinning around"
|
|
270
|
+
model={fal.videoModel("wan-2.5")}
|
|
271
|
+
duration={3}
|
|
272
|
+
/>
|
|
273
|
+
</Clip>
|
|
274
|
+
|
|
275
|
+
<Clip duration={3} transition={{ name: "fade", duration: 0.5 }}>
|
|
276
|
+
<Animate
|
|
277
|
+
image={character}
|
|
278
|
+
motion="fox blows a kiss at camera, winks"
|
|
279
|
+
model={fal.videoModel("wan-2.5")}
|
|
280
|
+
duration={3}
|
|
281
|
+
/>
|
|
282
|
+
</Clip>
|
|
283
|
+
</Render>,
|
|
284
|
+
{ output: "output/fox-video.mp4" }
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
main();
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## Split Screen Comparison
|
|
294
|
+
|
|
295
|
+
**Requirements:** FAL_API_KEY
|
|
296
|
+
|
|
297
|
+
Side-by-side comparison layout.
|
|
298
|
+
|
|
299
|
+
```tsx
|
|
300
|
+
// split-screen.tsx
|
|
301
|
+
import { render, Render, Clip, Image, Animate, Split, Title } from "vargai/react";
|
|
302
|
+
import { fal } from "vargai/ai";
|
|
303
|
+
|
|
304
|
+
async function main() {
|
|
305
|
+
const before = Image({
|
|
306
|
+
prompt: "messy room, clothes everywhere, unmade bed",
|
|
307
|
+
aspectRatio: "3:4"
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
const after = Image({
|
|
311
|
+
prompt: "clean organized room, made bed, tidy shelves",
|
|
312
|
+
aspectRatio: "3:4"
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
await render(
|
|
316
|
+
<Render width={1080} height={1920}>
|
|
317
|
+
<Clip duration={5}>
|
|
318
|
+
<Split direction="horizontal">
|
|
319
|
+
<Animate
|
|
320
|
+
image={before}
|
|
321
|
+
motion="camera slowly pans across messy room"
|
|
322
|
+
model={fal.videoModel("wan-2.5")}
|
|
323
|
+
/>
|
|
324
|
+
<Animate
|
|
325
|
+
image={after}
|
|
326
|
+
motion="camera slowly pans across clean room"
|
|
327
|
+
model={fal.videoModel("wan-2.5")}
|
|
328
|
+
/>
|
|
329
|
+
</Split>
|
|
330
|
+
<Title position="bottom">
|
|
331
|
+
BEFORE AFTER
|
|
332
|
+
</Title>
|
|
333
|
+
</Clip>
|
|
334
|
+
</Render>,
|
|
335
|
+
{ output: "output/split-comparison.mp4" }
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
main();
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## Component Reference
|
|
345
|
+
|
|
346
|
+
| Component | Props | Description |
|
|
347
|
+
|-----------|-------|-------------|
|
|
348
|
+
| `<Render>` | `width`, `height`, `fps` | Root container |
|
|
349
|
+
| `<Clip>` | `duration`, `transition` | Sequential segment |
|
|
350
|
+
| `<Image>` | `prompt`, `src`, `model`, `aspectRatio`, `zoom` | AI or static image |
|
|
351
|
+
| `<Animate>` | `image`, `motion`, `model`, `duration` | Image-to-video |
|
|
352
|
+
| `<Video>` | `src`, `prompt`, `model`, `keepAudio` | Video file or generated |
|
|
353
|
+
| `<Music>` | `prompt`, `model`, `duration`, `volume`, `loop` | Background music |
|
|
354
|
+
| `<Speech>` | `voice`, `model`, `children` | Text-to-speech |
|
|
355
|
+
| `<Title>` | `position`, `color`, `start`, `end` | Text overlay |
|
|
356
|
+
| `<Split>` | `direction` | Side-by-side layout |
|
|
357
|
+
|
|
358
|
+
## Transitions
|
|
359
|
+
|
|
360
|
+
Available transition effects:
|
|
361
|
+
|
|
362
|
+
- `fade` - Simple fade
|
|
363
|
+
- `crossfade` - Cross dissolve
|
|
364
|
+
- `wipeleft`, `wiperight`, `wipeup`, `wipedown` - Directional wipes
|
|
365
|
+
- `slideleft`, `slideright`, `slideup`, `slidedown` - Slides
|
|
366
|
+
- `cube` - 3D cube rotation
|
|
367
|
+
- `pixelize` - Pixelation effect
|
|
368
|
+
|
|
369
|
+
```tsx
|
|
370
|
+
<Clip transition={{ name: "cube", duration: 0.8 }}>
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
## Aspect Ratios
|
|
374
|
+
|
|
375
|
+
| Ratio | Use Case | Dimensions |
|
|
376
|
+
|-------|----------|------------|
|
|
377
|
+
| `9:16` | TikTok, Reels, Shorts | 1080x1920 |
|
|
378
|
+
| `16:9` | YouTube, Twitter | 1920x1080 |
|
|
379
|
+
| `1:1` | Instagram posts | 1080x1080 |
|
|
380
|
+
| `4:5` | Instagram portrait | 1080x1350 |
|