@vargai/sdk 0.1.1

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.
Files changed (67) hide show
  1. package/.env.example +24 -0
  2. package/CLAUDE.md +118 -0
  3. package/HIGGSFIELD_REWRITE_SUMMARY.md +300 -0
  4. package/README.md +231 -0
  5. package/SKILLS.md +157 -0
  6. package/STRUCTURE.md +92 -0
  7. package/TEST_RESULTS.md +122 -0
  8. package/action/captions/SKILL.md +170 -0
  9. package/action/captions/index.ts +169 -0
  10. package/action/edit/SKILL.md +235 -0
  11. package/action/edit/index.ts +437 -0
  12. package/action/image/SKILL.md +140 -0
  13. package/action/image/index.ts +105 -0
  14. package/action/sync/SKILL.md +136 -0
  15. package/action/sync/index.ts +145 -0
  16. package/action/transcribe/SKILL.md +179 -0
  17. package/action/transcribe/index.ts +210 -0
  18. package/action/video/SKILL.md +116 -0
  19. package/action/video/index.ts +125 -0
  20. package/action/voice/SKILL.md +125 -0
  21. package/action/voice/index.ts +136 -0
  22. package/biome.json +33 -0
  23. package/bun.lock +842 -0
  24. package/cli/commands/find.ts +58 -0
  25. package/cli/commands/help.ts +70 -0
  26. package/cli/commands/list.ts +49 -0
  27. package/cli/commands/run.ts +237 -0
  28. package/cli/commands/which.ts +66 -0
  29. package/cli/discover.ts +66 -0
  30. package/cli/index.ts +33 -0
  31. package/cli/runner.ts +65 -0
  32. package/cli/types.ts +49 -0
  33. package/cli/ui.ts +185 -0
  34. package/index.ts +75 -0
  35. package/lib/README.md +144 -0
  36. package/lib/ai-sdk/fal.ts +106 -0
  37. package/lib/ai-sdk/replicate.ts +107 -0
  38. package/lib/elevenlabs.ts +382 -0
  39. package/lib/fal.ts +467 -0
  40. package/lib/ffmpeg.ts +467 -0
  41. package/lib/fireworks.ts +235 -0
  42. package/lib/groq.ts +246 -0
  43. package/lib/higgsfield/MIGRATION.md +308 -0
  44. package/lib/higgsfield/README.md +273 -0
  45. package/lib/higgsfield/example.ts +228 -0
  46. package/lib/higgsfield/index.ts +241 -0
  47. package/lib/higgsfield/soul.ts +262 -0
  48. package/lib/higgsfield.ts +176 -0
  49. package/lib/remotion/SKILL.md +823 -0
  50. package/lib/remotion/cli.ts +115 -0
  51. package/lib/remotion/functions.ts +283 -0
  52. package/lib/remotion/index.ts +19 -0
  53. package/lib/remotion/templates.ts +73 -0
  54. package/lib/replicate.ts +304 -0
  55. package/output.txt +1 -0
  56. package/package.json +42 -0
  57. package/pipeline/cookbooks/SKILL.md +285 -0
  58. package/pipeline/cookbooks/remotion-video.md +585 -0
  59. package/pipeline/cookbooks/round-video-character.md +337 -0
  60. package/pipeline/cookbooks/talking-character.md +59 -0
  61. package/scripts/produce-menopause-campaign.sh +202 -0
  62. package/service/music/SKILL.md +229 -0
  63. package/service/music/index.ts +296 -0
  64. package/test-import.ts +7 -0
  65. package/test-services.ts +97 -0
  66. package/tsconfig.json +29 -0
  67. package/utilities/s3.ts +147 -0
@@ -0,0 +1,585 @@
1
+ # remotion video creation pipeline
2
+
3
+ ## overview
4
+ create programmatic videos using react components with remotion
5
+
6
+ ## what remotion can do
7
+
8
+ ### video editing & effects
9
+ - **trim & cut**: extract specific frame ranges from videos
10
+ - **zoom & pan**: smooth ken burns effects, dynamic camera movements
11
+ - **speed control**: slow motion, time-lapse, variable playback speed
12
+ - **filters**: apply CSS filters (brightness, contrast, blur, grayscale)
13
+ - **transitions**: crossfades, wipes, custom transitions between clips
14
+
15
+ ### combining content
16
+ - **concatenate videos**: join multiple videos sequentially
17
+ - **multi-track**: side-by-side, grid layouts, picture-in-picture
18
+ - **audio mixing**: combine background music, voiceover, sound effects
19
+ - **volume control**: fade in/out, dynamic volume adjustment
20
+ - **layering**: overlay graphics, text, images on video
21
+
22
+ ### beautiful subtitles
23
+ - **word-by-word captions**: sync text with audio timing
24
+ - **custom styling**: fonts, colors, backgrounds, borders
25
+ - **animations**: fade in/out, slide up, bounce effects
26
+ - **positioning**: center, bottom, top, custom placement
27
+ - **karaoke mode**: highlight current word
28
+ - **rich formatting**: bold, italic, emoji, multi-line
29
+
30
+ ### thumbnail generation
31
+ - **specific frame render**: capture any frame as still image using renderStill
32
+ - **custom thumbnails**: create compositions with overlaid text/graphics
33
+ - **multiple previews**: render several frames at different timestamps
34
+ - **branded thumbnails**: add logos, titles, watermarks to frame captures
35
+
36
+ ### advanced capabilities
37
+ - **motion graphics**: animated text, shapes, data visualizations
38
+ - **responsive layouts**: adapt to different aspect ratios
39
+ - **programmatic content**: generate videos from data/templates
40
+ - **frame-perfect timing**: precise control down to single frame
41
+ - **react ecosystem**: use any react library (charts, animations, etc)
42
+
43
+ ## when to use
44
+ - need precise control over video composition
45
+ - want to add dynamic captions/subtitles
46
+ - combining multiple videos with effects
47
+ - creating videos from templates
48
+ - need frame-perfect synchronization
49
+ - editing videos programmatically
50
+ - generating thumbnails and previews
51
+ - creating social media content at scale
52
+
53
+ ## prerequisites
54
+ ```bash
55
+ bun install remotion @remotion/cli
56
+ ```
57
+
58
+ ## pipeline steps
59
+
60
+ ### step 1: analyze source media
61
+ probe all input videos to get metadata
62
+
63
+ ```bash
64
+ bun run lib/ffmpeg.ts probe media/video1.mp4
65
+ bun run lib/ffmpeg.ts probe media/video2.mp4
66
+ ```
67
+
68
+ **capture:**
69
+ - duration (seconds)
70
+ - fps (frames per second)
71
+ - resolution (width x height)
72
+ - codec
73
+
74
+ **calculate:**
75
+ - total frames = duration * fps
76
+ - end frame for concatenation
77
+
78
+ ### step 2: setup composition
79
+ ```bash
80
+ bun run lib/remotion/index.ts create MyVideo
81
+ ```
82
+
83
+ **output:**
84
+ - compositionPath: lib/remotion/compositions/MyVideo.tsx
85
+ - rootPath: lib/remotion/compositions/MyVideo.root.tsx
86
+ - compositionsDir: lib/remotion/compositions/
87
+
88
+ ### step 3: create composition component
89
+ edit generated file `lib/remotion/compositions/MyVideo.tsx`
90
+
91
+ **media files:**
92
+ - copy media to `lib/remotion/public/` directory
93
+ - use `staticFile("filename.ext")` to reference files
94
+ - never use absolute paths in compositions
95
+
96
+ ```bash
97
+ mkdir -p lib/remotion/public
98
+ cp media/video.mp4 media/audio.mp3 lib/remotion/public/
99
+ ```
100
+
101
+ if using subtitles, copy SRT and read:
102
+ ```bash
103
+ cp media/subtitles.srt lib/remotion/public/
104
+ ```
105
+
106
+ ```typescript
107
+ import { staticFile } from "remotion";
108
+ const srtContent = await Bun.file(staticFile("subtitles.srt")).text();
109
+ ```
110
+
111
+ **basic structure:**
112
+ ```typescript
113
+ import { AbsoluteFill, OffthreadVideo, useCurrentFrame, useVideoConfig, staticFile } from "remotion";
114
+
115
+ export const MyComposition: React.FC = () => {
116
+ const frame = useCurrentFrame();
117
+ const { fps } = useVideoConfig();
118
+
119
+ const video = staticFile("video1.mp4");
120
+
121
+ return (
122
+ <AbsoluteFill>
123
+ <OffthreadVideo src={video} />
124
+ </AbsoluteFill>
125
+ );
126
+ };
127
+ ```
128
+
129
+ **for captions:**
130
+ ```typescript
131
+ // parse SRT at top of file
132
+ const subtitles = parseSRT(`1
133
+ 00:00:00,231 --> 00:00:00,491
134
+ Hello
135
+
136
+ 2
137
+ 00:00:00,491 --> 00:00:00,651
138
+ World
139
+ `);
140
+
141
+ // in component
142
+ const currentTime = frame / fps;
143
+ const currentSubtitle = subtitles.find(
144
+ sub => currentTime >= sub.startTime && currentTime <= sub.endTime
145
+ );
146
+
147
+ {currentSubtitle && (
148
+ <div style={{
149
+ fontFamily: "Inter",
150
+ fontSize: 48,
151
+ fontWeight: "bold",
152
+ color: "white",
153
+ backgroundColor: "rgba(0,0,0,0.7)",
154
+ padding: "20px 40px",
155
+ borderRadius: 12,
156
+ }}>
157
+ {currentSubtitle.text}
158
+ </div>
159
+ )}
160
+ ```
161
+
162
+ **for concatenation:**
163
+ ```typescript
164
+ const video1 = staticFile("video1.mp4");
165
+ const video2 = staticFile("video2.mp4");
166
+
167
+ const video1EndFrame = 1430; // calculated from probe
168
+ const video2StartFrame = video1EndFrame;
169
+
170
+ {frame < video1EndFrame ? (
171
+ <OffthreadVideo src={video1} />
172
+ ) : (
173
+ <OffthreadVideo
174
+ src={video2}
175
+ startFrom={Math.floor((frame - video2StartFrame) * (24/30))}
176
+ />
177
+ )}
178
+ ```
179
+
180
+ ### step 4: register composition
181
+ edit generated file `lib/remotion/compositions/MyVideo.root.tsx`
182
+
183
+ ```typescript
184
+ import React from "react";
185
+ import { Composition, registerRoot } from "remotion";
186
+ import { MyComposition } from "./MyVideo";
187
+
188
+ const fps = 30;
189
+ const durationInFrames = 1582; // total frames
190
+ const width = 1920;
191
+ const height = 1080;
192
+
193
+ registerRoot(() => {
194
+ return (
195
+ <>
196
+ <Composition
197
+ id="MyVideo"
198
+ component={MyComposition}
199
+ durationInFrames={durationInFrames}
200
+ fps={fps}
201
+ width={width}
202
+ height={height}
203
+ />
204
+ </>
205
+ );
206
+ });
207
+ ```
208
+
209
+ **calculate durationInFrames:**
210
+ - single video: `duration * fps`
211
+ - concatenated: `video1Frames + video2Frames`
212
+ - use fps from probe results
213
+
214
+ ### step 5: verify compositions
215
+ ```bash
216
+ bun run lib/remotion/index.ts compositions lib/remotion/compositions/MyVideo.root.tsx
217
+ ```
218
+
219
+ **check output:**
220
+ - composition id matches
221
+ - dimensions are correct
222
+ - fps is correct
223
+ - durationInFrames is correct
224
+
225
+ ### step 6: render video
226
+ ```bash
227
+ bun run lib/remotion/index.ts render lib/remotion/compositions/MyVideo.root.tsx MyVideo media/output.mp4
228
+ ```
229
+
230
+ **rendering process:**
231
+ 1. bundles project with webpack
232
+ 2. launches chrome headless
233
+ 3. renders each frame
234
+ 4. encodes with ffmpeg (h264 codec)
235
+ 5. saves to output.mp4
236
+
237
+ **monitor:**
238
+ - progress percentage
239
+ - frames rendered
240
+ - frames encoded
241
+
242
+ ### step 7: verify output
243
+ ```bash
244
+ bun run lib/ffmpeg.ts probe media/output.mp4
245
+ ```
246
+
247
+ check:
248
+ - duration matches expected
249
+ - fps is correct
250
+ - resolution is correct
251
+
252
+ ## common workflows
253
+
254
+ ### workflow 1: video + captions
255
+ ```
256
+ 1. probe video → get duration, fps
257
+ 2. setup composition
258
+ 3. create composition with Video + captions
259
+ 4. parse SRT file into subtitle array
260
+ 5. sync captions with useCurrentFrame()
261
+ 6. register composition in root
262
+ 7. render
263
+ ```
264
+
265
+ ### workflow 2: concatenate videos
266
+ ```
267
+ 1. probe all videos → get durations, fps
268
+ 2. calculate frame boundaries
269
+ 3. setup composition
270
+ 4. create composition with frame-based switching
271
+ 5. use absolute paths to media files
272
+ 6. handle fps conversions if needed
273
+ 7. register composition with total duration
274
+ 8. render
275
+ ```
276
+
277
+ ### workflow 3: video with overlay graphics
278
+ ```
279
+ 1. probe video
280
+ 2. setup composition
281
+ 3. copy video + images to lib/remotion/public/
282
+ 4. create composition with layers using staticFile()
283
+ 5. use interpolate() for animations
284
+ 6. position overlays with AbsoluteFill
285
+ 7. register composition with registerRoot()
286
+ 8. render
287
+ ```
288
+
289
+ ### workflow 4: render custom thumbnail
290
+ ```
291
+ 1. setup composition
292
+ 2. copy video to lib/remotion/public/
293
+ 3. create thumbnail composition with OffthreadVideo + overlays
294
+ 4. use staticFile() for video path
295
+ 5. add text, logos, graphics on top
296
+ 6. register composition with registerRoot()
297
+ 7. render specific frame as png/jpg using renderStill
298
+ ```
299
+
300
+ ### workflow 5: zoom & pan effect
301
+ ```
302
+ 1. probe video or image
303
+ 2. setup composition
304
+ 3. copy media to lib/remotion/public/
305
+ 4. create composition with transform animations
306
+ 5. use staticFile() for media paths
307
+ 6. use interpolate() for scale and translate
308
+ 7. set easing for smooth motion
309
+ 8. register composition with registerRoot()
310
+ 9. render
311
+ ```
312
+
313
+ ### workflow 6: multi-track audio/video
314
+ ```
315
+ 1. probe all media files
316
+ 2. setup composition
317
+ 3. copy videos + audio files to lib/remotion/public/
318
+ 4. create composition with multiple OffthreadVideo/Audio components
319
+ 5. use staticFile() for all media paths
320
+ 6. adjust volume levels with interpolate()
321
+ 7. sync timing using frame calculations
322
+ 8. register composition with registerRoot()
323
+ 9. render
324
+ ```
325
+
326
+ ## calculation formulas
327
+
328
+ ### frames to seconds
329
+ ```typescript
330
+ const seconds = frames / fps;
331
+ ```
332
+
333
+ ### seconds to frames
334
+ ```typescript
335
+ const frames = Math.floor(seconds * fps);
336
+ ```
337
+
338
+ ### fps conversion
339
+ ```typescript
340
+ // video is 24fps, composition is 30fps
341
+ const adjustedFrame = Math.floor(frame * (24 / 30));
342
+ ```
343
+
344
+ ### srt time to seconds
345
+ ```typescript
346
+ function parseTime(time: string) {
347
+ const [hours, minutes, rest] = time.split(":");
348
+ const [seconds, ms] = rest.split(",");
349
+ return (
350
+ parseInt(hours) * 3600 +
351
+ parseInt(minutes) * 60 +
352
+ parseInt(seconds) +
353
+ parseInt(ms) / 1000
354
+ );
355
+ }
356
+ ```
357
+
358
+ ## tips & tricks
359
+
360
+ ### caption styling
361
+ ```typescript
362
+ // word-by-word bold captions
363
+ {
364
+ fontFamily: "Inter",
365
+ fontSize: 48,
366
+ fontWeight: "bold",
367
+ color: "white",
368
+ textAlign: "center",
369
+ backgroundColor: "rgba(0, 0, 0, 0.7)",
370
+ padding: "20px 40px",
371
+ borderRadius: 12,
372
+ textTransform: "uppercase",
373
+ letterSpacing: 2,
374
+ }
375
+ ```
376
+
377
+ ### smooth transitions
378
+ ```typescript
379
+ import { interpolate } from "remotion";
380
+
381
+ const opacity = interpolate(
382
+ frame,
383
+ [0, 30, 60],
384
+ [0, 1, 0],
385
+ { extrapolateRight: "clamp" }
386
+ );
387
+ ```
388
+
389
+ ### loading fonts
390
+ ```typescript
391
+ import { loadFont } from "@remotion/google-fonts/Inter";
392
+ const { fontFamily } = loadFont();
393
+ ```
394
+
395
+ ### responsive layouts
396
+ ```typescript
397
+ const { width, height } = useVideoConfig();
398
+ const scale = Math.min(width / 1920, height / 1080);
399
+ ```
400
+
401
+ ## troubleshooting
402
+
403
+ ### issue: video not loading
404
+ **solution:**
405
+ - copy media files to `lib/remotion/public/`
406
+ - use `staticFile("filename.ext")` not absolute paths
407
+ - verify file exists in public directory
408
+ - check file permissions
409
+
410
+ ### issue: captions out of sync
411
+ **solution:**
412
+ - verify SRT timestamps
413
+ - check fps matches video fps
414
+ - log currentTime to debug: `console.log(frame / fps)`
415
+
416
+ ### issue: wrong video duration
417
+ **solution:**
418
+ - probe video to get exact duration
419
+ - calculate frames correctly: `duration * fps`
420
+ - round to nearest frame
421
+
422
+ ### issue: concatenation glitch
423
+ **solution:**
424
+ - calculate exact end frame of first video
425
+ - adjust `startFrom` for fps differences
426
+ - use `Math.floor()` for frame calculations
427
+
428
+ ### issue: render fails
429
+ **solution:**
430
+ - verify all media files exist in `lib/remotion/public/`
431
+ - check composition is registered with `registerRoot()`
432
+ - ensure durationInFrames is sufficient
433
+ - verify all media paths use `staticFile()`
434
+ - check console for webpack errors
435
+
436
+ ## performance optimization
437
+
438
+ ### use OffthreadVideo
439
+ for better performance when concatenating:
440
+ ```typescript
441
+ <OffthreadVideo src={staticFile("video.mp4")} />
442
+ ```
443
+
444
+ ### limit font requests
445
+ ```typescript
446
+ loadFont({
447
+ weights: ["400", "700"], // only needed weights
448
+ subsets: ["latin"], // only needed subsets
449
+ });
450
+ ```
451
+
452
+ ### optimize media files
453
+ ```bash
454
+ # compress video before using
455
+ bun run lib/ffmpeg.ts convert input.mp4 output.mp4
456
+ ```
457
+
458
+ ## example workflows
459
+
460
+ ### example 1: video with captions and concatenation
461
+ ```bash
462
+ # 1. probe videos
463
+ bun run lib/ffmpeg.ts probe media/fitness-demo.mp4
464
+ # output: 360x640 @ 30fps, 47.67s
465
+
466
+ bun run lib/ffmpeg.ts probe media/kangaroo-scene.mp4
467
+ # output: 1920x1080 @ 24fps, 5.04s
468
+
469
+ # 2. setup composition
470
+ bun run lib/remotion/index.ts create Demo
471
+
472
+ # 3. create composition files
473
+ # edit lib/remotion/compositions/Demo.tsx
474
+ # edit lib/remotion/compositions/Demo.root.tsx
475
+
476
+ # 4. verify
477
+ bun run lib/remotion/index.ts compositions lib/remotion/compositions/Demo.root.tsx
478
+ # Demo: 360x640 @ 30fps (1582 frames)
479
+
480
+ # 5. render
481
+ bun run lib/remotion/index.ts render lib/remotion/compositions/Demo.root.tsx Demo media/output.mp4
482
+ # [remotion] progress: 100.0% | rendered: 1582 | encoded: 1582
483
+ # [remotion] saved to media/output.mp4
484
+
485
+ # 6. verify output
486
+ bun run lib/ffmpeg.ts probe media/output.mp4
487
+ # 360x640 @ 30fps, 52.73s
488
+ ```
489
+
490
+ ### example 2: custom thumbnail with overlay
491
+ ```bash
492
+ # 1. setup composition
493
+ bun run lib/remotion/index.ts create Thumbnail
494
+
495
+ # 2. copy media
496
+ cp media/video.mp4 lib/remotion/public/
497
+
498
+ # 3. edit thumbnail composition lib/remotion/compositions/Thumbnail.tsx
499
+ # import { AbsoluteFill, OffthreadVideo, staticFile } from "remotion";
500
+ # export const Thumbnail = () => {
501
+ # const video = staticFile("video.mp4");
502
+ # return (
503
+ # <AbsoluteFill>
504
+ # <OffthreadVideo src={video} />
505
+ # <div style={{
506
+ # position: "absolute",
507
+ # bottom: 50,
508
+ # left: 50,
509
+ # fontSize: 72,
510
+ # fontWeight: "bold",
511
+ # color: "white",
512
+ # textShadow: "4px 4px 8px black"
513
+ # }}>
514
+ # MY VIDEO TITLE
515
+ # </div>
516
+ # </AbsoluteFill>
517
+ # );
518
+ # };
519
+
520
+ # 4. edit root with registerRoot() lib/remotion/compositions/Thumbnail.root.tsx
521
+
522
+ # 5. render frame 90 (3 seconds in @ 30fps)
523
+ bun run lib/remotion/index.ts still lib/remotion/compositions/Thumbnail.root.tsx Thumbnail 90 media/thumbnail.png
524
+ # [remotion] saved to media/thumbnail.png
525
+ ```
526
+
527
+ ### example 3: zoom effect with audio
528
+ ```bash
529
+ # 1. setup composition
530
+ bun run lib/remotion/index.ts create Zoom
531
+
532
+ # 2. copy media
533
+ cp media/image.jpg media/music.mp3 lib/remotion/public/
534
+
535
+ # 3. edit composition lib/remotion/compositions/Zoom.tsx
536
+ # import { Img, Audio, staticFile, interpolate, useCurrentFrame } from "remotion";
537
+ # const frame = useCurrentFrame();
538
+ # const image = staticFile("image.jpg");
539
+ # const audio = staticFile("music.mp3");
540
+ # const scale = interpolate(frame, [0, 150], [1, 1.5]);
541
+ # <div style={{ transform: `scale(${scale})` }}>
542
+ # <Img src={image} />
543
+ # </div>
544
+ # <Audio src={audio} />
545
+
546
+ # 4. edit root with registerRoot() and durationInFrames: 150 (5 seconds @ 30fps)
547
+
548
+ # 5. render
549
+ bun run lib/remotion/index.ts render lib/remotion/compositions/Zoom.root.tsx Zoom media/zoomed.mp4
550
+ ```
551
+
552
+ ### example 4: side-by-side comparison
553
+ ```bash
554
+ # 1. probe videos
555
+ bun run lib/ffmpeg.ts probe media/before.mp4
556
+ bun run lib/ffmpeg.ts probe media/after.mp4
557
+
558
+ # 2. setup composition
559
+ bun run lib/remotion/index.ts create Comparison
560
+
561
+ # 3. copy media
562
+ cp media/before.mp4 media/after.mp4 lib/remotion/public/
563
+
564
+ # 4. edit composition lib/remotion/compositions/Comparison.tsx
565
+ # import { AbsoluteFill, OffthreadVideo, staticFile } from "remotion";
566
+ # const before = staticFile("before.mp4");
567
+ # const after = staticFile("after.mp4");
568
+ # <AbsoluteFill style={{ width: "50%", left: 0 }}>
569
+ # <OffthreadVideo src={before} />
570
+ # </AbsoluteFill>
571
+ # <AbsoluteFill style={{ width: "50%", left: "50%" }}>
572
+ # <OffthreadVideo src={after} />
573
+ # </AbsoluteFill>
574
+
575
+ # 5. edit root with registerRoot()
576
+
577
+ # 6. render
578
+ bun run lib/remotion/index.ts render lib/remotion/compositions/Comparison.root.tsx Comparison media/comparison.mp4
579
+ ```
580
+
581
+ ## see also
582
+ - lib/remotion/SKILL.md - detailed remotion skill reference
583
+ - lib/ffmpeg.ts - video probing and editing
584
+ - service/captions/ - automated caption generation
585
+ - service/edit/ - video editing workflows