vargai 0.4.0-alpha2 → 0.4.0-alpha21
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/README.md +483 -61
- 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 +8 -4
- package/skills/varg-video-generation/SKILL.md +213 -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 -1
- 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/editly/index.ts +110 -53
- package/src/ai-sdk/providers/editly/types.ts +2 -0
- package/src/ai-sdk/providers/elevenlabs.ts +10 -2
- package/src/ai-sdk/providers/fal.ts +6 -1
- package/src/cli/commands/find.tsx +1 -0
- package/src/cli/commands/hello.ts +85 -0
- package/src/cli/commands/help.tsx +18 -30
- package/src/cli/commands/index.ts +9 -1
- package/src/cli/commands/init.tsx +412 -0
- package/src/cli/commands/list.tsx +1 -0
- package/src/cli/commands/render.tsx +292 -80
- package/src/cli/commands/run.tsx +1 -0
- package/src/cli/commands/studio.ts +47 -0
- package/src/cli/commands/which.tsx +1 -0
- package/src/cli/index.ts +20 -5
- 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/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/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 +97 -0
- package/src/react/index.ts +1 -2
- package/src/react/react.test.ts +10 -10
- package/src/react/renderers/clip.ts +13 -24
- package/src/react/renderers/context.ts +3 -0
- package/src/react/renderers/image.ts +4 -2
- package/src/react/renderers/index.ts +0 -1
- package/src/react/renderers/music.ts +3 -3
- package/src/react/renderers/progress.ts +1 -3
- package/src/react/renderers/render.ts +49 -63
- package/src/react/renderers/speech.ts +2 -2
- package/src/react/renderers/video.ts +46 -9
- package/src/react/types.ts +18 -14
- package/src/studio/stages.ts +4 -24
- package/src/studio/step-renderer.ts +0 -15
- package/test-sync-v2.ts +30 -0
- package/test-sync-v2.tsx +29 -0
- package/tsconfig.json +5 -3
- package/video.tsx +7 -0
- package/src/react/cli.ts +0 -52
- package/src/react/renderers/animate.ts +0 -59
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Launch Video #7: UGC Weight Loss Transformation
|
|
3
|
+
*
|
|
4
|
+
* Ultra realistic AI UGC ad - split screen before/after with voiceover and captions.
|
|
5
|
+
* Left: overweight person (Higgsfield), Right: slim fit person (nano-banana-pro/edit)
|
|
6
|
+
*
|
|
7
|
+
* Run: bunx vargai render launch-videos/07-ugc-weight-loss.tsx
|
|
8
|
+
*
|
|
9
|
+
* Note: Requires GROQ_API_KEY for auto-captions transcription
|
|
10
|
+
*/
|
|
11
|
+
import { elevenlabs, fal, higgsfield } from "vargai/ai";
|
|
12
|
+
import {
|
|
13
|
+
Captions,
|
|
14
|
+
Clip,
|
|
15
|
+
Image,
|
|
16
|
+
Music,
|
|
17
|
+
Render,
|
|
18
|
+
Speech,
|
|
19
|
+
SplitLayout,
|
|
20
|
+
Title,
|
|
21
|
+
Video,
|
|
22
|
+
} from "vargai/react";
|
|
23
|
+
|
|
24
|
+
// === VOICEOVER SCRIPT ===
|
|
25
|
+
const VOICEOVER_SCRIPT =
|
|
26
|
+
"With this technique I lost 40 pounds in just 3 months!";
|
|
27
|
+
|
|
28
|
+
// === VOICE SETTINGS ===
|
|
29
|
+
// Using turbo model for faster generation, and a more energetic voice
|
|
30
|
+
const VOICE_ID = "aMSt68OGf4xUZAnLpTU8"; // energetic female voice
|
|
31
|
+
const VOICE_MODEL = elevenlabs.speechModel("eleven_multilingual_v2");
|
|
32
|
+
|
|
33
|
+
// === CHARACTER DEFINITION ===
|
|
34
|
+
const CHARACTER_DESCRIPTION = "woman in her 30s, brown hair, green eyes";
|
|
35
|
+
const BEFORE_BODY = "overweight, puffy face, double chin, tired expression";
|
|
36
|
+
const AFTER_BODY =
|
|
37
|
+
"fit slim, defined jawline, glowing skin, confident radiant smile";
|
|
38
|
+
|
|
39
|
+
// === SCENE SETTINGS ===
|
|
40
|
+
const SCENE_SETTING = "bathroom mirror selfie, iPhone photo quality";
|
|
41
|
+
const BEFORE_LIGHTING =
|
|
42
|
+
"soft unflattering lighting, no makeup, messy hair in bun";
|
|
43
|
+
const AFTER_LIGHTING =
|
|
44
|
+
"good lighting, light natural makeup, hair down and styled";
|
|
45
|
+
|
|
46
|
+
// === PROMPTS ===
|
|
47
|
+
const BEFORE_PROMPT = `ultra realistic photo of ${CHARACTER_DESCRIPTION}, ${BEFORE_BODY}, wearing loose grey t-shirt, ${SCENE_SETTING}, ${BEFORE_LIGHTING}, slightly sad eyes, authentic candid look, photorealistic, 8k`;
|
|
48
|
+
|
|
49
|
+
const AFTER_PROMPT = `ultra realistic photo of ${CHARACTER_DESCRIPTION}, ${AFTER_BODY}, wearing fitted black tank top, ${SCENE_SETTING}, ${AFTER_LIGHTING}, bright happy eyes, authentic proud look, same woman as before but 40 pounds lighter, photorealistic, 8k`;
|
|
50
|
+
|
|
51
|
+
// === MOTION DESCRIPTIONS ===
|
|
52
|
+
const BEFORE_MOTION =
|
|
53
|
+
"woman looks down sadly, sighs, then looks at camera with tired expression, subtle breathing, authentic movement";
|
|
54
|
+
const AFTER_MOTION =
|
|
55
|
+
"woman smiles confidently, touches hair, looks at camera proudly, slight head tilt, happy subtle movement";
|
|
56
|
+
|
|
57
|
+
// === IMAGES ===
|
|
58
|
+
// Before image - generated with Higgsfield Soul (realistic style)
|
|
59
|
+
const beforeImage = Image({
|
|
60
|
+
prompt: BEFORE_PROMPT,
|
|
61
|
+
model: higgsfield.imageModel("soul", {
|
|
62
|
+
styleId: higgsfield.styles.REALISTIC,
|
|
63
|
+
}),
|
|
64
|
+
aspectRatio: "9:16",
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// After image - generated with nano-banana-pro/edit using before as reference
|
|
68
|
+
const afterImage = Image({
|
|
69
|
+
prompt: { text: AFTER_PROMPT, images: [beforeImage] },
|
|
70
|
+
model: fal.imageModel("nano-banana-pro/edit"),
|
|
71
|
+
aspectRatio: "9:16",
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// === VIDEOS ===
|
|
75
|
+
// Before video - sad/tired movement
|
|
76
|
+
const beforeVideo = Video({
|
|
77
|
+
prompt: { text: BEFORE_MOTION, images: [beforeImage] },
|
|
78
|
+
model: fal.videoModel("kling-v2.5"),
|
|
79
|
+
duration: 5,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// After video - confident/happy movement
|
|
83
|
+
const afterVideo = Video({
|
|
84
|
+
prompt: { text: AFTER_MOTION, images: [afterImage] },
|
|
85
|
+
model: fal.videoModel("kling-v2.5"),
|
|
86
|
+
duration: 5,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// === VOICEOVER ===
|
|
90
|
+
const voiceover = Speech({
|
|
91
|
+
model: VOICE_MODEL,
|
|
92
|
+
voice: VOICE_ID,
|
|
93
|
+
children: VOICEOVER_SCRIPT,
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// === MUSIC ===
|
|
97
|
+
const MUSIC_PROMPT =
|
|
98
|
+
"upbeat motivational pop, inspiring transformation music, energetic but not overwhelming, modern fitness vibe";
|
|
99
|
+
const MUSIC_DURATION = 15;
|
|
100
|
+
const MUSIC_VOLUME = 0.15; // Low volume so voiceover is clear
|
|
101
|
+
|
|
102
|
+
// === CAPTIONS SETTINGS ===
|
|
103
|
+
const CAPTIONS_STYLE = "tiktok";
|
|
104
|
+
const CAPTIONS_COLOR = "#ffffff";
|
|
105
|
+
|
|
106
|
+
// === TITLE TEXT ===
|
|
107
|
+
const TITLE_TEXT = "My 3-Month Transformation";
|
|
108
|
+
|
|
109
|
+
export default (
|
|
110
|
+
<Render width={1080 * 2} height={1920}>
|
|
111
|
+
{/* Background music (low volume) */}
|
|
112
|
+
<Music prompt={MUSIC_PROMPT} model={elevenlabs.musicModel()} />
|
|
113
|
+
|
|
114
|
+
{/* Main clip with split screen */}
|
|
115
|
+
<Clip duration={5}>
|
|
116
|
+
{/* Split layout - before on left, after on right */}
|
|
117
|
+
<SplitLayout
|
|
118
|
+
direction="horizontal"
|
|
119
|
+
left={beforeVideo}
|
|
120
|
+
right={afterVideo}
|
|
121
|
+
/>
|
|
122
|
+
|
|
123
|
+
{/* Title at top */}
|
|
124
|
+
<Title position="top" color="#ffffff">
|
|
125
|
+
{TITLE_TEXT}
|
|
126
|
+
</Title>
|
|
127
|
+
</Clip>
|
|
128
|
+
|
|
129
|
+
{/* TikTok-style captions with voiceover */}
|
|
130
|
+
<Captions src={voiceover} style={CAPTIONS_STYLE} color={CAPTIONS_COLOR} />
|
|
131
|
+
</Render>
|
|
132
|
+
);
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Launch Video #8: Talking Head - varg Promo with Lipsync
|
|
3
|
+
*
|
|
4
|
+
* A beautiful character says "with varg you can create anything at scale"
|
|
5
|
+
* Uses Higgsfield Soul for character, nano-banana-pro/edit for branded clothing,
|
|
6
|
+
* Animate for image-to-video, and Video with sync-v2 for lip synchronization
|
|
7
|
+
*
|
|
8
|
+
* Run: bunx vargai render launch-videos/08-talking-head-varg.tsx
|
|
9
|
+
*/
|
|
10
|
+
import { elevenlabs, fal, higgsfield } from "vargai/ai";
|
|
11
|
+
import {
|
|
12
|
+
Captions,
|
|
13
|
+
Clip,
|
|
14
|
+
Image,
|
|
15
|
+
Music,
|
|
16
|
+
Render,
|
|
17
|
+
Speech,
|
|
18
|
+
Video,
|
|
19
|
+
} from "vargai/react";
|
|
20
|
+
|
|
21
|
+
// === VOICEOVER SCRIPT ===
|
|
22
|
+
const VOICEOVER_SCRIPT =
|
|
23
|
+
"With varg, you can create any videos anything at scale!";
|
|
24
|
+
|
|
25
|
+
// === VOICE SETTINGS ===
|
|
26
|
+
const VOICE_ID = "5l5f8iK3YPeGga21rQIX"; // friendly female voice
|
|
27
|
+
|
|
28
|
+
// === CHARACTER PROMPT ===
|
|
29
|
+
const CHARACTER_BASE_PROMPT = `A close, spontaneous iPhone selfie of a beautiful East Asian woman in her early 20s with sleek jet-black chin-length bob hair and porcelain skin. She wears a fitted black t-shirt, with dewy, natural skin textures and almond-shaped dark brown eyes filling the frame. The soft morning light filters through a minimalist Scandinavian bedroom with blurred details, including simple, natural wood furniture and neutral textiles. Her calm, inviting expression appears relaxed and looking at camera, with a casual, slightly off-center framing emphasizing genuine intimacy. The image embodies authentic iPhone lighting and texture, capturing an intimate, natural moment with understated elegance.`;
|
|
30
|
+
|
|
31
|
+
// === CLOTHING MODIFICATION PROMPT ===
|
|
32
|
+
const CLOTHING_EDIT_PROMPT = `Same woman, same pose, same lighting. Her black tank t-shirt now has a stylish geometric pattern printed on it. Keep everything else identical - face, hair, expression, background.`;
|
|
33
|
+
|
|
34
|
+
// === VARG PATTERN REFERENCE ===
|
|
35
|
+
const VARG_PATTERN_URL =
|
|
36
|
+
"https://s3.varg.ai/uploads/images/varg-pattern_631fa5f2.png";
|
|
37
|
+
|
|
38
|
+
// === MOTION PROMPT ===
|
|
39
|
+
const MOTION_PROMPT =
|
|
40
|
+
"woman speaking naturally, subtle head movements, friendly expression, looking at camera";
|
|
41
|
+
|
|
42
|
+
// === IMAGES ===
|
|
43
|
+
// Base character - generated with Higgsfield Soul (realistic style)
|
|
44
|
+
const baseCharacter = Image({
|
|
45
|
+
prompt: CHARACTER_BASE_PROMPT,
|
|
46
|
+
model: higgsfield.imageModel("soul", {
|
|
47
|
+
styleId: higgsfield.styles.REALISTIC,
|
|
48
|
+
}),
|
|
49
|
+
aspectRatio: "9:16",
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// Character with varg pattern on clothing
|
|
53
|
+
const brandedCharacter = Image({
|
|
54
|
+
prompt: {
|
|
55
|
+
text: CLOTHING_EDIT_PROMPT,
|
|
56
|
+
images: [baseCharacter, VARG_PATTERN_URL],
|
|
57
|
+
},
|
|
58
|
+
model: fal.imageModel("nano-banana-pro/edit"),
|
|
59
|
+
aspectRatio: "9:16",
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// === ANIMATED CHARACTER (image-to-video) ===
|
|
63
|
+
const animatedCharacter = Video({
|
|
64
|
+
prompt: {
|
|
65
|
+
text: MOTION_PROMPT,
|
|
66
|
+
images: [brandedCharacter],
|
|
67
|
+
},
|
|
68
|
+
model: fal.videoModel("kling-v2.5"),
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
// === VOICEOVER ===
|
|
72
|
+
const voiceover = Speech({
|
|
73
|
+
model: elevenlabs.speechModel("eleven_v3"),
|
|
74
|
+
voice: VOICE_ID,
|
|
75
|
+
children: VOICEOVER_SCRIPT,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
// === MUSIC ===
|
|
79
|
+
const MUSIC_PROMPT =
|
|
80
|
+
"modern tech ambient, subtle electronic, confident corporate vibe, minimal and clean";
|
|
81
|
+
const MUSIC_VOLUME = 0.1;
|
|
82
|
+
|
|
83
|
+
export default (
|
|
84
|
+
<Render width={1080} height={1920}>
|
|
85
|
+
{/* Subtle background music */}
|
|
86
|
+
<Music
|
|
87
|
+
prompt={MUSIC_PROMPT}
|
|
88
|
+
model={elevenlabs.musicModel()}
|
|
89
|
+
volume={MUSIC_VOLUME}
|
|
90
|
+
/>
|
|
91
|
+
|
|
92
|
+
{/* Main talking head clip with lipsync */}
|
|
93
|
+
<Clip duration={5}>
|
|
94
|
+
{/* Lipsync: animated video + speech audio -> sync-v2 */}
|
|
95
|
+
<Video
|
|
96
|
+
prompt={{
|
|
97
|
+
video: animatedCharacter,
|
|
98
|
+
audio: voiceover,
|
|
99
|
+
}}
|
|
100
|
+
model={fal.videoModel("sync-v2-pro")}
|
|
101
|
+
/>
|
|
102
|
+
</Clip>
|
|
103
|
+
|
|
104
|
+
{/* TikTok-style captions */}
|
|
105
|
+
<Captions src={voiceover} style="tiktok" color="#ffffff" />
|
|
106
|
+
</Render>
|
|
107
|
+
);
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { fal } from "vargai/ai";
|
|
2
|
+
import { Clip, Image, Render, Video } from "vargai/react";
|
|
3
|
+
|
|
4
|
+
// ============ REFERENCES ============
|
|
5
|
+
|
|
6
|
+
const WOMAN_REF =
|
|
7
|
+
"https://s3.varg.ai/uploads/images/tlhzlrio6janrkhrwd29h-qp3ofcnoqv0-m4z6gr_280fee62.png";
|
|
8
|
+
const VARG_PATTERN = "https://s3.varg.ai/uploads/images/varg-pattern.png";
|
|
9
|
+
|
|
10
|
+
// ============ CONFIG ============
|
|
11
|
+
|
|
12
|
+
const OUTFIT =
|
|
13
|
+
"elegant black dress with bold graphic pattern from reference — fitted silhouette, off-shoulder neckline, knee-length, subtle sheen. Pattern integrated seamlessly into fabric";
|
|
14
|
+
|
|
15
|
+
const characterBase = `Same girl from reference, consistent face and body proportions, same hairstyle, same posture.`;
|
|
16
|
+
|
|
17
|
+
const location = `Elegant apartment with full-length mirror, warm ambient lighting, minimalist modern decor, soft evening glow through sheer curtains, neutral tones`;
|
|
18
|
+
|
|
19
|
+
// ============ STEP 1: BASE CHARACTER IN WHITE ============
|
|
20
|
+
|
|
21
|
+
const baseCharacter = Image({
|
|
22
|
+
prompt: {
|
|
23
|
+
text: `${characterBase}. She's taking a mirror selfie wearing a simple white cocktail dress. Standing in ${location}. Phone held up. Confident poised pose, weight on one hip. Full body visible in mirror reflection.`,
|
|
24
|
+
images: [WOMAN_REF],
|
|
25
|
+
},
|
|
26
|
+
model: fal.imageModel("nano-banana-pro/edit"),
|
|
27
|
+
aspectRatio: "9:16",
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// ============ STEP 2: EXTRACT BACKGROUND ============
|
|
31
|
+
|
|
32
|
+
const background = Image({
|
|
33
|
+
prompt: {
|
|
34
|
+
text: `Remove the character completely from the image. Empty elegant apartment with full-length mirror, same lighting, same composition. No person.`,
|
|
35
|
+
images: [baseCharacter],
|
|
36
|
+
},
|
|
37
|
+
model: fal.imageModel("nano-banana-pro/edit"),
|
|
38
|
+
aspectRatio: "9:16",
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// ============ STEP 3: APPLY PATTERN TO DRESS ============
|
|
42
|
+
|
|
43
|
+
const patternDressChar = Image({
|
|
44
|
+
prompt: {
|
|
45
|
+
text: `Change the dress to black with the exact pattern from the pattern reference image. Apply the pattern naturally across the dress fabric. Keep everything else exactly the same — same woman, same face, same pose, same lighting, same background.`,
|
|
46
|
+
images: [baseCharacter, VARG_PATTERN, background],
|
|
47
|
+
},
|
|
48
|
+
model: fal.imageModel("nano-banana-pro/edit"),
|
|
49
|
+
aspectRatio: "9:16",
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// ============ STEP 4: POSE VARIATIONS ============
|
|
53
|
+
|
|
54
|
+
// Pose 2: Adjusting earring — close to mirror
|
|
55
|
+
const pose2_earring = Image({
|
|
56
|
+
prompt: {
|
|
57
|
+
text: `${characterBase}. Wearing ${OUTFIT}. Mirror selfie in ${location}. Standing close to mirror, one hand adjusting earring, other holding phone. Soft smile, chin slightly lifted. Full body in reflection. Elegant posture. Dress has pattern from reference.`,
|
|
58
|
+
images: [patternDressChar, WOMAN_REF, VARG_PATTERN, background],
|
|
59
|
+
},
|
|
60
|
+
model: fal.imageModel("nano-banana-pro/edit"),
|
|
61
|
+
aspectRatio: "9:16",
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// Pose 3: Side angle — showing silhouette
|
|
65
|
+
const pose3_side = Image({
|
|
66
|
+
prompt: {
|
|
67
|
+
text: `${characterBase}. Wearing ${OUTFIT}. Mirror selfie in ${location}. Standing at three-quarter angle to mirror, looking over shoulder at phone. Shows elegant silhouette and dress drape with pattern visible. Confident smile. Hand on hip.`,
|
|
68
|
+
images: [patternDressChar, WOMAN_REF, VARG_PATTERN, background],
|
|
69
|
+
},
|
|
70
|
+
model: fal.imageModel("nano-banana-pro/edit"),
|
|
71
|
+
aspectRatio: "9:16",
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// Pose 4: Back angle — DETAILED CONSISTENCY PROMPT
|
|
75
|
+
const pose4_back = Image({
|
|
76
|
+
prompt: {
|
|
77
|
+
text: `Full back-view studio shot of the same girl from the reference, with perfect consistency of her body proportions, hairstyle, and posture. She is wearing the exact same outfit from the reference, including the identical fabric texture, the same material, the same pattern placement, the same silhouette, and the same fit across the shoulders, collar, sleeves, and back panel. Mirror selfie in ${location}. Looking over shoulder at phone with classy expression. One foot slightly forward.`,
|
|
78
|
+
images: [patternDressChar, WOMAN_REF, VARG_PATTERN, background],
|
|
79
|
+
},
|
|
80
|
+
model: fal.imageModel("nano-banana-pro/edit"),
|
|
81
|
+
aspectRatio: "9:16",
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// ============ MOTION PROMPTS ============
|
|
85
|
+
|
|
86
|
+
const motion1 = `Takes mirror selfie, shifts weight gracefully. Smooths dress with free hand. Tilts head finding best angle. Soft smile, taps phone. Confident elegant energy.`;
|
|
87
|
+
|
|
88
|
+
const motion2 = `Standing close to mirror, adjusts earring. Touches hair, fixes strand behind ear. Lifts chin, takes pic. Checks phone, satisfied nod.`;
|
|
89
|
+
|
|
90
|
+
const motion3 = `Turns to show side profile. Hand on hip, elongates posture. Looks over shoulder at mirror. Playful confident smile. Snaps pic.`;
|
|
91
|
+
|
|
92
|
+
const motion4 = `Shows back to mirror, looks over shoulder elegantly. Slight sway, shows off dress back detail. Classy expression, subtle smile. Takes pic. Happy with result.`;
|
|
93
|
+
|
|
94
|
+
// ============ VIDEOS ============
|
|
95
|
+
|
|
96
|
+
const vid1 = Video({
|
|
97
|
+
prompt: {
|
|
98
|
+
images: [patternDressChar],
|
|
99
|
+
text: motion1,
|
|
100
|
+
},
|
|
101
|
+
model: fal.videoModel("kling-v2.5"),
|
|
102
|
+
duration: 5,
|
|
103
|
+
aspectRatio: "9:16",
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
const vid2 = Video({
|
|
107
|
+
prompt: {
|
|
108
|
+
images: [pose2_earring],
|
|
109
|
+
text: motion2,
|
|
110
|
+
},
|
|
111
|
+
model: fal.videoModel("kling-v2.5"),
|
|
112
|
+
duration: 5,
|
|
113
|
+
aspectRatio: "9:16",
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
const vid3 = Video({
|
|
117
|
+
prompt: {
|
|
118
|
+
images: [pose3_side],
|
|
119
|
+
text: motion3,
|
|
120
|
+
},
|
|
121
|
+
model: fal.videoModel("kling-v2.5"),
|
|
122
|
+
duration: 5,
|
|
123
|
+
aspectRatio: "9:16",
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
const vid4 = Video({
|
|
127
|
+
prompt: {
|
|
128
|
+
images: [pose4_back],
|
|
129
|
+
text: motion4,
|
|
130
|
+
},
|
|
131
|
+
model: fal.videoModel("kling-v2.5"),
|
|
132
|
+
duration: 5,
|
|
133
|
+
aspectRatio: "9:16",
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// ============ FINAL RENDER ============
|
|
137
|
+
|
|
138
|
+
export default (
|
|
139
|
+
<Render width={1080} height={1920}>
|
|
140
|
+
{/* Front pose — finding angle */}
|
|
141
|
+
<Clip cutFrom={0.5} cutTo={3}>
|
|
142
|
+
{vid1}
|
|
143
|
+
</Clip>
|
|
144
|
+
|
|
145
|
+
{/* Earring adjust — close-up vibes */}
|
|
146
|
+
<Clip cutFrom={0.5} cutTo={2.5}>
|
|
147
|
+
{vid2}
|
|
148
|
+
</Clip>
|
|
149
|
+
|
|
150
|
+
{/* Side — shows silhouette */}
|
|
151
|
+
<Clip cutFrom={0.5} cutTo={2.5}>
|
|
152
|
+
{vid3}
|
|
153
|
+
</Clip>
|
|
154
|
+
|
|
155
|
+
{/* Back — elegant reveal ✦ */}
|
|
156
|
+
<Clip cutFrom={0.5} cutTo={3}>
|
|
157
|
+
{vid4}
|
|
158
|
+
</Clip>
|
|
159
|
+
</Render>
|
|
160
|
+
);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Launch Videos
|
|
2
|
+
|
|
3
|
+
Pre-made video templates for vargai launch and demo purposes.
|
|
4
|
+
|
|
5
|
+
## Videos
|
|
6
|
+
|
|
7
|
+
| # | File | Description | Duration |
|
|
8
|
+
|---|------|-------------|----------|
|
|
9
|
+
| 1 | `01-hero.tsx` | Hero showcase - all capabilities in 15s | ~15s |
|
|
10
|
+
| 2 | `02-talking-head.tsx` | AI presenter explaining vargai | ~25s |
|
|
11
|
+
| 3 | `03-slideshow.tsx` | Dreamy AI-generated slideshow with music | ~25s |
|
|
12
|
+
| 4 | `04-tiktok-style.tsx` | TikTok-style character video | ~10s |
|
|
13
|
+
| 5 | `05-simple-demo.tsx` | Simplest possible video (one clip) | ~5s |
|
|
14
|
+
|
|
15
|
+
## How to Render
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Preview mode (fast, uses placeholders)
|
|
19
|
+
bunx vargai render launch-videos/01-hero.tsx --preview
|
|
20
|
+
|
|
21
|
+
# Full render (uses AI generation)
|
|
22
|
+
bunx vargai render launch-videos/01-hero.tsx
|
|
23
|
+
|
|
24
|
+
# Output to specific path
|
|
25
|
+
bunx vargai render launch-videos/01-hero.tsx -o my-video.mp4
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Requirements
|
|
29
|
+
|
|
30
|
+
- `FAL_API_KEY` - Required for image/video generation
|
|
31
|
+
- `ELEVENLABS_API_KEY` - Required for music/voice (videos 1, 2, 3, 4)
|
|
32
|
+
|
|
33
|
+
## Output
|
|
34
|
+
|
|
35
|
+
Videos are rendered to `output/` by default:
|
|
36
|
+
- `output/01-hero.mp4`
|
|
37
|
+
- `output/02-talking-head.mp4`
|
|
38
|
+
- etc.
|
|
39
|
+
|
|
40
|
+
## Customization
|
|
41
|
+
|
|
42
|
+
Each file is a self-contained TSX component. Edit prompts, durations, or add/remove clips as needed.
|
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,7 +34,8 @@
|
|
|
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",
|
|
@@ -61,9 +62,10 @@
|
|
|
61
62
|
"react-dom": "^19.2.0",
|
|
62
63
|
"remotion": "^4.0.377",
|
|
63
64
|
"replicate": "^1.4.0",
|
|
65
|
+
"vargai": "^0.4.0-alpha11",
|
|
64
66
|
"zod": "^4.2.1"
|
|
65
67
|
},
|
|
66
|
-
"version": "0.4.0-
|
|
68
|
+
"version": "0.4.0-alpha21",
|
|
67
69
|
"exports": {
|
|
68
70
|
".": "./src/index.ts",
|
|
69
71
|
"./ai": "./src/ai-sdk/index.ts",
|
|
@@ -71,6 +73,8 @@
|
|
|
71
73
|
"./providers": "./src/providers/index.ts",
|
|
72
74
|
"./definitions": "./src/definitions/index.ts",
|
|
73
75
|
"./react": "./src/react/index.ts",
|
|
74
|
-
"./studio": "./src/studio/index.ts"
|
|
76
|
+
"./studio": "./src/studio/index.ts",
|
|
77
|
+
"./jsx-runtime": "./src/react/runtime/jsx-runtime.ts",
|
|
78
|
+
"./jsx-dev-runtime": "./src/react/runtime/jsx-dev-runtime.ts"
|
|
75
79
|
}
|
|
76
80
|
}
|
|
@@ -0,0 +1,213 @@
|
|
|
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. Always run onboarding first to check API keys.
|
|
4
|
+
license: MIT
|
|
5
|
+
metadata:
|
|
6
|
+
author: vargHQ
|
|
7
|
+
version: "1.0.0"
|
|
8
|
+
compatibility: Requires bun runtime. FAL_API_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
|
+
Run the setup script to initialize a project:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
bun scripts/setup.ts
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Or manually check API keys:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
cat .env 2>/dev/null | grep -E "^(FAL_API_KEY|ELEVENLABS_API_KEY)=" || echo "No API keys found"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Required API Keys
|
|
31
|
+
|
|
32
|
+
### FAL_API_KEY (Required)
|
|
33
|
+
|
|
34
|
+
| Detail | Value |
|
|
35
|
+
|--------|-------|
|
|
36
|
+
| Provider | Fal.ai |
|
|
37
|
+
| Get it | https://fal.ai/dashboard/keys |
|
|
38
|
+
| Free tier | Yes (limited credits) |
|
|
39
|
+
| Used for | Image generation (Flux), Video generation (Wan 2.5, Kling) |
|
|
40
|
+
|
|
41
|
+
If user doesn't have `FAL_API_KEY`:
|
|
42
|
+
1. Direct them to https://fal.ai/dashboard/keys
|
|
43
|
+
2. Create account and generate API key
|
|
44
|
+
3. Add to `.env` file: `FAL_API_KEY=fal_xxxxx`
|
|
45
|
+
|
|
46
|
+
### Optional Keys
|
|
47
|
+
|
|
48
|
+
| Feature | Key | Provider | URL |
|
|
49
|
+
|---------|-----|----------|-----|
|
|
50
|
+
| Music/Voice | `ELEVENLABS_API_KEY` | ElevenLabs | https://elevenlabs.io/app/settings/api-keys |
|
|
51
|
+
| Lipsync | `REPLICATE_API_TOKEN` | Replicate | https://replicate.com/account/api-tokens |
|
|
52
|
+
| Transcription | `GROQ_API_KEY` | Groq | https://console.groq.com/keys |
|
|
53
|
+
|
|
54
|
+
**Warn user about missing optional keys but continue with available features.**
|
|
55
|
+
|
|
56
|
+
## Available Features by API Key
|
|
57
|
+
|
|
58
|
+
**FAL_API_KEY only:**
|
|
59
|
+
- Image generation (Flux models)
|
|
60
|
+
- Image-to-video animation (Wan 2.5, Kling)
|
|
61
|
+
- Text-to-video generation
|
|
62
|
+
- Slideshows with transitions
|
|
63
|
+
- Ken Burns zoom effects
|
|
64
|
+
|
|
65
|
+
**FAL + ELEVENLABS:**
|
|
66
|
+
- All above, plus:
|
|
67
|
+
- AI-generated background music
|
|
68
|
+
- Text-to-speech voiceovers
|
|
69
|
+
- Talking character videos
|
|
70
|
+
|
|
71
|
+
**All keys:**
|
|
72
|
+
- Full production pipeline with lipsync and auto-captions
|
|
73
|
+
|
|
74
|
+
## Quick Templates
|
|
75
|
+
|
|
76
|
+
### Simple Slideshow (FAL only)
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
import { render, Render, Clip, Image } from "vargai/react";
|
|
80
|
+
|
|
81
|
+
const SCENES = ["sunset over ocean", "mountain peaks", "city at night"];
|
|
82
|
+
|
|
83
|
+
await render(
|
|
84
|
+
<Render width={1080} height={1920}>
|
|
85
|
+
{SCENES.map((prompt, i) => (
|
|
86
|
+
<Clip key={i} duration={3} transition={{ name: "fade", duration: 0.5 }}>
|
|
87
|
+
<Image prompt={prompt} zoom="in" />
|
|
88
|
+
</Clip>
|
|
89
|
+
))}
|
|
90
|
+
</Render>,
|
|
91
|
+
{ output: "output/slideshow.mp4" }
|
|
92
|
+
);
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Animated Video (FAL + ElevenLabs)
|
|
96
|
+
|
|
97
|
+
```tsx
|
|
98
|
+
import { render, Render, Clip, Image, Animate, Music } from "vargai/react";
|
|
99
|
+
import { fal, elevenlabs } from "vargai/ai";
|
|
100
|
+
|
|
101
|
+
await render(
|
|
102
|
+
<Render width={1080} height={1920}>
|
|
103
|
+
<Music prompt="upbeat electronic" model={elevenlabs.musicModel()} duration={10} />
|
|
104
|
+
<Clip duration={5}>
|
|
105
|
+
<Animate
|
|
106
|
+
image={Image({ prompt: "cute cat on windowsill" })}
|
|
107
|
+
motion="cat turns head, blinks slowly"
|
|
108
|
+
model={fal.videoModel("wan-2.5")}
|
|
109
|
+
duration={5}
|
|
110
|
+
/>
|
|
111
|
+
</Clip>
|
|
112
|
+
</Render>,
|
|
113
|
+
{ output: "output/video.mp4" }
|
|
114
|
+
);
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Talking Character
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
import { render, Render, Clip, Image, Animate, Speech } from "vargai/react";
|
|
121
|
+
import { fal, elevenlabs } from "vargai/ai";
|
|
122
|
+
|
|
123
|
+
await render(
|
|
124
|
+
<Render width={1080} height={1920}>
|
|
125
|
+
<Clip duration="auto">
|
|
126
|
+
<Animate
|
|
127
|
+
image={Image({ prompt: "friendly robot, blue metallic", aspectRatio: "9:16" })}
|
|
128
|
+
motion="robot talking, subtle head movements"
|
|
129
|
+
model={fal.videoModel("wan-2.5")}
|
|
130
|
+
/>
|
|
131
|
+
<Speech voice="adam" model={elevenlabs.speechModel("turbo")}>
|
|
132
|
+
Hello! I'm your AI assistant. Let's create something amazing!
|
|
133
|
+
</Speech>
|
|
134
|
+
</Clip>
|
|
135
|
+
</Render>,
|
|
136
|
+
{ output: "output/talking-robot.mp4" }
|
|
137
|
+
);
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
See [references/templates.md](references/templates.md) for more templates.
|
|
141
|
+
|
|
142
|
+
## Running Videos
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
bun run your-video.tsx
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Key Components
|
|
149
|
+
|
|
150
|
+
| Component | Purpose | Required Key |
|
|
151
|
+
|-----------|---------|--------------|
|
|
152
|
+
| `<Render>` | Root container | - |
|
|
153
|
+
| `<Clip>` | Sequential segment | - |
|
|
154
|
+
| `<Image>` | AI image | FAL |
|
|
155
|
+
| `<Animate>` | Image-to-video | FAL |
|
|
156
|
+
| `<Music>` | Background music | ElevenLabs |
|
|
157
|
+
| `<Speech>` | Text-to-speech | ElevenLabs |
|
|
158
|
+
|
|
159
|
+
## Common Patterns
|
|
160
|
+
|
|
161
|
+
### Character Consistency
|
|
162
|
+
|
|
163
|
+
```tsx
|
|
164
|
+
const character = Image({ prompt: "blue robot" });
|
|
165
|
+
// Reuse same reference = same generated image
|
|
166
|
+
<Animate image={character} motion="waving" />
|
|
167
|
+
<Animate image={character} motion="dancing" />
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Transitions
|
|
171
|
+
|
|
172
|
+
```tsx
|
|
173
|
+
<Clip transition={{ name: "fade", duration: 0.5 }}>
|
|
174
|
+
// Options: fade, crossfade, wipeleft, cube, slideup, etc.
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### Aspect Ratios
|
|
178
|
+
|
|
179
|
+
- `9:16` - TikTok, Reels, Shorts (vertical)
|
|
180
|
+
- `16:9` - YouTube (horizontal)
|
|
181
|
+
- `1:1` - Instagram (square)
|
|
182
|
+
|
|
183
|
+
### Zoom Effects
|
|
184
|
+
|
|
185
|
+
```tsx
|
|
186
|
+
<Image prompt="landscape" zoom="in" /> // Zoom in
|
|
187
|
+
<Image prompt="landscape" zoom="out" /> // Zoom out
|
|
188
|
+
<Image prompt="landscape" zoom="left" /> // Pan left
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Troubleshooting
|
|
192
|
+
|
|
193
|
+
### "FAL_API_KEY not found"
|
|
194
|
+
- Check `.env` file exists in project root
|
|
195
|
+
- Ensure no spaces around `=` sign
|
|
196
|
+
- Restart terminal after adding keys
|
|
197
|
+
|
|
198
|
+
### "Rate limit exceeded"
|
|
199
|
+
- Free tier has limited credits
|
|
200
|
+
- Wait or upgrade plan
|
|
201
|
+
- Use caching to avoid regenerating
|
|
202
|
+
|
|
203
|
+
### "Video generation failed"
|
|
204
|
+
- Check prompt doesn't violate content policy
|
|
205
|
+
- Try simpler motion descriptions
|
|
206
|
+
- Reduce video duration
|
|
207
|
+
|
|
208
|
+
## Next Steps
|
|
209
|
+
|
|
210
|
+
1. Run `bun scripts/setup.ts` to initialize project
|
|
211
|
+
2. Add your FAL_API_KEY to `.env`
|
|
212
|
+
3. Run `bun run examples/my-first-video.tsx`
|
|
213
|
+
4. Or ask the agent: "create a 10 second tiktok video about cats"
|