visualfries 0.1.10115 → 0.3.2
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 +122 -0
- package/bin/visualfries.js +1570 -0
- package/dist/DIContainer.d.ts +2 -1
- package/dist/DIContainer.js +16 -5
- package/dist/SceneBuilder.svelte.d.ts +70 -1
- package/dist/SceneBuilder.svelte.js +96 -29
- package/dist/agent/audioMixer.d.ts +34 -0
- package/dist/agent/audioMixer.js +308 -0
- package/dist/agent/broll.d.ts +35 -0
- package/dist/agent/broll.js +226 -0
- package/dist/agent/capabilities.d.ts +34 -0
- package/dist/agent/capabilities.js +246 -0
- package/dist/agent/captionScene.d.ts +23 -0
- package/dist/agent/captionScene.js +204 -0
- package/dist/agent/catalog.d.ts +24 -0
- package/dist/agent/catalog.js +67 -0
- package/dist/agent/cueFiles.d.ts +54 -0
- package/dist/agent/cueFiles.js +219 -0
- package/dist/agent/cuePresets.d.ts +7 -0
- package/dist/agent/cuePresets.js +50 -0
- package/dist/agent/deterministicMedia.d.ts +61 -0
- package/dist/agent/deterministicMedia.js +303 -0
- package/dist/agent/index.d.ts +18 -0
- package/dist/agent/index.js +18 -0
- package/dist/agent/inspectScene.d.ts +36 -0
- package/dist/agent/inspectScene.js +139 -0
- package/dist/agent/localRender.d.ts +82 -0
- package/dist/agent/localRender.js +702 -0
- package/dist/agent/overlays.d.ts +40 -0
- package/dist/agent/overlays.js +325 -0
- package/dist/agent/productionPlan.d.ts +131 -0
- package/dist/agent/productionPlan.js +322 -0
- package/dist/agent/renderPlan.d.ts +27 -0
- package/dist/agent/renderPlan.js +68 -0
- package/dist/agent/renderRanges.d.ts +24 -0
- package/dist/agent/renderRanges.js +73 -0
- package/dist/agent/runtimeSupport.d.ts +19 -0
- package/dist/agent/runtimeSupport.js +192 -0
- package/dist/agent/streamingEncoder.d.ts +31 -0
- package/dist/agent/streamingEncoder.js +208 -0
- package/dist/agent/transcripts.d.ts +29 -0
- package/dist/agent/transcripts.js +146 -0
- package/dist/agent/transitions.d.ts +20 -0
- package/dist/agent/transitions.js +169 -0
- package/dist/animations/PixiAnimationTarget.d.ts +29 -0
- package/dist/animations/PixiAnimationTarget.js +63 -0
- package/dist/animations/builders/LineHighlighterAnimationBuilder.js +20 -3
- package/dist/animations/builders/WordHighlighterAnimationBuilder.js +15 -2
- package/dist/browser/browserExport.d.ts +73 -0
- package/dist/browser/browserExport.js +180 -0
- package/dist/browser/glTransitions.d.ts +37 -0
- package/dist/browser/glTransitions.js +261 -0
- package/dist/browser/index.d.ts +3 -0
- package/dist/browser/index.js +3 -0
- package/dist/browser/mediaDecode.d.ts +31 -0
- package/dist/browser/mediaDecode.js +152 -0
- package/dist/builders/PixiComponentBuilder.d.ts +6 -0
- package/dist/builders/PixiComponentBuilder.js +12 -0
- package/dist/builders/_ComponentState.svelte.d.ts +7 -5
- package/dist/builders/_ComponentState.svelte.js +29 -15
- package/dist/builders/html/StyleBuilder.js +9 -8
- package/dist/builders/html/TextComponentHtmlBuilder.js +4 -2
- package/dist/builders/html/processors/AppearanceStyleProcessor.js +1 -1
- package/dist/builders/html/processors/TextAppearanceStyleProcessor.js +7 -0
- package/dist/builders/html/processors/TextEffectsStyleProcessor.js +32 -13
- package/dist/commands/ReplaceSourceOnTimeCommand.js +9 -1
- package/dist/commands/SeekCommand.js +19 -6
- package/dist/components/AnimatedGIF.d.ts +3 -0
- package/dist/components/AnimatedGIF.js +28 -1
- package/dist/components/Component.svelte.d.ts +5 -5
- package/dist/components/Component.svelte.js +29 -13
- package/dist/components/ComponentContext.svelte.js +68 -23
- package/dist/components/hooks/AnimationHook.js +1 -1
- package/dist/components/hooks/CanvasFillHook.d.ts +12 -0
- package/dist/components/hooks/CanvasFillHook.js +75 -0
- package/dist/components/hooks/DeterministicMediaFrameHook.js +3 -0
- package/dist/components/hooks/HtmlTextHook.js +11 -3
- package/dist/components/hooks/HtmlToCanvasHook.js +8 -25
- package/dist/components/hooks/MediaHook.js +172 -47
- package/dist/components/hooks/MediaSeekingHook.js +138 -88
- package/dist/components/hooks/PixiGifHook.js +4 -4
- package/dist/components/hooks/PixiSplitScreenDisplayObjectHook.d.ts +3 -0
- package/dist/components/hooks/PixiSplitScreenDisplayObjectHook.js +85 -8
- package/dist/components/hooks/PixiVideoTextureHook.js +10 -4
- package/dist/components/hooks/PixiVisualTransformHook.d.ts +16 -0
- package/dist/components/hooks/PixiVisualTransformHook.js +102 -0
- package/dist/components/hooks/SubtitlesHook.js +48 -24
- package/dist/components/hooks/VerifyMediaHook.js +2 -2
- package/dist/directors/ComponentDirector.d.ts +1 -0
- package/dist/directors/ComponentDirector.js +41 -8
- package/dist/factories/SceneBuilderFactory.d.ts +3 -0
- package/dist/factories/SceneBuilderFactory.js +6 -0
- package/dist/fonts/fontDiscovery.js +12 -1
- package/dist/layers/Layer.svelte.d.ts +54 -0
- package/dist/layers/Layer.svelte.js +2 -25
- package/dist/managers/AppManager.svelte.d.ts +12 -0
- package/dist/managers/AppManager.svelte.js +180 -8
- package/dist/managers/ComponentsManager.svelte.d.ts +7 -7
- package/dist/managers/ComponentsManager.svelte.js +29 -15
- package/dist/managers/DeterministicMediaManager.d.ts +6 -0
- package/dist/managers/DeterministicMediaManager.js +57 -3
- package/dist/managers/EventManager.js +3 -1
- package/dist/managers/LayersManager.svelte.d.ts +54 -0
- package/dist/managers/RenderManager.d.ts +5 -0
- package/dist/managers/RenderManager.js +67 -21
- package/dist/managers/StateManager.svelte.d.ts +56 -0
- package/dist/managers/StateManager.svelte.js +60 -58
- package/dist/managers/SubtitlesManager.svelte.js +1 -3
- package/dist/managers/TimeManager.svelte.d.ts +4 -0
- package/dist/managers/TimeManager.svelte.js +23 -7
- package/dist/schemas/runtime/deterministic.d.ts +3 -0
- package/dist/schemas/runtime/deterministic.js +5 -1
- package/dist/schemas/runtime/types.d.ts +36 -15
- package/dist/schemas/scene/components.d.ts +126 -0
- package/dist/schemas/scene/components.js +11 -0
- package/dist/schemas/scene/core.d.ts +109 -10
- package/dist/schemas/scene/core.js +1 -1
- package/dist/utils/mediaWindow.d.ts +13 -0
- package/dist/utils/mediaWindow.js +25 -0
- package/dist/utils/svgGenerator.js +1 -1
- package/dist/utils/timelineWindow.d.ts +2 -0
- package/dist/utils/timelineWindow.js +7 -0
- package/dist/utils/utils.js +2 -4
- package/docs/AGENT_PATTERNS.md +243 -0
- package/docs/AGENT_WORKFLOW.md +364 -0
- package/docs/AUTHORING_BEST_PRACTICES.md +188 -0
- package/docs/AUTHORING_SYSTEM_AUDIT.md +98 -0
- package/docs/BROWSER_EXPORT_SPIKE.md +55 -0
- package/docs/DETERMINISTIC_RENDERER.md +83 -0
- package/docs/NEXT_RELEASE.md +28 -0
- package/docs/PROPOSED_VISUALFRIES_SKILL.md +68 -0
- package/docs/examples/agent-cues.json +49 -0
- package/docs/examples/agent-transcript.json +23 -0
- package/docs/examples/agent-transcript.srt +7 -0
- package/docs/examples/agent-transcript.vtt +7 -0
- package/docs/examples/image-animation.json +87 -0
- package/docs/examples/native-text-metric-badge.json +109 -0
- package/package.json +133 -100
- package/skills/visualfries/SKILL.md +328 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export const TIMELINE_BOUNDARY_EPSILON = 1e-7;
|
|
2
|
+
export function isTimeWithinTimeline(currentTime, startAt, endAt, epsilon = TIMELINE_BOUNDARY_EPSILON) {
|
|
3
|
+
if (endAt - startAt <= epsilon) {
|
|
4
|
+
return currentTime >= startAt - epsilon && currentTime <= endAt + epsilon;
|
|
5
|
+
}
|
|
6
|
+
return currentTime >= startAt - epsilon && currentTime < endAt - epsilon;
|
|
7
|
+
}
|
package/dist/utils/utils.js
CHANGED
|
@@ -41,9 +41,7 @@ export const buildCharactersListFromComponentsAndSubtitles = function (layers, s
|
|
|
41
41
|
const c = component;
|
|
42
42
|
const text = c.text;
|
|
43
43
|
if (text) {
|
|
44
|
-
|
|
45
|
-
// This prevents splitting emojis into unpaired surrogates
|
|
46
|
-
const textList = Array.from(text);
|
|
44
|
+
const textList = text.split('');
|
|
47
45
|
const missingChars = textList.filter((char) => {
|
|
48
46
|
// Check if the character is not whitespace, not in the characters list,
|
|
49
47
|
// is a Unicode letter or number, and is NOT an emoji
|
|
@@ -108,7 +106,7 @@ export const setPlacementAndOpacity = function (obj, c) {
|
|
|
108
106
|
obj.y = config.y;
|
|
109
107
|
obj.width = config.width;
|
|
110
108
|
obj.height = config.height;
|
|
111
|
-
obj.alpha = config.opacity
|
|
109
|
+
obj.alpha = config.opacity ?? 1;
|
|
112
110
|
if (config.rotation) {
|
|
113
111
|
obj.angle = config.rotation;
|
|
114
112
|
}
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
# VisualFries Agent Patterns
|
|
2
|
+
|
|
3
|
+
Reusable building blocks for agents that need short-form videos without writing raw scene JSON from scratch.
|
|
4
|
+
|
|
5
|
+
## New Agent Package
|
|
6
|
+
|
|
7
|
+
Use when starting a self-contained work folder:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
visualfries init ./video-package \
|
|
11
|
+
--video ./input.mp4 \
|
|
12
|
+
--transcript ./transcript.srt \
|
|
13
|
+
--preset hidden-engine-center \
|
|
14
|
+
--cue-preset hidden-engine-dynamic
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Generated structure:
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
video-package/
|
|
21
|
+
scene.json
|
|
22
|
+
cues.json
|
|
23
|
+
assets/
|
|
24
|
+
qa/
|
|
25
|
+
inspect.json
|
|
26
|
+
frames/
|
|
27
|
+
notes.md
|
|
28
|
+
transcript.example.json
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`cues.json` is generated from the selected cue preset and should be treated as the visual timeline map for the video.
|
|
32
|
+
|
|
33
|
+
## Captioned Video
|
|
34
|
+
|
|
35
|
+
Use when the base asset already contains the main story or voiceover.
|
|
36
|
+
|
|
37
|
+
Fastest preview path:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
visualfries compose \
|
|
41
|
+
--video ./input.mp4 \
|
|
42
|
+
--transcript ./transcript.srt \
|
|
43
|
+
--cue-preset hidden-engine-dynamic \
|
|
44
|
+
--cues ./cues.json \
|
|
45
|
+
--scene-output ./scene.json \
|
|
46
|
+
--qa-output ./qa/frames \
|
|
47
|
+
--render-mode preview \
|
|
48
|
+
--output ./out.mp4
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Use `compose` for routine agent previews. Use the step-by-step commands when debugging a scene. Final output for scenes with `VIDEO` or `GIF` components uses the local deterministic renderer path, which predecodes media into exact frame images before the browser compositor sees the scene. Browser media rendering is intentionally treated as preview-only.
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
visualfries caption-scene \
|
|
55
|
+
--video ./input.mp4 \
|
|
56
|
+
--transcript ./transcript.srt \
|
|
57
|
+
--preset hidden-engine-center \
|
|
58
|
+
--output ./scene.json
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
`--transcript` accepts JSON, SRT, or VTT. Prefer SRT/VTT when the agent already has timed subtitles from another tool.
|
|
62
|
+
|
|
63
|
+
Then QA:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
visualfries inspect ./scene.json --screenshots --samples 3 --output ./qa/frames --json
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Cue File Application
|
|
70
|
+
|
|
71
|
+
Use when an agent has a timeline map and should not write custom JavaScript.
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
visualfries preset-cues --duration 45 \
|
|
75
|
+
--preset hidden-engine-dynamic \
|
|
76
|
+
--output ./cues.json
|
|
77
|
+
|
|
78
|
+
visualfries apply-cues ./scene.json \
|
|
79
|
+
--cues ./cues.json \
|
|
80
|
+
--output ./scene.with-cues.json
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Cue file:
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"broll": [
|
|
88
|
+
{ "url": "./assets/profile-scroll.mp4", "start": 2, "end": 5, "type": "VIDEO" }
|
|
89
|
+
],
|
|
90
|
+
"overlays": [
|
|
91
|
+
{ "text": "LOVE THIS 😍", "start": 0.4, "end": 1.1, "style": "hook-punch" },
|
|
92
|
+
{ "text": "your move", "start": 41.5, "end": 43, "style": "cta-card" }
|
|
93
|
+
],
|
|
94
|
+
"transitions": [
|
|
95
|
+
{ "time": 2, "style": "dip-to-black" }
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Use this as the normal agent path:
|
|
101
|
+
|
|
102
|
+
```text
|
|
103
|
+
compose
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
For debugging:
|
|
107
|
+
|
|
108
|
+
```text
|
|
109
|
+
caption-scene -> preset-cues -> edit cues -> apply-cues -> inspect --screenshots -> render
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Available starter presets:
|
|
113
|
+
|
|
114
|
+
- `hidden-engine-dynamic`: cue skeleton for 40-60s story-driven shorts with hook/proof/mechanism/choice/CTA overlay beats.
|
|
115
|
+
- `captioned-clean`: minimal transition cues for caption-first videos.
|
|
116
|
+
|
|
117
|
+
## Timed Text Overlays
|
|
118
|
+
|
|
119
|
+
Use for quick reaction beats, keyword shocks, proof callouts, and hook emphasis.
|
|
120
|
+
|
|
121
|
+
```ts
|
|
122
|
+
import { addAgentTextOverlays } from 'visualfries/agent';
|
|
123
|
+
|
|
124
|
+
const withOverlays = addAgentTextOverlays({
|
|
125
|
+
scene,
|
|
126
|
+
overlays: [
|
|
127
|
+
{ text: 'LOVE THIS 😍', start: 0.4, end: 1.1, style: 'pop-label' },
|
|
128
|
+
{ text: 'NECK 🤯', start: 1.1, end: 1.7, style: 'shock-word' },
|
|
129
|
+
{ text: '1M PROFIT', start: 2.0, end: 3.0, style: 'metric-badge' }
|
|
130
|
+
]
|
|
131
|
+
});
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Overlay styles:
|
|
135
|
+
|
|
136
|
+
- `hook-punch`: loud yellow hook label for the first second.
|
|
137
|
+
- `shock-word`: large keyword reveal.
|
|
138
|
+
- `metric-badge`: big number/proof badge.
|
|
139
|
+
- `proof-pill`: smaller credibility/proof pill.
|
|
140
|
+
- `danger-crossout`: negative beat / wrong path callout.
|
|
141
|
+
- `cta-card`: final question or choice card.
|
|
142
|
+
- `pop-label`: generic fast reaction label.
|
|
143
|
+
- `soft-card`: calmer context card.
|
|
144
|
+
|
|
145
|
+
Rules:
|
|
146
|
+
|
|
147
|
+
- one overlay idea per beat,
|
|
148
|
+
- 0.4-1.4 seconds per overlay,
|
|
149
|
+
- keep captions readable,
|
|
150
|
+
- render sampled screenshots before final MP4.
|
|
151
|
+
|
|
152
|
+
## B-roll Sequence
|
|
153
|
+
|
|
154
|
+
Use when an agent has portrait stock footage, generated images, screen recordings, or proof visuals.
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
import { addAgentBrollSequence } from 'visualfries/agent';
|
|
158
|
+
|
|
159
|
+
const withBroll = addAgentBrollSequence({
|
|
160
|
+
scene,
|
|
161
|
+
cues: [
|
|
162
|
+
{ url: './broll/profile.mp4', start: 2.0, end: 5.0, type: 'VIDEO' },
|
|
163
|
+
{ url: './broll/chart.png', start: 5.0, end: 7.0, type: 'IMAGE', motion: 'slow-zoom-in' }
|
|
164
|
+
]
|
|
165
|
+
});
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Layer defaults:
|
|
169
|
+
|
|
170
|
+
- b-roll layer order: `5`
|
|
171
|
+
- captions layer from `caption-scene`: `10`
|
|
172
|
+
- text overlay layer: `90`
|
|
173
|
+
|
|
174
|
+
This means b-roll naturally replaces/augments the base media while captions and overlays stay visible.
|
|
175
|
+
|
|
176
|
+
Image motion:
|
|
177
|
+
|
|
178
|
+
- `slow-zoom-in` default for images,
|
|
179
|
+
- `slow-zoom-out`,
|
|
180
|
+
- `drift-up`,
|
|
181
|
+
- `none`.
|
|
182
|
+
|
|
183
|
+
## Beat Transitions
|
|
184
|
+
|
|
185
|
+
Use when a hard cut between b-roll/avatar/proof visuals needs a small cover at an exact beat.
|
|
186
|
+
|
|
187
|
+
```ts
|
|
188
|
+
import { addAgentTransitions } from 'visualfries/agent';
|
|
189
|
+
|
|
190
|
+
const withTransitions = addAgentTransitions({
|
|
191
|
+
scene,
|
|
192
|
+
transitions: [
|
|
193
|
+
{ time: 2.0, style: 'dip-to-black' },
|
|
194
|
+
{ time: 5.0, style: 'swipe-left', color: '#04483D' }
|
|
195
|
+
]
|
|
196
|
+
});
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Available styles:
|
|
200
|
+
|
|
201
|
+
- `dip-to-black` for invisible cuts,
|
|
202
|
+
- `flash` for punchy hook beats,
|
|
203
|
+
- `swipe-left` for editorial movement,
|
|
204
|
+
- `swipe-up` for vertical short-form movement.
|
|
205
|
+
|
|
206
|
+
Keep transition durations short, usually `0.18-0.32s`. Overusing them makes the edit feel templated.
|
|
207
|
+
|
|
208
|
+
## Agent QA Loop
|
|
209
|
+
|
|
210
|
+
For every non-trivial scene:
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
visualfries doctor --json
|
|
214
|
+
visualfries catalog --json
|
|
215
|
+
visualfries validate-cues ./cues.json --duration 45 --json
|
|
216
|
+
visualfries validate ./scene.json
|
|
217
|
+
visualfries qa ./scene.json --output ./qa
|
|
218
|
+
visualfries render ./scene.json --render-mode preview --output ./preview.mp4
|
|
219
|
+
ffprobe -v error -show_entries stream=codec_type,width,height -of json ./preview.mp4
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
If `visualfries render` blocks a final VIDEO/GIF scene, that is expected. Do not bypass it for shipped output. The scene needs deterministic predecoded media frames before final encode.
|
|
223
|
+
|
|
224
|
+
For final contiguous MP4 renders, prefer streaming encode after QA:
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
visualfries render ./scene.with-cues.json \
|
|
228
|
+
--stream-encode \
|
|
229
|
+
--image-format jpg \
|
|
230
|
+
--output ./out.mp4
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
This avoids writing every final frame to disk before encode.
|
|
234
|
+
|
|
235
|
+
For static-heavy agent videos, add `--skip-duplicates` after QA:
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
visualfries render ./scene.json --output ./out.mp4 --skip-duplicates
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
The CLI uses VisualFries `renderFrameRange()` for contiguous frame ranges. Sparse QA screenshots still use direct sampled frame renders.
|
|
242
|
+
|
|
243
|
+
If screenshot samples show overlap, fix the scene JSON or cue timing before encoding the full video.
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
# VisualFries Agent Workflow
|
|
2
|
+
|
|
3
|
+
This document defines the agent-facing contract for VisualFries.
|
|
4
|
+
|
|
5
|
+
Read [Authoring Best Practices](AUTHORING_BEST_PRACTICES.md) before authoring. It defines the
|
|
6
|
+
native semantic component policy, runtime support matrix, effect/compositing limits, and required
|
|
7
|
+
entry/settled/exit/reseek frame QA. Validation and inspection are structural gates, not rendering
|
|
8
|
+
proof.
|
|
9
|
+
|
|
10
|
+
## Goal
|
|
11
|
+
|
|
12
|
+
Make VisualFries usable by agents without requiring the ContentFries UI:
|
|
13
|
+
|
|
14
|
+
1. create render-ready scene JSON,
|
|
15
|
+
2. add captions from transcripts,
|
|
16
|
+
3. validate and inspect scenes,
|
|
17
|
+
4. render fast QA previews through the CLI browser adapter,
|
|
18
|
+
5. hand final VIDEO/GIF scenes to the local deterministic renderer path.
|
|
19
|
+
|
|
20
|
+
## CLI
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
visualfries validate <scene.json> [--json]
|
|
24
|
+
visualfries inspect <scene.json> [--json] [--screenshots --output <dir>]
|
|
25
|
+
visualfries init <dir> [--video <video> --transcript <file>]
|
|
26
|
+
visualfries caption-scene --video <video> --transcript <file> --output <scene.json>
|
|
27
|
+
visualfries preset-cues --duration <seconds> --output <cues.json>
|
|
28
|
+
visualfries validate-cues <cues.json> [--duration <seconds>] [--json]
|
|
29
|
+
visualfries apply-cues <scene.json> --cues <cues.json> --output <scene.json>
|
|
30
|
+
visualfries qa <scene.json> --output <dir>
|
|
31
|
+
visualfries compose --video <video> --transcript <file> --output <out.mp4>
|
|
32
|
+
visualfries produce <production-plan.json> --output <out.mp4> --scene-output <scene.json> --qa-output <dir>
|
|
33
|
+
visualfries render <scene.json> --output <out.mp4|frames-dir> [--frames-only]
|
|
34
|
+
visualfries catalog [--json]
|
|
35
|
+
visualfries doctor [--json]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Use `produce` for authored edits that need more than captions plus generic cues. A production plan groups the edit into named beats and supports source trims, automatic video freeze-frame holds, native TEXT editorial overlays, exact multi-track audio, transitions, and QA frames. Visible typography compiles to native TEXT by default. `renderAs: "SVG"` is an explicit compatibility fallback for a documented native limitation. The command emits ordinary VisualFries scene JSON, renders at timeline event boundaries, then checks the finished audio lead-in.
|
|
39
|
+
|
|
40
|
+
```json
|
|
41
|
+
{
|
|
42
|
+
"version": 1,
|
|
43
|
+
"id": "proof-hook",
|
|
44
|
+
"settings": { "width": 1080, "height": 1920, "duration": 6, "fps": 30 },
|
|
45
|
+
"beats": [
|
|
46
|
+
{
|
|
47
|
+
"id": "reaction",
|
|
48
|
+
"start": 0,
|
|
49
|
+
"end": 3,
|
|
50
|
+
"media": [
|
|
51
|
+
{ "id": "reaction", "url": "./reaction.mp4", "start": 0, "end": 3, "freezeAt": 1.8 }
|
|
52
|
+
],
|
|
53
|
+
"overlays": [{ "text": "NOT DEAD.", "start": 1.8, "end": 3, "style": "verdict-slam" }]
|
|
54
|
+
}
|
|
55
|
+
],
|
|
56
|
+
"audio": [{ "id": "voice", "url": "./voice.wav", "startAt": 0, "volume": 1 }],
|
|
57
|
+
"transitions": [{ "time": 3, "style": "focus-pull" }],
|
|
58
|
+
"qa": { "framesAt": [0.1, 1.9, 3.1], "maxLeadingSilence": 0.1, "requiredText": ["NOT DEAD."] }
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
visualfries produce ./production-plan.json \
|
|
64
|
+
--scene-output ./scene.json \
|
|
65
|
+
--qa-output ./qa \
|
|
66
|
+
--output ./final.mp4
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
`render` uses a controlled Vite browser page, Playwright, and `ffmpeg` for static scenes and fast previews. It never requires opening ContentFries UI.
|
|
70
|
+
|
|
71
|
+
Important render contract:
|
|
72
|
+
|
|
73
|
+
- `--render-mode final` is the default.
|
|
74
|
+
- Final scenes with `VIDEO` or `GIF` components require the local deterministic renderer. Native browser media seek is not trusted for final output because it can create stale, duplicated, or shifted frames.
|
|
75
|
+
- Use `--render-mode preview` for quick QA frames or rough local checks.
|
|
76
|
+
- `--allow-browser-media-final` exists only as an escape hatch for experiments. Do not use it for shipped output.
|
|
77
|
+
- In final mode, the CLI predecodes active `VIDEO`/`GIF` ranges to exact frame images and injects a deterministic media provider into the render page.
|
|
78
|
+
|
|
79
|
+
Useful render options:
|
|
80
|
+
|
|
81
|
+
- `--frames-only` renders a PNG frame sequence for QA instead of MP4.
|
|
82
|
+
- `--render-mode preview` permits the browser preview path for VIDEO/GIF scenes.
|
|
83
|
+
- `--engine browser-preview` or `--engine deterministic-local` can force renderer planning when debugging.
|
|
84
|
+
- `--from-frame <n>` and `--to-frame <n>` render a partial range for fast checks.
|
|
85
|
+
- Full contiguous renders use the browser-side `renderFrameRange()` path, avoiding one Playwright round trip per frame.
|
|
86
|
+
- `--stream-encode` pipes rendered frames directly into local `ffmpeg` with `image2pipe`. Prefer it for final contiguous MP4 renders once QA frames look right.
|
|
87
|
+
- `--skip-duplicates` asks VisualFries deterministic dirty checking to reuse unchanged frames when possible.
|
|
88
|
+
- `--fps <number>` overrides scene FPS.
|
|
89
|
+
- `--audio <path|none>` overrides automatic audio mapping from the local scene audio mix.
|
|
90
|
+
- Without `--audio`, final contiguous renders build a local mixed audio track from active VIDEO/AUDIO components, `audioTracks`, and `settings.audio`.
|
|
91
|
+
- `VISUALFRIES_NODE_MODULES=/path/to/node_modules` lets agents point the CLI at an existing Playwright install.
|
|
92
|
+
- `doctor --json` checks ffmpeg, Vite, Svelte Vite plugin, Playwright, Chromium, and temp directory resolution before an agent starts a render.
|
|
93
|
+
- `catalog --json` lists supported caption presets, cue presets, overlay styles, b-roll motions, transitions, transcript formats, and CLI commands.
|
|
94
|
+
- `validate-cues --json` checks cue file shape, known styles/motions/transitions, and timing before an agent applies cues.
|
|
95
|
+
- `qa` writes `inspect.json`, `screenshots.json`, and sampled `frames/` into one QA directory.
|
|
96
|
+
|
|
97
|
+
Use `init` to create a self-contained agent working directory:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
visualfries init ./video-package \
|
|
101
|
+
--video ./input.mp4 \
|
|
102
|
+
--transcript ./transcript.srt \
|
|
103
|
+
--preset hidden-engine-center \
|
|
104
|
+
--cue-preset hidden-engine-dynamic
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
It creates `scene.json`, `cues.json`, `assets/`, `qa/frames/`, `qa/inspect.json`, `notes.md`, and transcript examples. `cues.json` is generated from the selected cue preset and can be edited before compose/render.
|
|
108
|
+
|
|
109
|
+
Use `compose` when an agent should prepare the scene and, for now, produce a preview MP4 in one command:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
visualfries compose \
|
|
113
|
+
--video ./input.mp4 \
|
|
114
|
+
--transcript ./transcript.srt \
|
|
115
|
+
--cue-preset hidden-engine-dynamic \
|
|
116
|
+
--cues ./cues.json \
|
|
117
|
+
--scene-output ./scene.json \
|
|
118
|
+
--qa-output ./qa/frames \
|
|
119
|
+
--render-mode preview \
|
|
120
|
+
--output ./out.mp4
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
`compose` runs the same underlying pipeline as the step-by-step workflow:
|
|
124
|
+
|
|
125
|
+
```text
|
|
126
|
+
caption-scene -> optional cue preset -> optional cue file -> inspect -> optional QA screenshots -> render
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Use `apply-cues` when an agent has already planned the visual timeline:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
visualfries preset-cues --duration 45 \
|
|
133
|
+
--preset hidden-engine-dynamic \
|
|
134
|
+
--output ./cues.json
|
|
135
|
+
|
|
136
|
+
visualfries apply-cues ./scene.json \
|
|
137
|
+
--cues ./cues.json \
|
|
138
|
+
--output ./scene.with-cues.json
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Cue files can contain `broll`, `overlays`, and `transitions` arrays:
|
|
142
|
+
|
|
143
|
+
```json
|
|
144
|
+
{
|
|
145
|
+
"broll": [
|
|
146
|
+
{ "url": "./assets/profile.mp4", "start": 2, "end": 5, "type": "VIDEO" },
|
|
147
|
+
{ "url": "./assets/chart.png", "start": 5, "end": 7, "type": "IMAGE", "motion": "slow-zoom-in" }
|
|
148
|
+
],
|
|
149
|
+
"overlays": [
|
|
150
|
+
{ "text": "LOVE THIS 😍", "start": 0.4, "end": 1.1, "style": "hook-punch" },
|
|
151
|
+
{ "text": "NECK 🤯", "start": 1.1, "end": 1.7, "style": "shock-word" }
|
|
152
|
+
],
|
|
153
|
+
"transitions": [
|
|
154
|
+
{ "time": 2, "style": "dip-to-black" },
|
|
155
|
+
{ "time": 5, "style": "swipe-left", "color": "#04483D" }
|
|
156
|
+
]
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Relative b-roll URLs are resolved relative to the cue file path, so an agent package can keep cues and assets together.
|
|
161
|
+
|
|
162
|
+
`preset-cues` creates a valid starter cue file. It is not meant to replace creative judgment; agents should replace placeholder overlay text and add b-roll paths before the final render.
|
|
163
|
+
|
|
164
|
+
## Node API
|
|
165
|
+
|
|
166
|
+
Use the agent-only subpath for automations and CLIs:
|
|
167
|
+
|
|
168
|
+
```ts
|
|
169
|
+
import { createCaptionScene, inspectScene, normalizeTranscript } from 'visualfries/agent';
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
The root `visualfries` export includes the full library surface. Agents should use `visualfries/agent` for captioning and inspection because it avoids browser/Svelte runtime imports.
|
|
173
|
+
|
|
174
|
+
Renderer planning is also agent-safe:
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
import { resolveAgentRenderPlan, requiresDeterministicRender } from 'visualfries/agent';
|
|
178
|
+
|
|
179
|
+
const plan = resolveAgentRenderPlan(scene, { mode: 'final' });
|
|
180
|
+
|
|
181
|
+
if (requiresDeterministicRender(scene)) {
|
|
182
|
+
// Final output needs local deterministic media predecode, not browser video seek.
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
For short-form overlays:
|
|
187
|
+
|
|
188
|
+
```ts
|
|
189
|
+
import {
|
|
190
|
+
addAgentBrollSequence,
|
|
191
|
+
addAgentTextOverlays,
|
|
192
|
+
addAgentTransitions
|
|
193
|
+
} from 'visualfries/agent';
|
|
194
|
+
|
|
195
|
+
const sceneWithOverlays = addAgentTextOverlays({
|
|
196
|
+
scene,
|
|
197
|
+
overlays: [
|
|
198
|
+
{ text: 'LOVE THIS 😍', start: 0.4, end: 1.1, style: 'pop-label' },
|
|
199
|
+
{ text: 'NECK 🤯', start: 1.1, end: 1.7, style: 'shock-word' }
|
|
200
|
+
]
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
const sceneWithBroll = addAgentBrollSequence({
|
|
204
|
+
scene,
|
|
205
|
+
cues: [
|
|
206
|
+
{ url: './broll/profile.mp4', start: 2.0, end: 5.0, type: 'VIDEO' },
|
|
207
|
+
{ url: './broll/chart.png', start: 5.0, end: 7.0, type: 'IMAGE', motion: 'slow-zoom-in' }
|
|
208
|
+
]
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
const sceneWithTransitions = addAgentTransitions({
|
|
212
|
+
scene,
|
|
213
|
+
transitions: [
|
|
214
|
+
{ time: 2.0, style: 'dip-to-black' },
|
|
215
|
+
{ time: 5.0, style: 'swipe-left', color: '#04483D' }
|
|
216
|
+
]
|
|
217
|
+
});
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### `caption-scene`
|
|
221
|
+
|
|
222
|
+
Creates a vertical 9:16 scene with:
|
|
223
|
+
|
|
224
|
+
- full-frame video component,
|
|
225
|
+
- subtitle component,
|
|
226
|
+
- scene asset registry,
|
|
227
|
+
- `settings.subtitles.data` populated from transcript JSON.
|
|
228
|
+
|
|
229
|
+
Example:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
visualfries caption-scene \
|
|
233
|
+
--video ./input.mp4 \
|
|
234
|
+
--transcript ./transcript.json \
|
|
235
|
+
--preset hidden-engine-center \
|
|
236
|
+
--output ./scene.json
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Accepted transcript shapes:
|
|
240
|
+
|
|
241
|
+
Plain subtitle files:
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
visualfries caption-scene \
|
|
245
|
+
--video ./input.mp4 \
|
|
246
|
+
--transcript ./captions.srt \
|
|
247
|
+
--preset hidden-engine-center \
|
|
248
|
+
--output ./scene.json
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Supported subtitle file formats:
|
|
252
|
+
|
|
253
|
+
- `.srt`
|
|
254
|
+
- `.vtt`
|
|
255
|
+
|
|
256
|
+
Structured JSON:
|
|
257
|
+
|
|
258
|
+
```json
|
|
259
|
+
{
|
|
260
|
+
"segments": [
|
|
261
|
+
{
|
|
262
|
+
"text": "The best content asset is not always a post.",
|
|
263
|
+
"start": 0,
|
|
264
|
+
"end": 2.4,
|
|
265
|
+
"words": [{ "text": "The", "start": 0, "end": 0.12 }]
|
|
266
|
+
}
|
|
267
|
+
]
|
|
268
|
+
}
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
```json
|
|
272
|
+
{
|
|
273
|
+
"words": [
|
|
274
|
+
{ "text": "The", "start": 0, "end": 0.12 },
|
|
275
|
+
{ "text": "best", "start": 0.12, "end": 0.35 }
|
|
276
|
+
]
|
|
277
|
+
}
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
## Presets
|
|
281
|
+
|
|
282
|
+
Initial caption presets:
|
|
283
|
+
|
|
284
|
+
- `reels-center`
|
|
285
|
+
- `reels-lower`
|
|
286
|
+
- `podcast-clean`
|
|
287
|
+
- `hidden-engine-center`
|
|
288
|
+
|
|
289
|
+
Initial agent overlay styles:
|
|
290
|
+
|
|
291
|
+
- `pop-label` for quick reaction labels above/below captions.
|
|
292
|
+
- `shock-word` for large emphatic keyword reveals.
|
|
293
|
+
- `soft-card` for calmer proof/context callouts.
|
|
294
|
+
- `hook-punch` for the first loud hook label.
|
|
295
|
+
- `proof-pill` for compact proof/credibility beats.
|
|
296
|
+
- `metric-badge` for big numbers and business proof.
|
|
297
|
+
- `danger-crossout` for wrong-path / negative beats.
|
|
298
|
+
- `cta-card` for final choice/question cards.
|
|
299
|
+
|
|
300
|
+
Initial agent b-roll helper:
|
|
301
|
+
|
|
302
|
+
- `addAgentBrollSequence` for timed portrait video/image/GIF cues below captions and overlays.
|
|
303
|
+
- Image cues default to subtle `slow-zoom-in`; use `motion: 'none' | 'slow-zoom-in' | 'slow-zoom-out' | 'drift-up'`.
|
|
304
|
+
|
|
305
|
+
Initial agent transition helper:
|
|
306
|
+
|
|
307
|
+
- `addAgentTransitions` for fast full-frame transition covers at exact beat times.
|
|
308
|
+
- Transition helper covers use animated native SHAPE rectangles.
|
|
309
|
+
- Supported styles: `dip-to-black`, `flash`, `swipe-left`, `swipe-up`.
|
|
310
|
+
|
|
311
|
+
Overlay rules:
|
|
312
|
+
|
|
313
|
+
- Keep the center caption lane free unless the overlay replaces captions for that moment.
|
|
314
|
+
- Use one overlay idea per beat. Split “LOVE THIS” and “NECK” into separate timed cues.
|
|
315
|
+
- Prefer 0.4-1.4 second overlay durations. Longer overlays start feeling like static slides.
|
|
316
|
+
- Render 1-3 QA frames before MP4 encode when a new overlay style is used.
|
|
317
|
+
|
|
318
|
+
See [AGENT_PATTERNS.md](AGENT_PATTERNS.md) for repeatable caption, overlay, b-roll, and QA patterns.
|
|
319
|
+
|
|
320
|
+
## Quality Gates
|
|
321
|
+
|
|
322
|
+
Before a scene is accepted:
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
visualfries validate scene.json
|
|
326
|
+
visualfries inspect scene.json --json
|
|
327
|
+
visualfries inspect scene.json --screenshots --samples 3 --output ./qa/frames --json
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
`inspect` checks schema validity, timeline bounds, missing assets, and subtitle data anchors. With `--screenshots`, it also renders sampled QA frames and returns their paths in the JSON report.
|
|
331
|
+
|
|
332
|
+
Before publishing a rendered video:
|
|
333
|
+
|
|
334
|
+
```bash
|
|
335
|
+
visualfries inspect scene.json --screenshots --samples 3 --output ./qa-frames --json
|
|
336
|
+
visualfries render scene.json --output ./out.mp4
|
|
337
|
+
ffprobe -v error -show_entries stream=codec_type,width,height -of json ./out.mp4
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
For static-heavy scenes, proof screenshots, and overlay sections, the faster render path is:
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
visualfries render scene.json --output ./out.mp4 --skip-duplicates
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
Do not use `--skip-duplicates` blindly on complex video-heavy scenes until QA frames look correct.
|
|
347
|
+
|
|
348
|
+
## Complete Agent Production Path
|
|
349
|
+
|
|
350
|
+
VisualFries uses these layers for complete agent-driven production:
|
|
351
|
+
|
|
352
|
+
1. CLI scene creation and validation. Done.
|
|
353
|
+
2. Caption scene generator. Done.
|
|
354
|
+
3. Renderer adapter: `visualfries render scene.json --output out.mp4`. Done for local browser + ffmpeg rendering.
|
|
355
|
+
4. Agent text overlay cues. Done for initial pop/shock/card styles.
|
|
356
|
+
5. Screenshot inspect: `visualfries inspect scene.json --screenshots`. Done.
|
|
357
|
+
6. Agent project scaffold: `visualfries init <dir>`. Done.
|
|
358
|
+
7. Pattern registry for transitions and b-roll layouts. Initial b-roll sequence helper, image motion, transition helper, and cookbook done.
|
|
359
|
+
8. Cue-file CLI application for b-roll/overlays/transitions. Done.
|
|
360
|
+
9. Starter cue presets: `visualfries preset-cues`. Done for `hidden-engine-dynamic` and `captioned-clean`.
|
|
361
|
+
10. One-command agent compose workflow: `visualfries compose`. Done.
|
|
362
|
+
11. Skill/cookbook examples for common agent jobs.
|
|
363
|
+
|
|
364
|
+
The current implementation supports caption-scene creation, validation, inspection, QA frame rendering, MP4 rendering, b-roll cues, text overlays, simple transition cues, cue-file application from the CLI, starter cue presets, and one-command compose.
|