@mevdragon/vidfarm-devcli 0.2.12 → 0.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +37 -1
- package/README.md +27 -183
- package/SKILL.director.md +293 -0
- package/SKILL.platform.md +312 -0
- package/auto-create-hyperframe-templates/AUTO_CREATE_HYPERFRAME_TEMPLATES.md +275 -0
- package/auto-create-hyperframe-templates/extractor-system-prompt.md +128 -0
- package/auto-create-hyperframe-templates/input-manifest.schema.json +56 -0
- package/auto-create-hyperframe-templates/lambda-memory-estimator.md +118 -0
- package/auto-create-hyperframe-templates/production-graph.schema.json +314 -0
- package/auto-create-hyperframe-templates/runbook.md +198 -0
- package/auto-create-hyperframe-templates/scripts/create-hyperframe-template.mjs +368 -0
- package/auto-create-hyperframe-templates/template-plan.schema.json +311 -0
- package/auto-create-hyperframe-templates/template-planner-prompt.md +144 -0
- package/auto-create-templates/AUTO_CREATE_TEMPLATES.md +116 -0
- package/auto-create-templates/extractor-system-prompt.md +6 -1
- package/auto-create-templates/template-plan.schema.json +73 -2
- package/auto-create-templates/template-planner-prompt.md +62 -1
- package/dist/src/account-pages-legacy.js +361 -89
- package/dist/src/account-pages-legacy.js.map +1 -0
- package/dist/src/account-pages.js +13 -3
- package/dist/src/account-pages.js.map +1 -0
- package/dist/src/app.js +7060 -946
- package/dist/src/app.js.map +1 -0
- package/dist/src/cli.js +110 -29
- package/dist/src/cli.js.map +1 -0
- package/dist/src/composition-runtime.js +581 -0
- package/dist/src/composition-runtime.js.map +1 -0
- package/dist/src/config.js +69 -11
- package/dist/src/config.js.map +1 -0
- package/dist/src/context.js +280 -21
- package/dist/src/context.js.map +1 -0
- package/dist/src/dev-app-legacy.js +18 -17
- package/dist/src/dev-app-legacy.js.map +1 -0
- package/dist/src/dev-app.js +1 -0
- package/dist/src/dev-app.js.map +1 -0
- package/dist/src/domain.js +2 -1
- package/dist/src/domain.js.map +1 -0
- package/dist/src/editor-chat-history.js +10 -0
- package/dist/src/editor-chat-history.js.map +1 -0
- package/dist/src/editor-chat.js +133 -24
- package/dist/src/editor-chat.js.map +1 -0
- package/dist/src/frontend/flockposter-cache-store.js +10 -2
- package/dist/src/frontend/flockposter-cache-store.js.map +1 -0
- package/dist/src/frontend/homepage-client.js +6 -3
- package/dist/src/frontend/homepage-client.js.map +1 -0
- package/dist/src/frontend/homepage-shared.js +1 -0
- package/dist/src/frontend/homepage-shared.js.map +1 -0
- package/dist/src/frontend/homepage-store.js +1 -0
- package/dist/src/frontend/homepage-store.js.map +1 -0
- package/dist/src/frontend/homepage-view.js +131 -18
- package/dist/src/frontend/homepage-view.js.map +1 -0
- package/dist/src/frontend/page-runtime-client.js +5 -2
- package/dist/src/frontend/page-runtime-client.js.map +1 -0
- package/dist/src/frontend/page-runtime-store.js +1 -0
- package/dist/src/frontend/page-runtime-store.js.map +1 -0
- package/dist/src/frontend/sentry.js +42 -0
- package/dist/src/frontend/sentry.js.map +1 -0
- package/dist/src/frontend/template-editor-chat.js +1719 -213
- package/dist/src/frontend/template-editor-chat.js.map +1 -0
- package/dist/src/help-page.js +333 -0
- package/dist/src/help-page.js.map +1 -0
- package/dist/src/homepage.js +169 -47
- package/dist/src/homepage.js.map +1 -0
- package/dist/src/hyperframes/composition.js +180 -0
- package/dist/src/hyperframes/composition.js.map +1 -0
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/instrument.js +30 -0
- package/dist/src/instrument.js.map +1 -0
- package/dist/src/lib/crypto.js +1 -0
- package/dist/src/lib/crypto.js.map +1 -0
- package/dist/src/lib/dev-log.js +54 -0
- package/dist/src/lib/dev-log.js.map +1 -0
- package/dist/src/lib/display-name.js +11 -0
- package/dist/src/lib/display-name.js.map +1 -0
- package/dist/src/lib/ids.js +21 -1
- package/dist/src/lib/ids.js.map +1 -0
- package/dist/src/lib/images.js +1 -0
- package/dist/src/lib/images.js.map +1 -0
- package/dist/src/lib/json.js +1 -0
- package/dist/src/lib/json.js.map +1 -0
- package/dist/src/lib/template-dna.js +1 -0
- package/dist/src/lib/template-dna.js.map +1 -0
- package/dist/src/lib/template-paths.js +1 -0
- package/dist/src/lib/template-paths.js.map +1 -0
- package/dist/src/lib/template-style-options.js +29 -3
- package/dist/src/lib/template-style-options.js.map +1 -0
- package/dist/src/lib/time.js +1 -0
- package/dist/src/lib/time.js.map +1 -0
- package/dist/src/lib/video-quality-harness.js +60 -0
- package/dist/src/lib/video-quality-harness.js.map +1 -0
- package/dist/src/page-runtime.js +1 -0
- package/dist/src/page-runtime.js.map +1 -0
- package/dist/src/page-shell.js +1501 -49
- package/dist/src/page-shell.js.map +1 -0
- package/dist/src/primitive-context.js +144 -8
- package/dist/src/primitive-context.js.map +1 -0
- package/dist/src/primitive-registry.js +1919 -78
- package/dist/src/primitive-registry.js.map +1 -0
- package/dist/src/primitive-sdk.js +1 -0
- package/dist/src/primitive-sdk.js.map +1 -0
- package/dist/src/primitives/remotion/html-image.js +3 -1
- package/dist/src/primitives/remotion/html-image.js.map +1 -0
- package/dist/src/primitives/remotion/media-slideshow.js +60 -0
- package/dist/src/primitives/remotion/media-slideshow.js.map +1 -0
- package/dist/src/react-page-shell.js +1 -0
- package/dist/src/react-page-shell.js.map +1 -0
- package/dist/src/ready-post-schedule-component.js +1 -0
- package/dist/src/ready-post-schedule-component.js.map +1 -0
- package/dist/src/registry.js +237 -24
- package/dist/src/registry.js.map +1 -0
- package/dist/src/runtime.js +3 -0
- package/dist/src/runtime.js.map +1 -0
- package/dist/src/services/api-call-history.js +4 -0
- package/dist/src/services/api-call-history.js.map +1 -0
- package/dist/src/services/auth.js +40 -50
- package/dist/src/services/auth.js.map +1 -0
- package/dist/src/services/billing.js +20 -44
- package/dist/src/services/billing.js.map +1 -0
- package/dist/src/services/chat-threads.js +10 -6
- package/dist/src/services/chat-threads.js.map +1 -0
- package/dist/src/services/fork-access.js +94 -0
- package/dist/src/services/fork-access.js.map +1 -0
- package/dist/src/services/ghostcut.js +132 -0
- package/dist/src/services/ghostcut.js.map +1 -0
- package/dist/src/services/hyperframes.js +1014 -0
- package/dist/src/services/hyperframes.js.map +1 -0
- package/dist/src/services/job-capacity.js +14 -0
- package/dist/src/services/job-capacity.js.map +1 -0
- package/dist/src/services/job-logs.js +4 -0
- package/dist/src/services/job-logs.js.map +1 -0
- package/dist/src/services/jobs.js +99 -91
- package/dist/src/services/jobs.js.map +1 -0
- package/dist/src/services/media-processing.js +743 -0
- package/dist/src/services/media-processing.js.map +1 -0
- package/dist/src/services/primitive-media-lambda.js +280 -0
- package/dist/src/services/primitive-media-lambda.js.map +1 -0
- package/dist/src/services/providers.js +1560 -178
- package/dist/src/services/providers.js.map +1 -0
- package/dist/src/services/rate-limits.js +3 -2
- package/dist/src/services/rate-limits.js.map +1 -0
- package/dist/src/services/remotion.js +495 -92
- package/dist/src/services/remotion.js.map +1 -0
- package/dist/src/services/serverless-auth.js +374 -0
- package/dist/src/services/serverless-auth.js.map +1 -0
- package/dist/src/services/serverless-jobs.js +1074 -0
- package/dist/src/services/serverless-jobs.js.map +1 -0
- package/dist/src/services/serverless-provider-keys.js +401 -0
- package/dist/src/services/serverless-provider-keys.js.map +1 -0
- package/dist/src/services/serverless-records.js +1086 -0
- package/dist/src/services/serverless-records.js.map +1 -0
- package/dist/src/services/serverless-template-configs.js +67 -0
- package/dist/src/services/serverless-template-configs.js.map +1 -0
- package/dist/src/services/storage.js +170 -35
- package/dist/src/services/storage.js.map +1 -0
- package/dist/src/services/template-certification.js +295 -3
- package/dist/src/services/template-certification.js.map +1 -0
- package/dist/src/services/template-loader.js +45 -1
- package/dist/src/services/template-loader.js.map +1 -0
- package/dist/src/services/template-runtime-bundles.js +217 -0
- package/dist/src/services/template-runtime-bundles.js.map +1 -0
- package/dist/src/services/template-sources.js +452 -87
- package/dist/src/services/template-sources.js.map +1 -0
- package/dist/src/services/video-normalization.js +2 -0
- package/dist/src/services/video-normalization.js.map +1 -0
- package/dist/src/services/webhooks.js +7 -6
- package/dist/src/services/webhooks.js.map +1 -0
- package/dist/src/template-editor-pages.js +5637 -1322
- package/dist/src/template-editor-pages.js.map +1 -0
- package/dist/src/template-editor-shell.js +1376 -170
- package/dist/src/template-editor-shell.js.map +1 -0
- package/dist/src/template-sdk.js +1 -0
- package/dist/src/template-sdk.js.map +1 -0
- package/dist/src/worker.js +11 -226
- package/dist/src/worker.js.map +1 -0
- package/package.json +47 -12
- package/public/assets/homepage-client-app.js +34 -8
- package/public/assets/page-runtime-client-app.js +44 -18
- package/readme.secret.md +89 -0
- package/templates/vidfarm_template_0000/README.md +106 -0
- package/templates/vidfarm_template_0000/SKILL.md +266 -0
- package/templates/vidfarm_template_0000/assets/Abel-Regular.ttf +0 -0
- package/templates/vidfarm_template_0000/assets/DMSerifDisplay-Regular.ttf +0 -0
- package/templates/vidfarm_template_0000/assets/Montserrat[wght].ttf +0 -0
- package/templates/vidfarm_template_0000/assets/SourceCodePro[wght].ttf +0 -0
- package/templates/vidfarm_template_0000/assets/TikTokSans-SemiBold.ttf +0 -0
- package/templates/vidfarm_template_0000/assets/Yesteryear-Regular.ttf +0 -0
- package/templates/vidfarm_template_0000/composition.json +11 -0
- package/templates/vidfarm_template_0000/src/lib/images.js +221 -0
- package/templates/vidfarm_template_0000/src/remotion/Root.js +33 -0
- package/templates/vidfarm_template_0000/src/remotion/index.js +3 -0
- package/templates/vidfarm_template_0000/src/sdk.js +3 -0
- package/templates/vidfarm_template_0000/src/style-options.js +200 -0
- package/templates/vidfarm_template_0000/src/template-dna.js +9 -0
- package/templates/vidfarm_template_0000/src/template.js +1566 -0
- package/templates/vidfarm_template_0000/template.config.json +21 -0
- package/GETTING_STARTED.developers.md +0 -87
- package/SKILL.developer.md +0 -1186
- package/dist/src/db.js +0 -2007
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# HyperFrames Production Graph Extractor Prompt
|
|
2
|
+
|
|
3
|
+
You are a HyperFrames production analyst.
|
|
4
|
+
|
|
5
|
+
Your job is to inspect one MP4, screenshot set, or PNG/JPG/WebP slideshow and extract the repeatable HyperFrames production process as structured JSON. Do not merely describe the media. Convert it into an editable composition graph that can become `composition.html`, `composition.json`, and a production Lambda site.
|
|
6
|
+
|
|
7
|
+
Return only JSON matching `production-graph.schema.json`.
|
|
8
|
+
|
|
9
|
+
## Inputs You May Receive
|
|
10
|
+
|
|
11
|
+
- source notes
|
|
12
|
+
- source video or slides
|
|
13
|
+
- contact sheet
|
|
14
|
+
- representative frames
|
|
15
|
+
- ffprobe metadata
|
|
16
|
+
- scene cut list
|
|
17
|
+
- STT transcript with word timestamps
|
|
18
|
+
- OCR text from frames
|
|
19
|
+
- layout analysis with bounding boxes
|
|
20
|
+
- existing `composition.html` or `composition.json`
|
|
21
|
+
- desired output dimensions and fps
|
|
22
|
+
|
|
23
|
+
## Extraction Rules
|
|
24
|
+
|
|
25
|
+
- Treat all supplied media as one reusable HyperFrames format.
|
|
26
|
+
- Separate source media, deterministic overlays, captions, audio, and generated assets.
|
|
27
|
+
- Identify which visual surfaces are editable layers and which are source-media content.
|
|
28
|
+
- Important readable text should default to deterministic HTML/caption layers, not baked generated media.
|
|
29
|
+
- Extract exact or inferred timing for scenes, slides, captions, overlays, transitions, zooms, holds, and loop points.
|
|
30
|
+
- Record source media slices with `media_start` when a layer uses a segment from a longer MP4.
|
|
31
|
+
- Preserve blank gaps as intentional timeline ranges when no layer should be visible.
|
|
32
|
+
- Do not depend on an always-on source video for publish correctness. Preview playback sources are allowed only as editor affordances.
|
|
33
|
+
- Distinguish `mode: "both"`, `mode: "editor"`, and `mode: "publish"`.
|
|
34
|
+
- Use percent geometry for layer placement: `x`, `y`, `width`, `height`.
|
|
35
|
+
- Use seconds for `start`, `duration`, `media_start`, and `media_end`.
|
|
36
|
+
- Track source audio separately from source video if audio should continue across scene cuts.
|
|
37
|
+
- Keep one editable timeline track collision-free unless the track is explicitly marked as composited.
|
|
38
|
+
- Identify caption safe areas and collisions with TikTok/Reels chrome.
|
|
39
|
+
- Record Lambda memory estimate inputs: resolution, duration, active video streams, source resolution, layer count, DOM complexity, effects, audio mixing, and known risk flags.
|
|
40
|
+
|
|
41
|
+
## Required Analysis Dimensions
|
|
42
|
+
|
|
43
|
+
Extract:
|
|
44
|
+
|
|
45
|
+
- format summary and source mode
|
|
46
|
+
- output dimensions, fps, and total duration
|
|
47
|
+
- source asset inventory
|
|
48
|
+
- scene or slide timeline
|
|
49
|
+
- layer decomposition
|
|
50
|
+
- deterministic caption and text surfaces
|
|
51
|
+
- HTML overlay surfaces
|
|
52
|
+
- media replacement slots
|
|
53
|
+
- audio plan
|
|
54
|
+
- safe areas and subject bounds
|
|
55
|
+
- caption positioning and wrapping rules
|
|
56
|
+
- visual rules that must survive adaptation
|
|
57
|
+
- editable controls
|
|
58
|
+
- generated asset needs, if any
|
|
59
|
+
- Lambda memory estimate
|
|
60
|
+
- production Lambda site readiness
|
|
61
|
+
- validation checklist
|
|
62
|
+
|
|
63
|
+
## Layer Classification
|
|
64
|
+
|
|
65
|
+
For every meaningful visual or audio element choose one kind:
|
|
66
|
+
|
|
67
|
+
- `video`: timed video layer or scene slice
|
|
68
|
+
- `image`: timed image/slide layer
|
|
69
|
+
- `audio`: timed audio layer
|
|
70
|
+
- `caption`: text intended as subtitle/creator caption
|
|
71
|
+
- `html`: custom deterministic HTML overlay, UI card, comment, notification, or app shell
|
|
72
|
+
- `shape`: non-text geometric layer
|
|
73
|
+
- `effect`: deterministic transform/filter/mask/highlight
|
|
74
|
+
|
|
75
|
+
For every layer choose one source of truth:
|
|
76
|
+
|
|
77
|
+
- `source_media`: the original media asset is the visual/audio content
|
|
78
|
+
- `deterministic_html`: HTML/CSS/text is the source of truth
|
|
79
|
+
- `generated_asset`: AI/generated media is the source of truth
|
|
80
|
+
- `user_asset`: caller-provided replacement asset is required
|
|
81
|
+
- `computed_effect`: derived motion, mask, crop, zoom, or highlight
|
|
82
|
+
|
|
83
|
+
## Caption Rules
|
|
84
|
+
|
|
85
|
+
Strongly identify typography:
|
|
86
|
+
|
|
87
|
+
- font family match
|
|
88
|
+
- fallback font stack
|
|
89
|
+
- font weight
|
|
90
|
+
- case
|
|
91
|
+
- color
|
|
92
|
+
- outline, stroke, radial halo, shadow
|
|
93
|
+
- background chip style
|
|
94
|
+
- line wrapping
|
|
95
|
+
- line height
|
|
96
|
+
- alignment
|
|
97
|
+
- safe area
|
|
98
|
+
- phone-size legibility
|
|
99
|
+
|
|
100
|
+
When captions have colored backgrounds, classify them as inline highlight chips unless the source clearly uses a panel. Chips must hug measured wrapped lines.
|
|
101
|
+
|
|
102
|
+
When captions are white TikTok-native captions, distinguish radial black halo/outline from a web-style directional shadow.
|
|
103
|
+
|
|
104
|
+
For multiline captions, require one shared font size and line height for the block. Do not recommend per-line rendered images.
|
|
105
|
+
|
|
106
|
+
## Lambda Memory Estimate Rules
|
|
107
|
+
|
|
108
|
+
Estimate memory from composition complexity, not vibes.
|
|
109
|
+
|
|
110
|
+
Use these defaults:
|
|
111
|
+
|
|
112
|
+
- `2048` MB for static/slideshow/simple image compositions with low DOM complexity.
|
|
113
|
+
- `3072` MB for standard 720x1280 or 1080x1920 social video with one active video stream and deterministic overlays.
|
|
114
|
+
- `4096` MB for 1080p video, multiple active videos, heavy captions, masks, filters, or long audio.
|
|
115
|
+
- `6144` MB or higher only when high resolution, many simultaneous layers, or prior failures justify it.
|
|
116
|
+
|
|
117
|
+
Return both a recommendation and a confidence. Include benchmark guidance only when the source sits near a threshold.
|
|
118
|
+
|
|
119
|
+
## Output Bias
|
|
120
|
+
|
|
121
|
+
Be concrete. A production graph should be implementable.
|
|
122
|
+
|
|
123
|
+
Bad: "Add captions around the video."
|
|
124
|
+
|
|
125
|
+
Good: "Render a 2-line white TikTok Sans Semibold caption block at x=8, y=42, width=84, height=14, fontSize=46, lineHeight=1.08, black radial halo, max 18 chars per line, timed 0.0-2.4s."
|
|
126
|
+
|
|
127
|
+
Publish correctness bias: if a source video is split into scenes, every scene must be its own timed layer or publish proxy. Deleting scene 2 must delete scene 2 from the final render.
|
|
128
|
+
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "Auto-Create HyperFrame Input Manifest",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"required": [
|
|
6
|
+
"mode",
|
|
7
|
+
"input_path",
|
|
8
|
+
"output_path",
|
|
9
|
+
"slug_id",
|
|
10
|
+
"source_mode",
|
|
11
|
+
"render_defaults",
|
|
12
|
+
"lambda",
|
|
13
|
+
"publish"
|
|
14
|
+
],
|
|
15
|
+
"properties": {
|
|
16
|
+
"mode": { "const": "autocreate-hyperframe-template" },
|
|
17
|
+
"harness_entry": { "type": "string" },
|
|
18
|
+
"input_path": { "type": "string" },
|
|
19
|
+
"output_path": { "type": "string" },
|
|
20
|
+
"slug_id": { "type": "string" },
|
|
21
|
+
"source_mode": { "enum": ["auto", "single_video", "scene_split_video", "slideshow", "mixed_media"] },
|
|
22
|
+
"source_notes_path": { "type": "string" },
|
|
23
|
+
"render_defaults": {
|
|
24
|
+
"type": "object",
|
|
25
|
+
"required": ["width", "height", "fps"],
|
|
26
|
+
"properties": {
|
|
27
|
+
"width": { "type": "integer", "minimum": 1 },
|
|
28
|
+
"height": { "type": "integer", "minimum": 1 },
|
|
29
|
+
"fps": { "type": "number", "minimum": 1 }
|
|
30
|
+
},
|
|
31
|
+
"additionalProperties": false
|
|
32
|
+
},
|
|
33
|
+
"lambda": {
|
|
34
|
+
"type": "object",
|
|
35
|
+
"required": ["stack_name", "region", "memory_strategy"],
|
|
36
|
+
"properties": {
|
|
37
|
+
"stack_name": { "type": "string" },
|
|
38
|
+
"region": { "type": "string" },
|
|
39
|
+
"memory_strategy": { "enum": ["estimate", "fixed"] },
|
|
40
|
+
"fixed_memory_mb": { "enum": [2048, 3072, 4096, 6144, 8192, 10240] }
|
|
41
|
+
},
|
|
42
|
+
"additionalProperties": false
|
|
43
|
+
},
|
|
44
|
+
"publish": {
|
|
45
|
+
"type": "object",
|
|
46
|
+
"required": ["prestage_site", "output_url_policy"],
|
|
47
|
+
"properties": {
|
|
48
|
+
"prestage_site": { "type": "boolean" },
|
|
49
|
+
"output_url_policy": { "enum": ["signed_https_final_output_only"] }
|
|
50
|
+
},
|
|
51
|
+
"additionalProperties": false
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"additionalProperties": false
|
|
55
|
+
}
|
|
56
|
+
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# HyperFrames Lambda Memory Estimator
|
|
2
|
+
|
|
3
|
+
Use this rubric to estimate Lambda memory before benchmarking.
|
|
4
|
+
|
|
5
|
+
The goal is not perfect prediction. The goal is a sane first render configuration that avoids the historical overpowered default while keeping publish reliable.
|
|
6
|
+
|
|
7
|
+
## Recommended Buckets
|
|
8
|
+
|
|
9
|
+
| Memory | Use For |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| `2048` MB | Static image, simple slideshow, low DOM, no video decode pressure, 720p target. |
|
|
12
|
+
| `3072` MB | Default vertical social video: one active video stream, 720x1280 or 1080x1920, deterministic captions/HTML overlays. |
|
|
13
|
+
| `4096` MB | 1080p video with heavy overlays, multiple active video streams, masks/filters, large shadows, long audio, or >30s timelines. |
|
|
14
|
+
| `6144` MB | High-resolution outputs, many simultaneous media layers, complex CSS filters/masks, prior 3GB/4GB failure, or large generated assets. |
|
|
15
|
+
| `8192` MB+ | Exceptional cases only. Use after measured failure or very high complexity. |
|
|
16
|
+
| `10240` MB | Last resort, not a default. |
|
|
17
|
+
|
|
18
|
+
## Scoring
|
|
19
|
+
|
|
20
|
+
Start at `1536` MB.
|
|
21
|
+
|
|
22
|
+
Add output pixel score:
|
|
23
|
+
|
|
24
|
+
- `0` MB for <= 1.0 megapixel output
|
|
25
|
+
- `512` MB for <= 2.1 megapixel output
|
|
26
|
+
- `1024` MB for <= 4.0 megapixel output
|
|
27
|
+
- `2048` MB for > 4.0 megapixel output
|
|
28
|
+
|
|
29
|
+
Add media score:
|
|
30
|
+
|
|
31
|
+
- `0` MB for no video layers
|
|
32
|
+
- `768` MB for one active video stream
|
|
33
|
+
- `512` MB for each additional simultaneous active video stream
|
|
34
|
+
- `256` MB for each additional unique source video decoded across the timeline
|
|
35
|
+
- `512` MB if source media is much larger than output resolution
|
|
36
|
+
|
|
37
|
+
Add DOM/caption score:
|
|
38
|
+
|
|
39
|
+
- `0` MB for <= 10 simple layers
|
|
40
|
+
- `256` MB for 11-30 layers
|
|
41
|
+
- `512` MB for > 30 layers
|
|
42
|
+
- `256` MB for frequent timed captions
|
|
43
|
+
- `512` MB for word-level caption highlighting or many HTML overlays
|
|
44
|
+
|
|
45
|
+
Add effect score:
|
|
46
|
+
|
|
47
|
+
- `256` MB for large text shadows, outlines, or chips on many layers
|
|
48
|
+
- `512` MB for masks, blend modes, blur, filter chains, or large CSS transforms
|
|
49
|
+
- `1024` MB for several effects active over video at once
|
|
50
|
+
|
|
51
|
+
Add duration/audio score:
|
|
52
|
+
|
|
53
|
+
- `0` MB for <= 30 seconds
|
|
54
|
+
- `256` MB for 31-60 seconds
|
|
55
|
+
- `512` MB for 61-180 seconds
|
|
56
|
+
- `1024` MB for > 180 seconds
|
|
57
|
+
- `256` MB for continuous audio mix
|
|
58
|
+
- `512` MB for multiple audio streams or heavy audio processing
|
|
59
|
+
|
|
60
|
+
Round up to the next bucket: `2048`, `3072`, `4096`, `6144`, `8192`, or `10240`.
|
|
61
|
+
|
|
62
|
+
Clamp ordinary compositions to `2048`-`4096` unless risk flags justify more.
|
|
63
|
+
|
|
64
|
+
## Fast Rules
|
|
65
|
+
|
|
66
|
+
- If there is no video and the output is <= 1080x1920, start at `2048`.
|
|
67
|
+
- If there is exactly one active video stream and ordinary captions, start at `3072`.
|
|
68
|
+
- If there are two or more simultaneous videos, start at `4096`.
|
|
69
|
+
- If output is 4K or the source is 4K and actively decoded, start at `6144`.
|
|
70
|
+
- If 3GB succeeds with similar wall time to 4GB, keep 3GB.
|
|
71
|
+
- If 2GB succeeds but wall time grows enough to erase savings, keep 3GB.
|
|
72
|
+
|
|
73
|
+
## Output Shape
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"recommended_memory_mb": 3072,
|
|
78
|
+
"confidence": "medium",
|
|
79
|
+
"complexity_scores": {
|
|
80
|
+
"output_pixels": 921600,
|
|
81
|
+
"output_pixel_score_mb": 0,
|
|
82
|
+
"max_simultaneous_video_streams": 1,
|
|
83
|
+
"media_score_mb": 768,
|
|
84
|
+
"layer_count": 8,
|
|
85
|
+
"dom_caption_score_mb": 256,
|
|
86
|
+
"effect_score_mb": 0,
|
|
87
|
+
"duration_seconds": 12.7,
|
|
88
|
+
"duration_audio_score_mb": 256,
|
|
89
|
+
"raw_estimate_mb": 2816,
|
|
90
|
+
"rounded_bucket_mb": 3072
|
|
91
|
+
},
|
|
92
|
+
"risk_flags": [
|
|
93
|
+
"source_video_decode",
|
|
94
|
+
"continuous_audio"
|
|
95
|
+
],
|
|
96
|
+
"rationale": "One active 720x1280 video stream with a small deterministic HTML overlay and continuous source audio fits the 3GB baseline.",
|
|
97
|
+
"benchmark_override": null
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Cost Estimate
|
|
102
|
+
|
|
103
|
+
Use this rough formula:
|
|
104
|
+
|
|
105
|
+
```txt
|
|
106
|
+
lambda_cost = memory_gb * billed_seconds_total * 0.0000166667
|
|
107
|
+
step_functions_cost = state_transitions * 0.000025
|
|
108
|
+
estimated_cost = lambda_cost + step_functions_cost
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
For planning, estimate billed seconds from similar templates:
|
|
112
|
+
|
|
113
|
+
- static/slideshow: 20-60 billed seconds
|
|
114
|
+
- 10-20s social video: 90-180 billed seconds at 3GB
|
|
115
|
+
- 30-60s social video: 180-420 billed seconds at 3GB
|
|
116
|
+
|
|
117
|
+
Record the estimate, but treat the first production render as the real calibration.
|
|
118
|
+
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"title": "HyperFrames Production Graph",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"required": [
|
|
6
|
+
"format_summary",
|
|
7
|
+
"input_contract",
|
|
8
|
+
"visual_system",
|
|
9
|
+
"timeline",
|
|
10
|
+
"layer_decomposition",
|
|
11
|
+
"caption_system",
|
|
12
|
+
"lambda_memory_estimate",
|
|
13
|
+
"deployment",
|
|
14
|
+
"validation"
|
|
15
|
+
],
|
|
16
|
+
"properties": {
|
|
17
|
+
"format_summary": {
|
|
18
|
+
"type": "object",
|
|
19
|
+
"required": ["slug_id", "title", "source_type", "summary", "width", "height", "duration_seconds"],
|
|
20
|
+
"properties": {
|
|
21
|
+
"slug_id": { "type": "string" },
|
|
22
|
+
"title": { "type": "string" },
|
|
23
|
+
"source_type": { "enum": ["single_video", "scene_split_video", "slideshow", "mixed_media"] },
|
|
24
|
+
"summary": { "type": "string" },
|
|
25
|
+
"width": { "type": "integer", "minimum": 1 },
|
|
26
|
+
"height": { "type": "integer", "minimum": 1 },
|
|
27
|
+
"fps": { "type": "number", "minimum": 1 },
|
|
28
|
+
"duration_seconds": { "type": "number", "minimum": 0 }
|
|
29
|
+
},
|
|
30
|
+
"additionalProperties": false
|
|
31
|
+
},
|
|
32
|
+
"input_contract": {
|
|
33
|
+
"type": "object",
|
|
34
|
+
"required": ["source_assets", "replaceable_slots"],
|
|
35
|
+
"properties": {
|
|
36
|
+
"source_assets": {
|
|
37
|
+
"type": "array",
|
|
38
|
+
"items": { "$ref": "#/$defs/sourceAsset" }
|
|
39
|
+
},
|
|
40
|
+
"replaceable_slots": {
|
|
41
|
+
"type": "array",
|
|
42
|
+
"items": {
|
|
43
|
+
"type": "object",
|
|
44
|
+
"required": ["name", "kind", "required", "description"],
|
|
45
|
+
"properties": {
|
|
46
|
+
"name": { "type": "string" },
|
|
47
|
+
"kind": { "enum": ["text", "image", "video", "audio", "html", "style", "duration", "cta"] },
|
|
48
|
+
"required": { "type": "boolean" },
|
|
49
|
+
"description": { "type": "string" },
|
|
50
|
+
"constraints": { "type": "array", "items": { "type": "string" } }
|
|
51
|
+
},
|
|
52
|
+
"additionalProperties": false
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"additionalProperties": false
|
|
57
|
+
},
|
|
58
|
+
"viral_mechanics": {
|
|
59
|
+
"type": "object",
|
|
60
|
+
"properties": {
|
|
61
|
+
"hook_mechanic": { "type": "string" },
|
|
62
|
+
"retention_mechanic": { "type": "string" },
|
|
63
|
+
"payoff": { "type": "string" },
|
|
64
|
+
"must_preserve": { "type": "array", "items": { "type": "string" } },
|
|
65
|
+
"must_not_dilute": { "type": "array", "items": { "type": "string" } }
|
|
66
|
+
},
|
|
67
|
+
"additionalProperties": false
|
|
68
|
+
},
|
|
69
|
+
"visual_system": {
|
|
70
|
+
"type": "object",
|
|
71
|
+
"required": ["safe_areas", "layout_rules", "style_rules"],
|
|
72
|
+
"properties": {
|
|
73
|
+
"safe_areas": { "$ref": "#/$defs/safeAreas" },
|
|
74
|
+
"layout_rules": { "type": "array", "items": { "type": "string" } },
|
|
75
|
+
"style_rules": { "type": "array", "items": { "type": "string" } },
|
|
76
|
+
"subject_regions": {
|
|
77
|
+
"type": "array",
|
|
78
|
+
"items": {
|
|
79
|
+
"type": "object",
|
|
80
|
+
"required": ["id", "role", "geometry"],
|
|
81
|
+
"properties": {
|
|
82
|
+
"id": { "type": "string" },
|
|
83
|
+
"role": { "type": "string" },
|
|
84
|
+
"geometry": { "$ref": "#/$defs/geometry" }
|
|
85
|
+
},
|
|
86
|
+
"additionalProperties": false
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
"additionalProperties": false
|
|
91
|
+
},
|
|
92
|
+
"timeline": {
|
|
93
|
+
"type": "object",
|
|
94
|
+
"required": ["total_duration_seconds", "beats"],
|
|
95
|
+
"properties": {
|
|
96
|
+
"total_duration_seconds": { "type": "number", "minimum": 0 },
|
|
97
|
+
"beats": {
|
|
98
|
+
"type": "array",
|
|
99
|
+
"items": {
|
|
100
|
+
"type": "object",
|
|
101
|
+
"required": ["id", "start", "duration", "role", "coverage"],
|
|
102
|
+
"properties": {
|
|
103
|
+
"id": { "type": "string" },
|
|
104
|
+
"start": { "type": "number", "minimum": 0 },
|
|
105
|
+
"duration": { "type": "number", "exclusiveMinimum": 0 },
|
|
106
|
+
"role": { "type": "string" },
|
|
107
|
+
"coverage": { "enum": ["media", "html_overlay", "caption_only", "blank_background", "audio_only"] },
|
|
108
|
+
"notes": { "type": "string" }
|
|
109
|
+
},
|
|
110
|
+
"additionalProperties": false
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
"additionalProperties": false
|
|
115
|
+
},
|
|
116
|
+
"layer_decomposition": {
|
|
117
|
+
"type": "object",
|
|
118
|
+
"required": ["composition_id", "background_color", "layers"],
|
|
119
|
+
"properties": {
|
|
120
|
+
"composition_id": { "type": "string" },
|
|
121
|
+
"background_color": { "type": "string" },
|
|
122
|
+
"layers": {
|
|
123
|
+
"type": "array",
|
|
124
|
+
"items": { "$ref": "#/$defs/layer" }
|
|
125
|
+
},
|
|
126
|
+
"track_policy": {
|
|
127
|
+
"type": "object",
|
|
128
|
+
"properties": {
|
|
129
|
+
"collision_free_by_default": { "type": "boolean" },
|
|
130
|
+
"composited_tracks": { "type": "array", "items": { "type": "integer" } }
|
|
131
|
+
},
|
|
132
|
+
"additionalProperties": false
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
"additionalProperties": false
|
|
136
|
+
},
|
|
137
|
+
"caption_system": {
|
|
138
|
+
"type": "object",
|
|
139
|
+
"required": ["surfaces", "default_style"],
|
|
140
|
+
"properties": {
|
|
141
|
+
"surfaces": {
|
|
142
|
+
"type": "array",
|
|
143
|
+
"items": {
|
|
144
|
+
"type": "object",
|
|
145
|
+
"required": ["id", "layer_ids", "placement", "safe_area_notes"],
|
|
146
|
+
"properties": {
|
|
147
|
+
"id": { "type": "string" },
|
|
148
|
+
"layer_ids": { "type": "array", "items": { "type": "string" } },
|
|
149
|
+
"placement": { "$ref": "#/$defs/geometry" },
|
|
150
|
+
"safe_area_notes": { "type": "string" },
|
|
151
|
+
"wrap_rules": { "type": "array", "items": { "type": "string" } }
|
|
152
|
+
},
|
|
153
|
+
"additionalProperties": false
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
"default_style": { "$ref": "#/$defs/textStyle" }
|
|
157
|
+
},
|
|
158
|
+
"additionalProperties": false
|
|
159
|
+
},
|
|
160
|
+
"lambda_memory_estimate": { "$ref": "#/$defs/lambdaMemoryEstimate" },
|
|
161
|
+
"deployment": {
|
|
162
|
+
"type": "object",
|
|
163
|
+
"required": ["stack_name", "region", "site_strategy", "output_url_policy"],
|
|
164
|
+
"properties": {
|
|
165
|
+
"stack_name": { "type": "string" },
|
|
166
|
+
"region": { "type": "string" },
|
|
167
|
+
"site_strategy": { "enum": ["pre_stage_site", "stage_on_publish", "manual"] },
|
|
168
|
+
"output_url_policy": { "enum": ["signed_https_final_output_only"] },
|
|
169
|
+
"render_defaults": {
|
|
170
|
+
"type": "object",
|
|
171
|
+
"properties": {
|
|
172
|
+
"width": { "type": "integer", "minimum": 1 },
|
|
173
|
+
"height": { "type": "integer", "minimum": 1 },
|
|
174
|
+
"fps": { "type": "number", "minimum": 1 }
|
|
175
|
+
},
|
|
176
|
+
"additionalProperties": false
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
"additionalProperties": false
|
|
180
|
+
},
|
|
181
|
+
"validation": {
|
|
182
|
+
"type": "object",
|
|
183
|
+
"required": ["checks"],
|
|
184
|
+
"properties": {
|
|
185
|
+
"checks": { "type": "array", "items": { "type": "string" } },
|
|
186
|
+
"known_risks": { "type": "array", "items": { "type": "string" } }
|
|
187
|
+
},
|
|
188
|
+
"additionalProperties": false
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
"additionalProperties": false,
|
|
192
|
+
"$defs": {
|
|
193
|
+
"sourceAsset": {
|
|
194
|
+
"type": "object",
|
|
195
|
+
"required": ["id", "type", "path"],
|
|
196
|
+
"properties": {
|
|
197
|
+
"id": { "type": "string" },
|
|
198
|
+
"type": { "enum": ["video", "image", "audio", "font", "json", "html"] },
|
|
199
|
+
"path": { "type": "string" },
|
|
200
|
+
"width": { "type": "integer", "minimum": 0 },
|
|
201
|
+
"height": { "type": "integer", "minimum": 0 },
|
|
202
|
+
"duration_seconds": { "type": "number", "minimum": 0 },
|
|
203
|
+
"role": { "type": "string" }
|
|
204
|
+
},
|
|
205
|
+
"additionalProperties": false
|
|
206
|
+
},
|
|
207
|
+
"geometry": {
|
|
208
|
+
"type": "object",
|
|
209
|
+
"required": ["x", "y", "width", "height"],
|
|
210
|
+
"properties": {
|
|
211
|
+
"x": { "type": "number" },
|
|
212
|
+
"y": { "type": "number" },
|
|
213
|
+
"width": { "type": "number", "exclusiveMinimum": 0 },
|
|
214
|
+
"height": { "type": "number", "exclusiveMinimum": 0 },
|
|
215
|
+
"unit": { "const": "percent" }
|
|
216
|
+
},
|
|
217
|
+
"additionalProperties": false
|
|
218
|
+
},
|
|
219
|
+
"safeAreas": {
|
|
220
|
+
"type": "object",
|
|
221
|
+
"properties": {
|
|
222
|
+
"top_percent": { "type": "number", "minimum": 0 },
|
|
223
|
+
"right_percent": { "type": "number", "minimum": 0 },
|
|
224
|
+
"bottom_percent": { "type": "number", "minimum": 0 },
|
|
225
|
+
"left_percent": { "type": "number", "minimum": 0 },
|
|
226
|
+
"notes": { "type": "array", "items": { "type": "string" } }
|
|
227
|
+
},
|
|
228
|
+
"additionalProperties": false
|
|
229
|
+
},
|
|
230
|
+
"textStyle": {
|
|
231
|
+
"type": "object",
|
|
232
|
+
"properties": {
|
|
233
|
+
"font_family": { "type": "string" },
|
|
234
|
+
"font_weight": { "type": "integer" },
|
|
235
|
+
"font_size_px": { "type": "number" },
|
|
236
|
+
"line_height": { "type": "number" },
|
|
237
|
+
"color": { "type": "string" },
|
|
238
|
+
"background": { "type": "string" },
|
|
239
|
+
"background_style": { "enum": ["plain", "outline", "radial_halo", "highlight_solid", "highlight_translucent", "panel"] },
|
|
240
|
+
"text_align": { "enum": ["left", "center", "right"] },
|
|
241
|
+
"max_lines": { "type": "integer", "minimum": 1 }
|
|
242
|
+
},
|
|
243
|
+
"additionalProperties": false
|
|
244
|
+
},
|
|
245
|
+
"layer": {
|
|
246
|
+
"type": "object",
|
|
247
|
+
"required": ["id", "kind", "start", "duration", "track", "z", "mode", "source_of_truth", "geometry", "viral_alignment"],
|
|
248
|
+
"properties": {
|
|
249
|
+
"id": { "type": "string" },
|
|
250
|
+
"kind": { "enum": ["video", "image", "audio", "caption", "html", "shape", "effect"] },
|
|
251
|
+
"start": { "type": "number", "minimum": 0 },
|
|
252
|
+
"duration": { "type": "number", "exclusiveMinimum": 0 },
|
|
253
|
+
"track": { "type": "integer", "minimum": 0 },
|
|
254
|
+
"z": { "type": "integer" },
|
|
255
|
+
"mode": { "enum": ["both", "editor", "publish"] },
|
|
256
|
+
"source_of_truth": { "enum": ["source_media", "deterministic_html", "generated_asset", "user_asset", "computed_effect"] },
|
|
257
|
+
"geometry": { "$ref": "#/$defs/geometry" },
|
|
258
|
+
"media": {
|
|
259
|
+
"type": "object",
|
|
260
|
+
"properties": {
|
|
261
|
+
"src": { "type": "string" },
|
|
262
|
+
"asset_id": { "type": "string" },
|
|
263
|
+
"media_start": { "type": "number", "minimum": 0 },
|
|
264
|
+
"media_end": { "type": "number", "minimum": 0 },
|
|
265
|
+
"fit": { "enum": ["cover", "contain", "fill", "none"] },
|
|
266
|
+
"muted": { "type": "boolean" },
|
|
267
|
+
"volume": { "type": "number", "minimum": 0 }
|
|
268
|
+
},
|
|
269
|
+
"additionalProperties": false
|
|
270
|
+
},
|
|
271
|
+
"text": {
|
|
272
|
+
"type": "object",
|
|
273
|
+
"properties": {
|
|
274
|
+
"content": { "type": "string" },
|
|
275
|
+
"style": { "$ref": "#/$defs/textStyle" }
|
|
276
|
+
},
|
|
277
|
+
"additionalProperties": false
|
|
278
|
+
},
|
|
279
|
+
"html_contract": {
|
|
280
|
+
"type": "object",
|
|
281
|
+
"properties": {
|
|
282
|
+
"description": { "type": "string" },
|
|
283
|
+
"required_classes": { "type": "array", "items": { "type": "string" } },
|
|
284
|
+
"editable_fields": { "type": "array", "items": { "type": "string" } }
|
|
285
|
+
},
|
|
286
|
+
"additionalProperties": false
|
|
287
|
+
},
|
|
288
|
+
"viral_alignment": { "type": "string" },
|
|
289
|
+
"publish_notes": { "type": "string" }
|
|
290
|
+
},
|
|
291
|
+
"additionalProperties": false
|
|
292
|
+
},
|
|
293
|
+
"lambdaMemoryEstimate": {
|
|
294
|
+
"type": "object",
|
|
295
|
+
"required": ["recommended_memory_mb", "confidence", "complexity_scores", "rationale", "risk_flags"],
|
|
296
|
+
"properties": {
|
|
297
|
+
"recommended_memory_mb": { "enum": [2048, 3072, 4096, 6144, 8192, 10240] },
|
|
298
|
+
"confidence": { "enum": ["low", "medium", "high"] },
|
|
299
|
+
"complexity_scores": { "type": "object", "additionalProperties": { "type": ["number", "integer", "string", "boolean"] } },
|
|
300
|
+
"rationale": { "type": "string" },
|
|
301
|
+
"risk_flags": { "type": "array", "items": { "type": "string" } },
|
|
302
|
+
"benchmark_override": {
|
|
303
|
+
"type": ["object", "null"],
|
|
304
|
+
"properties": {
|
|
305
|
+
"memory_mb": { "enum": [2048, 3072, 4096, 6144, 8192, 10240] },
|
|
306
|
+
"reason": { "type": "string" }
|
|
307
|
+
},
|
|
308
|
+
"additionalProperties": false
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
"additionalProperties": false
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|