@mevdragon/vidfarm-devcli 0.20.5 → 0.20.8
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/.agents/skills/editor-capabilities/SKILL.md +15 -1
- package/.agents/skills/vidfarm-director/SKILL.md +106 -0
- package/.agents/skills/vidfarm-director/recipes/find-and-fork-template.md +16 -0
- package/.agents/skills/vidfarm-director/recipes/local-edit-render-approve.md +13 -0
- package/.agents/skills/vidfarm-director/recipes/onboard-a-new-director.md +13 -0
- package/.agents/skills/vidfarm-director/recipes/retheme-template.md +17 -0
- package/.agents/skills/vidfarm-director/references/assets-and-sourcing.md +111 -0
- package/.agents/skills/vidfarm-director/references/automation-and-local-dev.md +243 -0
- package/.agents/skills/vidfarm-director/references/core-workflows.md +273 -0
- package/.agents/skills/vidfarm-director/references/editor-workflows.md +365 -0
- package/.agents/skills/vidfarm-director/references/onboarding.md +28 -0
- package/.agents/skills/vidfarm-director/references/primitives.md +265 -0
- package/SKILL.director.md +521 -261
- package/dist/src/cli.js +404 -96
- package/dist/src/devcli/clips.js +15 -10
- package/dist/src/devcli/doctor.js +2 -2
- package/dist/src/devcli/local-backend.js +46 -2
- package/dist/src/services/clip-curation/cost.js +5 -1
- package/dist/src/services/clip-curation/gemini.js +10 -0
- package/package.json +30 -10
- package/SKILL.platform.md +0 -432
- package/demo/README.md +0 -28
- package/demo/dist/app.css +0 -1
- package/demo/dist/app.js +0 -1850
- package/demo/dist/chunks/chunk-DXB73IDG.js +0 -1
- package/demo/dist/chunks/chunk-S7OWAJDS.js +0 -36
- package/demo/dist/chunks/chunk-VTIBZ6AN.js +0 -1
- package/demo/dist/chunks/dist-ADSJKBVE.js +0 -332
- package/demo/dist/chunks/domEditingLayers-VZMLL4AP-SGHWPND4.js +0 -1
- package/demo/dist/chunks/hyperframes-player-XB65TCD6.js +0 -425
- package/demo/dist/chunks/lib-XAQ37YOE.js +0 -1
- package/demo/dist/chunks/src-TJ2QYA4U.js +0 -207
- package/demo/dist/favicon.ico +0 -0
- package/demo/dist/icons/timeline/audio.svg +0 -7
- package/demo/dist/icons/timeline/captions.svg +0 -5
- package/demo/dist/icons/timeline/composition.svg +0 -12
- package/demo/dist/icons/timeline/image.svg +0 -18
- package/demo/dist/icons/timeline/music.svg +0 -10
- package/demo/dist/icons/timeline/text.svg +0 -3
- package/demo/dist/index.html +0 -15
- package/dist/src/account-pages-legacy.js +0 -9396
- package/dist/src/account-pages.js +0 -61
- package/dist/src/app.js +0 -21602
- package/dist/src/composition-runtime.js +0 -1053
- package/dist/src/config.js +0 -217
- package/dist/src/context.js +0 -447
- package/dist/src/dev-app-legacy.js +0 -739
- package/dist/src/dev-app.js +0 -6
- package/dist/src/devcli/migrate-local.js +0 -140
- package/dist/src/devcli/sync.js +0 -368
- package/dist/src/domain.js +0 -5
- package/dist/src/editor-chat-history.js +0 -82
- package/dist/src/editor-chat.js +0 -756
- package/dist/src/editor-dark-theme.js +0 -1128
- package/dist/src/frontend/debug.js +0 -71
- package/dist/src/frontend/discover-client.js +0 -130
- package/dist/src/frontend/discover-store.js +0 -23
- package/dist/src/frontend/file-directory.js +0 -1018
- package/dist/src/frontend/flockposter-cache-store.js +0 -124
- package/dist/src/frontend/homepage-client.js +0 -446
- package/dist/src/frontend/homepage-shared.js +0 -201
- package/dist/src/frontend/homepage-store.js +0 -66
- package/dist/src/frontend/homepage-view.js +0 -705
- package/dist/src/frontend/page-runtime-client.js +0 -132
- package/dist/src/frontend/page-runtime-store.js +0 -9
- package/dist/src/frontend/sentry.js +0 -42
- package/dist/src/frontend/template-editor-chat.js +0 -4181
- package/dist/src/help-page.js +0 -346
- package/dist/src/homepage.js +0 -1458
- package/dist/src/index.js +0 -16
- package/dist/src/instrument.js +0 -30
- package/dist/src/landing-page.js +0 -384
- package/dist/src/page-runtime.js +0 -2
- package/dist/src/page-shell.js +0 -1452
- package/dist/src/primitive-context.js +0 -416
- package/dist/src/primitive-registry.js +0 -3940
- package/dist/src/primitive-sdk.js +0 -4
- package/dist/src/primitives/hyperframes-media.js +0 -108
- package/dist/src/react-page-shell.js +0 -35
- package/dist/src/ready-post-schedule-component.js +0 -1540
- package/dist/src/registry.js +0 -296
- package/dist/src/reskin/agency-page.js +0 -299
- package/dist/src/reskin/calendar-page.js +0 -568
- package/dist/src/reskin/chat-page.js +0 -942
- package/dist/src/reskin/discover-page.js +0 -1788
- package/dist/src/reskin/document.js +0 -1587
- package/dist/src/reskin/help-page.js +0 -357
- package/dist/src/reskin/index-page.js +0 -62
- package/dist/src/reskin/inpaint-clipper-page.js +0 -890
- package/dist/src/reskin/inpaint-page.js +0 -2554
- package/dist/src/reskin/inpaint-video-page.js +0 -1339
- package/dist/src/reskin/job-runs-page.js +0 -477
- package/dist/src/reskin/library-page.js +0 -1634
- package/dist/src/reskin/login-page.js +0 -262
- package/dist/src/reskin/portfolio-page.js +0 -687
- package/dist/src/reskin/pricing-page.js +0 -390
- package/dist/src/reskin/settings-page.js +0 -732
- package/dist/src/reskin/theme.js +0 -711
- package/dist/src/runtime.js +0 -35
- package/dist/src/services/api-call-history.js +0 -249
- package/dist/src/services/auth.js +0 -152
- package/dist/src/services/billing-pricing.js +0 -39
- package/dist/src/services/billing.js +0 -241
- package/dist/src/services/cast.js +0 -127
- package/dist/src/services/chat-threads.js +0 -92
- package/dist/src/services/clip-records.js +0 -250
- package/dist/src/services/clip-search.js +0 -77
- package/dist/src/services/clip-vectors.js +0 -125
- package/dist/src/services/composition-sanitize.js +0 -124
- package/dist/src/services/composition-watch.js +0 -79
- package/dist/src/services/elevenlabs.js +0 -222
- package/dist/src/services/file-directory.js +0 -117
- package/dist/src/services/fork-access.js +0 -93
- package/dist/src/services/fork-manifest.js +0 -42
- package/dist/src/services/ghostcut.js +0 -179
- package/dist/src/services/hyperframes.js +0 -3517
- package/dist/src/services/job-capacity.js +0 -14
- package/dist/src/services/job-logs.js +0 -197
- package/dist/src/services/jobs.js +0 -136
- package/dist/src/services/local-dynamo.js +0 -0
- package/dist/src/services/media-processing.js +0 -766
- package/dist/src/services/primitive-media-lambda.js +0 -280
- package/dist/src/services/providers.js +0 -2748
- package/dist/src/services/rate-limits.js +0 -262
- package/dist/src/services/scene-annotations.js +0 -32
- package/dist/src/services/serverless-auth.js +0 -382
- package/dist/src/services/serverless-jobs.js +0 -1084
- package/dist/src/services/serverless-provider-keys.js +0 -409
- package/dist/src/services/serverless-records.js +0 -1515
- package/dist/src/services/serverless-template-configs.js +0 -75
- package/dist/src/services/storage.js +0 -461
- package/dist/src/services/swipe-customize.js +0 -437
- package/dist/src/services/template-certification.js +0 -413
- package/dist/src/services/template-loader.js +0 -99
- package/dist/src/services/template-runtime-bundles.js +0 -217
- package/dist/src/services/template-sources.js +0 -1017
- package/dist/src/services/upstream.js +0 -248
- package/dist/src/services/video-normalization.js +0 -2
- package/dist/src/services/webhooks.js +0 -62
- package/dist/src/template-editor-pages.js +0 -2576
- package/dist/src/template-editor-shell.js +0 -2893
- package/dist/src/template-sdk.js +0 -4
- package/dist/src/worker.js +0 -17
- package/public/assets/discover-client-app.js +0 -1
- package/public/assets/file-directory-app.js +0 -3
- package/public/assets/homepage-app.js +0 -54
- package/public/assets/homepage-client-app.js +0 -80
- package/public/assets/page-runtime-client-app.js +0 -94
- package/public/assets/placeholders/scene-placeholder.png +0 -0
- package/src/assets/SELLING_AWARENESS_STAGES.md +0 -579
- package/src/assets/SELLING_WITH_HOOKS.md +0 -377
- package/src/assets/SELLING_WITH_VSLS.md +0 -606
- package/src/assets/favicon.ico +0 -0
- package/src/assets/logo-vidfarm.png +0 -0
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
## Primitive: image_remove_background
|
|
2
|
+
|
|
3
|
+
Remove the background from any image URL. Result is a transparent PNG/WebP stored at a durable Vidfarm URL you can reuse in compositions or downstream primitives.
|
|
4
|
+
|
|
5
|
+
- `POST /api/v1/primitives/images/remove-background`
|
|
6
|
+
- Body: `{ "source_image_url": "https://...", "output_format": "webp" | "png" | "jpeg" }` (`output_format` defaults to `webp`)
|
|
7
|
+
- Response: standard primitive job; poll for completion, then read `image.file_url` / `primary_file_url`
|
|
8
|
+
- Billing: flat pass-through fee via RapidAPI (`rapidapi_remove_background` cost center)
|
|
9
|
+
- Reach for this only for an **arbitrary photo with a messy background**. If the image already sits on a **flat solid background** (anything you generated on a controlled backdrop), use the far cheaper `image_remove_background_greenscreen` below instead.
|
|
10
|
+
|
|
11
|
+
Example:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
curl -X POST "$VIDFARM_BASE/api/v1/primitives/images/remove-background" \
|
|
15
|
+
-H "vidfarm-api-key: $VIDFARM_API_KEY" \
|
|
16
|
+
-H "content-type: application/json" \
|
|
17
|
+
-d '{"source_image_url": "https://cdn.example.com/photo.jpg"}'
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Primitive: image_remove_background_greenscreen
|
|
21
|
+
|
|
22
|
+
Cheap **local chroma-key** background removal — no third-party API, just `sharp` doing per-pixel color-distance keying, so it costs a fraction of `image_remove_background`. Use it whenever the source sits on a **flat, solid, evenly-lit background**: a green screen, or any single fill color you pass via `key_color` (e.g. `#FFFFFF` for a white background, `#0047BB` for blue). The result is a transparent PNG/WebP at a durable Vidfarm URL.
|
|
23
|
+
|
|
24
|
+
- `POST /api/v1/primitives/images/remove-background-greenscreen` (flat alias: `POST /api/v1/primitives/remove-background-greenscreen`)
|
|
25
|
+
- Body: `{ "tracer": "...", "payload": { "source_image_url": "https://...", "key_color"?: "#00FF00", "tolerance"?: 0.3, "softness"?: 0.1, "despill"?: true, "output_format"?: "png" | "webp" }, "webhook_url"?: "..." }`
|
|
26
|
+
- `key_color` — the background color to key out (hex / `rgb(...)` / named `green`/`white`/`blue`/`black`). Default `#00FF00`.
|
|
27
|
+
- `tolerance` (0–1, default `0.3`) — how close a pixel must be to `key_color` to be removed. Raise it if fringe survives, lower it if the subject is being eaten.
|
|
28
|
+
- `softness` (0–1, default `0.1`) — feather band beyond `tolerance` for anti-aliased edges.
|
|
29
|
+
- `despill` (default `true`) — suppresses the residual key-color rim on the subject's edges (only applied for chromatic keys like green/blue).
|
|
30
|
+
- Response: standard primitive job; poll for completion, then read `image.file_url` / `primary_file_url`. `keyed_fraction` in the output tells you what share of pixels were removed (near-0 usually means the wrong `key_color` or too-low `tolerance`).
|
|
31
|
+
- Billing: small compute-only wallet fee (`greenscreen_chroma_key` cost center) — cheaper than the RapidAPI route.
|
|
32
|
+
|
|
33
|
+
## Primitive: media_overlay ("create media overlay" — Vox-style)
|
|
34
|
+
|
|
35
|
+
**The go-to way to mint a transparent overlay graphic to float over a composition.** So-called "Vox-style" animations are really just AI-generated illustrations with transparent backgrounds animated in HTML over the timeline — this primitive is that two-step process fused into one job: it (1) generates an AI image of your subject on a **forced flat key-color background** (using the caller's own BYOK image keys, with the greenscreen instruction injected into the prompt automatically) and (2) chroma-keys that background out, returning a ready-to-composite transparent PNG/WebP. **Prefer this over generate-then-manually-remove**, and reach for it *frequently* whenever a scene wants a floating illustration, prop, icon, sticker, or cut-out character.
|
|
36
|
+
|
|
37
|
+
- `POST /api/v1/primitives/images/create-overlay` (flat alias: `POST /api/v1/primitives/create-media-overlay`)
|
|
38
|
+
- Body: `{ "tracer": "...", "payload": { "prompt": "a cartoon rocket ship, flat vector illustration", "provider"?: "...", "model"?: "...", "prompt_attachments"?: ["https://..."], "aspect_ratio"?: "1:1", "image_size"?: "1K"|"2K"|"4K", "key_color"?: "#00FF00", "tolerance"?: 0.3, "softness"?: 0.1, "despill"?: true, "output_format"?: "png"|"webp" }, "webhook_url"?: "..." }`
|
|
39
|
+
- Just describe the **subject** in `prompt` — do NOT describe the background; the primitive appends the flat key-color background requirement for you.
|
|
40
|
+
- `key_color` lets you key against something other than green if your subject is itself green-heavy (e.g. key against `#FF00FF` magenta for a green frog).
|
|
41
|
+
- The chroma-key params (`tolerance`/`softness`/`despill`) behave exactly as in `image_remove_background_greenscreen`.
|
|
42
|
+
- Response: `primary_file_url` is the finished transparent overlay; `greenscreen_source_url` is the raw pre-key frame (kept so you can re-key at a different tolerance without paying for another generation).
|
|
43
|
+
- Billing: small platform wallet fee (`media_overlay` cost center) **plus** the BYOK image-generation cost on the caller's own provider key.
|
|
44
|
+
- Placement: once the job settles, `add_layer` (or the editor's `generate_layer`/`add_layer`) the `primary_file_url` as an image layer over the video and animate it (Ken Burns, keyframes, entrance transitions) like any other overlay.
|
|
45
|
+
|
|
46
|
+
Example:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
curl -X POST "$VIDFARM_BASE/api/v1/primitives/images/create-overlay" \
|
|
50
|
+
-H "vidfarm-api-key: $VIDFARM_API_KEY" \
|
|
51
|
+
-H "content-type: application/json" \
|
|
52
|
+
-d '{"tracer": "vox-overlay", "payload": {"prompt": "a friendly cartoon lightbulb mascot, flat vector illustration", "aspect_ratio": "1:1"}}'
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Primitive: video_remove_captions
|
|
56
|
+
|
|
57
|
+
Remove burned-in captions/subtitles/on-screen text from any video URL (GhostCut-powered — the same pipeline auto-decompose uses for its caption-free mirror, exposed as a standalone reusable primitive). Result is a durable caption-free MP4 stored at a Vidfarm URL.
|
|
58
|
+
|
|
59
|
+
- `POST /api/v1/primitives/videos/remove-captions` (alias: `POST /api/v1/primitives/remove-video-captions`)
|
|
60
|
+
- Body: `{ "tracer": "...", "payload": { "source_video_url": "https://..." }, "webhook_url"?: "..." }`
|
|
61
|
+
- Response: standard primitive job (`202 { job_id }`). The job probes the source, submits to GhostCut, polls to completion server-side (typically a few minutes), and mirrors the result. Poll `GET /api/v1/primitives/jobs/:jobId` until `status: "succeeded"`, then read `primary_file_url` / `video.file_url` (`captionsRemovedVideoUrl` in the output).
|
|
62
|
+
- Billing: `~$0.10 per 30 seconds` of source video (per-chunk, 1-chunk minimum; `ghostcut_subtitle_removal` cost center), plus the small probe cost.
|
|
63
|
+
- For the CURRENT fork's decompose flow, don't re-run this primitive — the caption-free mirror already exists via `GET /api/v1/compositions/:forkId/remove-video-captions`.
|
|
64
|
+
- **Short clips only — hard cap ~15 minutes** (`GHOSTCUT_MAX_DURATION_SEC`, default 900s). Never point this at a long-form source: for "clips without captions" from a long video, run a raws hunt with `avoid_text: true` (scene selection — see "Raws") and, if needed, apply this primitive to the individual FINISHED raws.
|
|
65
|
+
|
|
66
|
+
Example:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
curl -X POST "$VIDFARM_BASE/api/v1/primitives/videos/remove-captions" \
|
|
70
|
+
-H "vidfarm-api-key: $VIDFARM_API_KEY" \
|
|
71
|
+
-H "content-type: application/json" \
|
|
72
|
+
-d '{"tracer": "demo-remove-captions", "payload": {"source_video_url": "https://cdn.example.com/clip.mp4"}}'
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Primitive: media_dedupe
|
|
76
|
+
|
|
77
|
+
Apply subtle camouflage transforms (zoom, tilt, rotate, saturation, playback speed, contrast, brightness, hue rotate, blur, horizontal flip, tint overlay) to any source **image or video** URL. Useful when reposting existing media and you want small perceptual differences to reduce duplicate-detection.
|
|
78
|
+
|
|
79
|
+
- `POST /api/v1/primitives/media/dedupe`
|
|
80
|
+
- Body: `{ "tracer": "...", "payload": { ...fields... }, "webhook_url"?: "..." }`
|
|
81
|
+
- Note: webhook delivery is not yet active — `webhook_url` is accepted and persisted on the job but never fired. Poll the job endpoints (`GET /api/v1/primitives/jobs/:jobId`) for completion.
|
|
82
|
+
- Response: standard primitive job. Poll to completion, then read `primary_file_url` (also `video.file_url` for MP4 or `image.file_url` for stills)
|
|
83
|
+
- Billing: metered as a HyperFrames render (via `hyperframes_lambda` on prod cloud render; free on a local serve box)
|
|
84
|
+
|
|
85
|
+
Payload fields:
|
|
86
|
+
|
|
87
|
+
- `source_media_url` (required, URL) — the image or video to transform
|
|
88
|
+
- `media_type` (`"image" | "video"`, optional) — auto-detected from URL extension if omitted (`.mp4/.mov/.webm/.m4v` → video, else image)
|
|
89
|
+
- `effects` (optional object). All fields optional; defaults camouflage lightly:
|
|
90
|
+
- `zoom` (default `1.04`) — scale factor
|
|
91
|
+
- `tilt` (default `3`) — degrees of 3D X-axis tilt (perspective 1000px)
|
|
92
|
+
- `rotate` (default `3`) — degrees of 2D rotation
|
|
93
|
+
- `saturation` (default `1.05`)
|
|
94
|
+
- `speed` (default `1.05`, video only) — playback rate, also compresses output duration accordingly
|
|
95
|
+
- `horizontal_flip` (default `false`)
|
|
96
|
+
- `contrast` (default `1.05`)
|
|
97
|
+
- `brightness` (default `1.05`)
|
|
98
|
+
- `hue_rotate` (default `0`) — degrees
|
|
99
|
+
- `blur` (default `0`) — pixels
|
|
100
|
+
- `tint_color` (default `"#FF8C00"`), `tint_opacity` (default `0.08`) — subtle color overlay
|
|
101
|
+
- `width` (default `1080`), `height` (default `1920`) — output canvas
|
|
102
|
+
- `duration_ms` — output duration for video; if omitted, `fallback_duration_ms` (default `5000`) is used
|
|
103
|
+
- `object_fit` (`"cover" | "contain" | "fill" | "none" | "scale-down"`, default `"cover"`)
|
|
104
|
+
- `background_color` (default `"#000000"`) — visible when `object_fit` leaves letterboxing
|
|
105
|
+
- `muted` (default `false`), `volume` (default `1`) — audio pass-through on video
|
|
106
|
+
- `output_format` (`"png" | "jpeg" | "webp"`, default `"png"`) — image mode only; video mode always outputs MP4
|
|
107
|
+
|
|
108
|
+
Video example (camouflage a reused clip):
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
curl -X POST "$VIDFARM_BASE/api/v1/primitives/media/dedupe" \
|
|
112
|
+
-H "vidfarm-api-key: $VIDFARM_API_KEY" \
|
|
113
|
+
-H "content-type: application/json" \
|
|
114
|
+
-d '{
|
|
115
|
+
"tracer": "dedupe-2026-07-01-abc",
|
|
116
|
+
"payload": {
|
|
117
|
+
"source_media_url": "https://cdn.example.com/reel.mp4",
|
|
118
|
+
"media_type": "video",
|
|
119
|
+
"duration_ms": 8500,
|
|
120
|
+
"effects": {
|
|
121
|
+
"zoom": 1.05,
|
|
122
|
+
"tilt": 2,
|
|
123
|
+
"rotate": -2,
|
|
124
|
+
"speed": 1.03,
|
|
125
|
+
"hue_rotate": 4,
|
|
126
|
+
"horizontal_flip": true
|
|
127
|
+
},
|
|
128
|
+
"tint_color": "#00A3FF",
|
|
129
|
+
"tint_opacity": 0.06
|
|
130
|
+
}
|
|
131
|
+
}'
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Image example:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
curl -X POST "$VIDFARM_BASE/api/v1/primitives/media/dedupe" \
|
|
138
|
+
-H "vidfarm-api-key: $VIDFARM_API_KEY" \
|
|
139
|
+
-H "content-type: application/json" \
|
|
140
|
+
-d '{
|
|
141
|
+
"tracer": "dedupe-still-01",
|
|
142
|
+
"payload": {
|
|
143
|
+
"source_media_url": "https://cdn.example.com/photo.jpg",
|
|
144
|
+
"media_type": "image",
|
|
145
|
+
"effects": { "zoom": 1.06, "rotate": -1, "hue_rotate": 8 },
|
|
146
|
+
"output_format": "webp"
|
|
147
|
+
}
|
|
148
|
+
}'
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Primitive: music (text → music)
|
|
152
|
+
|
|
153
|
+
Generate music (instrumental, songs with lyrics, background beds, jingles, scores) via ElevenLabs. **Default this on freely — music is a core primitive.** `use_wallet_credits` defaults **true**: it runs on vidfarm's platform ElevenLabs key and bills the customer's wallet. Recommend keeping it on; set it false only to save wallet credits or to use the customer's OWN saved ElevenLabs key.
|
|
154
|
+
|
|
155
|
+
- `POST /api/v1/primitives/music/generate` (alias: `POST /api/v1/primitives/music`)
|
|
156
|
+
- Body: `{ "tracer": "...", "payload": { "prompt": "...", "music_length_ms"?: 30000, "composition_plan"?: {...}, "model"?: "...", "use_wallet_credits"?: true }, "webhook_url"?: "..." }`
|
|
157
|
+
- `prompt` — describe the vibe/genre/instrumentation. `music_length_ms` ≤ 300000 (5 min), default 30000.
|
|
158
|
+
- `composition_plan` (optional) — ElevenLabs section-by-section plan for granular lyric/style control (see the loadable `music` skill pack).
|
|
159
|
+
- Result: durable mp3 (`primary_file_url` / `audio.file_url`). Mount as its own `<audio>` layer ~0.1–0.2 under narration.
|
|
160
|
+
- devcli: `vidfarm music "<prompt>" --length 30` (`--own-key` to use your ElevenLabs key).
|
|
161
|
+
|
|
162
|
+
## Primitive: tts (text → speech)
|
|
163
|
+
|
|
164
|
+
Generate spoken narration audio from text. **`use_wallet_credits` defaults true** → high-quality ElevenLabs narration on vidfarm's platform key, billed to the wallet — the recommended default. Set it false to use the customer's OWN ElevenLabs key or a BYOK OpenAI/Gemini/OpenRouter key (BYOK is never wallet-billed). The **voice style is promptable** via `instructions` (tone/pacing/accent/emotion/persona). Result is a durable Vidfarm audio URL (mp3/wav) ready to drop into a composition as an audio layer.
|
|
165
|
+
|
|
166
|
+
- `POST /api/v1/primitives/audio/speech` (alias: `POST /api/v1/primitives/tts`)
|
|
167
|
+
- Body: `{ "tracer": "...", "payload": { "text": "...", "voice"?: "...", "instructions"?: "...", "use_wallet_credits"?: true, "provider"?: "openai" | "gemini" | "openrouter", "model"?: "...", "output_format"?: "mp3" | "wav" }, "webhook_url"?: "..." }`
|
|
168
|
+
- `text` (required, ≤8000 chars) — the words to speak, verbatim. Aliases: `input`, `script`.
|
|
169
|
+
- `voice` (optional) — on the ElevenLabs path, an ElevenLabs **voice_id** (or friendly name george/sarah/…); on the BYOK path a provider preset (OpenAI `alloy`/…; Gemini `Kore`/…). **Default a sensible voice and tell the user they can pick from many** — list them with `GET /api/v1/primitives/audio/voices` (or `vidfarm voices`).
|
|
170
|
+
- `instructions` (optional) — the voice-STYLE prompt. Aliases: `style`, `style_instructions`, `voice_style`.
|
|
171
|
+
- `output_format` defaults to `mp3` (Gemini/ElevenLabs may answer in wav — read `audio.content_type`).
|
|
172
|
+
- Response: standard primitive job. Poll to completion, then read `primary_file_url` / `audio.file_url`.
|
|
173
|
+
- Billing: wallet-billed on the platform ElevenLabs key (default); free/BYOK when `use_wallet_credits: false` and the caller's own key serves it.
|
|
174
|
+
- devcli: `vidfarm tts "…" --style "…"` runs LOCAL-FIRST on your own env key (no job); add `--cloud` for the ElevenLabs platform job (`--own-key` = your key). `vidfarm voices` lists voices.
|
|
175
|
+
|
|
176
|
+
## Primitive: audio/voices (list ElevenLabs voices)
|
|
177
|
+
|
|
178
|
+
`GET /api/v1/primitives/audio/voices` returns the ElevenLabs voice catalog — `{ scope, default_voice_id, voice_library_url, voices: [{ voice_id, name, category, labels, description, preview_url }] }`. Default scope is vidfarm's platform account; add `?use_wallet_credits=false` to list the voices on the customer's OWN saved ElevenLabs key. Pick a `voice_id` and pass it as `voice` to `/audio/speech`. devcli: `vidfarm voices` (`--own-key` for the user's account).
|
|
179
|
+
|
|
180
|
+
Example:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
curl -X POST "$VIDFARM_BASE/api/v1/primitives/audio/speech" \
|
|
184
|
+
-H "vidfarm-api-key: $VIDFARM_API_KEY" \
|
|
185
|
+
-H "content-type: application/json" \
|
|
186
|
+
-d '{
|
|
187
|
+
"tracer": "demo-tts",
|
|
188
|
+
"payload": {
|
|
189
|
+
"text": "Welcome back. Today we are testing the three most viral hooks.",
|
|
190
|
+
"voice": "coral",
|
|
191
|
+
"instructions": "energetic UGC creator, conversational, slightly breathless"
|
|
192
|
+
}
|
|
193
|
+
}'
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Primitive: stt (video/audio → transcript)
|
|
197
|
+
|
|
198
|
+
Transcribe speech from **any video or audio URL** on the caller's saved AI provider keys (video sources are demuxed to audio automatically via the platform ffmpeg seam). One job returns **BOTH formats**:
|
|
199
|
+
|
|
200
|
+
1. **Simple subtitle version** — the plain transcript (`output.text`, `transcript.txt`) plus timed SRT cues (`output.subtitles.srt`, `transcript.srt`) with no speaker labels — drop-in captions.
|
|
201
|
+
2. **Advanced multi-speaker version** — speaker-attributed, timestamped segments (`output.segments`, each `{ speaker, start_sec, end_sec, text }`, with `output.speakers` listing the cast) for multi-narration sources like podcasts, interviews, and skits — stored durably as `transcript.json`.
|
|
202
|
+
|
|
203
|
+
- `POST /api/v1/primitives/audio/transcribe` (alias: `POST /api/v1/primitives/stt`)
|
|
204
|
+
- Body: `{ "tracer": "...", "payload": { "source_url": "https://...", "diarize"?: true, "word_timestamps"?: false, "use_wallet_credits"?: true, "language"?: "en", "prompt"?: "...", "provider"?: "gemini" | "openai" | "openrouter", "model"?: "...", "media_type"?: "auto" | "video" | "audio" }, "webhook_url"?: "..." }`
|
|
205
|
+
- `source_url` (required) — video OR audio URL. Aliases: `source_video_url`, `source_audio_url`, `video_url`, `audio_url`, `url`. For a fork's composition, pick the right source via `GET /api/v1/compositions/:forkId/remove-video-captions` first.
|
|
206
|
+
- `use_wallet_credits` (default `true`) — ElevenLabs Scribe on the platform key (native diarization + real word timestamps), billed to the wallet. Set false to use the customer's OWN ElevenLabs key or a BYOK gemini/openai/openrouter key.
|
|
207
|
+
- `diarize` (default `true`) — attribute segments to speakers. On the BYOK path speaker labels need a **Gemini key**; OpenAI/OpenRouter degrade to a single-speaker transcript. ElevenLabs Scribe (the default) diarizes natively.
|
|
208
|
+
- `prompt` (optional) — domain/vocabulary hint; `language` (optional) — expected language code.
|
|
209
|
+
- Response: standard primitive job. Poll to completion; `output` carries both formats inline (very long transcripts set `text_truncated: true` and keep the full copy in the `transcript.json` artifact), and the artifacts `transcript.json` / `transcript.srt` / `transcript.txt` are durable URLs.
|
|
210
|
+
- Limits: ~40 minutes of speech per job (20MB extracted audio) — trim longer sources with `/videos/trim` or `/audio/trim` and transcribe in parts.
|
|
211
|
+
- Billing: wallet-billed on the platform ElevenLabs key (default); free/BYOK when `use_wallet_credits: false`. The tiny audio-demux compute step always bills (`primitive_media_lambda`), like every media primitive.
|
|
212
|
+
- For the CURRENT fork, the decompose-time transcript may already exist via `video-context.json` — prefer it before paying for a new transcription; use this primitive for other URLs, multi-speaker attribution, or SRT output.
|
|
213
|
+
- devcli: `vidfarm stt <file|url>` runs LOCAL-FIRST (local ffmpeg + your own key); add `--cloud` to run this route instead.
|
|
214
|
+
|
|
215
|
+
Example:
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
curl -X POST "$VIDFARM_BASE/api/v1/primitives/audio/transcribe" \
|
|
219
|
+
-H "vidfarm-api-key: $VIDFARM_API_KEY" \
|
|
220
|
+
-H "content-type: application/json" \
|
|
221
|
+
-d '{
|
|
222
|
+
"tracer": "demo-stt",
|
|
223
|
+
"payload": {
|
|
224
|
+
"source_url": "https://cdn.example.com/podcast-clip.mp4",
|
|
225
|
+
"diarize": true,
|
|
226
|
+
"language": "en"
|
|
227
|
+
}
|
|
228
|
+
}'
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Brainstorm primitives
|
|
232
|
+
|
|
233
|
+
The `brainstorm/*` primitives are the strategy toolkit. They are reusable, billable AI reasoning steps — the same family the AI Copilot exposes as chip suggestions. Treat **product placement** as a first-class member of this family, right alongside angles and hooks:
|
|
234
|
+
|
|
235
|
+
- `POST /api/v1/primitives/brainstorm/coldstart` — `{ payload: { user_message } }` → foundational questionnaire for a customer starting from zero.
|
|
236
|
+
- `POST /api/v1/primitives/brainstorm/awareness_stages` — `{ payload: { offer_description } }` → which Eugene-Schwartz awareness stages to target first.
|
|
237
|
+
- `POST /api/v1/primitives/brainstorm/angles` — `{ payload: { offer_description, problem_awareness, solution_awareness } }` → persuasive angles.
|
|
238
|
+
- `POST /api/v1/primitives/brainstorm/hooks` — `{ payload: { offer_description } }` → many TikTok-native hooks.
|
|
239
|
+
- `POST /api/v1/primitives/brainstorm/product_placement` — `{ payload: { source_video_url, offer_description } }` → **watches the video** and returns concrete, timestamped opportunities to natively place the product.
|
|
240
|
+
|
|
241
|
+
### Primitive: brainstorm_product_placement
|
|
242
|
+
|
|
243
|
+
Analyze a source video and identify where a product can be organically placed so it feels native rather than bolted on. This is a **multimodal** primitive: it feeds the actual video to a vision-capable model, so prefer a saved **Gemini** key (native video understanding). OpenRouter multimodal models also work; plain OpenAI chat keys cannot watch video.
|
|
244
|
+
|
|
245
|
+
- `POST /api/v1/primitives/brainstorm/product_placement`
|
|
246
|
+
- Body: `{ "tracer": "...", "payload": { "source_video_url": "...", "offer_description": "...", "count"?: 8, "provider"?: "gemini" }, "webhook_url"?: "..." }`
|
|
247
|
+
- `source_video_url` (required, URL) — the exact durable/public video to analyze. Aliases accepted: `video_url`, `source_url`, `url`. For a fork's composition, call `GET /api/v1/compositions/:forkId/remove-video-captions` first and pass the correct URL — the **original video** (`original_source_url`) or the **decomposed video** (`mirrored_url`).
|
|
248
|
+
- `offer_description` (required) — the product/offer to place. Aliases: `offer`, `description`, `details`.
|
|
249
|
+
- `count` (optional, 3–30, default 8) — number of opportunities; only send when the user asks for a specific number.
|
|
250
|
+
- Response: standard primitive job. Poll `GET /api/v1/primitives/jobs/:jobId` to completion, then read `result.json` (also surfaced on the job output as `opportunities[]`), where each entry has `timestamp`, `scene`, `placement_type`, `placement_idea`, and `why_it_works`.
|
|
251
|
+
|
|
252
|
+
You can also satisfy a quick, conversational product-placement question by reasoning over an attached video directly instead of calling this primitive — use the primitive when you want a durable, structured, billable artifact the customer can save and reuse.
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
curl -X POST "$VIDFARM_BASE/api/v1/primitives/brainstorm/product_placement" \
|
|
256
|
+
-H "vidfarm-api-key: $VIDFARM_API_KEY" \
|
|
257
|
+
-H "content-type: application/json" \
|
|
258
|
+
-d '{
|
|
259
|
+
"tracer": "product-placement-01",
|
|
260
|
+
"payload": {
|
|
261
|
+
"source_video_url": "https://cdn.example.com/source.mp4",
|
|
262
|
+
"offer_description": "A $29/mo AI meal-planning app for busy parents."
|
|
263
|
+
}
|
|
264
|
+
}'
|
|
265
|
+
```
|