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,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Builds a shot manifest by scanning scene directories for MP4s,
|
|
3
|
+
* running ffprobe for timing data, and reading video.json for metadata.
|
|
4
|
+
*/
|
|
5
|
+
import { readdir, readFile } from 'node:fs/promises';
|
|
6
|
+
import { join, resolve } from 'node:path';
|
|
7
|
+
import { existsSync } from 'node:fs';
|
|
8
|
+
import { execSync } from 'node:child_process';
|
|
9
|
+
const DEFAULT_FPS = 30;
|
|
10
|
+
const DEFAULT_WIDTH = 1280;
|
|
11
|
+
const DEFAULT_HEIGHT = 720;
|
|
12
|
+
/** Map screenplay transition strings to our TransitionType */
|
|
13
|
+
function parseTransition(raw) {
|
|
14
|
+
if (!raw)
|
|
15
|
+
return 'cut';
|
|
16
|
+
const t = raw.toUpperCase().trim();
|
|
17
|
+
if (t.includes('DISSOLVE'))
|
|
18
|
+
return 'dissolve';
|
|
19
|
+
if (t.includes('FADE'))
|
|
20
|
+
return 'fade';
|
|
21
|
+
if (t.includes('WIPE'))
|
|
22
|
+
return 'wipe';
|
|
23
|
+
return 'cut';
|
|
24
|
+
}
|
|
25
|
+
/** Get transition duration in frames based on type */
|
|
26
|
+
function transitionFrames(type, fps) {
|
|
27
|
+
switch (type) {
|
|
28
|
+
case 'cut': return 1;
|
|
29
|
+
case 'fade': return Math.round(fps * 0.5); // 0.5s
|
|
30
|
+
case 'dissolve': return Math.round(fps * 0.75); // 0.75s
|
|
31
|
+
case 'wipe': return Math.round(fps * 0.5);
|
|
32
|
+
default: return 1;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** Run ffprobe on an MP4 to get duration, fps, and dimensions */
|
|
36
|
+
function probeVideo(filePath) {
|
|
37
|
+
try {
|
|
38
|
+
const raw = execSync(`ffprobe -v quiet -print_format json -show_format -show_streams -select_streams v "${filePath}"`, { encoding: 'utf-8', timeout: 10000 });
|
|
39
|
+
const data = JSON.parse(raw);
|
|
40
|
+
const stream = data.streams?.[0] ?? {};
|
|
41
|
+
const format = data.format ?? {};
|
|
42
|
+
const duration = parseFloat(format.duration || stream.duration || '0');
|
|
43
|
+
// Parse fps from r_frame_rate (e.g. "24/1")
|
|
44
|
+
let fps = DEFAULT_FPS;
|
|
45
|
+
if (stream.r_frame_rate) {
|
|
46
|
+
const [num, den] = stream.r_frame_rate.split('/').map(Number);
|
|
47
|
+
if (den && den > 0)
|
|
48
|
+
fps = num / den;
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
duration,
|
|
52
|
+
fps,
|
|
53
|
+
width: stream.width || DEFAULT_WIDTH,
|
|
54
|
+
height: stream.height || DEFAULT_HEIGHT,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
console.warn(` ffprobe failed for ${filePath}, using defaults`);
|
|
59
|
+
return { duration: 8, fps: DEFAULT_FPS, width: DEFAULT_WIDTH, height: DEFAULT_HEIGHT };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/** Read video.json metadata for a shot */
|
|
63
|
+
async function readVideoJson(jsonPath) {
|
|
64
|
+
if (!existsSync(jsonPath))
|
|
65
|
+
return null;
|
|
66
|
+
try {
|
|
67
|
+
const raw = await readFile(jsonPath, 'utf-8');
|
|
68
|
+
return JSON.parse(raw);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/** Find all scene directories sorted numerically */
|
|
75
|
+
async function findSceneDirs(projectDir) {
|
|
76
|
+
const entries = await readdir(projectDir, { withFileTypes: true });
|
|
77
|
+
const sceneDirs = [];
|
|
78
|
+
for (const entry of entries) {
|
|
79
|
+
if (!entry.isDirectory())
|
|
80
|
+
continue;
|
|
81
|
+
const match = entry.name.match(/^scene-(\d+)$/);
|
|
82
|
+
if (match) {
|
|
83
|
+
sceneDirs.push({
|
|
84
|
+
dir: join(projectDir, entry.name),
|
|
85
|
+
num: parseInt(match[1], 10),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return sceneDirs.sort((a, b) => a.num - b.num);
|
|
90
|
+
}
|
|
91
|
+
/** Find all shot MP4s in a scene directory, sorted by shot number */
|
|
92
|
+
async function findShotMp4s(sceneDir) {
|
|
93
|
+
const entries = await readdir(sceneDir);
|
|
94
|
+
const shots = [];
|
|
95
|
+
for (const entry of entries) {
|
|
96
|
+
const match = entry.match(/^shot-(\d+)\.mp4$/);
|
|
97
|
+
if (match) {
|
|
98
|
+
shots.push({
|
|
99
|
+
path: join(sceneDir, entry),
|
|
100
|
+
num: parseInt(match[1], 10),
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return shots.sort((a, b) => a.num - b.num);
|
|
105
|
+
}
|
|
106
|
+
export async function buildManifest(project) {
|
|
107
|
+
const targetFps = DEFAULT_FPS;
|
|
108
|
+
const projectDir = resolve(project.outputDir);
|
|
109
|
+
console.log(`Scanning ${projectDir} for scene directories...`);
|
|
110
|
+
const sceneDirs = await findSceneDirs(projectDir);
|
|
111
|
+
if (sceneDirs.length === 0) {
|
|
112
|
+
throw new Error('No scene directories found. Run storyboard generation first.');
|
|
113
|
+
}
|
|
114
|
+
console.log(`Found ${sceneDirs.length} scene(s)`);
|
|
115
|
+
const scenes = [];
|
|
116
|
+
let totalShots = 0;
|
|
117
|
+
for (const { dir: sceneDir, num: sceneNum } of sceneDirs) {
|
|
118
|
+
const mp4s = await findShotMp4s(sceneDir);
|
|
119
|
+
if (mp4s.length === 0) {
|
|
120
|
+
console.log(` Scene ${sceneNum}: no MP4s found, skipping`);
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
console.log(` Scene ${sceneNum}: ${mp4s.length} shots`);
|
|
124
|
+
// Find the scene data from project state for heading/mood
|
|
125
|
+
const sceneData = project.scenes.find(s => s.number === sceneNum);
|
|
126
|
+
const shots = [];
|
|
127
|
+
for (const mp4 of mp4s) {
|
|
128
|
+
const probe = probeVideo(mp4.path);
|
|
129
|
+
const videoJsonPath = mp4.path.replace(/\.mp4$/, '.video.json');
|
|
130
|
+
const videoMeta = await readVideoJson(videoJsonPath);
|
|
131
|
+
const transition = parseTransition(videoMeta?.transition);
|
|
132
|
+
const durationInFrames = Math.round(probe.duration * targetFps);
|
|
133
|
+
// Build relative path for Remotion public/ dir
|
|
134
|
+
const sceneFolder = `scene-${String(sceneNum).padStart(3, '0')}`;
|
|
135
|
+
const shotFile = `shot-${String(mp4.num).padStart(3, '0')}.mp4`;
|
|
136
|
+
const relativePath = `${sceneFolder}/${shotFile}`;
|
|
137
|
+
shots.push({
|
|
138
|
+
file: relativePath,
|
|
139
|
+
absolutePath: mp4.path,
|
|
140
|
+
sceneNumber: sceneNum,
|
|
141
|
+
shotNumber: mp4.num,
|
|
142
|
+
panelId: videoMeta?.panelId || `S${sceneNum}-P${mp4.num}`,
|
|
143
|
+
durationSec: probe.duration,
|
|
144
|
+
durationInFrames,
|
|
145
|
+
fps: probe.fps,
|
|
146
|
+
width: probe.width,
|
|
147
|
+
height: probe.height,
|
|
148
|
+
transition,
|
|
149
|
+
transitionDurationInFrames: transitionFrames(transition, targetFps),
|
|
150
|
+
characters: videoMeta?.characters || [],
|
|
151
|
+
dialogue: videoMeta?.dialogue,
|
|
152
|
+
cameraMovement: videoMeta?.cameraMovement || '',
|
|
153
|
+
mood: sceneData?.mood,
|
|
154
|
+
});
|
|
155
|
+
totalShots++;
|
|
156
|
+
}
|
|
157
|
+
// Calculate scene duration (sum of shots minus transition overlaps)
|
|
158
|
+
const shotFrames = shots.reduce((sum, s) => sum + s.durationInFrames, 0);
|
|
159
|
+
// Transitions between shots (not before first shot)
|
|
160
|
+
const transitionOverlap = shots
|
|
161
|
+
.slice(1)
|
|
162
|
+
.reduce((sum, s) => sum + s.transitionDurationInFrames, 0);
|
|
163
|
+
const sceneDurationFrames = shotFrames - transitionOverlap;
|
|
164
|
+
scenes.push({
|
|
165
|
+
sceneNumber: sceneNum,
|
|
166
|
+
heading: sceneData?.heading || `Scene ${sceneNum}`,
|
|
167
|
+
mood: sceneData?.mood || 'neutral',
|
|
168
|
+
shots,
|
|
169
|
+
durationInFrames: sceneDurationFrames,
|
|
170
|
+
durationSec: sceneDurationFrames / targetFps,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
// Total duration: sum of all scene durations plus scene-to-scene transitions
|
|
174
|
+
// Between scenes, we use a 1-second fade
|
|
175
|
+
const sceneTransitionFrames = Math.round(targetFps * 1); // 1s between scenes
|
|
176
|
+
const totalSceneFrames = scenes.reduce((sum, s) => sum + s.durationInFrames, 0);
|
|
177
|
+
const totalSceneTransitions = Math.max(0, scenes.length - 1) * sceneTransitionFrames;
|
|
178
|
+
const totalDurationInFrames = totalSceneFrames - totalSceneTransitions;
|
|
179
|
+
const manifest = {
|
|
180
|
+
projectName: project.name,
|
|
181
|
+
targetFps,
|
|
182
|
+
targetWidth: DEFAULT_WIDTH,
|
|
183
|
+
targetHeight: DEFAULT_HEIGHT,
|
|
184
|
+
scenes,
|
|
185
|
+
totalDurationInFrames,
|
|
186
|
+
totalDurationSec: totalDurationInFrames / targetFps,
|
|
187
|
+
totalShots,
|
|
188
|
+
createdAt: new Date().toISOString(),
|
|
189
|
+
};
|
|
190
|
+
console.log(`\nManifest built:`);
|
|
191
|
+
console.log(` Scenes: ${scenes.length}`);
|
|
192
|
+
console.log(` Total shots: ${totalShots}`);
|
|
193
|
+
console.log(` Total duration: ${manifest.totalDurationSec.toFixed(1)}s (${totalDurationInFrames} frames @ ${targetFps}fps)`);
|
|
194
|
+
return manifest;
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=manifest-builder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-builder.js","sourceRoot":"","sources":["../../src/assembly/manifest-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scaffolds a complete Remotion project inside the project's output directory.
|
|
3
|
+
* Generates package.json, tsconfig, and all React components from the manifest.
|
|
4
|
+
*/
|
|
5
|
+
import type { ShotManifest } from './types.js';
|
|
6
|
+
export interface ScaffoldResult {
|
|
7
|
+
remotionDir: string;
|
|
8
|
+
manifestPath: string;
|
|
9
|
+
entryPoint: string;
|
|
10
|
+
/** The directory to pass as --public-dir (the project output dir with real MP4s) */
|
|
11
|
+
publicDir: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function scaffoldRemotionProject(projectOutputDir: string, manifest: ShotManifest): Promise<ScaffoldResult>;
|
|
14
|
+
//# sourceMappingURL=remotion-scaffold.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remotion-scaffold.d.ts","sourceRoot":"","sources":["../../src/assembly/remotion-scaffold.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,YAAY,EAAoC,MAAM,YAAY,CAAC;AAEjF,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,SAAS,EAAE,MAAM,CAAC;CACnB;AASD,wBAAsB,uBAAuB,CAC3C,gBAAgB,EAAE,MAAM,EACxB,QAAQ,EAAE,YAAY,GACrB,OAAO,CAAC,cAAc,CAAC,CAkCzB"}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scaffolds a complete Remotion project inside the project's output directory.
|
|
3
|
+
* Generates package.json, tsconfig, and all React components from the manifest.
|
|
4
|
+
*/
|
|
5
|
+
import { writeFile, mkdir } from 'node:fs/promises';
|
|
6
|
+
import { join, resolve } from 'node:path';
|
|
7
|
+
import { existsSync } from 'node:fs';
|
|
8
|
+
/** Ensure a directory exists */
|
|
9
|
+
async function ensureDir(dir) {
|
|
10
|
+
if (!existsSync(dir)) {
|
|
11
|
+
await mkdir(dir, { recursive: true });
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export async function scaffoldRemotionProject(projectOutputDir, manifest) {
|
|
15
|
+
const remotionDir = join(projectOutputDir, 'remotion');
|
|
16
|
+
const srcDir = join(remotionDir, 'src');
|
|
17
|
+
// Use the project output dir itself as the public dir --
|
|
18
|
+
// it already contains scene-NNN/shot-NNN.mp4 files in the right structure.
|
|
19
|
+
// Remotion's --public-dir flag will point here.
|
|
20
|
+
const publicDir = resolve(projectOutputDir);
|
|
21
|
+
console.log(`\nScaffolding Remotion project at ${remotionDir}`);
|
|
22
|
+
// Create directory structure
|
|
23
|
+
await ensureDir(srcDir);
|
|
24
|
+
// Write manifest
|
|
25
|
+
const manifestPath = join(remotionDir, 'shot-manifest.json');
|
|
26
|
+
await writeFile(manifestPath, JSON.stringify(manifest, null, 2));
|
|
27
|
+
console.log('Wrote shot-manifest.json');
|
|
28
|
+
// Write all project files
|
|
29
|
+
await writeFile(join(remotionDir, 'package.json'), generatePackageJson(manifest));
|
|
30
|
+
await writeFile(join(remotionDir, 'tsconfig.json'), generateTsConfig());
|
|
31
|
+
await writeFile(join(srcDir, 'index.ts'), generateEntryPoint());
|
|
32
|
+
await writeFile(join(srcDir, 'Root.tsx'), generateRoot(manifest));
|
|
33
|
+
await writeFile(join(srcDir, 'Film.tsx'), generateFilm());
|
|
34
|
+
await writeFile(join(srcDir, 'Scene.tsx'), generateScene());
|
|
35
|
+
await writeFile(join(srcDir, 'types.ts'), generateClientTypes());
|
|
36
|
+
console.log('Wrote Remotion source files');
|
|
37
|
+
return {
|
|
38
|
+
remotionDir,
|
|
39
|
+
manifestPath,
|
|
40
|
+
entryPoint: join(srcDir, 'index.ts'),
|
|
41
|
+
publicDir,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
// ── File generators ──────────────────────────────────────────────────
|
|
45
|
+
function generatePackageJson(manifest) {
|
|
46
|
+
const pkg = {
|
|
47
|
+
name: `${manifest.projectName}-remotion`,
|
|
48
|
+
version: '1.0.0',
|
|
49
|
+
private: true,
|
|
50
|
+
type: 'module',
|
|
51
|
+
scripts: {
|
|
52
|
+
preview: 'npx remotion preview src/index.ts',
|
|
53
|
+
render: `npx remotion render src/index.ts Film --codec=h264 --crf=18`,
|
|
54
|
+
'render:scene': 'echo "Usage: npm run render:scene -- SceneN"',
|
|
55
|
+
},
|
|
56
|
+
dependencies: {
|
|
57
|
+
'@remotion/cli': '^4.0.0',
|
|
58
|
+
'@remotion/transitions': '^4.0.0',
|
|
59
|
+
'@remotion/renderer': '^4.0.0',
|
|
60
|
+
'@remotion/bundler': '^4.0.0',
|
|
61
|
+
react: '^18.3.0',
|
|
62
|
+
'react-dom': '^18.3.0',
|
|
63
|
+
remotion: '^4.0.0',
|
|
64
|
+
},
|
|
65
|
+
devDependencies: {
|
|
66
|
+
'@types/react': '^18.3.0',
|
|
67
|
+
typescript: '^5.7.0',
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
return JSON.stringify(pkg, null, 2) + '\n';
|
|
71
|
+
}
|
|
72
|
+
function generateTsConfig() {
|
|
73
|
+
const config = {
|
|
74
|
+
compilerOptions: {
|
|
75
|
+
target: 'ES2022',
|
|
76
|
+
module: 'preserve',
|
|
77
|
+
moduleResolution: 'bundler',
|
|
78
|
+
jsx: 'react-jsx',
|
|
79
|
+
strict: true,
|
|
80
|
+
esModuleInterop: true,
|
|
81
|
+
skipLibCheck: true,
|
|
82
|
+
resolveJsonModule: true,
|
|
83
|
+
outDir: 'dist',
|
|
84
|
+
},
|
|
85
|
+
include: ['src/**/*'],
|
|
86
|
+
};
|
|
87
|
+
return JSON.stringify(config, null, 2) + '\n';
|
|
88
|
+
}
|
|
89
|
+
function generateEntryPoint() {
|
|
90
|
+
return `import { registerRoot } from "remotion";
|
|
91
|
+
import { RemotionRoot } from "./Root";
|
|
92
|
+
|
|
93
|
+
registerRoot(RemotionRoot);
|
|
94
|
+
`;
|
|
95
|
+
}
|
|
96
|
+
function generateRoot(manifest) {
|
|
97
|
+
// Build per-scene compositions + full film composition
|
|
98
|
+
const sceneComps = manifest.scenes
|
|
99
|
+
.map((scene) => {
|
|
100
|
+
const id = `Scene${scene.sceneNumber}`;
|
|
101
|
+
return ` <Composition
|
|
102
|
+
id="${id}"
|
|
103
|
+
component={Film}
|
|
104
|
+
durationInFrames={${scene.durationInFrames}}
|
|
105
|
+
fps={${manifest.targetFps}}
|
|
106
|
+
width={${manifest.targetWidth}}
|
|
107
|
+
height={${manifest.targetHeight}}
|
|
108
|
+
defaultProps={{
|
|
109
|
+
scenes: manifest.scenes.filter((s) => s.sceneNumber === ${scene.sceneNumber}),
|
|
110
|
+
fps: ${manifest.targetFps},
|
|
111
|
+
sceneTransitionFrames: SCENE_TRANSITION_FRAMES,
|
|
112
|
+
}}
|
|
113
|
+
/>`;
|
|
114
|
+
})
|
|
115
|
+
.join('\n');
|
|
116
|
+
return `import React from "react";
|
|
117
|
+
import { Composition } from "remotion";
|
|
118
|
+
import { Film } from "./Film";
|
|
119
|
+
import manifest from "../shot-manifest.json";
|
|
120
|
+
import type { ShotManifest } from "./types";
|
|
121
|
+
|
|
122
|
+
const typedManifest = manifest as unknown as ShotManifest;
|
|
123
|
+
const SCENE_TRANSITION_FRAMES = ${manifest.targetFps}; // 1s between scenes
|
|
124
|
+
|
|
125
|
+
export const RemotionRoot: React.FC = () => {
|
|
126
|
+
return (
|
|
127
|
+
<>
|
|
128
|
+
<Composition
|
|
129
|
+
id="Film"
|
|
130
|
+
component={Film}
|
|
131
|
+
durationInFrames={${manifest.totalDurationInFrames}}
|
|
132
|
+
fps={${manifest.targetFps}}
|
|
133
|
+
width={${manifest.targetWidth}}
|
|
134
|
+
height={${manifest.targetHeight}}
|
|
135
|
+
defaultProps={{
|
|
136
|
+
scenes: typedManifest.scenes,
|
|
137
|
+
fps: ${manifest.targetFps},
|
|
138
|
+
sceneTransitionFrames: SCENE_TRANSITION_FRAMES,
|
|
139
|
+
}}
|
|
140
|
+
/>
|
|
141
|
+
${sceneComps}
|
|
142
|
+
</>
|
|
143
|
+
);
|
|
144
|
+
};
|
|
145
|
+
`;
|
|
146
|
+
}
|
|
147
|
+
function generateFilm() {
|
|
148
|
+
return `import React from "react";
|
|
149
|
+
import { TransitionSeries, linearTiming } from "@remotion/transitions";
|
|
150
|
+
import { fade } from "@remotion/transitions/fade";
|
|
151
|
+
import { Scene } from "./Scene";
|
|
152
|
+
import type { SceneManifest } from "./types";
|
|
153
|
+
|
|
154
|
+
interface FilmProps {
|
|
155
|
+
scenes: SceneManifest[];
|
|
156
|
+
fps: number;
|
|
157
|
+
sceneTransitionFrames: number;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export const Film: React.FC<FilmProps> = ({
|
|
161
|
+
scenes,
|
|
162
|
+
fps,
|
|
163
|
+
sceneTransitionFrames,
|
|
164
|
+
}) => {
|
|
165
|
+
return (
|
|
166
|
+
<TransitionSeries>
|
|
167
|
+
{scenes.map((scene, i) => (
|
|
168
|
+
<React.Fragment key={scene.sceneNumber}>
|
|
169
|
+
<TransitionSeries.Sequence durationInFrames={scene.durationInFrames}>
|
|
170
|
+
<Scene scene={scene} fps={fps} />
|
|
171
|
+
</TransitionSeries.Sequence>
|
|
172
|
+
{i < scenes.length - 1 && (
|
|
173
|
+
<TransitionSeries.Transition
|
|
174
|
+
presentation={fade()}
|
|
175
|
+
timing={linearTiming({
|
|
176
|
+
durationInFrames: sceneTransitionFrames,
|
|
177
|
+
})}
|
|
178
|
+
/>
|
|
179
|
+
)}
|
|
180
|
+
</React.Fragment>
|
|
181
|
+
))}
|
|
182
|
+
</TransitionSeries>
|
|
183
|
+
);
|
|
184
|
+
};
|
|
185
|
+
`;
|
|
186
|
+
}
|
|
187
|
+
function generateScene() {
|
|
188
|
+
return `import React from "react";
|
|
189
|
+
import { AbsoluteFill, OffthreadVideo, staticFile } from "remotion";
|
|
190
|
+
import { TransitionSeries, linearTiming } from "@remotion/transitions";
|
|
191
|
+
import { fade } from "@remotion/transitions/fade";
|
|
192
|
+
import { slide } from "@remotion/transitions/slide";
|
|
193
|
+
import type { SceneManifest, TransitionType } from "./types";
|
|
194
|
+
|
|
195
|
+
interface SceneProps {
|
|
196
|
+
scene: SceneManifest;
|
|
197
|
+
fps: number;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
function getPresentation(type: TransitionType) {
|
|
201
|
+
switch (type) {
|
|
202
|
+
case "fade":
|
|
203
|
+
case "dissolve":
|
|
204
|
+
return fade();
|
|
205
|
+
case "wipe":
|
|
206
|
+
return slide({ direction: "from-right" });
|
|
207
|
+
case "cut":
|
|
208
|
+
default:
|
|
209
|
+
return fade(); // 1-frame fade = hard cut
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export const Scene: React.FC<SceneProps> = ({ scene, fps }) => {
|
|
214
|
+
const { shots } = scene;
|
|
215
|
+
|
|
216
|
+
return (
|
|
217
|
+
<TransitionSeries>
|
|
218
|
+
{shots.map((shot, i) => (
|
|
219
|
+
<React.Fragment key={shot.panelId}>
|
|
220
|
+
<TransitionSeries.Sequence durationInFrames={shot.durationInFrames}>
|
|
221
|
+
<AbsoluteFill style={{ backgroundColor: "black" }}>
|
|
222
|
+
<OffthreadVideo
|
|
223
|
+
src={staticFile(shot.file)}
|
|
224
|
+
style={{
|
|
225
|
+
width: "100%",
|
|
226
|
+
height: "100%",
|
|
227
|
+
objectFit: "cover",
|
|
228
|
+
}}
|
|
229
|
+
/>
|
|
230
|
+
</AbsoluteFill>
|
|
231
|
+
</TransitionSeries.Sequence>
|
|
232
|
+
{i < shots.length - 1 && (
|
|
233
|
+
<TransitionSeries.Transition
|
|
234
|
+
presentation={getPresentation(shots[i + 1].transition)}
|
|
235
|
+
timing={linearTiming({
|
|
236
|
+
durationInFrames: shots[i + 1].transitionDurationInFrames,
|
|
237
|
+
})}
|
|
238
|
+
/>
|
|
239
|
+
)}
|
|
240
|
+
</React.Fragment>
|
|
241
|
+
))}
|
|
242
|
+
</TransitionSeries>
|
|
243
|
+
);
|
|
244
|
+
};
|
|
245
|
+
`;
|
|
246
|
+
}
|
|
247
|
+
function generateClientTypes() {
|
|
248
|
+
return `/** Shared types for Remotion components -- mirrors assembly/types.ts */
|
|
249
|
+
|
|
250
|
+
export type TransitionType = "cut" | "fade" | "dissolve" | "wipe";
|
|
251
|
+
|
|
252
|
+
export interface ShotManifestEntry {
|
|
253
|
+
file: string;
|
|
254
|
+
sceneNumber: number;
|
|
255
|
+
shotNumber: number;
|
|
256
|
+
panelId: string;
|
|
257
|
+
durationSec: number;
|
|
258
|
+
durationInFrames: number;
|
|
259
|
+
fps: number;
|
|
260
|
+
width: number;
|
|
261
|
+
height: number;
|
|
262
|
+
transition: TransitionType;
|
|
263
|
+
transitionDurationInFrames: number;
|
|
264
|
+
characters: string[];
|
|
265
|
+
dialogue?: { character: string; line: string };
|
|
266
|
+
cameraMovement: string;
|
|
267
|
+
mood?: string;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export interface SceneManifest {
|
|
271
|
+
sceneNumber: number;
|
|
272
|
+
heading: string;
|
|
273
|
+
mood: string;
|
|
274
|
+
shots: ShotManifestEntry[];
|
|
275
|
+
durationInFrames: number;
|
|
276
|
+
durationSec: number;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
export interface ShotManifest {
|
|
280
|
+
projectName: string;
|
|
281
|
+
targetFps: number;
|
|
282
|
+
targetWidth: number;
|
|
283
|
+
targetHeight: number;
|
|
284
|
+
scenes: SceneManifest[];
|
|
285
|
+
totalDurationInFrames: number;
|
|
286
|
+
totalDurationSec: number;
|
|
287
|
+
totalShots: number;
|
|
288
|
+
createdAt: string;
|
|
289
|
+
}
|
|
290
|
+
`;
|
|
291
|
+
}
|
|
292
|
+
//# sourceMappingURL=remotion-scaffold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remotion-scaffold.js","sourceRoot":"","sources":["../../src/assembly/remotion-scaffold.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for the Remotion assembly pipeline.
|
|
3
|
+
*/
|
|
4
|
+
export interface ShotManifestEntry {
|
|
5
|
+
/** Relative path from remotion public/ dir, e.g. "scene-001/shot-001.mp4" */
|
|
6
|
+
file: string;
|
|
7
|
+
/** Absolute path to the source MP4 */
|
|
8
|
+
absolutePath: string;
|
|
9
|
+
/** Scene number */
|
|
10
|
+
sceneNumber: number;
|
|
11
|
+
/** Shot number within scene */
|
|
12
|
+
shotNumber: number;
|
|
13
|
+
/** Panel ID, e.g. "S1-P1" */
|
|
14
|
+
panelId: string;
|
|
15
|
+
/** Duration in seconds (from ffprobe) */
|
|
16
|
+
durationSec: number;
|
|
17
|
+
/** Duration in frames at target FPS */
|
|
18
|
+
durationInFrames: number;
|
|
19
|
+
/** Video FPS (from ffprobe) */
|
|
20
|
+
fps: number;
|
|
21
|
+
/** Video width */
|
|
22
|
+
width: number;
|
|
23
|
+
/** Video height */
|
|
24
|
+
height: number;
|
|
25
|
+
/** Transition type from video.json metadata */
|
|
26
|
+
transition: TransitionType;
|
|
27
|
+
/** Transition duration in frames */
|
|
28
|
+
transitionDurationInFrames: number;
|
|
29
|
+
/** Characters in this shot */
|
|
30
|
+
characters: string[];
|
|
31
|
+
/** Dialogue if present */
|
|
32
|
+
dialogue?: {
|
|
33
|
+
character: string;
|
|
34
|
+
line: string;
|
|
35
|
+
};
|
|
36
|
+
/** Camera movement description */
|
|
37
|
+
cameraMovement: string;
|
|
38
|
+
/** Mood of the scene */
|
|
39
|
+
mood?: string;
|
|
40
|
+
}
|
|
41
|
+
export type TransitionType = 'cut' | 'fade' | 'dissolve' | 'wipe';
|
|
42
|
+
export interface ShotManifest {
|
|
43
|
+
projectName: string;
|
|
44
|
+
targetFps: number;
|
|
45
|
+
targetWidth: number;
|
|
46
|
+
targetHeight: number;
|
|
47
|
+
scenes: SceneManifest[];
|
|
48
|
+
totalDurationInFrames: number;
|
|
49
|
+
totalDurationSec: number;
|
|
50
|
+
totalShots: number;
|
|
51
|
+
createdAt: string;
|
|
52
|
+
}
|
|
53
|
+
export interface SceneManifest {
|
|
54
|
+
sceneNumber: number;
|
|
55
|
+
heading: string;
|
|
56
|
+
mood: string;
|
|
57
|
+
shots: ShotManifestEntry[];
|
|
58
|
+
durationInFrames: number;
|
|
59
|
+
durationSec: number;
|
|
60
|
+
}
|
|
61
|
+
export interface RemotionProjectConfig {
|
|
62
|
+
projectDir: string;
|
|
63
|
+
publicDir: string;
|
|
64
|
+
srcDir: string;
|
|
65
|
+
manifest: ShotManifest;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/assembly/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,iBAAiB;IAChC,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,gBAAgB,EAAE,MAAM,CAAC;IACzB,+BAA+B;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,kBAAkB;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,mBAAmB;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,UAAU,EAAE,cAAc,CAAC;IAC3B,oCAAoC;IACpC,0BAA0B,EAAE,MAAM,CAAC;IACnC,8BAA8B;IAC9B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,0BAA0B;IAC1B,QAAQ,CAAC,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,kCAAkC;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,wBAAwB;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;AAElE,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,gBAAgB,EAAE,MAAM,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,iBAAiB,EAAE,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,YAAY,CAAC;CACxB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/assembly/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { CharacterProfile } from "./extractor.js";
|
|
2
|
+
/** Fully synthesized character description ready for prompt injection. */
|
|
3
|
+
export interface CharacterDescription {
|
|
4
|
+
/** Canonical character name. */
|
|
5
|
+
name: string;
|
|
6
|
+
/** 1-2 sentence summary suitable for quick reference. */
|
|
7
|
+
shortDescription: string;
|
|
8
|
+
/**
|
|
9
|
+
* Exhaustive paragraph covering all known physical attributes.
|
|
10
|
+
* Formatted for direct injection into image generation prompts.
|
|
11
|
+
*/
|
|
12
|
+
fullDescription: string;
|
|
13
|
+
/** Default wardrobe description (most commonly described outfit). */
|
|
14
|
+
wardrobe: string;
|
|
15
|
+
/**
|
|
16
|
+
* Per-scene wardrobe overrides.
|
|
17
|
+
* Key is the 1-based scene number; value is the wardrobe description
|
|
18
|
+
* specific to that scene. Only populated when distinct wardrobe changes
|
|
19
|
+
* are detected in the screenplay text.
|
|
20
|
+
*/
|
|
21
|
+
wardrobeByScene: Map<number, string>;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Transform an array of `CharacterProfile` objects into structured
|
|
25
|
+
* `CharacterDescription` entries. Each description synthesizes scattered
|
|
26
|
+
* physical-description fragments into a coherent, prompt-ready format.
|
|
27
|
+
*
|
|
28
|
+
* @param profiles - Array of profiles from `extractCharacterProfiles`.
|
|
29
|
+
* @returns Array of `CharacterDescription` in the same order as input.
|
|
30
|
+
*/
|
|
31
|
+
export declare function buildCharacterDescriptions(profiles: CharacterProfile[]): CharacterDescription[];
|
|
32
|
+
//# sourceMappingURL=describer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"describer.d.ts","sourceRoot":"","sources":["../../src/characters/describer.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAIvD,0EAA0E;AAC1E,MAAM,WAAW,oBAAoB;IACnC,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAC;IAEb,yDAAyD;IACzD,gBAAgB,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB,qEAAqE;IACrE,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;;OAKG;IACH,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AA4VD;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,gBAAgB,EAAE,GAC3B,oBAAoB,EAAE,CAuCxB"}
|