@contractspec/lib.video-gen 1.42.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/dist/browser/compositions/api-overview.js +645 -0
- package/dist/browser/compositions/index.js +1133 -0
- package/dist/browser/compositions/primitives/animated-text.js +144 -0
- package/dist/browser/compositions/primitives/brand-frame.js +181 -0
- package/dist/browser/compositions/primitives/code-block.js +226 -0
- package/dist/browser/compositions/primitives/index.js +656 -0
- package/dist/browser/compositions/primitives/progress-bar.js +59 -0
- package/dist/browser/compositions/primitives/terminal.js +265 -0
- package/dist/browser/compositions/primitives/transition.js +98 -0
- package/dist/browser/compositions/social-clip.js +500 -0
- package/dist/browser/compositions/terminal-demo.js +558 -0
- package/dist/browser/design/index.js +155 -0
- package/dist/browser/design/layouts.js +50 -0
- package/dist/browser/design/motion.js +43 -0
- package/dist/browser/design/tokens.js +28 -0
- package/dist/browser/design/typography.js +61 -0
- package/dist/browser/docs/compositions.docblock.js +182 -0
- package/dist/browser/docs/design.docblock.js +187 -0
- package/dist/browser/docs/generators.docblock.js +187 -0
- package/dist/browser/docs/rendering.docblock.js +197 -0
- package/dist/browser/docs/video-gen.docblock.js +141 -0
- package/dist/browser/generators/index.js +416 -0
- package/dist/browser/generators/scene-planner.js +205 -0
- package/dist/browser/generators/script-generator.js +147 -0
- package/dist/browser/generators/video-generator.js +414 -0
- package/dist/browser/index.js +1550 -0
- package/dist/browser/player/demo-player.js +1136 -0
- package/dist/browser/player/index.js +1136 -0
- package/dist/browser/remotion/Root.js +1189 -0
- package/dist/browser/remotion/index.js +1190 -0
- package/dist/browser/renderers/config.js +40 -0
- package/dist/browser/renderers/index.js +160 -0
- package/dist/browser/renderers/local.js +156 -0
- package/dist/browser/types.js +13 -0
- package/dist/compositions/api-overview.d.ts +16 -0
- package/dist/compositions/api-overview.js +640 -0
- package/dist/compositions/index.d.ts +7 -0
- package/dist/compositions/index.js +1128 -0
- package/dist/compositions/primitives/animated-text.d.ts +22 -0
- package/dist/compositions/primitives/animated-text.js +139 -0
- package/dist/compositions/primitives/brand-frame.d.ts +14 -0
- package/dist/compositions/primitives/brand-frame.js +176 -0
- package/dist/compositions/primitives/code-block.d.ts +18 -0
- package/dist/compositions/primitives/code-block.js +221 -0
- package/dist/compositions/primitives/index.d.ts +12 -0
- package/dist/compositions/primitives/index.js +651 -0
- package/dist/compositions/primitives/progress-bar.d.ts +12 -0
- package/dist/compositions/primitives/progress-bar.js +54 -0
- package/dist/compositions/primitives/terminal.d.ts +24 -0
- package/dist/compositions/primitives/terminal.js +260 -0
- package/dist/compositions/primitives/transition.d.ts +14 -0
- package/dist/compositions/primitives/transition.js +93 -0
- package/dist/compositions/social-clip.d.ts +16 -0
- package/dist/compositions/social-clip.js +495 -0
- package/dist/compositions/terminal-demo.d.ts +17 -0
- package/dist/compositions/terminal-demo.js +553 -0
- package/dist/design/index.d.ts +4 -0
- package/dist/design/index.js +150 -0
- package/dist/design/layouts.d.ts +69 -0
- package/dist/design/layouts.js +45 -0
- package/dist/design/motion.d.ts +72 -0
- package/dist/design/motion.js +38 -0
- package/dist/design/tokens.d.ts +31 -0
- package/dist/design/tokens.js +23 -0
- package/dist/design/typography.d.ts +61 -0
- package/dist/design/typography.js +56 -0
- package/dist/docs/compositions.docblock.d.ts +1 -0
- package/dist/docs/compositions.docblock.js +183 -0
- package/dist/docs/design.docblock.d.ts +1 -0
- package/dist/docs/design.docblock.js +188 -0
- package/dist/docs/generators.docblock.d.ts +1 -0
- package/dist/docs/generators.docblock.js +188 -0
- package/dist/docs/rendering.docblock.d.ts +1 -0
- package/dist/docs/rendering.docblock.js +198 -0
- package/dist/docs/video-gen.docblock.d.ts +1 -0
- package/dist/docs/video-gen.docblock.js +142 -0
- package/dist/generators/index.d.ts +5 -0
- package/dist/generators/index.js +411 -0
- package/dist/generators/scene-planner.d.ts +23 -0
- package/dist/generators/scene-planner.js +200 -0
- package/dist/generators/script-generator.d.ts +49 -0
- package/dist/generators/script-generator.js +142 -0
- package/dist/generators/video-generator.d.ts +20 -0
- package/dist/generators/video-generator.js +409 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +1545 -0
- package/dist/node/compositions/api-overview.js +640 -0
- package/dist/node/compositions/index.js +1128 -0
- package/dist/node/compositions/primitives/animated-text.js +139 -0
- package/dist/node/compositions/primitives/brand-frame.js +176 -0
- package/dist/node/compositions/primitives/code-block.js +221 -0
- package/dist/node/compositions/primitives/index.js +651 -0
- package/dist/node/compositions/primitives/progress-bar.js +54 -0
- package/dist/node/compositions/primitives/terminal.js +260 -0
- package/dist/node/compositions/primitives/transition.js +93 -0
- package/dist/node/compositions/social-clip.js +495 -0
- package/dist/node/compositions/terminal-demo.js +553 -0
- package/dist/node/design/index.js +150 -0
- package/dist/node/design/layouts.js +45 -0
- package/dist/node/design/motion.js +38 -0
- package/dist/node/design/tokens.js +23 -0
- package/dist/node/design/typography.js +56 -0
- package/dist/node/docs/compositions.docblock.js +182 -0
- package/dist/node/docs/design.docblock.js +187 -0
- package/dist/node/docs/generators.docblock.js +187 -0
- package/dist/node/docs/rendering.docblock.js +197 -0
- package/dist/node/docs/video-gen.docblock.js +141 -0
- package/dist/node/generators/index.js +411 -0
- package/dist/node/generators/scene-planner.js +200 -0
- package/dist/node/generators/script-generator.js +142 -0
- package/dist/node/generators/video-generator.js +409 -0
- package/dist/node/index.js +1545 -0
- package/dist/node/player/demo-player.js +1131 -0
- package/dist/node/player/index.js +1131 -0
- package/dist/node/remotion/Root.js +1184 -0
- package/dist/node/remotion/index.js +1185 -0
- package/dist/node/renderers/config.js +35 -0
- package/dist/node/renderers/index.js +155 -0
- package/dist/node/renderers/local.js +151 -0
- package/dist/node/types.js +8 -0
- package/dist/player/demo-player.d.ts +55 -0
- package/dist/player/demo-player.js +1131 -0
- package/dist/player/index.d.ts +2 -0
- package/dist/player/index.js +1131 -0
- package/dist/remotion/Root.d.ts +2 -0
- package/dist/remotion/Root.js +1184 -0
- package/dist/remotion/index.d.ts +1 -0
- package/dist/remotion/index.js +1185 -0
- package/dist/renderers/config.d.ts +28 -0
- package/dist/renderers/config.js +35 -0
- package/dist/renderers/index.d.ts +3 -0
- package/dist/renderers/index.js +155 -0
- package/dist/renderers/local.d.ts +17 -0
- package/dist/renderers/local.js +151 -0
- package/dist/types.d.ts +63 -0
- package/dist/types.js +8 -0
- package/package.json +637 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { RenderConfig, VideoCodec, VideoOutputFormat } from '@contractspec/lib.contracts-integrations/integrations/providers/video';
|
|
2
|
+
/** Default render configuration for local rendering. */
|
|
3
|
+
export declare const defaultRenderConfig: Required<Pick<RenderConfig, 'codec' | 'outputFormat' | 'crf' | 'pixelFormat'>>;
|
|
4
|
+
/** Codec-to-output-format mapping. */
|
|
5
|
+
export declare const codecFormatMap: Record<VideoCodec, VideoOutputFormat>;
|
|
6
|
+
/** Quality presets. */
|
|
7
|
+
export declare const qualityPresets: {
|
|
8
|
+
/** Fastest render, lower quality (previews) */
|
|
9
|
+
readonly draft: {
|
|
10
|
+
readonly crf: 28;
|
|
11
|
+
readonly concurrency: 1;
|
|
12
|
+
};
|
|
13
|
+
/** Balanced quality/speed */
|
|
14
|
+
readonly standard: {
|
|
15
|
+
readonly crf: 18;
|
|
16
|
+
readonly concurrency: undefined;
|
|
17
|
+
};
|
|
18
|
+
/** Highest quality (final output) */
|
|
19
|
+
readonly high: {
|
|
20
|
+
readonly crf: 12;
|
|
21
|
+
readonly concurrency: undefined;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
export type QualityPreset = keyof typeof qualityPresets;
|
|
25
|
+
/**
|
|
26
|
+
* Merge user config with defaults.
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveRenderConfig(userConfig: RenderConfig, preset?: QualityPreset): RenderConfig;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __require = import.meta.require;
|
|
3
|
+
|
|
4
|
+
// src/renderers/config.ts
|
|
5
|
+
var defaultRenderConfig = {
|
|
6
|
+
codec: "h264",
|
|
7
|
+
outputFormat: "mp4",
|
|
8
|
+
crf: 18,
|
|
9
|
+
pixelFormat: "yuv420p"
|
|
10
|
+
};
|
|
11
|
+
var codecFormatMap = {
|
|
12
|
+
h264: "mp4",
|
|
13
|
+
h265: "mp4",
|
|
14
|
+
vp8: "webm",
|
|
15
|
+
vp9: "webm"
|
|
16
|
+
};
|
|
17
|
+
var qualityPresets = {
|
|
18
|
+
draft: { crf: 28, concurrency: 1 },
|
|
19
|
+
standard: { crf: 18, concurrency: undefined },
|
|
20
|
+
high: { crf: 12, concurrency: undefined }
|
|
21
|
+
};
|
|
22
|
+
function resolveRenderConfig(userConfig, preset) {
|
|
23
|
+
const presetValues = preset ? qualityPresets[preset] : {};
|
|
24
|
+
return {
|
|
25
|
+
...defaultRenderConfig,
|
|
26
|
+
...presetValues,
|
|
27
|
+
...userConfig
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
resolveRenderConfig,
|
|
32
|
+
qualityPresets,
|
|
33
|
+
defaultRenderConfig,
|
|
34
|
+
codecFormatMap
|
|
35
|
+
};
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __require = import.meta.require;
|
|
3
|
+
|
|
4
|
+
// src/design/layouts.ts
|
|
5
|
+
import { VIDEO_FORMATS } from "@contractspec/lib.contracts-integrations/integrations/providers/video";
|
|
6
|
+
var DEFAULT_FPS = 30;
|
|
7
|
+
var videoSafeZone = {
|
|
8
|
+
horizontal: 120,
|
|
9
|
+
vertical: 80,
|
|
10
|
+
contentWidth: 1680,
|
|
11
|
+
contentHeight: 920
|
|
12
|
+
};
|
|
13
|
+
function scaleSafeZone(format) {
|
|
14
|
+
const scaleX = format.width / 1920;
|
|
15
|
+
const scaleY = format.height / 1080;
|
|
16
|
+
return {
|
|
17
|
+
horizontal: Math.round(videoSafeZone.horizontal * scaleX),
|
|
18
|
+
vertical: Math.round(videoSafeZone.vertical * scaleY),
|
|
19
|
+
contentWidth: Math.round(videoSafeZone.contentWidth * scaleX),
|
|
20
|
+
contentHeight: Math.round(videoSafeZone.contentHeight * scaleY)
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
var videoPositions = {
|
|
24
|
+
center: { x: 960, y: 540 },
|
|
25
|
+
topLeft: { x: 120, y: 80 },
|
|
26
|
+
topRight: { x: 1800, y: 80 },
|
|
27
|
+
bottomLeft: { x: 120, y: 1000 },
|
|
28
|
+
bottomRight: { x: 1800, y: 1000 },
|
|
29
|
+
bottomCenter: { x: 960, y: 960 }
|
|
30
|
+
};
|
|
31
|
+
function getAllFormatVariants() {
|
|
32
|
+
return [
|
|
33
|
+
VIDEO_FORMATS.landscape,
|
|
34
|
+
VIDEO_FORMATS.square,
|
|
35
|
+
VIDEO_FORMATS.portrait
|
|
36
|
+
];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/renderers/config.ts
|
|
40
|
+
var defaultRenderConfig = {
|
|
41
|
+
codec: "h264",
|
|
42
|
+
outputFormat: "mp4",
|
|
43
|
+
crf: 18,
|
|
44
|
+
pixelFormat: "yuv420p"
|
|
45
|
+
};
|
|
46
|
+
var codecFormatMap = {
|
|
47
|
+
h264: "mp4",
|
|
48
|
+
h265: "mp4",
|
|
49
|
+
vp8: "webm",
|
|
50
|
+
vp9: "webm"
|
|
51
|
+
};
|
|
52
|
+
var qualityPresets = {
|
|
53
|
+
draft: { crf: 28, concurrency: 1 },
|
|
54
|
+
standard: { crf: 18, concurrency: undefined },
|
|
55
|
+
high: { crf: 12, concurrency: undefined }
|
|
56
|
+
};
|
|
57
|
+
function resolveRenderConfig(userConfig, preset) {
|
|
58
|
+
const presetValues = preset ? qualityPresets[preset] : {};
|
|
59
|
+
return {
|
|
60
|
+
...defaultRenderConfig,
|
|
61
|
+
...presetValues,
|
|
62
|
+
...userConfig
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// src/renderers/local.ts
|
|
67
|
+
class LocalRenderer {
|
|
68
|
+
entryPoint;
|
|
69
|
+
constructor(options) {
|
|
70
|
+
this.entryPoint = options.entryPoint;
|
|
71
|
+
}
|
|
72
|
+
async render(project, config) {
|
|
73
|
+
const resolved = resolveRenderConfig(config);
|
|
74
|
+
const { bundle } = await import("@remotion/bundler");
|
|
75
|
+
const { renderMedia, selectComposition } = await import("@remotion/renderer");
|
|
76
|
+
const bundleLocation = await bundle({
|
|
77
|
+
entryPoint: this.entryPoint
|
|
78
|
+
});
|
|
79
|
+
const firstScene = project.scenes[0];
|
|
80
|
+
const mainCompositionId = project.scenes.length === 1 && firstScene ? firstScene.compositionId : "Master";
|
|
81
|
+
const composition = await selectComposition({
|
|
82
|
+
serveUrl: bundleLocation,
|
|
83
|
+
id: mainCompositionId,
|
|
84
|
+
inputProps: {
|
|
85
|
+
project
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
await renderMedia({
|
|
89
|
+
composition,
|
|
90
|
+
serveUrl: bundleLocation,
|
|
91
|
+
codec: resolved.codec,
|
|
92
|
+
outputLocation: resolved.outputPath,
|
|
93
|
+
inputProps: { project },
|
|
94
|
+
...resolved.crf && { crf: resolved.crf },
|
|
95
|
+
...resolved.concurrency && {
|
|
96
|
+
concurrency: resolved.concurrency
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
const result = {
|
|
100
|
+
outputPath: resolved.outputPath,
|
|
101
|
+
format: resolved.outputFormat ?? defaultRenderConfig.outputFormat,
|
|
102
|
+
codec: resolved.codec ?? defaultRenderConfig.codec,
|
|
103
|
+
durationSeconds: project.totalDurationInFrames / project.fps,
|
|
104
|
+
fileSizeBytes: 0,
|
|
105
|
+
dimensions: {
|
|
106
|
+
width: project.format.width,
|
|
107
|
+
height: project.format.height
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
if (config.autoVariants) {
|
|
111
|
+
const variants = getAllFormatVariants().filter((f) => f.type !== project.format.type);
|
|
112
|
+
const variantResults = [];
|
|
113
|
+
for (const variantFormat of variants) {
|
|
114
|
+
const variantPath = resolved.outputPath.replace(/(\.[^.]+)$/, `-${variantFormat.type}$1`);
|
|
115
|
+
const variantProject = {
|
|
116
|
+
...project,
|
|
117
|
+
format: variantFormat
|
|
118
|
+
};
|
|
119
|
+
const variantComposition = await selectComposition({
|
|
120
|
+
serveUrl: bundleLocation,
|
|
121
|
+
id: mainCompositionId,
|
|
122
|
+
inputProps: { project: variantProject }
|
|
123
|
+
});
|
|
124
|
+
await renderMedia({
|
|
125
|
+
composition: variantComposition,
|
|
126
|
+
serveUrl: bundleLocation,
|
|
127
|
+
codec: resolved.codec,
|
|
128
|
+
outputLocation: variantPath,
|
|
129
|
+
inputProps: { project: variantProject },
|
|
130
|
+
...resolved.crf && { crf: resolved.crf }
|
|
131
|
+
});
|
|
132
|
+
variantResults.push({
|
|
133
|
+
outputPath: variantPath,
|
|
134
|
+
format: resolved.outputFormat ?? defaultRenderConfig.outputFormat,
|
|
135
|
+
codec: resolved.codec ?? defaultRenderConfig.codec,
|
|
136
|
+
durationSeconds: project.totalDurationInFrames / project.fps,
|
|
137
|
+
fileSizeBytes: 0,
|
|
138
|
+
dimensions: {
|
|
139
|
+
width: variantFormat.width,
|
|
140
|
+
height: variantFormat.height
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
result.variants = variantResults;
|
|
145
|
+
}
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
export {
|
|
150
|
+
resolveRenderConfig,
|
|
151
|
+
qualityPresets,
|
|
152
|
+
defaultRenderConfig,
|
|
153
|
+
codecFormatMap,
|
|
154
|
+
LocalRenderer
|
|
155
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { RenderConfig, RenderResult, VideoProject, VideoProvider } from '@contractspec/lib.contracts-integrations/integrations/providers/video';
|
|
2
|
+
/**
|
|
3
|
+
* Local video renderer using @remotion/renderer.
|
|
4
|
+
*
|
|
5
|
+
* Usage:
|
|
6
|
+
* ```ts
|
|
7
|
+
* const renderer = new LocalRenderer({ entryPoint: './src/remotion/index.ts' });
|
|
8
|
+
* const result = await renderer.render(project, { outputPath: 'out/video.mp4' });
|
|
9
|
+
* ```
|
|
10
|
+
*/
|
|
11
|
+
export declare class LocalRenderer implements VideoProvider {
|
|
12
|
+
private readonly entryPoint;
|
|
13
|
+
constructor(options: {
|
|
14
|
+
entryPoint: string;
|
|
15
|
+
});
|
|
16
|
+
render(project: VideoProject, config: RenderConfig): Promise<RenderResult>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __require = import.meta.require;
|
|
3
|
+
|
|
4
|
+
// src/design/layouts.ts
|
|
5
|
+
import { VIDEO_FORMATS } from "@contractspec/lib.contracts-integrations/integrations/providers/video";
|
|
6
|
+
var DEFAULT_FPS = 30;
|
|
7
|
+
var videoSafeZone = {
|
|
8
|
+
horizontal: 120,
|
|
9
|
+
vertical: 80,
|
|
10
|
+
contentWidth: 1680,
|
|
11
|
+
contentHeight: 920
|
|
12
|
+
};
|
|
13
|
+
function scaleSafeZone(format) {
|
|
14
|
+
const scaleX = format.width / 1920;
|
|
15
|
+
const scaleY = format.height / 1080;
|
|
16
|
+
return {
|
|
17
|
+
horizontal: Math.round(videoSafeZone.horizontal * scaleX),
|
|
18
|
+
vertical: Math.round(videoSafeZone.vertical * scaleY),
|
|
19
|
+
contentWidth: Math.round(videoSafeZone.contentWidth * scaleX),
|
|
20
|
+
contentHeight: Math.round(videoSafeZone.contentHeight * scaleY)
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
var videoPositions = {
|
|
24
|
+
center: { x: 960, y: 540 },
|
|
25
|
+
topLeft: { x: 120, y: 80 },
|
|
26
|
+
topRight: { x: 1800, y: 80 },
|
|
27
|
+
bottomLeft: { x: 120, y: 1000 },
|
|
28
|
+
bottomRight: { x: 1800, y: 1000 },
|
|
29
|
+
bottomCenter: { x: 960, y: 960 }
|
|
30
|
+
};
|
|
31
|
+
function getAllFormatVariants() {
|
|
32
|
+
return [
|
|
33
|
+
VIDEO_FORMATS.landscape,
|
|
34
|
+
VIDEO_FORMATS.square,
|
|
35
|
+
VIDEO_FORMATS.portrait
|
|
36
|
+
];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/renderers/config.ts
|
|
40
|
+
var defaultRenderConfig = {
|
|
41
|
+
codec: "h264",
|
|
42
|
+
outputFormat: "mp4",
|
|
43
|
+
crf: 18,
|
|
44
|
+
pixelFormat: "yuv420p"
|
|
45
|
+
};
|
|
46
|
+
var codecFormatMap = {
|
|
47
|
+
h264: "mp4",
|
|
48
|
+
h265: "mp4",
|
|
49
|
+
vp8: "webm",
|
|
50
|
+
vp9: "webm"
|
|
51
|
+
};
|
|
52
|
+
var qualityPresets = {
|
|
53
|
+
draft: { crf: 28, concurrency: 1 },
|
|
54
|
+
standard: { crf: 18, concurrency: undefined },
|
|
55
|
+
high: { crf: 12, concurrency: undefined }
|
|
56
|
+
};
|
|
57
|
+
function resolveRenderConfig(userConfig, preset) {
|
|
58
|
+
const presetValues = preset ? qualityPresets[preset] : {};
|
|
59
|
+
return {
|
|
60
|
+
...defaultRenderConfig,
|
|
61
|
+
...presetValues,
|
|
62
|
+
...userConfig
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// src/renderers/local.ts
|
|
67
|
+
class LocalRenderer {
|
|
68
|
+
entryPoint;
|
|
69
|
+
constructor(options) {
|
|
70
|
+
this.entryPoint = options.entryPoint;
|
|
71
|
+
}
|
|
72
|
+
async render(project, config) {
|
|
73
|
+
const resolved = resolveRenderConfig(config);
|
|
74
|
+
const { bundle } = await import("@remotion/bundler");
|
|
75
|
+
const { renderMedia, selectComposition } = await import("@remotion/renderer");
|
|
76
|
+
const bundleLocation = await bundle({
|
|
77
|
+
entryPoint: this.entryPoint
|
|
78
|
+
});
|
|
79
|
+
const firstScene = project.scenes[0];
|
|
80
|
+
const mainCompositionId = project.scenes.length === 1 && firstScene ? firstScene.compositionId : "Master";
|
|
81
|
+
const composition = await selectComposition({
|
|
82
|
+
serveUrl: bundleLocation,
|
|
83
|
+
id: mainCompositionId,
|
|
84
|
+
inputProps: {
|
|
85
|
+
project
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
await renderMedia({
|
|
89
|
+
composition,
|
|
90
|
+
serveUrl: bundleLocation,
|
|
91
|
+
codec: resolved.codec,
|
|
92
|
+
outputLocation: resolved.outputPath,
|
|
93
|
+
inputProps: { project },
|
|
94
|
+
...resolved.crf && { crf: resolved.crf },
|
|
95
|
+
...resolved.concurrency && {
|
|
96
|
+
concurrency: resolved.concurrency
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
const result = {
|
|
100
|
+
outputPath: resolved.outputPath,
|
|
101
|
+
format: resolved.outputFormat ?? defaultRenderConfig.outputFormat,
|
|
102
|
+
codec: resolved.codec ?? defaultRenderConfig.codec,
|
|
103
|
+
durationSeconds: project.totalDurationInFrames / project.fps,
|
|
104
|
+
fileSizeBytes: 0,
|
|
105
|
+
dimensions: {
|
|
106
|
+
width: project.format.width,
|
|
107
|
+
height: project.format.height
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
if (config.autoVariants) {
|
|
111
|
+
const variants = getAllFormatVariants().filter((f) => f.type !== project.format.type);
|
|
112
|
+
const variantResults = [];
|
|
113
|
+
for (const variantFormat of variants) {
|
|
114
|
+
const variantPath = resolved.outputPath.replace(/(\.[^.]+)$/, `-${variantFormat.type}$1`);
|
|
115
|
+
const variantProject = {
|
|
116
|
+
...project,
|
|
117
|
+
format: variantFormat
|
|
118
|
+
};
|
|
119
|
+
const variantComposition = await selectComposition({
|
|
120
|
+
serveUrl: bundleLocation,
|
|
121
|
+
id: mainCompositionId,
|
|
122
|
+
inputProps: { project: variantProject }
|
|
123
|
+
});
|
|
124
|
+
await renderMedia({
|
|
125
|
+
composition: variantComposition,
|
|
126
|
+
serveUrl: bundleLocation,
|
|
127
|
+
codec: resolved.codec,
|
|
128
|
+
outputLocation: variantPath,
|
|
129
|
+
inputProps: { project: variantProject },
|
|
130
|
+
...resolved.crf && { crf: resolved.crf }
|
|
131
|
+
});
|
|
132
|
+
variantResults.push({
|
|
133
|
+
outputPath: variantPath,
|
|
134
|
+
format: resolved.outputFormat ?? defaultRenderConfig.outputFormat,
|
|
135
|
+
codec: resolved.codec ?? defaultRenderConfig.codec,
|
|
136
|
+
durationSeconds: project.totalDurationInFrames / project.fps,
|
|
137
|
+
fileSizeBytes: 0,
|
|
138
|
+
dimensions: {
|
|
139
|
+
width: variantFormat.width,
|
|
140
|
+
height: variantFormat.height
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
result.variants = variantResults;
|
|
145
|
+
}
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
export {
|
|
150
|
+
LocalRenderer
|
|
151
|
+
};
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { LLMProvider } from '@contractspec/lib.contracts-integrations/integrations/providers/llm';
|
|
2
|
+
import type { VoiceProvider } from '@contractspec/lib.contracts-integrations/integrations/providers/voice';
|
|
3
|
+
import type { ContentBrief } from '@contractspec/lib.content-gen/types';
|
|
4
|
+
import type { NarrationConfig, VideoFormat, VideoProject, VideoStyleOverrides } from '@contractspec/lib.contracts-integrations/integrations/providers/video';
|
|
5
|
+
export type { AudioTrack, CompositionMeta, CompositionRegistry, NarrationConfig, RenderConfig, RenderResult, SceneTransition, SceneTransitionType, VideoCodec, VideoFormat, VideoFormatCustom, VideoFormatLandscape, VideoFormatPortrait, VideoFormatSquare, VideoOutputFormat, VideoProject, VideoProjectMetadata, VideoProvider, VideoScene, VideoStyleOverrides, } from '@contractspec/lib.contracts-integrations/integrations/providers/video';
|
|
6
|
+
export { VIDEO_FORMATS } from '@contractspec/lib.contracts-integrations/integrations/providers/video';
|
|
7
|
+
/**
|
|
8
|
+
* Input for the video generation pipeline.
|
|
9
|
+
* Builds on top of ContentBrief to keep a unified content pipeline.
|
|
10
|
+
*/
|
|
11
|
+
export interface VideoBrief {
|
|
12
|
+
/** The content brief driving the video narrative */
|
|
13
|
+
content: ContentBrief;
|
|
14
|
+
/** Target video format / dimensions */
|
|
15
|
+
format: VideoFormat;
|
|
16
|
+
/** Target duration in seconds. Auto-calculated from scenes if omitted. */
|
|
17
|
+
targetDurationSeconds?: number;
|
|
18
|
+
/** Narration configuration */
|
|
19
|
+
narration?: NarrationConfig;
|
|
20
|
+
/** Visual style overrides */
|
|
21
|
+
style?: VideoStyleOverrides;
|
|
22
|
+
/** Composition template to use (if known). Otherwise scene planner picks. */
|
|
23
|
+
compositionId?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface VideoGeneratorOptions {
|
|
26
|
+
/** Optional LLM for enhanced scene planning & script generation */
|
|
27
|
+
llm?: LLMProvider;
|
|
28
|
+
/** Optional voice provider for narration synthesis */
|
|
29
|
+
voice?: VoiceProvider;
|
|
30
|
+
/** LLM model override */
|
|
31
|
+
model?: string;
|
|
32
|
+
/** LLM temperature (0-1). Default 0.4 for determinism. */
|
|
33
|
+
temperature?: number;
|
|
34
|
+
/** Default voice ID for narration */
|
|
35
|
+
defaultVoiceId?: string;
|
|
36
|
+
/** Default FPS. Default 30. */
|
|
37
|
+
fps?: number;
|
|
38
|
+
}
|
|
39
|
+
export interface GeneratedVideo {
|
|
40
|
+
project: VideoProject;
|
|
41
|
+
/** Set after rendering */
|
|
42
|
+
outputPath?: string;
|
|
43
|
+
format: 'mp4' | 'webm' | 'gif';
|
|
44
|
+
/** Auto-generated social format variants */
|
|
45
|
+
variants?: GeneratedVideoVariant[];
|
|
46
|
+
}
|
|
47
|
+
export interface GeneratedVideoVariant {
|
|
48
|
+
format: VideoFormat;
|
|
49
|
+
outputPath: string;
|
|
50
|
+
durationSeconds: number;
|
|
51
|
+
}
|
|
52
|
+
export interface ScenePlan {
|
|
53
|
+
scenes: PlannedScene[];
|
|
54
|
+
estimatedDurationSeconds: number;
|
|
55
|
+
narrationScript?: string;
|
|
56
|
+
}
|
|
57
|
+
export interface PlannedScene {
|
|
58
|
+
compositionId: string;
|
|
59
|
+
props: Record<string, unknown>;
|
|
60
|
+
durationInFrames: number;
|
|
61
|
+
narrationText?: string;
|
|
62
|
+
notes?: string;
|
|
63
|
+
}
|