@happyvertical/smrt-video 0.30.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/AGENTS.md +32 -0
- package/CLAUDE.md +1 -0
- package/LICENSE +7 -0
- package/README.md +146 -0
- package/dist/index.d.ts +1277 -0
- package/dist/index.js +1898 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.json +16449 -0
- package/dist/smrt-knowledge.json +6258 -0
- package/package.json +74 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1277 @@
|
|
|
1
|
+
import { Asset } from '@happyvertical/smrt-assets';
|
|
2
|
+
import { AssetOptions } from '@happyvertical/smrt-assets';
|
|
3
|
+
import { Content } from '@happyvertical/smrt-content';
|
|
4
|
+
import { ContentOptions } from '@happyvertical/smrt-content';
|
|
5
|
+
import { MediaBundleFileDescriptor } from '@happyvertical/smrt-assets';
|
|
6
|
+
import { MediaBundleGpsTrackPoint } from '@happyvertical/smrt-assets';
|
|
7
|
+
import { MediaBundleInspection } from '@happyvertical/smrt-assets';
|
|
8
|
+
import { MediaBundleInspectionLike } from '@happyvertical/smrt-assets';
|
|
9
|
+
import { MediaBundleNormalizedMetadata } from '@happyvertical/smrt-assets';
|
|
10
|
+
import { MediaBundleSupportFileInspection } from '@happyvertical/smrt-assets';
|
|
11
|
+
import { MediaSupportFileVisibility } from '@happyvertical/smrt-assets';
|
|
12
|
+
import { PersistMediaBundleAssetInput } from '@happyvertical/smrt-assets';
|
|
13
|
+
import { PersistMediaBundleAssociationInput } from '@happyvertical/smrt-assets';
|
|
14
|
+
import { persistMediaBundleInspection } from '@happyvertical/smrt-assets';
|
|
15
|
+
import { PersistMediaBundleInspectionOptions } from '@happyvertical/smrt-assets';
|
|
16
|
+
import { PersistMediaBundleInspectionResult } from '@happyvertical/smrt-assets';
|
|
17
|
+
import { PersistMediaBundleMetadataArtifactInput } from '@happyvertical/smrt-assets';
|
|
18
|
+
import { SmrtCollection } from '@happyvertical/smrt-core';
|
|
19
|
+
import { SmrtJunction } from '@happyvertical/smrt-core';
|
|
20
|
+
import { SmrtMediaBundlePersistenceAdapter } from '@happyvertical/smrt-assets';
|
|
21
|
+
import { SmrtObject } from '@happyvertical/smrt-core';
|
|
22
|
+
import { SmrtObjectOptions } from '@happyvertical/smrt-core';
|
|
23
|
+
import { WordTiming } from '@happyvertical/smrt-voice';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Anchor point for character placement in scene
|
|
27
|
+
*/
|
|
28
|
+
export declare interface AnchorPoint {
|
|
29
|
+
/** Anchor point identifier */
|
|
30
|
+
id: string;
|
|
31
|
+
/** Human-readable name */
|
|
32
|
+
name: string;
|
|
33
|
+
/** Position as normalized coordinates (0-1) */
|
|
34
|
+
position: {
|
|
35
|
+
x: number;
|
|
36
|
+
y: number;
|
|
37
|
+
};
|
|
38
|
+
/** Suggested character scale at this point */
|
|
39
|
+
suggestedScale: number;
|
|
40
|
+
/** Ground plane Y coordinate for perspective */
|
|
41
|
+
groundY: number;
|
|
42
|
+
/** Optional viewpoint this anchor belongs to */
|
|
43
|
+
viewpointId?: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Branding configuration for video overlays
|
|
48
|
+
*/
|
|
49
|
+
export declare interface BrandingConfig {
|
|
50
|
+
/** Asset ID for logo overlay */
|
|
51
|
+
logoAssetId?: string | null;
|
|
52
|
+
/** Primary brand color (hex) */
|
|
53
|
+
primaryColor?: string | null;
|
|
54
|
+
/** Background color (hex) */
|
|
55
|
+
backgroundColor?: string | null;
|
|
56
|
+
/** Lower-third template name */
|
|
57
|
+
lowerThirdTemplate?: string | null;
|
|
58
|
+
/** Font family for text overlays */
|
|
59
|
+
fontFamily?: string | null;
|
|
60
|
+
/** Whether to show news ticker */
|
|
61
|
+
tickerEnabled?: boolean;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Virtual character for AI-powered video production
|
|
66
|
+
*
|
|
67
|
+
* Character represents a virtual persona combining:
|
|
68
|
+
* - Visual identity: Seed image for I2V (image-to-video) generation
|
|
69
|
+
* - Voice identity: Link to a VoiceProfile for TTS
|
|
70
|
+
* - Branding: Logo overlays, lower-thirds, colors
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* import { Character } from '@happyvertical/smrt-video';
|
|
75
|
+
*
|
|
76
|
+
* const character = new Character({
|
|
77
|
+
* name: 'Bentley News Anchor',
|
|
78
|
+
* description: 'Professional news anchor for local broadcasts',
|
|
79
|
+
* imageAssetId: 'asset-123',
|
|
80
|
+
* voiceProfileId: 'voice-456',
|
|
81
|
+
* brandingKit: {
|
|
82
|
+
* logoAssetId: 'asset-789',
|
|
83
|
+
* primaryColor: '#1a73e8',
|
|
84
|
+
* lowerThirdTemplate: 'news-standard',
|
|
85
|
+
* tickerEnabled: true,
|
|
86
|
+
* },
|
|
87
|
+
* });
|
|
88
|
+
* await character.save();
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
declare class Character extends SmrtObject {
|
|
92
|
+
/** Tenant ID for multi-tenant isolation */
|
|
93
|
+
tenantId: string | null;
|
|
94
|
+
/** Human-readable name for the character */
|
|
95
|
+
name: string;
|
|
96
|
+
/** Description of the character persona */
|
|
97
|
+
description: string | null;
|
|
98
|
+
/** Asset ID of the seed image for I2V generation */
|
|
99
|
+
imageAssetId: string | null;
|
|
100
|
+
/** Asset ID of pre-baked base motion video */
|
|
101
|
+
baseMotionAssetId: string | null;
|
|
102
|
+
/** Voice profile ID for speech synthesis */
|
|
103
|
+
voiceProfileId: string | null;
|
|
104
|
+
/** Branding configuration for video overlays */
|
|
105
|
+
brandingKit: BrandingConfig;
|
|
106
|
+
/** Character status */
|
|
107
|
+
status: CharacterStatus;
|
|
108
|
+
/** Linked performer for IP-Adapter face consistency */
|
|
109
|
+
performerId: string | null;
|
|
110
|
+
/** Default scene for this character */
|
|
111
|
+
defaultSceneId: string | null;
|
|
112
|
+
/** Scene-specific configurations */
|
|
113
|
+
sceneConfigs: CharacterSceneConfig[];
|
|
114
|
+
/** 1-1 profile record for this character */
|
|
115
|
+
profileId: string | null;
|
|
116
|
+
constructor(options?: CharacterOptions);
|
|
117
|
+
private getCharacterAssetCollection;
|
|
118
|
+
private getLegacyFieldAssetIds;
|
|
119
|
+
private setLegacyFieldAssetId;
|
|
120
|
+
private clearLegacyFieldAssetId;
|
|
121
|
+
getAssets(role?: CharacterAssetRole): Promise<Asset[]>;
|
|
122
|
+
getAssetByRole(role: CharacterAssetRole): Promise<Asset | null>;
|
|
123
|
+
addAsset(asset: Asset, role?: CharacterAssetRole, sortOrder?: number): Promise<void>;
|
|
124
|
+
removeAsset(assetId: string, role?: CharacterAssetRole): Promise<void>;
|
|
125
|
+
/**
|
|
126
|
+
* Check if the character has a pre-baked base motion video
|
|
127
|
+
* @deprecated Use getAssetByRole('base-motion') instead
|
|
128
|
+
*/
|
|
129
|
+
get hasBaseMotion(): boolean;
|
|
130
|
+
/** Check if the character is complete and ready for video generation */
|
|
131
|
+
get isComplete(): boolean;
|
|
132
|
+
}
|
|
133
|
+
export { Character }
|
|
134
|
+
export { Character as PersonalityProfile }
|
|
135
|
+
|
|
136
|
+
export declare class CharacterAsset extends Asset {
|
|
137
|
+
characterId: string | null;
|
|
138
|
+
role: CharacterAssetRole;
|
|
139
|
+
constructor(options?: CharacterAssetOptions);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export declare interface CharacterAssetOptions extends AssetOptions {
|
|
143
|
+
/** Character this asset belongs to */
|
|
144
|
+
characterId?: string | null;
|
|
145
|
+
/** Role of this asset for the character */
|
|
146
|
+
role?: CharacterAssetRole;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/** Roles a character asset can play */
|
|
150
|
+
export declare type CharacterAssetRole = 'seed-image' | 'base-motion' | 'logo';
|
|
151
|
+
|
|
152
|
+
export declare class CharacterCollection extends SmrtCollection<Character> {
|
|
153
|
+
static readonly _itemClass: typeof Character;
|
|
154
|
+
/** Find all characters belonging to a specific tenant */
|
|
155
|
+
findByTenant(tenantId: string): Promise<Character[]>;
|
|
156
|
+
/** Find all global characters (without a tenant) */
|
|
157
|
+
findGlobal(): Promise<Character[]>;
|
|
158
|
+
/** Find characters by performer */
|
|
159
|
+
findByPerformer(performerId: string): Promise<Character[]>;
|
|
160
|
+
/** Find characters that are ready for video generation */
|
|
161
|
+
findReady(): Promise<Character[]>;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Character creation options
|
|
166
|
+
*/
|
|
167
|
+
declare interface CharacterOptions extends SmrtObjectOptions {
|
|
168
|
+
/** Human-readable name for the character */
|
|
169
|
+
name?: string;
|
|
170
|
+
/** Description of the character persona */
|
|
171
|
+
description?: string | null;
|
|
172
|
+
/** Asset ID of the seed image for image-to-video generation */
|
|
173
|
+
imageAssetId?: string | null;
|
|
174
|
+
/** Asset ID of pre-baked base motion video */
|
|
175
|
+
baseMotionAssetId?: string | null;
|
|
176
|
+
/** Voice profile ID for speech synthesis */
|
|
177
|
+
voiceProfileId?: string | null;
|
|
178
|
+
/** Branding configuration for video overlays */
|
|
179
|
+
brandingKit?: BrandingConfig;
|
|
180
|
+
/** Character status */
|
|
181
|
+
status?: CharacterStatus;
|
|
182
|
+
/** Linked performer for IP-Adapter face consistency */
|
|
183
|
+
performerId?: string | null;
|
|
184
|
+
/** Default scene for this character */
|
|
185
|
+
defaultSceneId?: string | null;
|
|
186
|
+
/** Scene-specific configurations */
|
|
187
|
+
sceneConfigs?: CharacterSceneConfig[];
|
|
188
|
+
/** 1-1 profile record for this character */
|
|
189
|
+
profileId?: string | null;
|
|
190
|
+
/** Tenant ID for multi-tenant isolation */
|
|
191
|
+
tenantId?: string | null;
|
|
192
|
+
}
|
|
193
|
+
export { CharacterOptions }
|
|
194
|
+
export { CharacterOptions as PersonalityProfileOptions }
|
|
195
|
+
|
|
196
|
+
export declare class CharacterOwnedAsset extends SmrtObject {
|
|
197
|
+
tenantId: string | null;
|
|
198
|
+
characterId: string;
|
|
199
|
+
assetId: string;
|
|
200
|
+
role: CharacterAssetRole;
|
|
201
|
+
sortOrder: number;
|
|
202
|
+
constructor(options?: CharacterOwnedAssetOptions);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export declare class CharacterOwnedAssetCollection extends SmrtJunction<CharacterOwnedAsset> {
|
|
206
|
+
static readonly _itemClass: typeof CharacterOwnedAsset;
|
|
207
|
+
protected leftField: string;
|
|
208
|
+
protected rightField: string;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export declare interface CharacterOwnedAssetOptions extends SmrtObjectOptions {
|
|
212
|
+
characterId?: string;
|
|
213
|
+
assetId?: string;
|
|
214
|
+
role?: CharacterAssetRole;
|
|
215
|
+
sortOrder?: number;
|
|
216
|
+
tenantId?: string | null;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Scene-specific configuration for a character
|
|
221
|
+
*/
|
|
222
|
+
export declare interface CharacterSceneConfig {
|
|
223
|
+
/** Scene ID */
|
|
224
|
+
sceneId: string;
|
|
225
|
+
/** Preferred viewpoint ID (for 360° scenes) */
|
|
226
|
+
viewpointId?: string;
|
|
227
|
+
/** Anchor point ID for placement */
|
|
228
|
+
anchorPointId?: string;
|
|
229
|
+
/** Character scale in this scene */
|
|
230
|
+
scale: number;
|
|
231
|
+
/** Character position in this scene (normalized 0-1) */
|
|
232
|
+
position: {
|
|
233
|
+
x: number;
|
|
234
|
+
y: number;
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Character status
|
|
240
|
+
*/
|
|
241
|
+
declare type CharacterStatus = 'pending' | 'ready';
|
|
242
|
+
export { CharacterStatus }
|
|
243
|
+
export { CharacterStatus as PersonalityProfileStatus }
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Composite job for tracking virtual production compositing
|
|
247
|
+
*
|
|
248
|
+
* @example
|
|
249
|
+
* ```typescript
|
|
250
|
+
* import { CompositeJob } from '@happyvertical/smrt-video';
|
|
251
|
+
*
|
|
252
|
+
* const job = new CompositeJob({
|
|
253
|
+
* characterVideoAssetId: 'asset-video-123',
|
|
254
|
+
* sceneId: 'scene-townhall',
|
|
255
|
+
* scale: 0.8,
|
|
256
|
+
* position: { x: 0.5, y: 0.7 },
|
|
257
|
+
* });
|
|
258
|
+
* await job.save();
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
export declare class CompositeJob extends SmrtObject {
|
|
262
|
+
tenantId: string | null;
|
|
263
|
+
/** Character video asset ID (after lip-sync) */
|
|
264
|
+
characterVideoAssetId: string | null;
|
|
265
|
+
/** Scene ID to composite onto */
|
|
266
|
+
sceneId: string | null;
|
|
267
|
+
/** Viewpoint ID (for 360° scenes) */
|
|
268
|
+
viewpointId: string | null;
|
|
269
|
+
/** Anchor point ID for placement */
|
|
270
|
+
anchorPointId: string | null;
|
|
271
|
+
/** Character scale */
|
|
272
|
+
scale: number;
|
|
273
|
+
/** Character position (normalized 0-1) */
|
|
274
|
+
position: {
|
|
275
|
+
x: number;
|
|
276
|
+
y: number;
|
|
277
|
+
};
|
|
278
|
+
/** Job status */
|
|
279
|
+
status: CompositeJobStatus;
|
|
280
|
+
/** Progress percentage (0-100) */
|
|
281
|
+
progress: number;
|
|
282
|
+
/** Output video asset ID */
|
|
283
|
+
outputAssetId: string | null;
|
|
284
|
+
/** Error message if failed */
|
|
285
|
+
errorMessage: string | null;
|
|
286
|
+
constructor(options?: CompositeJobOptions);
|
|
287
|
+
/** Check if the job is complete */
|
|
288
|
+
get isComplete(): boolean;
|
|
289
|
+
/** Check if the job is in progress */
|
|
290
|
+
get isProcessing(): boolean;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Composite job creation options
|
|
295
|
+
*/
|
|
296
|
+
export declare interface CompositeJobOptions extends SmrtObjectOptions {
|
|
297
|
+
/** Character video asset ID (after lip-sync) */
|
|
298
|
+
characterVideoAssetId?: string | null;
|
|
299
|
+
/** Scene ID to composite onto */
|
|
300
|
+
sceneId?: string | null;
|
|
301
|
+
/** Viewpoint ID (for 360° scenes) */
|
|
302
|
+
viewpointId?: string | null;
|
|
303
|
+
/** Anchor point ID for placement */
|
|
304
|
+
anchorPointId?: string | null;
|
|
305
|
+
/** Character scale */
|
|
306
|
+
scale?: number;
|
|
307
|
+
/** Character position (normalized 0-1) */
|
|
308
|
+
position?: {
|
|
309
|
+
x: number;
|
|
310
|
+
y: number;
|
|
311
|
+
};
|
|
312
|
+
/** Job status */
|
|
313
|
+
status?: CompositeJobStatus;
|
|
314
|
+
/** Progress percentage (0-100) */
|
|
315
|
+
progress?: number;
|
|
316
|
+
/** Output video asset ID */
|
|
317
|
+
outputAssetId?: string | null;
|
|
318
|
+
/** Error message if failed */
|
|
319
|
+
errorMessage?: string | null;
|
|
320
|
+
/** Tenant ID for multi-tenant isolation */
|
|
321
|
+
tenantId?: string | null;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Composite job status
|
|
326
|
+
*/
|
|
327
|
+
export declare type CompositeJobStatus = 'pending' | 'removing_bg' | 'analyzing_light' | 'compositing' | 'complete' | 'failed';
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Lighting profile for IC-Light matching
|
|
331
|
+
*/
|
|
332
|
+
export declare interface LightingProfile {
|
|
333
|
+
/** Dominant light direction (normalized vector) */
|
|
334
|
+
direction?: {
|
|
335
|
+
x: number;
|
|
336
|
+
y: number;
|
|
337
|
+
z: number;
|
|
338
|
+
};
|
|
339
|
+
/** Light color temperature (Kelvin) */
|
|
340
|
+
colorTemperature?: number;
|
|
341
|
+
/** Ambient light intensity (0-1) */
|
|
342
|
+
ambientIntensity?: number;
|
|
343
|
+
/** Key light intensity (0-1) */
|
|
344
|
+
keyLightIntensity?: number;
|
|
345
|
+
/** Shadow softness (0-1) */
|
|
346
|
+
shadowSoftness?: number;
|
|
347
|
+
/** Environment map asset ID for reflections */
|
|
348
|
+
envMapAssetId?: string;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
export { MediaBundleFileDescriptor }
|
|
352
|
+
|
|
353
|
+
export { MediaBundleGpsTrackPoint }
|
|
354
|
+
|
|
355
|
+
export { MediaBundleInspection }
|
|
356
|
+
|
|
357
|
+
export { MediaBundleInspectionLike }
|
|
358
|
+
|
|
359
|
+
export { MediaBundleNormalizedMetadata }
|
|
360
|
+
|
|
361
|
+
export { MediaBundleSupportFileInspection }
|
|
362
|
+
|
|
363
|
+
export { MediaSupportFileVisibility }
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Node mapping for dynamic parameter injection
|
|
367
|
+
*/
|
|
368
|
+
export declare interface NodeMapping {
|
|
369
|
+
/**
|
|
370
|
+
* Node ID for anchor seed image input
|
|
371
|
+
*/
|
|
372
|
+
seedImage?: string;
|
|
373
|
+
/**
|
|
374
|
+
* Node ID for TTS audio input
|
|
375
|
+
*/
|
|
376
|
+
audioFile?: string;
|
|
377
|
+
/**
|
|
378
|
+
* Node ID for base motion video input
|
|
379
|
+
*/
|
|
380
|
+
baseVideo?: string;
|
|
381
|
+
/**
|
|
382
|
+
* Node ID for final video output
|
|
383
|
+
*/
|
|
384
|
+
outputVideo?: string;
|
|
385
|
+
/**
|
|
386
|
+
* Node ID for text prompt input
|
|
387
|
+
*/
|
|
388
|
+
prompt?: string;
|
|
389
|
+
/**
|
|
390
|
+
* Node ID for negative prompt input
|
|
391
|
+
*/
|
|
392
|
+
negativePrompt?: string;
|
|
393
|
+
/**
|
|
394
|
+
* Node ID for sampler/scheduler settings
|
|
395
|
+
*/
|
|
396
|
+
sampler?: string;
|
|
397
|
+
/**
|
|
398
|
+
* Node ID for video duration control
|
|
399
|
+
*/
|
|
400
|
+
duration?: string;
|
|
401
|
+
/**
|
|
402
|
+
* Additional custom node mappings
|
|
403
|
+
*/
|
|
404
|
+
[key: string]: string | undefined;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Performer - The physical likeness/face DNA
|
|
409
|
+
*
|
|
410
|
+
* A Performer represents a person's visual identity for consistent
|
|
411
|
+
* face generation across multiple Characters. One Performer can play
|
|
412
|
+
* many Characters (e.g., same face as "Evening Anchor" and "Weekend Host").
|
|
413
|
+
*
|
|
414
|
+
* @example
|
|
415
|
+
* ```typescript
|
|
416
|
+
* import { Performer } from '@happyvertical/smrt-video';
|
|
417
|
+
*
|
|
418
|
+
* const performer = new Performer({
|
|
419
|
+
* name: 'Alex Bentley',
|
|
420
|
+
* dna: {
|
|
421
|
+
* gender: 'male',
|
|
422
|
+
* ageRange: 'adult',
|
|
423
|
+
* ipAdapterWeight: 0.75,
|
|
424
|
+
* },
|
|
425
|
+
* referenceAssetIds: ['ref-img-1', 'ref-img-2'],
|
|
426
|
+
* });
|
|
427
|
+
* await performer.save();
|
|
428
|
+
* ```
|
|
429
|
+
*/
|
|
430
|
+
export declare class Performer extends SmrtObject {
|
|
431
|
+
tenantId: string | null;
|
|
432
|
+
/** Human-readable name */
|
|
433
|
+
name: string;
|
|
434
|
+
/** Description */
|
|
435
|
+
description: string | null;
|
|
436
|
+
/** Performer DNA for consistent face generation */
|
|
437
|
+
dna: PerformerDNA;
|
|
438
|
+
/** Reference images for IP-Adapter (multiple angles/expressions) */
|
|
439
|
+
referenceAssetIds: string[];
|
|
440
|
+
/** Generated seed image asset ID */
|
|
441
|
+
seedImageAssetId: string | null;
|
|
442
|
+
/** Default voice profile for this performer */
|
|
443
|
+
voiceProfileId: string | null;
|
|
444
|
+
/** Performer status */
|
|
445
|
+
status: PerformerStatus;
|
|
446
|
+
/** 1-1 profile record for this performer */
|
|
447
|
+
profileId: string | null;
|
|
448
|
+
constructor(options?: PerformerOptions);
|
|
449
|
+
private getPerformerAssetCollection;
|
|
450
|
+
private getLegacyFieldAssetIds;
|
|
451
|
+
private setLegacyFieldAssetId;
|
|
452
|
+
private clearLegacyFieldAssetId;
|
|
453
|
+
getAssets(role?: PerformerAssetRole): Promise<Asset[]>;
|
|
454
|
+
getAssetByRole(role: PerformerAssetRole): Promise<Asset | null>;
|
|
455
|
+
addAsset(asset: Asset, role?: PerformerAssetRole, sortOrder?: number): Promise<void>;
|
|
456
|
+
removeAsset(assetId: string, role?: PerformerAssetRole): Promise<void>;
|
|
457
|
+
/** Check if the performer has reference images */
|
|
458
|
+
get hasReferences(): boolean;
|
|
459
|
+
/** Check if the performer has a face embedding */
|
|
460
|
+
get hasFaceEmbedding(): boolean;
|
|
461
|
+
/** Check if the performer is ready for generation */
|
|
462
|
+
get isReady(): boolean;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
export declare class PerformerAsset extends Asset {
|
|
466
|
+
performerId: string | null;
|
|
467
|
+
role: PerformerAssetRole;
|
|
468
|
+
constructor(options?: PerformerAssetOptions);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
export declare interface PerformerAssetOptions extends AssetOptions {
|
|
472
|
+
/** Performer this asset belongs to */
|
|
473
|
+
performerId?: string | null;
|
|
474
|
+
/** Role of this asset for the performer */
|
|
475
|
+
role?: PerformerAssetRole;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
/** Roles a performer asset can play */
|
|
479
|
+
export declare type PerformerAssetRole = 'reference' | 'seed';
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Performer DNA for IP-Adapter FaceID consistency
|
|
483
|
+
*/
|
|
484
|
+
export declare interface PerformerDNA {
|
|
485
|
+
/** Gender */
|
|
486
|
+
gender: 'male' | 'female' | 'neutral';
|
|
487
|
+
/** Age range */
|
|
488
|
+
ageRange: 'child' | 'teen' | 'young_adult' | 'adult' | 'middle_aged' | 'senior';
|
|
489
|
+
/** Face embedding for IP-Adapter FaceID (512-dim vector) */
|
|
490
|
+
faceEmbedding?: number[];
|
|
491
|
+
/** Default clothing style (can be overridden per Character) */
|
|
492
|
+
defaultClothing?: {
|
|
493
|
+
style: 'business' | 'casual' | 'formal' | 'outdoor';
|
|
494
|
+
colors?: string[];
|
|
495
|
+
description?: string;
|
|
496
|
+
};
|
|
497
|
+
/** IP-Adapter weight for consistency (0.5-1.0) */
|
|
498
|
+
ipAdapterWeight: number;
|
|
499
|
+
/** FaceID weight for face consistency */
|
|
500
|
+
faceIdWeight?: number;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Performer creation options
|
|
505
|
+
*/
|
|
506
|
+
export declare interface PerformerOptions extends SmrtObjectOptions {
|
|
507
|
+
/** Human-readable name */
|
|
508
|
+
name?: string;
|
|
509
|
+
/** Description */
|
|
510
|
+
description?: string | null;
|
|
511
|
+
/** Performer DNA for consistent face generation */
|
|
512
|
+
dna?: PerformerDNA;
|
|
513
|
+
/** Reference images for IP-Adapter (multiple angles/expressions) */
|
|
514
|
+
referenceAssetIds?: string[];
|
|
515
|
+
/** Generated seed image asset ID */
|
|
516
|
+
seedImageAssetId?: string | null;
|
|
517
|
+
/** Default voice profile for this performer */
|
|
518
|
+
voiceProfileId?: string | null;
|
|
519
|
+
/** Performer status */
|
|
520
|
+
status?: PerformerStatus;
|
|
521
|
+
/** 1-1 profile record for this performer */
|
|
522
|
+
profileId?: string | null;
|
|
523
|
+
/** Tenant ID for multi-tenant isolation */
|
|
524
|
+
tenantId?: string | null;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
export declare class PerformerOwnedAsset extends SmrtObject {
|
|
528
|
+
tenantId: string | null;
|
|
529
|
+
performerId: string;
|
|
530
|
+
assetId: string;
|
|
531
|
+
role: PerformerAssetRole;
|
|
532
|
+
sortOrder: number;
|
|
533
|
+
constructor(options?: PerformerOwnedAssetOptions);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
export declare class PerformerOwnedAssetCollection extends SmrtJunction<PerformerOwnedAsset> {
|
|
537
|
+
static readonly _itemClass: typeof PerformerOwnedAsset;
|
|
538
|
+
protected leftField: string;
|
|
539
|
+
protected rightField: string;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
export declare interface PerformerOwnedAssetOptions extends SmrtObjectOptions {
|
|
543
|
+
performerId?: string;
|
|
544
|
+
assetId?: string;
|
|
545
|
+
role?: PerformerAssetRole;
|
|
546
|
+
sortOrder?: number;
|
|
547
|
+
tenantId?: string | null;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Performer status
|
|
552
|
+
*/
|
|
553
|
+
export declare type PerformerStatus = 'pending' | 'ready';
|
|
554
|
+
|
|
555
|
+
export { PersistMediaBundleAssetInput }
|
|
556
|
+
|
|
557
|
+
export { PersistMediaBundleAssociationInput }
|
|
558
|
+
|
|
559
|
+
export { persistMediaBundleInspection }
|
|
560
|
+
|
|
561
|
+
export { PersistMediaBundleInspectionOptions }
|
|
562
|
+
|
|
563
|
+
export { PersistMediaBundleInspectionResult }
|
|
564
|
+
|
|
565
|
+
export { PersistMediaBundleMetadataArtifactInput }
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* Render status for the composition
|
|
569
|
+
*/
|
|
570
|
+
export declare type RenderStatus = 'draft' | 'rendering' | 'ready' | 'failed';
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* Scene for virtual production compositing
|
|
574
|
+
*
|
|
575
|
+
* Supports 360° panoramas, standard images, and video backgrounds
|
|
576
|
+
* with viewpoint extraction, lighting analysis, and character placement.
|
|
577
|
+
*
|
|
578
|
+
* @example
|
|
579
|
+
* ```typescript
|
|
580
|
+
* import { Scene } from '@happyvertical/smrt-video';
|
|
581
|
+
*
|
|
582
|
+
* const scene = new Scene({
|
|
583
|
+
* name: 'Town Hall Exterior',
|
|
584
|
+
* sourceAssetId: 'asset-townhall-pano',
|
|
585
|
+
* sourceType: 'panorama_360',
|
|
586
|
+
* projection: 'equirectangular',
|
|
587
|
+
* });
|
|
588
|
+
* await scene.save();
|
|
589
|
+
* ```
|
|
590
|
+
*/
|
|
591
|
+
export declare class Scene extends SmrtObject {
|
|
592
|
+
tenantId: string | null;
|
|
593
|
+
/** Human-readable name */
|
|
594
|
+
name: string;
|
|
595
|
+
/** Description */
|
|
596
|
+
description: string | null;
|
|
597
|
+
/** Source media asset ID */
|
|
598
|
+
sourceAssetId: string | null;
|
|
599
|
+
/** Type of source media */
|
|
600
|
+
sourceType: SceneSourceType;
|
|
601
|
+
/** Projection type for panoramas */
|
|
602
|
+
projection: SceneProjection | null;
|
|
603
|
+
/** Extracted camera angles from 360° panoramas */
|
|
604
|
+
viewpoints: SceneViewpoint[];
|
|
605
|
+
/** Lighting analysis for IC-Light matching */
|
|
606
|
+
lightingProfile: LightingProfile | null;
|
|
607
|
+
/** Location metadata */
|
|
608
|
+
location: {
|
|
609
|
+
name: string;
|
|
610
|
+
coordinates?: {
|
|
611
|
+
lat: number;
|
|
612
|
+
lng: number;
|
|
613
|
+
};
|
|
614
|
+
} | null;
|
|
615
|
+
/** Anchor points for character placement */
|
|
616
|
+
anchorPoints: AnchorPoint[];
|
|
617
|
+
/** Scene status */
|
|
618
|
+
status: SceneStatus;
|
|
619
|
+
constructor(options?: SceneOptions);
|
|
620
|
+
private getSceneAssetCollection;
|
|
621
|
+
private getLegacyFieldAssetIds;
|
|
622
|
+
private setLegacyFieldAssetId;
|
|
623
|
+
private clearLegacyFieldAssetId;
|
|
624
|
+
getAssets(role?: SceneAssetRole): Promise<Asset[]>;
|
|
625
|
+
getAssetByRole(role: SceneAssetRole): Promise<Asset | null>;
|
|
626
|
+
addAsset(asset: Asset, role?: SceneAssetRole, sortOrder?: number): Promise<void>;
|
|
627
|
+
removeAsset(assetId: string, role?: SceneAssetRole): Promise<void>;
|
|
628
|
+
/** Check if this is a 360° panorama */
|
|
629
|
+
get isPanorama(): boolean;
|
|
630
|
+
/** Check if the scene has viewpoints extracted */
|
|
631
|
+
get hasViewpoints(): boolean;
|
|
632
|
+
/** Check if the scene is ready for compositing */
|
|
633
|
+
get isReady(): boolean;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
export declare class SceneAsset extends Asset {
|
|
637
|
+
sceneId: string | null;
|
|
638
|
+
role: SceneAssetRole;
|
|
639
|
+
constructor(options?: SceneAssetOptions);
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
export declare interface SceneAssetOptions extends AssetOptions {
|
|
643
|
+
/** Scene this asset belongs to */
|
|
644
|
+
sceneId?: string | null;
|
|
645
|
+
/** Role of this asset for the scene */
|
|
646
|
+
role?: SceneAssetRole;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
/** Roles a scene asset can play */
|
|
650
|
+
export declare type SceneAssetRole = 'source' | 'viewpoint-extract' | 'env-map';
|
|
651
|
+
|
|
652
|
+
/**
|
|
653
|
+
* Scene creation options
|
|
654
|
+
*/
|
|
655
|
+
export declare interface SceneOptions extends SmrtObjectOptions {
|
|
656
|
+
/** Human-readable name */
|
|
657
|
+
name?: string;
|
|
658
|
+
/** Description */
|
|
659
|
+
description?: string | null;
|
|
660
|
+
/** Source media asset ID */
|
|
661
|
+
sourceAssetId?: string | null;
|
|
662
|
+
/** Type of source media */
|
|
663
|
+
sourceType?: SceneSourceType;
|
|
664
|
+
/** Projection type for panoramas */
|
|
665
|
+
projection?: SceneProjection | null;
|
|
666
|
+
/** Extracted camera angles from 360° panoramas */
|
|
667
|
+
viewpoints?: SceneViewpoint[];
|
|
668
|
+
/** Lighting analysis for IC-Light matching */
|
|
669
|
+
lightingProfile?: LightingProfile | null;
|
|
670
|
+
/** Location metadata */
|
|
671
|
+
location?: {
|
|
672
|
+
name: string;
|
|
673
|
+
coordinates?: {
|
|
674
|
+
lat: number;
|
|
675
|
+
lng: number;
|
|
676
|
+
};
|
|
677
|
+
} | null;
|
|
678
|
+
/** Anchor points for character placement */
|
|
679
|
+
anchorPoints?: AnchorPoint[];
|
|
680
|
+
/** Scene status */
|
|
681
|
+
status?: SceneStatus;
|
|
682
|
+
/** Tenant ID for multi-tenant isolation */
|
|
683
|
+
tenantId?: string | null;
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
export declare class SceneOwnedAsset extends SmrtObject {
|
|
687
|
+
tenantId: string | null;
|
|
688
|
+
sceneId: string;
|
|
689
|
+
assetId: string;
|
|
690
|
+
role: SceneAssetRole;
|
|
691
|
+
sortOrder: number;
|
|
692
|
+
constructor(options?: SceneOwnedAssetOptions);
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
export declare class SceneOwnedAssetCollection extends SmrtJunction<SceneOwnedAsset> {
|
|
696
|
+
static readonly _itemClass: typeof SceneOwnedAsset;
|
|
697
|
+
protected leftField: string;
|
|
698
|
+
protected rightField: string;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
export declare interface SceneOwnedAssetOptions extends SmrtObjectOptions {
|
|
702
|
+
sceneId?: string;
|
|
703
|
+
assetId?: string;
|
|
704
|
+
role?: SceneAssetRole;
|
|
705
|
+
sortOrder?: number;
|
|
706
|
+
tenantId?: string | null;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* Scene projection type
|
|
711
|
+
*/
|
|
712
|
+
export declare type SceneProjection = 'equirectangular' | 'cubemap';
|
|
713
|
+
|
|
714
|
+
/**
|
|
715
|
+
* Scene source type
|
|
716
|
+
*/
|
|
717
|
+
export declare type SceneSourceType = 'image' | 'video' | 'panorama_360' | 'panorama_180';
|
|
718
|
+
|
|
719
|
+
/**
|
|
720
|
+
* Scene status
|
|
721
|
+
*/
|
|
722
|
+
export declare type SceneStatus = 'pending' | 'processing' | 'ready' | 'failed';
|
|
723
|
+
|
|
724
|
+
/**
|
|
725
|
+
* Viewpoint extracted from 360° scene
|
|
726
|
+
*/
|
|
727
|
+
export declare interface SceneViewpoint {
|
|
728
|
+
/** Viewpoint identifier */
|
|
729
|
+
id: string;
|
|
730
|
+
/** Human-readable name */
|
|
731
|
+
name: string;
|
|
732
|
+
/** Horizontal rotation (-180 to 180°) */
|
|
733
|
+
pan: number;
|
|
734
|
+
/** Vertical rotation (-90 to 90°) */
|
|
735
|
+
tilt: number;
|
|
736
|
+
/** Field of view (60-120°) */
|
|
737
|
+
fov: number;
|
|
738
|
+
/** Generated rectilinear image asset ID */
|
|
739
|
+
extractedAssetId?: string;
|
|
740
|
+
/** Viewpoint-specific lighting profile */
|
|
741
|
+
lightingProfile?: LightingProfile;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
export { SmrtMediaBundlePersistenceAdapter }
|
|
745
|
+
|
|
746
|
+
/**
|
|
747
|
+
* Transition type to the next sequence
|
|
748
|
+
*/
|
|
749
|
+
export declare type TransitionType = 'none' | 'fade' | 'slide' | 'wipe';
|
|
750
|
+
|
|
751
|
+
/**
|
|
752
|
+
* Publishable video composition
|
|
753
|
+
*
|
|
754
|
+
* VideoComposition is the top-level container for a rendered video.
|
|
755
|
+
* It defines the render spec and contains ordered VideoSequences.
|
|
756
|
+
*
|
|
757
|
+
* @example
|
|
758
|
+
* ```typescript
|
|
759
|
+
* import { VideoComposition } from '@happyvertical/smrt-video';
|
|
760
|
+
*
|
|
761
|
+
* const composition = new VideoComposition({
|
|
762
|
+
* title: 'Evening News - January 25, 2026',
|
|
763
|
+
* fps: 30,
|
|
764
|
+
* width: 1920,
|
|
765
|
+
* height: 1080,
|
|
766
|
+
* });
|
|
767
|
+
* await composition.save();
|
|
768
|
+
* ```
|
|
769
|
+
*/
|
|
770
|
+
export declare class VideoComposition extends Content {
|
|
771
|
+
/** Frames per second — everything downstream is in frames */
|
|
772
|
+
fps: number;
|
|
773
|
+
/** Render width in pixels */
|
|
774
|
+
width: number;
|
|
775
|
+
/** Render height in pixels */
|
|
776
|
+
height: number;
|
|
777
|
+
/** Computed total: sum of sequences minus transition overlaps */
|
|
778
|
+
durationInFrames: number;
|
|
779
|
+
/** Render status */
|
|
780
|
+
renderStatus: RenderStatus;
|
|
781
|
+
/** Render progress (0-100) */
|
|
782
|
+
renderProgress: number;
|
|
783
|
+
constructor(options?: VideoCompositionOptions);
|
|
784
|
+
/** Duration in seconds */
|
|
785
|
+
get durationInSeconds(): number;
|
|
786
|
+
/** Check if the composition is ready for publishing */
|
|
787
|
+
get isReady(): boolean;
|
|
788
|
+
/** Check if the composition is currently rendering */
|
|
789
|
+
get isRendering(): boolean;
|
|
790
|
+
getAssets(relationship?: string): Promise<Asset[]>;
|
|
791
|
+
getAssets(role?: VideoCompositionAssetRole): Promise<Asset[]>;
|
|
792
|
+
getAssetByRole(role: VideoCompositionAssetRole): Promise<Asset | null>;
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
export declare class VideoCompositionAsset extends Asset {
|
|
796
|
+
videoCompositionId: string | null;
|
|
797
|
+
role: VideoCompositionAssetRole;
|
|
798
|
+
constructor(options?: VideoCompositionAssetOptions);
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
export declare interface VideoCompositionAssetOptions extends AssetOptions {
|
|
802
|
+
/** VideoComposition this asset belongs to */
|
|
803
|
+
videoCompositionId?: string | null;
|
|
804
|
+
/** Role of this asset for the composition */
|
|
805
|
+
role?: VideoCompositionAssetRole;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
/** Roles a video composition asset can play */
|
|
809
|
+
export declare type VideoCompositionAssetRole = 'video' | 'audio' | 'thumbnail';
|
|
810
|
+
|
|
811
|
+
export declare class VideoCompositionCollection extends SmrtCollection<VideoComposition> {
|
|
812
|
+
static readonly _itemClass: typeof VideoComposition;
|
|
813
|
+
/** Find compositions by render status */
|
|
814
|
+
findByRenderStatus(renderStatus: RenderStatus): Promise<VideoComposition[]>;
|
|
815
|
+
/** Find compositions that are ready for publishing */
|
|
816
|
+
findReady(): Promise<VideoComposition[]>;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
/**
|
|
820
|
+
* VideoComposition creation options
|
|
821
|
+
*/
|
|
822
|
+
export declare interface VideoCompositionOptions extends ContentOptions {
|
|
823
|
+
/** Frames per second (e.g., 30) — everything downstream is in frames */
|
|
824
|
+
fps?: number;
|
|
825
|
+
/** Render width in pixels */
|
|
826
|
+
width?: number;
|
|
827
|
+
/** Render height in pixels */
|
|
828
|
+
height?: number;
|
|
829
|
+
/** Computed total: sum of sequences minus transition overlaps */
|
|
830
|
+
durationInFrames?: number;
|
|
831
|
+
/** Render status */
|
|
832
|
+
renderStatus?: RenderStatus;
|
|
833
|
+
/** Render progress (0-100) */
|
|
834
|
+
renderProgress?: number;
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
/**
|
|
838
|
+
* Video metadata
|
|
839
|
+
*/
|
|
840
|
+
export declare interface VideoMetadata {
|
|
841
|
+
/** Actual duration in seconds */
|
|
842
|
+
duration?: number;
|
|
843
|
+
/** Video resolution (e.g., "1920x1080") */
|
|
844
|
+
resolution?: string;
|
|
845
|
+
/** Aspect ratio (e.g., "16:9", "9:16") */
|
|
846
|
+
aspectRatio?: string;
|
|
847
|
+
/** Video codec (e.g., "h264", "h265") */
|
|
848
|
+
codec?: string;
|
|
849
|
+
/** Frames per second */
|
|
850
|
+
fps?: number;
|
|
851
|
+
/** File size in bytes */
|
|
852
|
+
fileSize?: number;
|
|
853
|
+
/** Word timing data from TTS for lip-sync */
|
|
854
|
+
wordTimings?: WordTiming[];
|
|
855
|
+
/** ComfyUI prompt ID for tracking */
|
|
856
|
+
comfyPromptId?: string;
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
/**
|
|
860
|
+
* Thematic section of a video composition
|
|
861
|
+
*
|
|
862
|
+
* VideoSequence groups VideoShots into a logical section. It can belong
|
|
863
|
+
* to a VideoComposition or exist standalone (e.g., during long-video generation).
|
|
864
|
+
*
|
|
865
|
+
* @example
|
|
866
|
+
* ```typescript
|
|
867
|
+
* import { VideoSequence } from '@happyvertical/smrt-video';
|
|
868
|
+
*
|
|
869
|
+
* const sequence = new VideoSequence({
|
|
870
|
+
* title: 'Top Story',
|
|
871
|
+
* position: 0,
|
|
872
|
+
* transitionType: 'fade',
|
|
873
|
+
* transitionDurationFrames: 15,
|
|
874
|
+
* });
|
|
875
|
+
* await sequence.save();
|
|
876
|
+
* ```
|
|
877
|
+
*/
|
|
878
|
+
export declare class VideoSequence extends Content {
|
|
879
|
+
/** Composition this sequence belongs to */
|
|
880
|
+
compositionId: string | null;
|
|
881
|
+
/** Order within composition */
|
|
882
|
+
position: number;
|
|
883
|
+
/** Computed duration: sum of shot frames */
|
|
884
|
+
durationInFrames: number;
|
|
885
|
+
/** Transition type to the next sequence */
|
|
886
|
+
transitionType: TransitionType;
|
|
887
|
+
/** Overlap frames with next sequence for transition */
|
|
888
|
+
transitionDurationFrames: number;
|
|
889
|
+
constructor(options?: VideoSequenceOptions);
|
|
890
|
+
getAssets(relationship?: string): Promise<Asset[]>;
|
|
891
|
+
getAssets(role?: VideoSequenceAssetRole): Promise<Asset[]>;
|
|
892
|
+
getAssetByRole(role: VideoSequenceAssetRole): Promise<Asset | null>;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
export declare class VideoSequenceAsset extends Asset {
|
|
896
|
+
videoSequenceId: string | null;
|
|
897
|
+
role: VideoSequenceAssetRole;
|
|
898
|
+
constructor(options?: VideoSequenceAssetOptions);
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
export declare interface VideoSequenceAssetOptions extends AssetOptions {
|
|
902
|
+
/** VideoSequence this asset belongs to */
|
|
903
|
+
videoSequenceId?: string | null;
|
|
904
|
+
/** Role of this asset for the sequence */
|
|
905
|
+
role?: VideoSequenceAssetRole;
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
/** Roles a video sequence asset can play */
|
|
909
|
+
export declare type VideoSequenceAssetRole = 'video' | 'audio' | 'thumbnail';
|
|
910
|
+
|
|
911
|
+
export declare class VideoSequenceCollection extends SmrtCollection<VideoSequence> {
|
|
912
|
+
static readonly _itemClass: typeof VideoSequence;
|
|
913
|
+
/** Find sequences belonging to a composition, ordered by position */
|
|
914
|
+
findByComposition(compositionId: string): Promise<VideoSequence[]>;
|
|
915
|
+
/** Find standalone sequences (not in any composition) */
|
|
916
|
+
findStandalone(): Promise<VideoSequence[]>;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
/**
|
|
920
|
+
* VideoSequence creation options
|
|
921
|
+
*/
|
|
922
|
+
export declare interface VideoSequenceOptions extends ContentOptions {
|
|
923
|
+
/** Composition this sequence belongs to (nullable — can exist standalone) */
|
|
924
|
+
compositionId?: string | null;
|
|
925
|
+
/** Order within composition */
|
|
926
|
+
position?: number;
|
|
927
|
+
/** Computed duration: sum of shot frames */
|
|
928
|
+
durationInFrames?: number;
|
|
929
|
+
/** Transition type to the next sequence */
|
|
930
|
+
transitionType?: TransitionType;
|
|
931
|
+
/** Overlap frames with next sequence for transition */
|
|
932
|
+
transitionDurationFrames?: number;
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
/**
|
|
936
|
+
* Atomic video generation unit
|
|
937
|
+
*
|
|
938
|
+
* VideoShot represents a single pipeline run producing one video clip.
|
|
939
|
+
* It can belong to a VideoSequence (for multi-segment long videos) or
|
|
940
|
+
* exist standalone. Characters are linked via the VideoShotCharacter join model.
|
|
941
|
+
*
|
|
942
|
+
* @example
|
|
943
|
+
* ```typescript
|
|
944
|
+
* import { VideoShot } from '@happyvertical/smrt-video';
|
|
945
|
+
*
|
|
946
|
+
* const shot = new VideoShot({
|
|
947
|
+
* scriptText: 'Welcome to the evening news.',
|
|
948
|
+
* targetDuration: 30,
|
|
949
|
+
* title: 'Evening News - Opening',
|
|
950
|
+
* });
|
|
951
|
+
* await shot.save();
|
|
952
|
+
* ```
|
|
953
|
+
*/
|
|
954
|
+
declare class VideoShot extends Content {
|
|
955
|
+
/** Sequence this shot belongs to */
|
|
956
|
+
sequenceId: string | null;
|
|
957
|
+
/** Scene for this shot */
|
|
958
|
+
sceneId: string | null;
|
|
959
|
+
/** Order within sequence */
|
|
960
|
+
position: number;
|
|
961
|
+
/** Actual frame count of generated clip */
|
|
962
|
+
durationInFrames: number;
|
|
963
|
+
/** Frames to skip at start (overlap handling) */
|
|
964
|
+
trimBeforeFrames: number;
|
|
965
|
+
/** Frames to skip at end */
|
|
966
|
+
trimAfterFrames: number;
|
|
967
|
+
/** Script text to be spoken */
|
|
968
|
+
scriptText: string;
|
|
969
|
+
/** Word count in the script */
|
|
970
|
+
scriptWordCount: number;
|
|
971
|
+
/** Target duration in seconds */
|
|
972
|
+
targetDuration: number;
|
|
973
|
+
/** Video generation status */
|
|
974
|
+
shotStatus: VideoShotStatus;
|
|
975
|
+
/** Generation progress (0-100) */
|
|
976
|
+
progress: number;
|
|
977
|
+
/** Error message if status is 'failed' */
|
|
978
|
+
errorMessage: string | null;
|
|
979
|
+
/** Detailed status message for progress tracking */
|
|
980
|
+
statusMessage: string | null;
|
|
981
|
+
/** Video metadata (duration, resolution, etc.) */
|
|
982
|
+
videoMetadata: VideoMetadata;
|
|
983
|
+
constructor(options?: VideoShotOptions);
|
|
984
|
+
/** Estimate speech duration based on word count (2.7 words/sec) */
|
|
985
|
+
get estimatedDuration(): number;
|
|
986
|
+
/** Check if the script length matches target duration (+/- 15%) */
|
|
987
|
+
get isScriptLengthValid(): boolean;
|
|
988
|
+
/** Get the recommended word count for target duration */
|
|
989
|
+
get recommendedWordCount(): {
|
|
990
|
+
min: number;
|
|
991
|
+
max: number;
|
|
992
|
+
target: number;
|
|
993
|
+
};
|
|
994
|
+
/** Effective frame count after trimming */
|
|
995
|
+
get effectiveFrames(): number;
|
|
996
|
+
/** Check if video generation is in progress */
|
|
997
|
+
get isGenerating(): boolean;
|
|
998
|
+
/** Check if video is ready for publishing */
|
|
999
|
+
get isReady(): boolean;
|
|
1000
|
+
getAssets(relationship?: string): Promise<Asset[]>;
|
|
1001
|
+
getAssets(role?: VideoShotAssetRole): Promise<Asset[]>;
|
|
1002
|
+
getAssetByRole(role: VideoShotAssetRole): Promise<Asset | null>;
|
|
1003
|
+
/** Update script text and recalculate word count */
|
|
1004
|
+
setScript(text: string): void;
|
|
1005
|
+
}
|
|
1006
|
+
export { VideoShot as VideoContent }
|
|
1007
|
+
export { VideoShot }
|
|
1008
|
+
|
|
1009
|
+
export declare class VideoShotAsset extends Asset {
|
|
1010
|
+
videoShotId: string | null;
|
|
1011
|
+
role: VideoShotAssetRole;
|
|
1012
|
+
constructor(options?: VideoShotAssetOptions);
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
export declare interface VideoShotAssetOptions extends AssetOptions {
|
|
1016
|
+
/** VideoShot this asset belongs to */
|
|
1017
|
+
videoShotId?: string | null;
|
|
1018
|
+
/** Role of this asset for the shot */
|
|
1019
|
+
role?: VideoShotAssetRole;
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
/** Roles a video shot asset can play */
|
|
1023
|
+
export declare type VideoShotAssetRole = 'video' | 'audio' | 'thumbnail';
|
|
1024
|
+
|
|
1025
|
+
/**
|
|
1026
|
+
* Join model linking a VideoShot to a Character
|
|
1027
|
+
*
|
|
1028
|
+
* @example
|
|
1029
|
+
* ```typescript
|
|
1030
|
+
* import { VideoShotCharacter } from '@happyvertical/smrt-video';
|
|
1031
|
+
*
|
|
1032
|
+
* const link = new VideoShotCharacter({
|
|
1033
|
+
* videoShotId: 'shot-123',
|
|
1034
|
+
* characterId: 'char-456',
|
|
1035
|
+
* role: 'primary',
|
|
1036
|
+
* position: 0,
|
|
1037
|
+
* });
|
|
1038
|
+
* await link.save();
|
|
1039
|
+
* ```
|
|
1040
|
+
*/
|
|
1041
|
+
export declare class VideoShotCharacter extends SmrtObject {
|
|
1042
|
+
tenantId: string | null;
|
|
1043
|
+
/** Video shot ID */
|
|
1044
|
+
videoShotId: string;
|
|
1045
|
+
/** Character ID */
|
|
1046
|
+
characterId: string;
|
|
1047
|
+
/** Role of the character in this shot */
|
|
1048
|
+
role: VideoShotCharacterRole;
|
|
1049
|
+
/** Order/layer position within the shot */
|
|
1050
|
+
position: number;
|
|
1051
|
+
constructor(options: VideoShotCharacterOptions);
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
export declare class VideoShotCharacterCollection extends SmrtCollection<VideoShotCharacter> {
|
|
1055
|
+
static readonly _itemClass: typeof VideoShotCharacter;
|
|
1056
|
+
/** Find all character links for a shot, ordered by position */
|
|
1057
|
+
findByShot(videoShotId: string): Promise<VideoShotCharacter[]>;
|
|
1058
|
+
/** Find all shot links for a character */
|
|
1059
|
+
findByCharacter(characterId: string): Promise<VideoShotCharacter[]>;
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
/**
|
|
1063
|
+
* VideoShotCharacter creation options
|
|
1064
|
+
*/
|
|
1065
|
+
export declare interface VideoShotCharacterOptions extends SmrtObjectOptions {
|
|
1066
|
+
/** Video shot ID */
|
|
1067
|
+
videoShotId: string;
|
|
1068
|
+
/** Character ID */
|
|
1069
|
+
characterId: string;
|
|
1070
|
+
/** Role of the character in this shot */
|
|
1071
|
+
role?: VideoShotCharacterRole;
|
|
1072
|
+
/** Order/layer position within the shot */
|
|
1073
|
+
position?: number;
|
|
1074
|
+
/** Tenant ID for multi-tenant isolation */
|
|
1075
|
+
tenantId?: string | null;
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
/**
|
|
1079
|
+
* Character role within a shot
|
|
1080
|
+
*/
|
|
1081
|
+
export declare type VideoShotCharacterRole = 'primary' | 'secondary' | 'background';
|
|
1082
|
+
|
|
1083
|
+
export declare class VideoShotCollection extends SmrtCollection<VideoShot> {
|
|
1084
|
+
static readonly _itemClass: typeof VideoShot;
|
|
1085
|
+
/** Find shots belonging to a specific sequence, ordered by position */
|
|
1086
|
+
findBySequence(sequenceId: string): Promise<VideoShot[]>;
|
|
1087
|
+
/** Find shots by status */
|
|
1088
|
+
findByStatus(shotStatus: VideoShotStatus): Promise<VideoShot[]>;
|
|
1089
|
+
/** Find standalone shots (not in any sequence) */
|
|
1090
|
+
findStandalone(): Promise<VideoShot[]>;
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
/**
|
|
1094
|
+
* Video shot creation options
|
|
1095
|
+
*/
|
|
1096
|
+
declare interface VideoShotOptions extends ContentOptions {
|
|
1097
|
+
/** Sequence this shot belongs to (nullable — shots can exist standalone) */
|
|
1098
|
+
sequenceId?: string | null;
|
|
1099
|
+
/** Scene for this shot (nullable) */
|
|
1100
|
+
sceneId?: string | null;
|
|
1101
|
+
/** Order within sequence */
|
|
1102
|
+
position?: number;
|
|
1103
|
+
/** Actual frame count of generated clip */
|
|
1104
|
+
durationInFrames?: number;
|
|
1105
|
+
/** Frames to skip at start (overlap handling) */
|
|
1106
|
+
trimBeforeFrames?: number;
|
|
1107
|
+
/** Frames to skip at end */
|
|
1108
|
+
trimAfterFrames?: number;
|
|
1109
|
+
/** Script text to be spoken */
|
|
1110
|
+
scriptText?: string;
|
|
1111
|
+
/** Word count in the script */
|
|
1112
|
+
scriptWordCount?: number;
|
|
1113
|
+
/** Target duration in seconds */
|
|
1114
|
+
targetDuration?: number;
|
|
1115
|
+
/** Video generation status */
|
|
1116
|
+
shotStatus?: VideoShotStatus;
|
|
1117
|
+
/** Generation progress (0-100) */
|
|
1118
|
+
progress?: number;
|
|
1119
|
+
/** Error message if status is 'failed' */
|
|
1120
|
+
errorMessage?: string | null;
|
|
1121
|
+
/** Detailed status message for progress tracking */
|
|
1122
|
+
statusMessage?: string | null;
|
|
1123
|
+
/** Video metadata */
|
|
1124
|
+
videoMetadata?: VideoMetadata;
|
|
1125
|
+
}
|
|
1126
|
+
export { VideoShotOptions as VideoContentOptions }
|
|
1127
|
+
export { VideoShotOptions }
|
|
1128
|
+
|
|
1129
|
+
/**
|
|
1130
|
+
* Video shot status
|
|
1131
|
+
*/
|
|
1132
|
+
declare type VideoShotStatus = 'draft' | 'queued' | 'processing' | 'ready' | 'failed' | 'published';
|
|
1133
|
+
export { VideoShotStatus as VideoContentStatus }
|
|
1134
|
+
export { VideoShotStatus }
|
|
1135
|
+
|
|
1136
|
+
/**
|
|
1137
|
+
* ComfyUI workflow template for video generation
|
|
1138
|
+
*
|
|
1139
|
+
* VideoWorkflow stores ComfyUI workflow definitions with node mappings
|
|
1140
|
+
* for dynamic parameter injection. This allows the Histrio agent to
|
|
1141
|
+
* inject anchor images, audio, and other inputs at runtime.
|
|
1142
|
+
*
|
|
1143
|
+
* @example
|
|
1144
|
+
* ```typescript
|
|
1145
|
+
* import { VideoWorkflow } from '@happyvertical/smrt-video';
|
|
1146
|
+
*
|
|
1147
|
+
* const workflow = new VideoWorkflow({
|
|
1148
|
+
* name: 'Wan 2.6 + EchoMimic',
|
|
1149
|
+
* description: 'Full broadcast generation with lip-sync',
|
|
1150
|
+
* workflowType: 'broadcast',
|
|
1151
|
+
* workflowJson: comfyuiWorkflowJson,
|
|
1152
|
+
* nodeMapping: {
|
|
1153
|
+
* seedImage: '1',
|
|
1154
|
+
* audioFile: '5',
|
|
1155
|
+
* outputVideo: '12',
|
|
1156
|
+
* },
|
|
1157
|
+
* estimatedTime: 600, // 10 minutes
|
|
1158
|
+
* requiredModels: ['wan_2.6_t2v_14b_fp8', 'echomimic_v2'],
|
|
1159
|
+
* });
|
|
1160
|
+
* await workflow.save();
|
|
1161
|
+
* ```
|
|
1162
|
+
*/
|
|
1163
|
+
export declare class VideoWorkflow extends SmrtObject {
|
|
1164
|
+
/**
|
|
1165
|
+
* Tenant ID for multi-tenant isolation
|
|
1166
|
+
*/
|
|
1167
|
+
tenantId: string | null;
|
|
1168
|
+
/**
|
|
1169
|
+
* Human-readable name for the workflow
|
|
1170
|
+
*/
|
|
1171
|
+
name: string;
|
|
1172
|
+
/**
|
|
1173
|
+
* Description of what this workflow does
|
|
1174
|
+
*/
|
|
1175
|
+
description: string | null;
|
|
1176
|
+
/**
|
|
1177
|
+
* Workflow type classification
|
|
1178
|
+
* - prebake: Pre-generate base motion from seed image
|
|
1179
|
+
* - broadcast: Full video generation pipeline
|
|
1180
|
+
* - lipsync: Lip-sync only (requires base video + audio)
|
|
1181
|
+
* - postprod: Post-production overlays and effects
|
|
1182
|
+
* - custom: User-defined workflow
|
|
1183
|
+
*/
|
|
1184
|
+
workflowType: WorkflowType;
|
|
1185
|
+
/**
|
|
1186
|
+
* ComfyUI API format JSON
|
|
1187
|
+
* This is the workflow definition that will be sent to ComfyUI
|
|
1188
|
+
*/
|
|
1189
|
+
workflowJson: object | null;
|
|
1190
|
+
/**
|
|
1191
|
+
* Node ID mappings for dynamic parameter injection
|
|
1192
|
+
* Maps semantic names to ComfyUI node IDs
|
|
1193
|
+
*/
|
|
1194
|
+
nodeMapping: NodeMapping;
|
|
1195
|
+
/**
|
|
1196
|
+
* Estimated processing time in seconds
|
|
1197
|
+
* Used for progress estimation
|
|
1198
|
+
*/
|
|
1199
|
+
estimatedTime: number;
|
|
1200
|
+
/**
|
|
1201
|
+
* Whether this workflow is active/usable
|
|
1202
|
+
*/
|
|
1203
|
+
isActive: boolean;
|
|
1204
|
+
/**
|
|
1205
|
+
* ComfyUI models required by this workflow
|
|
1206
|
+
* Used for validation before queuing
|
|
1207
|
+
*/
|
|
1208
|
+
requiredModels: string[];
|
|
1209
|
+
constructor(options?: VideoWorkflowOptions);
|
|
1210
|
+
/**
|
|
1211
|
+
* Check if the workflow has all required node mappings
|
|
1212
|
+
*/
|
|
1213
|
+
get hasRequiredMappings(): boolean;
|
|
1214
|
+
/**
|
|
1215
|
+
* Get a copy of the workflow JSON with injected parameters
|
|
1216
|
+
*
|
|
1217
|
+
* Parameter injection follows ComfyUI node structure conventions:
|
|
1218
|
+
* - seedImage, audioFile, baseVideo → node.inputs.image (file path)
|
|
1219
|
+
* - prompt → node.inputs.text (string)
|
|
1220
|
+
* - Other parameters → node.inputs[paramKey]
|
|
1221
|
+
*
|
|
1222
|
+
* @param params - Key-value pairs of parameters to inject
|
|
1223
|
+
* @returns Modified workflow JSON or null if no workflowJson set
|
|
1224
|
+
*/
|
|
1225
|
+
injectParameters(params: Record<string, any>): object | null;
|
|
1226
|
+
}
|
|
1227
|
+
|
|
1228
|
+
/**
|
|
1229
|
+
* Video workflow creation options
|
|
1230
|
+
*/
|
|
1231
|
+
export declare interface VideoWorkflowOptions extends SmrtObjectOptions {
|
|
1232
|
+
/**
|
|
1233
|
+
* Human-readable name for the workflow
|
|
1234
|
+
*/
|
|
1235
|
+
name?: string;
|
|
1236
|
+
/**
|
|
1237
|
+
* Description of what this workflow does
|
|
1238
|
+
*/
|
|
1239
|
+
description?: string | null;
|
|
1240
|
+
/**
|
|
1241
|
+
* Workflow type classification
|
|
1242
|
+
* @default 'custom'
|
|
1243
|
+
*/
|
|
1244
|
+
workflowType?: WorkflowType;
|
|
1245
|
+
/**
|
|
1246
|
+
* ComfyUI API format JSON
|
|
1247
|
+
*/
|
|
1248
|
+
workflowJson?: object | null;
|
|
1249
|
+
/**
|
|
1250
|
+
* Node ID mappings for dynamic parameter injection
|
|
1251
|
+
*/
|
|
1252
|
+
nodeMapping?: NodeMapping;
|
|
1253
|
+
/**
|
|
1254
|
+
* Estimated processing time in seconds
|
|
1255
|
+
*/
|
|
1256
|
+
estimatedTime?: number;
|
|
1257
|
+
/**
|
|
1258
|
+
* Whether this workflow is active/usable
|
|
1259
|
+
* @default true
|
|
1260
|
+
*/
|
|
1261
|
+
isActive?: boolean;
|
|
1262
|
+
/**
|
|
1263
|
+
* ComfyUI models required by this workflow
|
|
1264
|
+
*/
|
|
1265
|
+
requiredModels?: string[];
|
|
1266
|
+
/**
|
|
1267
|
+
* Tenant ID for multi-tenant isolation
|
|
1268
|
+
*/
|
|
1269
|
+
tenantId?: string | null;
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
/**
|
|
1273
|
+
* Workflow type classification
|
|
1274
|
+
*/
|
|
1275
|
+
export declare type WorkflowType = 'prebake' | 'broadcast' | 'lipsync' | 'postprod' | 'custom';
|
|
1276
|
+
|
|
1277
|
+
export { }
|