venice-video-harness 2.4.0
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/CHANGELOG.md +28 -0
- package/LICENSE +21 -0
- package/README.md +598 -0
- package/dist/assembly/manifest-builder.d.ts +8 -0
- package/dist/assembly/manifest-builder.d.ts.map +1 -0
- package/dist/assembly/manifest-builder.js +196 -0
- package/dist/assembly/manifest-builder.js.map +1 -0
- package/dist/assembly/remotion-scaffold.d.ts +14 -0
- package/dist/assembly/remotion-scaffold.d.ts.map +1 -0
- package/dist/assembly/remotion-scaffold.js +292 -0
- package/dist/assembly/remotion-scaffold.js.map +1 -0
- package/dist/assembly/types.d.ts +67 -0
- package/dist/assembly/types.d.ts.map +1 -0
- package/dist/assembly/types.js +5 -0
- package/dist/assembly/types.js.map +1 -0
- package/dist/characters/describer.d.ts +32 -0
- package/dist/characters/describer.d.ts.map +1 -0
- package/dist/characters/describer.js +309 -0
- package/dist/characters/describer.js.map +1 -0
- package/dist/characters/extractor.d.ts +27 -0
- package/dist/characters/extractor.d.ts.map +1 -0
- package/dist/characters/extractor.js +274 -0
- package/dist/characters/extractor.js.map +1 -0
- package/dist/characters/reference-manager.d.ts +95 -0
- package/dist/characters/reference-manager.d.ts.map +1 -0
- package/dist/characters/reference-manager.js +346 -0
- package/dist/characters/reference-manager.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +310 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +22 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +66 -0
- package/dist/config.js.map +1 -0
- package/dist/editing/aligner.d.ts +44 -0
- package/dist/editing/aligner.d.ts.map +1 -0
- package/dist/editing/aligner.js +201 -0
- package/dist/editing/aligner.js.map +1 -0
- package/dist/editing/edl.d.ts +45 -0
- package/dist/editing/edl.d.ts.map +1 -0
- package/dist/editing/edl.js +133 -0
- package/dist/editing/edl.js.map +1 -0
- package/dist/editing/overlays.d.ts +97 -0
- package/dist/editing/overlays.d.ts.map +1 -0
- package/dist/editing/overlays.js +41 -0
- package/dist/editing/overlays.js.map +1 -0
- package/dist/editing/packer.d.ts +52 -0
- package/dist/editing/packer.d.ts.map +1 -0
- package/dist/editing/packer.js +170 -0
- package/dist/editing/packer.js.map +1 -0
- package/dist/editing/providers/whisper-cpp.d.ts +32 -0
- package/dist/editing/providers/whisper-cpp.d.ts.map +1 -0
- package/dist/editing/providers/whisper-cpp.js +239 -0
- package/dist/editing/providers/whisper-cpp.js.map +1 -0
- package/dist/editing/render.d.ts +36 -0
- package/dist/editing/render.d.ts.map +1 -0
- package/dist/editing/render.js +227 -0
- package/dist/editing/render.js.map +1 -0
- package/dist/editing/self-eval.d.ts +48 -0
- package/dist/editing/self-eval.d.ts.map +1 -0
- package/dist/editing/self-eval.js +293 -0
- package/dist/editing/self-eval.js.map +1 -0
- package/dist/editing/silence.d.ts +76 -0
- package/dist/editing/silence.d.ts.map +1 -0
- package/dist/editing/silence.js +189 -0
- package/dist/editing/silence.js.map +1 -0
- package/dist/editing/types.d.ts +178 -0
- package/dist/editing/types.d.ts.map +1 -0
- package/dist/editing/types.js +13 -0
- package/dist/editing/types.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/interactive.d.ts +12 -0
- package/dist/interactive.d.ts.map +1 -0
- package/dist/interactive.js +78 -0
- package/dist/interactive.js.map +1 -0
- package/dist/mini-drama/assembler.d.ts +61 -0
- package/dist/mini-drama/assembler.d.ts.map +1 -0
- package/dist/mini-drama/assembler.js +466 -0
- package/dist/mini-drama/assembler.js.map +1 -0
- package/dist/mini-drama/audio-mix.d.ts +65 -0
- package/dist/mini-drama/audio-mix.d.ts.map +1 -0
- package/dist/mini-drama/audio-mix.js +118 -0
- package/dist/mini-drama/audio-mix.js.map +1 -0
- package/dist/mini-drama/cli.d.ts +3 -0
- package/dist/mini-drama/cli.d.ts.map +1 -0
- package/dist/mini-drama/cli.js +2869 -0
- package/dist/mini-drama/cli.js.map +1 -0
- package/dist/mini-drama/fcpxml-export.d.ts +2 -0
- package/dist/mini-drama/fcpxml-export.d.ts.map +1 -0
- package/dist/mini-drama/fcpxml-export.js +5 -0
- package/dist/mini-drama/fcpxml-export.js.map +1 -0
- package/dist/mini-drama/generation-planner.d.ts +24 -0
- package/dist/mini-drama/generation-planner.d.ts.map +1 -0
- package/dist/mini-drama/generation-planner.js +304 -0
- package/dist/mini-drama/generation-planner.js.map +1 -0
- package/dist/mini-drama/location-generator.d.ts +23 -0
- package/dist/mini-drama/location-generator.d.ts.map +1 -0
- package/dist/mini-drama/location-generator.js +144 -0
- package/dist/mini-drama/location-generator.js.map +1 -0
- package/dist/mini-drama/music-cues.d.ts +96 -0
- package/dist/mini-drama/music-cues.d.ts.map +1 -0
- package/dist/mini-drama/music-cues.js +332 -0
- package/dist/mini-drama/music-cues.js.map +1 -0
- package/dist/mini-drama/panel-fixer.d.ts +12 -0
- package/dist/mini-drama/panel-fixer.d.ts.map +1 -0
- package/dist/mini-drama/panel-fixer.js +319 -0
- package/dist/mini-drama/panel-fixer.js.map +1 -0
- package/dist/mini-drama/prompt-builder.d.ts +149 -0
- package/dist/mini-drama/prompt-builder.d.ts.map +1 -0
- package/dist/mini-drama/prompt-builder.js +722 -0
- package/dist/mini-drama/prompt-builder.js.map +1 -0
- package/dist/mini-drama/reference-slots.d.ts +31 -0
- package/dist/mini-drama/reference-slots.d.ts.map +1 -0
- package/dist/mini-drama/reference-slots.js +161 -0
- package/dist/mini-drama/reference-slots.js.map +1 -0
- package/dist/mini-drama/shot-paths.d.ts +77 -0
- package/dist/mini-drama/shot-paths.d.ts.map +1 -0
- package/dist/mini-drama/shot-paths.js +101 -0
- package/dist/mini-drama/shot-paths.js.map +1 -0
- package/dist/mini-drama/storyboard-reference-generator.d.ts +47 -0
- package/dist/mini-drama/storyboard-reference-generator.d.ts.map +1 -0
- package/dist/mini-drama/storyboard-reference-generator.js +293 -0
- package/dist/mini-drama/storyboard-reference-generator.js.map +1 -0
- package/dist/mini-drama/subtitle-generator.d.ts +12 -0
- package/dist/mini-drama/subtitle-generator.d.ts.map +1 -0
- package/dist/mini-drama/subtitle-generator.js +139 -0
- package/dist/mini-drama/subtitle-generator.js.map +1 -0
- package/dist/mini-drama/timeline-export/davinci-fcpxml.d.ts +3 -0
- package/dist/mini-drama/timeline-export/davinci-fcpxml.d.ts.map +1 -0
- package/dist/mini-drama/timeline-export/davinci-fcpxml.js +150 -0
- package/dist/mini-drama/timeline-export/davinci-fcpxml.js.map +1 -0
- package/dist/mini-drama/timeline-export/fcpxml.d.ts +11 -0
- package/dist/mini-drama/timeline-export/fcpxml.d.ts.map +1 -0
- package/dist/mini-drama/timeline-export/fcpxml.js +140 -0
- package/dist/mini-drama/timeline-export/fcpxml.js.map +1 -0
- package/dist/mini-drama/timeline-export/index.d.ts +13 -0
- package/dist/mini-drama/timeline-export/index.d.ts.map +1 -0
- package/dist/mini-drama/timeline-export/index.js +26 -0
- package/dist/mini-drama/timeline-export/index.js.map +1 -0
- package/dist/mini-drama/timeline-export/premiere-xmeml.d.ts +3 -0
- package/dist/mini-drama/timeline-export/premiere-xmeml.d.ts.map +1 -0
- package/dist/mini-drama/timeline-export/premiere-xmeml.js +211 -0
- package/dist/mini-drama/timeline-export/premiere-xmeml.js.map +1 -0
- package/dist/mini-drama/timeline-export/probe.d.ts +53 -0
- package/dist/mini-drama/timeline-export/probe.d.ts.map +1 -0
- package/dist/mini-drama/timeline-export/probe.js +89 -0
- package/dist/mini-drama/timeline-export/probe.js.map +1 -0
- package/dist/mini-drama/timeline-export/types.d.ts +57 -0
- package/dist/mini-drama/timeline-export/types.d.ts.map +1 -0
- package/dist/mini-drama/timeline-export/types.js +14 -0
- package/dist/mini-drama/timeline-export/types.js.map +1 -0
- package/dist/mini-drama/video-generator.d.ts +22 -0
- package/dist/mini-drama/video-generator.d.ts.map +1 -0
- package/dist/mini-drama/video-generator.js +1305 -0
- package/dist/mini-drama/video-generator.js.map +1 -0
- package/dist/mini-drama/voice-reference.d.ts +42 -0
- package/dist/mini-drama/voice-reference.d.ts.map +1 -0
- package/dist/mini-drama/voice-reference.js +170 -0
- package/dist/mini-drama/voice-reference.js.map +1 -0
- package/dist/output/html-renderer.d.ts +2 -0
- package/dist/output/html-renderer.d.ts.map +1 -0
- package/dist/output/html-renderer.js +37 -0
- package/dist/output/html-renderer.js.map +1 -0
- package/dist/parsers/fountain-parser.d.ts +34 -0
- package/dist/parsers/fountain-parser.d.ts.map +1 -0
- package/dist/parsers/fountain-parser.js +71 -0
- package/dist/parsers/fountain-parser.js.map +1 -0
- package/dist/parsers/pdf-parser.d.ts +24 -0
- package/dist/parsers/pdf-parser.d.ts.map +1 -0
- package/dist/parsers/pdf-parser.js +237 -0
- package/dist/parsers/pdf-parser.js.map +1 -0
- package/dist/parsers/scene-extractor.d.ts +41 -0
- package/dist/parsers/scene-extractor.d.ts.map +1 -0
- package/dist/parsers/scene-extractor.js +400 -0
- package/dist/parsers/scene-extractor.js.map +1 -0
- package/dist/series/manager.d.ts +64 -0
- package/dist/series/manager.d.ts.map +1 -0
- package/dist/series/manager.js +282 -0
- package/dist/series/manager.js.map +1 -0
- package/dist/series/types.d.ts +641 -0
- package/dist/series/types.d.ts.map +1 -0
- package/dist/series/types.js +304 -0
- package/dist/series/types.js.map +1 -0
- package/dist/storyboard/assembler.d.ts +134 -0
- package/dist/storyboard/assembler.d.ts.map +1 -0
- package/dist/storyboard/assembler.js +319 -0
- package/dist/storyboard/assembler.js.map +1 -0
- package/dist/storyboard/prompt-builder.d.ts +113 -0
- package/dist/storyboard/prompt-builder.d.ts.map +1 -0
- package/dist/storyboard/prompt-builder.js +578 -0
- package/dist/storyboard/prompt-builder.js.map +1 -0
- package/dist/storyboard/shot-planner.d.ts +34 -0
- package/dist/storyboard/shot-planner.d.ts.map +1 -0
- package/dist/storyboard/shot-planner.js +446 -0
- package/dist/storyboard/shot-planner.js.map +1 -0
- package/dist/user-config.d.ts +15 -0
- package/dist/user-config.d.ts.map +1 -0
- package/dist/user-config.js +103 -0
- package/dist/user-config.js.map +1 -0
- package/dist/venice/audio-preflight.d.ts +80 -0
- package/dist/venice/audio-preflight.d.ts.map +1 -0
- package/dist/venice/audio-preflight.js +142 -0
- package/dist/venice/audio-preflight.js.map +1 -0
- package/dist/venice/audio.d.ts +88 -0
- package/dist/venice/audio.d.ts.map +1 -0
- package/dist/venice/audio.js +234 -0
- package/dist/venice/audio.js.map +1 -0
- package/dist/venice/client.d.ts +86 -0
- package/dist/venice/client.d.ts.map +1 -0
- package/dist/venice/client.js +375 -0
- package/dist/venice/client.js.map +1 -0
- package/dist/venice/edit.d.ts +57 -0
- package/dist/venice/edit.d.ts.map +1 -0
- package/dist/venice/edit.js +100 -0
- package/dist/venice/edit.js.map +1 -0
- package/dist/venice/generate.d.ts +47 -0
- package/dist/venice/generate.d.ts.map +1 -0
- package/dist/venice/generate.js +150 -0
- package/dist/venice/generate.js.map +1 -0
- package/dist/venice/image-bytes.d.ts +26 -0
- package/dist/venice/image-bytes.d.ts.map +1 -0
- package/dist/venice/image-bytes.js +101 -0
- package/dist/venice/image-bytes.js.map +1 -0
- package/dist/venice/models.d.ts +143 -0
- package/dist/venice/models.d.ts.map +1 -0
- package/dist/venice/models.js +984 -0
- package/dist/venice/models.js.map +1 -0
- package/dist/venice/multi-edit.d.ts +40 -0
- package/dist/venice/multi-edit.d.ts.map +1 -0
- package/dist/venice/multi-edit.js +97 -0
- package/dist/venice/multi-edit.js.map +1 -0
- package/dist/venice/provenance.d.ts +66 -0
- package/dist/venice/provenance.d.ts.map +1 -0
- package/dist/venice/provenance.js +151 -0
- package/dist/venice/provenance.js.map +1 -0
- package/dist/venice/recipe.d.ts +69 -0
- package/dist/venice/recipe.d.ts.map +1 -0
- package/dist/venice/recipe.js +103 -0
- package/dist/venice/recipe.js.map +1 -0
- package/dist/venice/rejection.d.ts +63 -0
- package/dist/venice/rejection.d.ts.map +1 -0
- package/dist/venice/rejection.js +111 -0
- package/dist/venice/rejection.js.map +1 -0
- package/dist/venice/seedance-preflight.d.ts +38 -0
- package/dist/venice/seedance-preflight.d.ts.map +1 -0
- package/dist/venice/seedance-preflight.js +29 -0
- package/dist/venice/seedance-preflight.js.map +1 -0
- package/dist/venice/types.d.ts +212 -0
- package/dist/venice/types.d.ts.map +1 -0
- package/dist/venice/types.js +9 -0
- package/dist/venice/types.js.map +1 -0
- package/dist/venice/video.d.ts +77 -0
- package/dist/venice/video.d.ts.map +1 -0
- package/dist/venice/video.js +163 -0
- package/dist/venice/video.js.map +1 -0
- package/dist/venice/voices.d.ts +40 -0
- package/dist/venice/voices.d.ts.map +1 -0
- package/dist/venice/voices.js +194 -0
- package/dist/venice/voices.js.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Prompt Builder -- converts a Shot + Scene + aesthetic profile into a
|
|
3
|
+
// structured image-generation prompt with character face references.
|
|
4
|
+
//
|
|
5
|
+
// The output is a PromptResult containing the final text prompt, collected
|
|
6
|
+
// reference images, a negative prompt, and an optional seed.
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// ---- Constants ------------------------------------------------------------
|
|
9
|
+
const DEFAULT_NEGATIVE_PROMPT = "deformed, blurry, bad anatomy, bad hands, extra fingers, mutation, " +
|
|
10
|
+
"poorly drawn face, watermark, text, signature";
|
|
11
|
+
// ---- Time-of-day to lighting mapping --------------------------------------
|
|
12
|
+
const LIGHTING_BY_TIME = {
|
|
13
|
+
day: "bright daylight, hard shadows",
|
|
14
|
+
night: "moonlight and practical lighting, deep shadows",
|
|
15
|
+
morning: "soft golden-hour light, long shadows",
|
|
16
|
+
dawn: "cool pre-dawn blue light fading to warm horizon glow",
|
|
17
|
+
dusk: "warm orange dusk light, long purple shadows",
|
|
18
|
+
evening: "warm tungsten interior light, window glow",
|
|
19
|
+
sunset: "rich golden-hour backlight, lens flare",
|
|
20
|
+
noon: "harsh overhead sun, minimal shadows",
|
|
21
|
+
afternoon: "warm angled sunlight, moderate shadows",
|
|
22
|
+
};
|
|
23
|
+
// ---- Interior/Exterior lighting hints -------------------------------------
|
|
24
|
+
const LIGHTING_BY_LOCATION_TYPE = {
|
|
25
|
+
INT: "interior practical lighting, motivated sources",
|
|
26
|
+
EXT: "natural ambient light",
|
|
27
|
+
"INT/EXT": "mixed interior and exterior light, window spill",
|
|
28
|
+
"EXT/INT": "exterior light filtering into interior",
|
|
29
|
+
};
|
|
30
|
+
// ---- Mood to lighting modifier --------------------------------------------
|
|
31
|
+
const LIGHTING_BY_MOOD = {
|
|
32
|
+
tense: "high contrast, chiaroscuro shadows",
|
|
33
|
+
romantic: "soft diffused light, warm tones, bokeh",
|
|
34
|
+
chaotic: "harsh strobing light, mixed color temperatures",
|
|
35
|
+
melancholy: "flat overcast light, desaturated",
|
|
36
|
+
suspenseful: "underexposed, rim lighting, silhouettes",
|
|
37
|
+
warm: "bright even lighting, warm color temperature",
|
|
38
|
+
mysterious: "low-key lighting, fog diffusion",
|
|
39
|
+
violent: "harsh directional light, deep red accents",
|
|
40
|
+
quiet: "soft natural light, pastel tones",
|
|
41
|
+
dark: "deep shadows, minimal fill, noir lighting",
|
|
42
|
+
bright: "vivid saturated lighting, high key",
|
|
43
|
+
};
|
|
44
|
+
// ---- Helpers --------------------------------------------------------------
|
|
45
|
+
/**
|
|
46
|
+
* Extract the INT/EXT prefix from a scene heading.
|
|
47
|
+
*/
|
|
48
|
+
function extractIntExt(heading) {
|
|
49
|
+
const upper = heading.toUpperCase().trim();
|
|
50
|
+
if (upper.startsWith("INT./EXT.") || upper.startsWith("INT/EXT"))
|
|
51
|
+
return "INT/EXT";
|
|
52
|
+
if (upper.startsWith("EXT./INT.") || upper.startsWith("EXT/INT"))
|
|
53
|
+
return "EXT/INT";
|
|
54
|
+
if (upper.startsWith("I/E."))
|
|
55
|
+
return "INT/EXT";
|
|
56
|
+
if (upper.startsWith("INT."))
|
|
57
|
+
return "INT";
|
|
58
|
+
if (upper.startsWith("EXT."))
|
|
59
|
+
return "EXT";
|
|
60
|
+
return "INT"; // default assumption
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Infer a lighting description from the scene's time of day, location type,
|
|
64
|
+
* and mood.
|
|
65
|
+
*/
|
|
66
|
+
function inferLighting(scene) {
|
|
67
|
+
const parts = [];
|
|
68
|
+
// Time of day
|
|
69
|
+
const timeLower = scene.timeOfDay.toLowerCase();
|
|
70
|
+
for (const [key, value] of Object.entries(LIGHTING_BY_TIME)) {
|
|
71
|
+
if (timeLower.includes(key)) {
|
|
72
|
+
parts.push(value);
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Interior / exterior
|
|
77
|
+
const intExt = extractIntExt(scene.heading);
|
|
78
|
+
const locationType = LIGHTING_BY_LOCATION_TYPE[intExt];
|
|
79
|
+
if (locationType) {
|
|
80
|
+
parts.push(locationType);
|
|
81
|
+
}
|
|
82
|
+
// Mood
|
|
83
|
+
const moodLower = scene.mood.toLowerCase();
|
|
84
|
+
for (const [key, value] of Object.entries(LIGHTING_BY_MOOD)) {
|
|
85
|
+
if (moodLower.includes(key)) {
|
|
86
|
+
parts.push(value);
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return parts.length > 0 ? parts.join(", ") : "natural lighting";
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Expand the shot setting with location context from the scene action.
|
|
94
|
+
*/
|
|
95
|
+
function expandLocationDescription(scene) {
|
|
96
|
+
// Use the first action line as a location description supplement.
|
|
97
|
+
if (scene.action.length > 0) {
|
|
98
|
+
const firstLine = scene.action[0].trim();
|
|
99
|
+
if (firstLine.length > 10) {
|
|
100
|
+
return `${scene.heading} -- ${firstLine}`;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return scene.heading;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Build the wardrobe string for a character in a specific scene.
|
|
107
|
+
*
|
|
108
|
+
* Checks for a per-scene override first, then falls back to the default
|
|
109
|
+
* wardrobe from the CharacterDescription.
|
|
110
|
+
*/
|
|
111
|
+
function getWardrobe(characterName, sceneNumber, descriptions) {
|
|
112
|
+
const desc = descriptions.get(characterName.toUpperCase());
|
|
113
|
+
if (!desc)
|
|
114
|
+
return "contextually appropriate attire";
|
|
115
|
+
const wbs = desc.wardrobeByScene;
|
|
116
|
+
const sceneWardrobe = wbs instanceof Map
|
|
117
|
+
? wbs.get(sceneNumber)
|
|
118
|
+
: (wbs && typeof wbs === "object" ? wbs[String(sceneNumber)] : undefined);
|
|
119
|
+
if (sceneWardrobe)
|
|
120
|
+
return sceneWardrobe;
|
|
121
|
+
return desc.wardrobe !== "unspecified"
|
|
122
|
+
? desc.wardrobe
|
|
123
|
+
: "contextually appropriate attire";
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Build a full character visual string from a CharacterDescription.
|
|
127
|
+
*
|
|
128
|
+
* Uses the pre-synthesized `fullDescription` from the describer module,
|
|
129
|
+
* which already contains age, build, hair, eyes, and distinguishing
|
|
130
|
+
* features in prompt-ready format.
|
|
131
|
+
*/
|
|
132
|
+
function getFullCharacterDescription(characterName, descriptions) {
|
|
133
|
+
const desc = descriptions.get(characterName.toUpperCase());
|
|
134
|
+
if (!desc)
|
|
135
|
+
return characterName;
|
|
136
|
+
// The fullDescription is the exhaustive, prompt-ready paragraph.
|
|
137
|
+
return desc.fullDescription || desc.shortDescription || characterName;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Infer a facial expression from the shot's action and dialogue context.
|
|
141
|
+
*/
|
|
142
|
+
function inferExpression(shot) {
|
|
143
|
+
const context = (shot.action + " " + (shot.dialogue ?? "")).toLowerCase();
|
|
144
|
+
if (/laugh|smile|grin|joy|happy|elat/.test(context))
|
|
145
|
+
return "smiling, joyful";
|
|
146
|
+
if (/cry|tear|weep|sob|grief|mourn/.test(context))
|
|
147
|
+
return "tearful, grief-stricken";
|
|
148
|
+
if (/anger|rage|fury|furious|yell|scream/.test(context))
|
|
149
|
+
return "angry, intense";
|
|
150
|
+
if (/fear|terror|scared|frighten|horror/.test(context))
|
|
151
|
+
return "fearful, wide-eyed";
|
|
152
|
+
if (/shock|stun|surprise|gasp/.test(context))
|
|
153
|
+
return "shocked, mouth slightly open";
|
|
154
|
+
if (/think|ponder|consider|contempl/.test(context))
|
|
155
|
+
return "thoughtful, contemplative";
|
|
156
|
+
if (/determin|resolv|focus|steely/.test(context))
|
|
157
|
+
return "determined, focused";
|
|
158
|
+
if (/love|tender|affection|gentle|soft/.test(context))
|
|
159
|
+
return "tender, warm";
|
|
160
|
+
if (/suspic|distrust|doubt|wary/.test(context))
|
|
161
|
+
return "suspicious, narrowed eyes";
|
|
162
|
+
if (/confus|bewilder|perplex/.test(context))
|
|
163
|
+
return "confused, furrowed brow";
|
|
164
|
+
return "neutral, composed";
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Convert a kebab-case shot type into a human-readable label.
|
|
168
|
+
*/
|
|
169
|
+
function formatShotType(type) {
|
|
170
|
+
return type
|
|
171
|
+
.split("-")
|
|
172
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
173
|
+
.join(" ");
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Convert a kebab-case movement into a human-readable description.
|
|
177
|
+
*/
|
|
178
|
+
function formatMovement(movement) {
|
|
179
|
+
const descriptions = {
|
|
180
|
+
static: "static camera",
|
|
181
|
+
"pan-left": "panning left",
|
|
182
|
+
"pan-right": "panning right",
|
|
183
|
+
"tilt-up": "tilting up",
|
|
184
|
+
"tilt-down": "tilting down",
|
|
185
|
+
"dolly-in": "dolly pushing in",
|
|
186
|
+
"dolly-out": "dolly pulling out",
|
|
187
|
+
tracking: "tracking shot",
|
|
188
|
+
crane: "crane movement",
|
|
189
|
+
handheld: "handheld camera",
|
|
190
|
+
"rack-focus": "rack focus",
|
|
191
|
+
};
|
|
192
|
+
return descriptions[movement] ?? movement;
|
|
193
|
+
}
|
|
194
|
+
// ---- Main builder ---------------------------------------------------------
|
|
195
|
+
/**
|
|
196
|
+
* Build a structured image-generation prompt from a shot, its parent scene,
|
|
197
|
+
* an aesthetic profile, and character data.
|
|
198
|
+
*
|
|
199
|
+
* The prompt follows a structured template with tagged sections so the
|
|
200
|
+
* image model can attend to each aspect independently:
|
|
201
|
+
*
|
|
202
|
+
* ```
|
|
203
|
+
* [AESTHETIC] ...
|
|
204
|
+
* [SHOT] ...
|
|
205
|
+
* [SETTING] ...
|
|
206
|
+
* [CHARACTERS] ...
|
|
207
|
+
* [ACTION] ...
|
|
208
|
+
* [MOOD] ...
|
|
209
|
+
* [LIGHTING] ...
|
|
210
|
+
* ```
|
|
211
|
+
*
|
|
212
|
+
* Reference images are collected from character locks (front-facing angles)
|
|
213
|
+
* and returned alongside the prompt for multi-reference generation.
|
|
214
|
+
*/
|
|
215
|
+
export function buildPrompt(shot, scene, aesthetic, characterDescriptions, characterLocks) {
|
|
216
|
+
const lines = [];
|
|
217
|
+
// ---- [AESTHETIC] --------------------------------------------------------
|
|
218
|
+
lines.push(`[AESTHETIC] ${aesthetic.style}, ${aesthetic.palette}, ` +
|
|
219
|
+
`${aesthetic.lighting}, ${aesthetic.lensCharacteristics}, ` +
|
|
220
|
+
`shot on ${aesthetic.filmStock}`);
|
|
221
|
+
lines.push("");
|
|
222
|
+
// ---- [SHOT] -------------------------------------------------------------
|
|
223
|
+
lines.push(`[SHOT] ${formatShotType(shot.type)} shot, ${shot.angle}, ` +
|
|
224
|
+
`${shot.lens}, ${formatMovement(shot.movement)}`);
|
|
225
|
+
lines.push("");
|
|
226
|
+
// ---- [SETTING] ----------------------------------------------------------
|
|
227
|
+
lines.push(`[SETTING] ${expandLocationDescription(scene)}`);
|
|
228
|
+
lines.push("");
|
|
229
|
+
// ---- [CHARACTERS] -------------------------------------------------------
|
|
230
|
+
const referenceImages = [];
|
|
231
|
+
let seed;
|
|
232
|
+
if (shot.characters.length > 0) {
|
|
233
|
+
lines.push("[CHARACTERS]");
|
|
234
|
+
for (let i = 0; i < shot.characters.length; i++) {
|
|
235
|
+
const charName = shot.characters[i];
|
|
236
|
+
const fullDesc = getFullCharacterDescription(charName, characterDescriptions);
|
|
237
|
+
const wardrobe = getWardrobe(charName, scene.number, characterDescriptions);
|
|
238
|
+
const expression = inferExpression(shot);
|
|
239
|
+
const isFocus = charName === shot.focusCharacter;
|
|
240
|
+
const position = isFocus ? "center frame" : i === 0 ? "frame left" : "frame right";
|
|
241
|
+
const facing = isFocus ? "facing camera" : "three-quarter angle";
|
|
242
|
+
lines.push(`- ${charName} (${position}, ${facing}): ${fullDesc}, ` +
|
|
243
|
+
`wearing ${wardrobe}, expression: ${expression}`);
|
|
244
|
+
// Collect reference image from character lock.
|
|
245
|
+
// CharacterLock stores base64 strings directly in referenceImages.front,
|
|
246
|
+
// .threeQuarter, .profile, and .fullBody.
|
|
247
|
+
const lock = characterLocks.get(charName.toUpperCase());
|
|
248
|
+
if (lock) {
|
|
249
|
+
// Prefer front face; fall back to three-quarter for variety
|
|
250
|
+
const faceRef = lock.referenceImages.front || lock.referenceImages.threeQuarter;
|
|
251
|
+
if (faceRef) {
|
|
252
|
+
referenceImages.push({
|
|
253
|
+
base64: faceRef,
|
|
254
|
+
role: `face reference for ${charName} - preserve exact facial identity`,
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
// Capture seed from the first lock that has one
|
|
258
|
+
if (seed === undefined && lock.seed !== undefined) {
|
|
259
|
+
seed = lock.seed;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
lines.push("");
|
|
264
|
+
}
|
|
265
|
+
// ---- [ACTION] -----------------------------------------------------------
|
|
266
|
+
lines.push(`[ACTION] ${shot.action}`);
|
|
267
|
+
if (shot.dialogue) {
|
|
268
|
+
lines.push(`[DIALOGUE] "${shot.dialogue}"`);
|
|
269
|
+
}
|
|
270
|
+
lines.push("");
|
|
271
|
+
// ---- [MOOD] -------------------------------------------------------------
|
|
272
|
+
lines.push(`[MOOD] ${scene.mood || "neutral"}`);
|
|
273
|
+
lines.push("");
|
|
274
|
+
// ---- [LIGHTING] ---------------------------------------------------------
|
|
275
|
+
lines.push(`[LIGHTING] ${inferLighting(scene)}`);
|
|
276
|
+
lines.push("");
|
|
277
|
+
// ---- Reference image annotations ---------------------------------------
|
|
278
|
+
if (referenceImages.length > 0) {
|
|
279
|
+
for (let i = 0; i < referenceImages.length; i++) {
|
|
280
|
+
lines.push(`Image ${i + 1}: ${referenceImages[i].role}`);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
const prompt = lines.join("\n").trim();
|
|
284
|
+
return {
|
|
285
|
+
prompt,
|
|
286
|
+
referenceImages,
|
|
287
|
+
negativePrompt: DEFAULT_NEGATIVE_PROMPT,
|
|
288
|
+
seed,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
// ---- Video prompt helpers -------------------------------------------------
|
|
292
|
+
/**
|
|
293
|
+
* Map shot movement + type + angle into a natural-language camera motion
|
|
294
|
+
* instruction suitable for video generation models.
|
|
295
|
+
*/
|
|
296
|
+
function describeVideoMovement(shot) {
|
|
297
|
+
const speed = inferMovementSpeed(shot);
|
|
298
|
+
const descriptions = {
|
|
299
|
+
static: "Camera holds static",
|
|
300
|
+
"pan-left": `Camera pans ${speed} to the left`,
|
|
301
|
+
"pan-right": `Camera pans ${speed} to the right`,
|
|
302
|
+
"tilt-up": `Camera tilts ${speed} upward`,
|
|
303
|
+
"tilt-down": `Camera tilts ${speed} downward`,
|
|
304
|
+
"dolly-in": `Camera ${speed} pushes forward`,
|
|
305
|
+
"dolly-out": `Camera ${speed} pulls back`,
|
|
306
|
+
tracking: `Camera tracks ${speed} alongside the subject`,
|
|
307
|
+
crane: `Camera cranes ${speed} upward, revealing the scene`,
|
|
308
|
+
handheld: `Handheld camera with ${speed === "slow" ? "subtle" : "energetic"} movement`,
|
|
309
|
+
"rack-focus": "Focus racks between foreground and background",
|
|
310
|
+
};
|
|
311
|
+
const base = descriptions[shot.movement] ?? `Camera moves ${shot.movement}`;
|
|
312
|
+
// Add framing context from shot type
|
|
313
|
+
const framingMap = {
|
|
314
|
+
"extreme-wide": "in an extreme wide shot",
|
|
315
|
+
wide: "in a wide shot",
|
|
316
|
+
"medium-wide": "framing a medium-wide shot",
|
|
317
|
+
medium: "in a medium shot",
|
|
318
|
+
"medium-close-up": "framing a medium close-up",
|
|
319
|
+
"close-up": "into a close-up",
|
|
320
|
+
"extreme-close-up": "into an extreme close-up",
|
|
321
|
+
insert: "on a detail insert",
|
|
322
|
+
};
|
|
323
|
+
const framing = framingMap[shot.type] ?? "";
|
|
324
|
+
return `${base} ${framing}`.trim();
|
|
325
|
+
}
|
|
326
|
+
/**
|
|
327
|
+
* Infer movement speed from context -- action shots are faster, dialogue slower.
|
|
328
|
+
*/
|
|
329
|
+
function inferMovementSpeed(shot) {
|
|
330
|
+
const actionLower = shot.action.toLowerCase();
|
|
331
|
+
if (/run|chase|fight|punch|kick|crash|explod|sprint|charge|slam/.test(actionLower)) {
|
|
332
|
+
return "quickly";
|
|
333
|
+
}
|
|
334
|
+
if (/walk|step|enter|exit|sit|stand|lean|turn/.test(actionLower)) {
|
|
335
|
+
return "steadily";
|
|
336
|
+
}
|
|
337
|
+
return "slowly";
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Convert shot action text into present-tense motion verbs for video prompts.
|
|
341
|
+
*/
|
|
342
|
+
function toMotionAction(shot) {
|
|
343
|
+
let text = shot.action;
|
|
344
|
+
// Convert common past/imperative forms to present continuous
|
|
345
|
+
text = text
|
|
346
|
+
.replace(/\bruns\b/gi, "is running")
|
|
347
|
+
.replace(/\bwalks\b/gi, "is walking")
|
|
348
|
+
.replace(/\blooks\b/gi, "is looking")
|
|
349
|
+
.replace(/\bturns\b/gi, "is turning")
|
|
350
|
+
.replace(/\bsits\b/gi, "is sitting")
|
|
351
|
+
.replace(/\bstands\b/gi, "is standing")
|
|
352
|
+
.replace(/\bspeaks\b/gi, "is speaking")
|
|
353
|
+
.replace(/\bstares\b/gi, "is staring");
|
|
354
|
+
return text;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Estimate clip duration based on shot characteristics, snapped to
|
|
358
|
+
* Veo 3.1 allowed values: 4, 6, or 8 seconds.
|
|
359
|
+
*/
|
|
360
|
+
function estimateDuration(shot) {
|
|
361
|
+
let raw;
|
|
362
|
+
// Insert and reaction shots are short
|
|
363
|
+
if (shot.type === "insert" || shot.notes?.toLowerCase().includes("reaction")) {
|
|
364
|
+
raw = 4;
|
|
365
|
+
}
|
|
366
|
+
else if (shot.dialogue) {
|
|
367
|
+
// Dialogue-driven shots scale with line length
|
|
368
|
+
const words = shot.dialogue.split(/\s+/).length;
|
|
369
|
+
// ~2.5 words/second for natural speech + 1s padding
|
|
370
|
+
raw = Math.ceil(words / 2.5) + 1;
|
|
371
|
+
}
|
|
372
|
+
else if (shot.type === "extreme-wide" ||
|
|
373
|
+
shot.type === "wide" ||
|
|
374
|
+
shot.action.toLowerCase().includes("establishing")) {
|
|
375
|
+
// Establishing shots are longer
|
|
376
|
+
raw = shot.movement === "crane" ? 8 : 6;
|
|
377
|
+
}
|
|
378
|
+
else if (/run|chase|fight|punch|kick|crash|explod|sprint/.test(shot.action.toLowerCase())) {
|
|
379
|
+
// Action beats
|
|
380
|
+
raw = 4;
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
raw = 6;
|
|
384
|
+
}
|
|
385
|
+
// Snap to Veo-allowed values: 4, 6, or 8
|
|
386
|
+
if (raw <= 5)
|
|
387
|
+
return 4;
|
|
388
|
+
if (raw <= 7)
|
|
389
|
+
return 6;
|
|
390
|
+
return 8;
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Extract audio cues from scene action lines and shot data.
|
|
394
|
+
*/
|
|
395
|
+
function extractAudioNotes(shot, scene) {
|
|
396
|
+
const notes = {};
|
|
397
|
+
// Dialogue
|
|
398
|
+
if (shot.dialogue) {
|
|
399
|
+
const speaker = shot.focusCharacter || shot.characters[0] || "CHARACTER";
|
|
400
|
+
notes.dialogue = `${speaker}: "${shot.dialogue}"`;
|
|
401
|
+
}
|
|
402
|
+
// SFX -- scan shot action for sound-producing words
|
|
403
|
+
const sfxPatterns = /\b(door|slam|crash|bang|click|beep|chirp|ring|buzz|hum|static|footstep|boot|step|knock|creak|shatter|break|explosion|gunshot|engine|alarm|siren|thunder|rain|wind|drip|splash|thud|clatter|scrape|whistle|hiss)\b/gi;
|
|
404
|
+
const actionText = shot.action + " " + scene.action.join(" ");
|
|
405
|
+
const sfxMatches = [...new Set(actionText.match(sfxPatterns) || [])];
|
|
406
|
+
if (sfxMatches.length > 0) {
|
|
407
|
+
notes.sfx = sfxMatches.map((s) => s.toLowerCase()).join(", ");
|
|
408
|
+
}
|
|
409
|
+
// Ambient -- infer from location and time of day
|
|
410
|
+
const ambientParts = [];
|
|
411
|
+
const heading = scene.heading.toUpperCase();
|
|
412
|
+
if (heading.includes("EXT.")) {
|
|
413
|
+
if (scene.timeOfDay.toLowerCase().includes("night")) {
|
|
414
|
+
ambientParts.push("night crickets", "distant traffic");
|
|
415
|
+
}
|
|
416
|
+
else {
|
|
417
|
+
ambientParts.push("outdoor ambience", "wind");
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
ambientParts.push("room tone");
|
|
422
|
+
if (/office|lab|station|building/i.test(scene.location)) {
|
|
423
|
+
ambientParts.push("fluorescent hum");
|
|
424
|
+
}
|
|
425
|
+
if (/bar|club|restaurant|cafe/i.test(scene.location)) {
|
|
426
|
+
ambientParts.push("background chatter");
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
if (ambientParts.length > 0) {
|
|
430
|
+
notes.ambient = ambientParts.join(", ");
|
|
431
|
+
}
|
|
432
|
+
return notes;
|
|
433
|
+
}
|
|
434
|
+
// ---- Video constants -------------------------------------------------------
|
|
435
|
+
const DEFAULT_VIDEO_MODEL = "kling-o3-pro-image-to-video";
|
|
436
|
+
// ---- Veo camera term mapping ----------------------------------------------
|
|
437
|
+
/** Map internal movement names to Veo-friendly camera terms. */
|
|
438
|
+
const VEO_CAMERA_TERMS = {
|
|
439
|
+
static: "locked-off static shot",
|
|
440
|
+
"pan-left": "slow pan left",
|
|
441
|
+
"pan-right": "slow pan right",
|
|
442
|
+
"tilt-up": "tilt up",
|
|
443
|
+
"tilt-down": "tilt down",
|
|
444
|
+
"dolly-in": "dolly shot pushing forward",
|
|
445
|
+
"dolly-out": "dolly shot pulling back",
|
|
446
|
+
tracking: "tracking shot",
|
|
447
|
+
crane: "crane shot rising upward",
|
|
448
|
+
handheld: "handheld shot",
|
|
449
|
+
"rack-focus": "rack focus",
|
|
450
|
+
};
|
|
451
|
+
// ---- Aesthetic register extraction ----------------------------------------
|
|
452
|
+
/**
|
|
453
|
+
* Extract the relevant aesthetic register for a given scene number.
|
|
454
|
+
*
|
|
455
|
+
* The multi-register aesthetic is structured as:
|
|
456
|
+
* - PRIMARY (scenes 1-7, 10-28): Clean Dystopia
|
|
457
|
+
* - HISTORICAL FLASHBACK (scenes 8-9): Baroque Oil Painting
|
|
458
|
+
* - FINAL DAWN (scenes 29-32): Warm Analog Photography
|
|
459
|
+
* - END CARDS (scenes 33-34): white text on black
|
|
460
|
+
*
|
|
461
|
+
* Each aesthetic field may contain all registers separated by labels like
|
|
462
|
+
* "CLEAN DYSTOPIA:", "BAROQUE:", "WARM ANALOG:". This function extracts
|
|
463
|
+
* only the portion relevant to the current scene.
|
|
464
|
+
*/
|
|
465
|
+
function extractRegister(fullText, sceneNumber) {
|
|
466
|
+
// Determine which register label to look for
|
|
467
|
+
let registerLabel;
|
|
468
|
+
if (sceneNumber >= 8 && sceneNumber <= 9) {
|
|
469
|
+
registerLabel = "BAROQUE";
|
|
470
|
+
}
|
|
471
|
+
else if (sceneNumber >= 29 && sceneNumber <= 32) {
|
|
472
|
+
registerLabel = "WARM ANALOG";
|
|
473
|
+
}
|
|
474
|
+
else {
|
|
475
|
+
registerLabel = "CLEAN DYSTOPIA";
|
|
476
|
+
}
|
|
477
|
+
// Try to extract just this register's content
|
|
478
|
+
// Pattern: "LABEL: content" up to the next "LABEL:" or end
|
|
479
|
+
const registerPattern = new RegExp(`${registerLabel}:\\s*(.+?)(?=(?:CLEAN DYSTOPIA|BAROQUE|WARM ANALOG|HISTORICAL|FINAL DAWN|Scenes? \\d):|$)`, "is");
|
|
480
|
+
const match = fullText.match(registerPattern);
|
|
481
|
+
if (match?.[1]) {
|
|
482
|
+
return match[1].trim().replace(/\.\s*$/, "");
|
|
483
|
+
}
|
|
484
|
+
// If no register labels found, the aesthetic is single-register -- use as-is
|
|
485
|
+
if (!fullText.includes("CLEAN DYSTOPIA") && !fullText.includes("BAROQUE") && !fullText.includes("WARM ANALOG")) {
|
|
486
|
+
return fullText.trim();
|
|
487
|
+
}
|
|
488
|
+
// Fallback: return the full text but truncated
|
|
489
|
+
return fullText.slice(0, 200).trim();
|
|
490
|
+
}
|
|
491
|
+
// ---- Main video prompt builder --------------------------------------------
|
|
492
|
+
/**
|
|
493
|
+
* Build a video-generation prompt from a shot, its parent scene, and
|
|
494
|
+
* aesthetic data.
|
|
495
|
+
*
|
|
496
|
+
* The prompt is plain descriptive prose kept under ~150 words: camera
|
|
497
|
+
* movement, subject + action, setting, style, and audio cues. Only the
|
|
498
|
+
* aesthetic register relevant to the current scene is included.
|
|
499
|
+
*
|
|
500
|
+
* Directing principle (see .claude/agents/prompt-engineer.md and the README
|
|
501
|
+
* "Directing layer"): the prose should DIRECT the shot -- one intention
|
|
502
|
+
* expressed through camera/light/blocking/performance/sound -- rather than
|
|
503
|
+
* stack "cinematic" adjectives. Camera, angle, and movement come from the
|
|
504
|
+
* shot's authored intention, not from a generic "make it cinematic" default.
|
|
505
|
+
*
|
|
506
|
+
* The returned `video` block is API-ready for any supported video model.
|
|
507
|
+
* The model field is a default -- the generation script chooses the actual
|
|
508
|
+
* model at runtime.
|
|
509
|
+
*/
|
|
510
|
+
export function buildVideoPrompt(shot, scene, aesthetic) {
|
|
511
|
+
const duration = estimateDuration(shot);
|
|
512
|
+
const audioNotes = extractAudioNotes(shot, scene);
|
|
513
|
+
const transition = shot.transitionOut || "CUT";
|
|
514
|
+
// Build the start-frame description (ties video to the image panel)
|
|
515
|
+
const startFrame = `${formatShotType(shot.type)} shot, ${shot.angle}, ` +
|
|
516
|
+
`${expandLocationDescription(scene)}` +
|
|
517
|
+
(shot.characters.length > 0
|
|
518
|
+
? ` with ${shot.characters.join(", ")}`
|
|
519
|
+
: "");
|
|
520
|
+
// ---- Extract only the relevant aesthetic register -----------------------
|
|
521
|
+
const regStyle = extractRegister(aesthetic.style, scene.number);
|
|
522
|
+
const regPalette = extractRegister(aesthetic.palette, scene.number);
|
|
523
|
+
const regLighting = extractRegister(aesthetic.lighting, scene.number);
|
|
524
|
+
const regLens = extractRegister(aesthetic.lensCharacteristics, scene.number);
|
|
525
|
+
const regFilm = extractRegister(aesthetic.filmStock, scene.number);
|
|
526
|
+
// ---- Build prompt in plain prose (target <150 words) --------------------
|
|
527
|
+
const sentences = [];
|
|
528
|
+
// 1. Camera movement + framing
|
|
529
|
+
const cameraTerm = VEO_CAMERA_TERMS[shot.movement] ?? shot.movement;
|
|
530
|
+
const shotTypeProse = formatShotType(shot.type).toLowerCase();
|
|
531
|
+
const speed = inferMovementSpeed(shot);
|
|
532
|
+
sentences.push(`A ${speed} ${cameraTerm} frames a ${shotTypeProse} at ${shot.angle.replace(/-/g, " ")} angle.`);
|
|
533
|
+
// 2. Subject + action
|
|
534
|
+
const cleanAction = toMotionAction(shot).replace(/\.\s*$/, "");
|
|
535
|
+
if (shot.characters.length > 0) {
|
|
536
|
+
const charList = shot.characters.join(" and ");
|
|
537
|
+
sentences.push(`${charList} ${cleanAction}.`);
|
|
538
|
+
}
|
|
539
|
+
else {
|
|
540
|
+
sentences.push(cleanAction.charAt(0).toUpperCase() + cleanAction.slice(1) + ".");
|
|
541
|
+
}
|
|
542
|
+
// 3. Setting
|
|
543
|
+
const intExt = extractIntExt(scene.heading);
|
|
544
|
+
const locationDesc = scene.location || "an interior space";
|
|
545
|
+
sentences.push(`${intExt.startsWith("EXT") ? "Outdoors" : "Inside"} ${locationDesc}. ${regLighting}.`);
|
|
546
|
+
// 4. Style (register-specific, concise)
|
|
547
|
+
sentences.push(`${regStyle}. ${regFilm}.`);
|
|
548
|
+
// 5. Audio cues
|
|
549
|
+
if (audioNotes.sfx) {
|
|
550
|
+
sentences.push(`Sound of ${audioNotes.sfx}.`);
|
|
551
|
+
}
|
|
552
|
+
if (audioNotes.ambient) {
|
|
553
|
+
sentences.push(`Ambient sound of ${audioNotes.ambient}.`);
|
|
554
|
+
}
|
|
555
|
+
// Assemble and enforce word limit
|
|
556
|
+
let videoPrompt = sentences.join(" ");
|
|
557
|
+
const words = videoPrompt.split(/\s+/);
|
|
558
|
+
if (words.length > 150) {
|
|
559
|
+
videoPrompt = words.slice(0, 145).join(" ") + ".";
|
|
560
|
+
}
|
|
561
|
+
// ---- Build video config block -------------------------------------------
|
|
562
|
+
const video = {
|
|
563
|
+
model: DEFAULT_VIDEO_MODEL,
|
|
564
|
+
prompt: videoPrompt,
|
|
565
|
+
duration: `${duration}s`,
|
|
566
|
+
audio: true,
|
|
567
|
+
};
|
|
568
|
+
return {
|
|
569
|
+
videoPrompt,
|
|
570
|
+
duration,
|
|
571
|
+
cameraMovement: `${shot.movement}, ${speed}`,
|
|
572
|
+
startFrame,
|
|
573
|
+
audioNotes,
|
|
574
|
+
transition,
|
|
575
|
+
video,
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
//# sourceMappingURL=prompt-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-builder.js","sourceRoot":"","sources":["../../src/storyboard/prompt-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Scene } from "../parsers/scene-extractor.js";
|
|
2
|
+
export type ShotType = "extreme-wide" | "wide" | "medium-wide" | "medium" | "medium-close-up" | "close-up" | "extreme-close-up" | "insert";
|
|
3
|
+
export type CameraAngle = "eye-level" | "low-angle" | "high-angle" | "dutch-angle" | "birds-eye" | "worms-eye";
|
|
4
|
+
export type CameraMovement = "static" | "pan-left" | "pan-right" | "tilt-up" | "tilt-down" | "dolly-in" | "dolly-out" | "tracking" | "crane" | "handheld" | "rack-focus";
|
|
5
|
+
export interface Shot {
|
|
6
|
+
shotNumber: number;
|
|
7
|
+
type: ShotType;
|
|
8
|
+
angle: CameraAngle;
|
|
9
|
+
movement: CameraMovement;
|
|
10
|
+
lens: string;
|
|
11
|
+
characters: string[];
|
|
12
|
+
focusCharacter?: string;
|
|
13
|
+
action: string;
|
|
14
|
+
dialogue?: string;
|
|
15
|
+
transitionIn?: string;
|
|
16
|
+
transitionOut?: string;
|
|
17
|
+
notes: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Plan a sequence of camera shots for a given scene.
|
|
21
|
+
*
|
|
22
|
+
* The planner follows classical cinematographic conventions:
|
|
23
|
+
*
|
|
24
|
+
* 1. Every scene opens with an establishing shot (extreme-wide or wide).
|
|
25
|
+
* 2. Action beats get wide-to-medium coverage with dynamic camera movement.
|
|
26
|
+
* 3. Dialogue exchanges are covered with a two-shot opener followed by
|
|
27
|
+
* over-the-shoulder singles alternating between speakers.
|
|
28
|
+
* 4. Emotional moments receive close-ups or extreme close-ups.
|
|
29
|
+
* 5. Important objects mentioned in action text receive insert shots.
|
|
30
|
+
* 6. Transitions default to CUT; DISSOLVE is used for time passages and
|
|
31
|
+
* MATCH CUT where the screenplay indicates one.
|
|
32
|
+
*/
|
|
33
|
+
export declare function planShots(scene: Scene): Shot[];
|
|
34
|
+
//# sourceMappingURL=shot-planner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shot-planner.d.ts","sourceRoot":"","sources":["../../src/storyboard/shot-planner.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,KAAK,EAAgB,MAAM,+BAA+B,CAAC;AAIzE,MAAM,MAAM,QAAQ,GAChB,cAAc,GACd,MAAM,GACN,aAAa,GACb,QAAQ,GACR,iBAAiB,GACjB,UAAU,GACV,kBAAkB,GAClB,QAAQ,CAAC;AAEb,MAAM,MAAM,WAAW,GACnB,WAAW,GACX,WAAW,GACX,YAAY,GACZ,aAAa,GACb,WAAW,GACX,WAAW,CAAC;AAEhB,MAAM,MAAM,cAAc,GACtB,QAAQ,GACR,UAAU,GACV,WAAW,GACX,SAAS,GACT,WAAW,GACX,UAAU,GACV,WAAW,GACX,UAAU,GACV,OAAO,GACP,UAAU,GACV,YAAY,CAAC;AAEjB,MAAM,WAAW,IAAI;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,cAAc,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAkRD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,CAiN9C"}
|