@scenerok/sdk 0.2.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/README.md +114 -0
- package/dist/duration.d.ts +29 -0
- package/dist/duration.d.ts.map +1 -0
- package/dist/duration.js +87 -0
- package/dist/grid.d.ts +61 -0
- package/dist/grid.d.ts.map +1 -0
- package/dist/grid.js +174 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/ir-builder.d.ts +28 -0
- package/dist/ir-builder.d.ts.map +1 -0
- package/dist/ir-builder.js +452 -0
- package/dist/ir.d.ts +204 -0
- package/dist/ir.d.ts.map +1 -0
- package/dist/ir.js +30 -0
- package/dist/media.d.ts +16 -0
- package/dist/media.d.ts.map +1 -0
- package/dist/media.js +105 -0
- package/dist/motion.d.ts +9 -0
- package/dist/motion.d.ts.map +1 -0
- package/dist/motion.js +31 -0
- package/dist/plugins/cloudflare.d.ts +80 -0
- package/dist/plugins/cloudflare.d.ts.map +1 -0
- package/dist/plugins/cloudflare.js +55 -0
- package/dist/plugins/elevenlabs-music.d.ts +37 -0
- package/dist/plugins/elevenlabs-music.d.ts.map +1 -0
- package/dist/plugins/elevenlabs-music.js +21 -0
- package/dist/plugins/invoke.d.ts +26 -0
- package/dist/plugins/invoke.d.ts.map +1 -0
- package/dist/plugins/invoke.js +109 -0
- package/dist/plugins/types.d.ts +21 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +4 -0
- package/dist/plugins/xai.d.ts +76 -0
- package/dist/plugins/xai.d.ts.map +1 -0
- package/dist/plugins/xai.js +60 -0
- package/dist/stdlib.d.ts +96 -0
- package/dist/stdlib.d.ts.map +1 -0
- package/dist/stdlib.js +66 -0
- package/dist/timeline.d.ts +27 -0
- package/dist/timeline.d.ts.map +1 -0
- package/dist/timeline.js +117 -0
- package/dist/transitions/catalog.d.ts +33 -0
- package/dist/transitions/catalog.d.ts.map +1 -0
- package/dist/transitions/catalog.js +51 -0
- package/dist/transitions/index.d.ts +62 -0
- package/dist/transitions/index.d.ts.map +1 -0
- package/dist/transitions/index.js +57 -0
- package/dist/types.d.ts +177 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +14 -0
- package/package.json +64 -0
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared IR builder — appends SDK nodes onto an IRTimeline.
|
|
3
|
+
* Used by @scenerok/sdk Timeline and (later) optionally by the VidScript compiler.
|
|
4
|
+
*/
|
|
5
|
+
import { defaultIRTimeline, } from './ir.js';
|
|
6
|
+
import { toSeconds } from './duration.js';
|
|
7
|
+
import { defaultGridSpec, placementFromGridArea, resolveGridAreas, } from './grid.js';
|
|
8
|
+
import { isSchedulable } from './types.js';
|
|
9
|
+
let idCounter = 0;
|
|
10
|
+
export function resetIrBuilderIds(seed = 0) {
|
|
11
|
+
idCounter = seed;
|
|
12
|
+
}
|
|
13
|
+
function nextId(prefix) {
|
|
14
|
+
idCounter += 1;
|
|
15
|
+
return `${prefix}-${idCounter}`;
|
|
16
|
+
}
|
|
17
|
+
function definedEntries(partial) {
|
|
18
|
+
const out = {};
|
|
19
|
+
for (const [key, value] of Object.entries(partial)) {
|
|
20
|
+
if (value !== undefined)
|
|
21
|
+
out[key] = value;
|
|
22
|
+
}
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
25
|
+
function defaultTextStyle(partial = {}) {
|
|
26
|
+
return {
|
|
27
|
+
font: 'Inter',
|
|
28
|
+
size: 48,
|
|
29
|
+
color: '#FFFFFF',
|
|
30
|
+
stroke: 'transparent',
|
|
31
|
+
strokeWidth: 0,
|
|
32
|
+
position: 'center',
|
|
33
|
+
bold: false,
|
|
34
|
+
italic: false,
|
|
35
|
+
x: '50%',
|
|
36
|
+
y: '50%',
|
|
37
|
+
rotation: 0,
|
|
38
|
+
opacity: 1,
|
|
39
|
+
align: 'center',
|
|
40
|
+
lineHeight: 1.2,
|
|
41
|
+
letterSpacing: 0,
|
|
42
|
+
shadowColor: 'transparent',
|
|
43
|
+
shadowBlur: 0,
|
|
44
|
+
shadowOffsetX: 0,
|
|
45
|
+
shadowOffsetY: 0,
|
|
46
|
+
...definedEntries(partial),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function isExitFade(descriptor) {
|
|
50
|
+
return (descriptor.type === 'fade'
|
|
51
|
+
&& descriptor.from?.opacity === 1
|
|
52
|
+
&& descriptor.to?.opacity === 0);
|
|
53
|
+
}
|
|
54
|
+
function resolveAnimationWindow(descriptor, blockStart, blockEnd) {
|
|
55
|
+
const span = Math.max(0, blockEnd - blockStart);
|
|
56
|
+
const duration = descriptor.duration > 0 ? Math.min(descriptor.duration, span) : span;
|
|
57
|
+
const alignEnd = descriptor.align === 'end' || isExitFade(descriptor);
|
|
58
|
+
if (alignEnd) {
|
|
59
|
+
return { start: blockEnd - duration, end: blockEnd };
|
|
60
|
+
}
|
|
61
|
+
return { start: blockStart, end: Math.min(blockEnd, blockStart + duration) };
|
|
62
|
+
}
|
|
63
|
+
function lowerAnimations(descriptors, blockStart, blockEnd) {
|
|
64
|
+
const animations = [];
|
|
65
|
+
const motion = [];
|
|
66
|
+
for (const descriptor of descriptors) {
|
|
67
|
+
const window = resolveAnimationWindow(descriptor, blockStart, blockEnd);
|
|
68
|
+
const id = nextId('anim');
|
|
69
|
+
animations.push({
|
|
70
|
+
id,
|
|
71
|
+
type: descriptor.type,
|
|
72
|
+
plugin: descriptor.plugin,
|
|
73
|
+
from: { ...descriptor.from },
|
|
74
|
+
to: { ...descriptor.to },
|
|
75
|
+
start: window.start,
|
|
76
|
+
end: window.end,
|
|
77
|
+
easing: descriptor.easing,
|
|
78
|
+
loop: descriptor.loop,
|
|
79
|
+
});
|
|
80
|
+
// Lower common opacity / transform props into motion tracks (preview/render parity).
|
|
81
|
+
for (const key of Object.keys({ ...descriptor.from, ...descriptor.to })) {
|
|
82
|
+
const fromVal = descriptor.from[key];
|
|
83
|
+
const toVal = descriptor.to[key];
|
|
84
|
+
if (fromVal === undefined && toVal === undefined)
|
|
85
|
+
continue;
|
|
86
|
+
motion.push({
|
|
87
|
+
id: nextId('motion'),
|
|
88
|
+
target: key,
|
|
89
|
+
sourceAnimationId: id,
|
|
90
|
+
plugin: descriptor.plugin,
|
|
91
|
+
keyframes: [
|
|
92
|
+
{ time: window.start, value: (fromVal ?? toVal) },
|
|
93
|
+
{ time: window.end, value: (toVal ?? fromVal) },
|
|
94
|
+
],
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return { animations, motion };
|
|
99
|
+
}
|
|
100
|
+
export function createIrBuilder(options = {}) {
|
|
101
|
+
const ir = defaultIRTimeline();
|
|
102
|
+
if (options.width != null)
|
|
103
|
+
ir.width = options.width;
|
|
104
|
+
if (options.height != null)
|
|
105
|
+
ir.height = options.height;
|
|
106
|
+
if (options.fps != null)
|
|
107
|
+
ir.fps = options.fps;
|
|
108
|
+
if (options.background != null)
|
|
109
|
+
ir.background = options.background;
|
|
110
|
+
const out = options.output ?? {};
|
|
111
|
+
ir.output = {
|
|
112
|
+
...ir.output,
|
|
113
|
+
path: out.path ?? ir.output.path,
|
|
114
|
+
format: out.format ?? ir.output.format,
|
|
115
|
+
codec: out.codec ?? ir.output.codec,
|
|
116
|
+
bitrate: out.bitrate ?? ir.output.bitrate,
|
|
117
|
+
resolution: out.resolution
|
|
118
|
+
?? `${ir.width}x${ir.height}`,
|
|
119
|
+
fps: out.fps ?? ir.fps,
|
|
120
|
+
};
|
|
121
|
+
return { ir, visualCursor: 0, audioCursor: 0, gridAreas: null };
|
|
122
|
+
}
|
|
123
|
+
/** Declare or replace the timeline grid used by `area:` text placement. */
|
|
124
|
+
export function setGrid(state, spec) {
|
|
125
|
+
const areas = resolveGridAreas(spec);
|
|
126
|
+
state.gridAreas = areas;
|
|
127
|
+
return areas;
|
|
128
|
+
}
|
|
129
|
+
function resolveTextAreaPlacement(state, areaName) {
|
|
130
|
+
const areas = state.gridAreas
|
|
131
|
+
?? resolveGridAreas(defaultGridSpec(state.ir.width, state.ir.height));
|
|
132
|
+
const rect = areas.get(areaName);
|
|
133
|
+
if (!rect) {
|
|
134
|
+
throw new Error(`Unknown grid area '${areaName}' (available: ${[...areas.keys()].join(', ')})`);
|
|
135
|
+
}
|
|
136
|
+
return placementFromGridArea(rect);
|
|
137
|
+
}
|
|
138
|
+
function bumpDuration(state, end) {
|
|
139
|
+
if (end > state.ir.duration)
|
|
140
|
+
state.ir.duration = end;
|
|
141
|
+
}
|
|
142
|
+
function scheduleVideo(state, start, end, clip) {
|
|
143
|
+
const { animations, motion } = lowerAnimations(clip.animations, start, end);
|
|
144
|
+
const irClip = {
|
|
145
|
+
id: nextId('clip'),
|
|
146
|
+
source: clip.source,
|
|
147
|
+
start,
|
|
148
|
+
end,
|
|
149
|
+
trimStart: clip.options.trimStart != null ? toSeconds(clip.options.trimStart) : 0,
|
|
150
|
+
trimEnd: clip.options.trimEnd != null ? toSeconds(clip.options.trimEnd) : 0,
|
|
151
|
+
speed: clip.options.speed ?? 1,
|
|
152
|
+
loop: clip.options.loop ?? 0,
|
|
153
|
+
opacity: clip.options.opacity ?? 1,
|
|
154
|
+
width: clip.options.width ?? state.ir.width,
|
|
155
|
+
height: clip.options.height ?? state.ir.height,
|
|
156
|
+
x: clip.options.x ?? 0,
|
|
157
|
+
y: clip.options.y ?? 0,
|
|
158
|
+
animations: animations.length ? animations : undefined,
|
|
159
|
+
motion: motion.length ? motion : undefined,
|
|
160
|
+
};
|
|
161
|
+
state.ir.clips.push(irClip);
|
|
162
|
+
state.visualCursor = Math.max(state.visualCursor, end);
|
|
163
|
+
bumpDuration(state, end);
|
|
164
|
+
}
|
|
165
|
+
function scheduleText(state, start, end, layer) {
|
|
166
|
+
const opts = layer.options;
|
|
167
|
+
const { animations, motion } = lowerAnimations(layer.animations, start, end);
|
|
168
|
+
// Resolve `area:` like VidScript: center in the cell and cap maxWidth/maxHeight.
|
|
169
|
+
// Explicit x/y/maxWidth/maxHeight win over the area.
|
|
170
|
+
let areaX;
|
|
171
|
+
let areaY;
|
|
172
|
+
let areaMaxWidth;
|
|
173
|
+
let areaMaxHeight;
|
|
174
|
+
if (opts.area) {
|
|
175
|
+
const placement = resolveTextAreaPlacement(state, opts.area);
|
|
176
|
+
areaX = placement.x;
|
|
177
|
+
areaY = placement.y;
|
|
178
|
+
areaMaxWidth = placement.maxWidth;
|
|
179
|
+
areaMaxHeight = placement.maxHeight;
|
|
180
|
+
}
|
|
181
|
+
const style = defaultTextStyle({
|
|
182
|
+
font: opts.font,
|
|
183
|
+
size: opts.size,
|
|
184
|
+
color: opts.color,
|
|
185
|
+
stroke: opts.stroke,
|
|
186
|
+
strokeWidth: opts.strokeWidth,
|
|
187
|
+
bold: opts.bold,
|
|
188
|
+
italic: opts.italic,
|
|
189
|
+
x: opts.x ?? areaX ?? '50%',
|
|
190
|
+
y: opts.y ?? areaY ?? '50%',
|
|
191
|
+
rotation: opts.rotation,
|
|
192
|
+
opacity: opts.opacity,
|
|
193
|
+
align: opts.align,
|
|
194
|
+
lineHeight: opts.lineHeight,
|
|
195
|
+
letterSpacing: opts.letterSpacing,
|
|
196
|
+
position: opts.position ?? 'center',
|
|
197
|
+
fit: opts.fit,
|
|
198
|
+
overflow: opts.overflow,
|
|
199
|
+
maxWidth: opts.maxWidth ?? areaMaxWidth,
|
|
200
|
+
maxHeight: opts.maxHeight ?? areaMaxHeight,
|
|
201
|
+
maxLines: opts.maxLines,
|
|
202
|
+
anchor: opts.anchor,
|
|
203
|
+
shadowColor: opts.shadowColor,
|
|
204
|
+
shadowBlur: opts.shadowBlur,
|
|
205
|
+
shadowOffsetX: opts.shadowOffsetX,
|
|
206
|
+
shadowOffsetY: opts.shadowOffsetY,
|
|
207
|
+
});
|
|
208
|
+
const textLayer = {
|
|
209
|
+
type: 'text',
|
|
210
|
+
id: nextId('text'),
|
|
211
|
+
content: layer.content,
|
|
212
|
+
start,
|
|
213
|
+
end,
|
|
214
|
+
style,
|
|
215
|
+
animations: animations.length ? animations : undefined,
|
|
216
|
+
motion: motion.length ? motion : undefined,
|
|
217
|
+
};
|
|
218
|
+
state.ir.layers.push(textLayer);
|
|
219
|
+
state.visualCursor = Math.max(state.visualCursor, end);
|
|
220
|
+
bumpDuration(state, end);
|
|
221
|
+
}
|
|
222
|
+
function scheduleAudio(state, start, end, track) {
|
|
223
|
+
const duration = Math.max(0, end - start);
|
|
224
|
+
const audio = {
|
|
225
|
+
id: nextId('audio'),
|
|
226
|
+
source: track.source,
|
|
227
|
+
start,
|
|
228
|
+
duration,
|
|
229
|
+
volume: track.options.volume ?? 1,
|
|
230
|
+
fadeIn: track.options.fadeIn != null ? toSeconds(track.options.fadeIn) : 0,
|
|
231
|
+
fadeOut: track.options.fadeOut != null ? toSeconds(track.options.fadeOut) : 0,
|
|
232
|
+
loudnessNormalization: track.options.loudnessNormalization,
|
|
233
|
+
targetLufs: track.options.targetLufs,
|
|
234
|
+
};
|
|
235
|
+
state.ir.audio.push(audio);
|
|
236
|
+
state.audioCursor = Math.max(state.audioCursor, end);
|
|
237
|
+
bumpDuration(state, end);
|
|
238
|
+
}
|
|
239
|
+
function scheduleFilter(state, start, end, effect) {
|
|
240
|
+
const builtin = {
|
|
241
|
+
type: 'builtin',
|
|
242
|
+
id: nextId('fx'),
|
|
243
|
+
name: effect.name,
|
|
244
|
+
start,
|
|
245
|
+
end,
|
|
246
|
+
params: { ...effect.params },
|
|
247
|
+
};
|
|
248
|
+
state.ir.effects.push(builtin);
|
|
249
|
+
bumpDuration(state, end);
|
|
250
|
+
}
|
|
251
|
+
function scheduleShader(state, start, end, effect) {
|
|
252
|
+
const shaderFx = {
|
|
253
|
+
type: 'shader',
|
|
254
|
+
id: nextId('shader'),
|
|
255
|
+
shaderSource: effect.shaderSource,
|
|
256
|
+
start,
|
|
257
|
+
end,
|
|
258
|
+
params: { ...effect.params },
|
|
259
|
+
};
|
|
260
|
+
state.ir.effects.push(shaderFx);
|
|
261
|
+
bumpDuration(state, end);
|
|
262
|
+
}
|
|
263
|
+
function scheduleTransition(state, start, end, effect) {
|
|
264
|
+
const opts = effect.options;
|
|
265
|
+
const surface = {
|
|
266
|
+
id: nextId('surface'),
|
|
267
|
+
type: 'transition',
|
|
268
|
+
start,
|
|
269
|
+
end,
|
|
270
|
+
data: {
|
|
271
|
+
shaderName: effect.shaderName,
|
|
272
|
+
// mode resolved by bindTransitions; user override wins when non-empty.
|
|
273
|
+
mode: opts.mode ?? '',
|
|
274
|
+
params: {
|
|
275
|
+
direction: opts.direction ?? '',
|
|
276
|
+
ease: opts.ease ?? 'power2',
|
|
277
|
+
strength: opts.strength !== undefined ? String(opts.strength) : '',
|
|
278
|
+
},
|
|
279
|
+
width: opts.width,
|
|
280
|
+
height: opts.height,
|
|
281
|
+
x: opts.x,
|
|
282
|
+
y: opts.y,
|
|
283
|
+
opacity: opts.opacity ?? 1,
|
|
284
|
+
},
|
|
285
|
+
metadata: {
|
|
286
|
+
package: '@scenerok/transitions',
|
|
287
|
+
transition: effect.name,
|
|
288
|
+
},
|
|
289
|
+
};
|
|
290
|
+
state.ir.surfaces.push(surface);
|
|
291
|
+
state.visualCursor = Math.max(state.visualCursor, end);
|
|
292
|
+
bumpDuration(state, end);
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Post-pass: resolve fromId/toId for transition surfaces from neighboring clips.
|
|
296
|
+
* Mirrors VidScript `bindTransitions` in compiler-v2.
|
|
297
|
+
*/
|
|
298
|
+
export function bindTransitions(ir, warnings = []) {
|
|
299
|
+
for (const surface of ir.surfaces) {
|
|
300
|
+
if (surface.type !== 'transition')
|
|
301
|
+
continue;
|
|
302
|
+
const Ts = surface.start;
|
|
303
|
+
const Te = surface.end;
|
|
304
|
+
const atFrom = ir.clips.filter((c) => c.start <= Ts && c.end >= Ts);
|
|
305
|
+
let fromId;
|
|
306
|
+
if (atFrom.length === 0) {
|
|
307
|
+
fromId = null;
|
|
308
|
+
}
|
|
309
|
+
else if (atFrom.length === 1) {
|
|
310
|
+
fromId = atFrom[0].id;
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
fromId = null;
|
|
314
|
+
warnings.push(`transition at ${Ts}s: multiple clips active at the start seam; transitions are only defined at a clean cut — use Overlay/Composite for layered clips`);
|
|
315
|
+
}
|
|
316
|
+
const atTo = ir.clips.filter((c) => c.start <= Te && c.end >= Te);
|
|
317
|
+
let toId;
|
|
318
|
+
if (atTo.length === 0) {
|
|
319
|
+
toId = null;
|
|
320
|
+
}
|
|
321
|
+
else if (atTo.length === 1) {
|
|
322
|
+
toId = atTo[0].id;
|
|
323
|
+
}
|
|
324
|
+
else {
|
|
325
|
+
toId = null;
|
|
326
|
+
warnings.push(`transition at ${Te}s: multiple clips active at the end seam; transitions are only defined at a clean cut — use Overlay/Composite for layered clips`);
|
|
327
|
+
}
|
|
328
|
+
const data = surface.data;
|
|
329
|
+
if (fromId && toId && fromId === toId) {
|
|
330
|
+
data.self = true;
|
|
331
|
+
}
|
|
332
|
+
const userMode = typeof data.mode === 'string' ? data.mode : '';
|
|
333
|
+
if (!userMode) {
|
|
334
|
+
data.mode = fromId && toId ? 'roll' : 'freeze';
|
|
335
|
+
}
|
|
336
|
+
data.fromId = fromId;
|
|
337
|
+
data.toId = toId;
|
|
338
|
+
data.progressStart = Ts;
|
|
339
|
+
data.progressEnd = Te;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
function scheduleNestedTimeline(state, start, end, nested) {
|
|
343
|
+
const nestedIr = nested.toIR();
|
|
344
|
+
const offset = start;
|
|
345
|
+
const span = Math.max(0, end - start);
|
|
346
|
+
const scale = nestedIr.duration > 0 ? span / nestedIr.duration : 1;
|
|
347
|
+
const remap = (t) => offset + t * scale;
|
|
348
|
+
for (const clip of nestedIr.clips) {
|
|
349
|
+
state.ir.clips.push({
|
|
350
|
+
...clip,
|
|
351
|
+
id: nextId('clip'),
|
|
352
|
+
start: remap(clip.start),
|
|
353
|
+
end: remap(clip.end),
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
for (const layer of nestedIr.layers) {
|
|
357
|
+
state.ir.layers.push({
|
|
358
|
+
...layer,
|
|
359
|
+
id: nextId(layer.type === 'text' ? 'text' : 'layer'),
|
|
360
|
+
start: remap(layer.start),
|
|
361
|
+
end: remap(layer.end),
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
for (const effect of nestedIr.effects) {
|
|
365
|
+
state.ir.effects.push({
|
|
366
|
+
...effect,
|
|
367
|
+
id: nextId('fx'),
|
|
368
|
+
start: remap(effect.start),
|
|
369
|
+
end: remap(effect.end),
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
for (const audio of nestedIr.audio) {
|
|
373
|
+
state.ir.audio.push({
|
|
374
|
+
...audio,
|
|
375
|
+
id: nextId('audio'),
|
|
376
|
+
start: remap(audio.start),
|
|
377
|
+
duration: audio.duration * scale,
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
for (const surface of nestedIr.surfaces) {
|
|
381
|
+
state.ir.surfaces.push({
|
|
382
|
+
...surface,
|
|
383
|
+
id: nextId('surface'),
|
|
384
|
+
start: remap(surface.start),
|
|
385
|
+
end: remap(surface.end),
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
const use = {
|
|
389
|
+
name: nested.options.name ?? 'nested',
|
|
390
|
+
sourceOffset: 0,
|
|
391
|
+
start,
|
|
392
|
+
end,
|
|
393
|
+
};
|
|
394
|
+
state.ir.timelineUses = [...(state.ir.timelineUses ?? []), use];
|
|
395
|
+
state.visualCursor = Math.max(state.visualCursor, end);
|
|
396
|
+
bumpDuration(state, end);
|
|
397
|
+
}
|
|
398
|
+
export function scheduleAt(state, start, end, value) {
|
|
399
|
+
if (end < start) {
|
|
400
|
+
throw new RangeError(`Invalid range: end (${end}) < start (${start})`);
|
|
401
|
+
}
|
|
402
|
+
switch (value.kind) {
|
|
403
|
+
case 'video':
|
|
404
|
+
scheduleVideo(state, start, end, value);
|
|
405
|
+
break;
|
|
406
|
+
case 'text':
|
|
407
|
+
scheduleText(state, start, end, value);
|
|
408
|
+
break;
|
|
409
|
+
case 'audio':
|
|
410
|
+
scheduleAudio(state, start, end, value);
|
|
411
|
+
break;
|
|
412
|
+
case 'filter':
|
|
413
|
+
scheduleFilter(state, start, end, value);
|
|
414
|
+
break;
|
|
415
|
+
case 'shader':
|
|
416
|
+
scheduleShader(state, start, end, value);
|
|
417
|
+
break;
|
|
418
|
+
case 'transition':
|
|
419
|
+
scheduleTransition(state, start, end, value);
|
|
420
|
+
break;
|
|
421
|
+
case 'timeline':
|
|
422
|
+
scheduleNestedTimeline(state, start, end, value);
|
|
423
|
+
break;
|
|
424
|
+
default:
|
|
425
|
+
throw new TypeError(`Unsupported schedulable kind: ${value.kind}`);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
export function inferAutoDuration(value, explicit) {
|
|
429
|
+
if (explicit !== undefined)
|
|
430
|
+
return toSeconds(explicit);
|
|
431
|
+
switch (value.kind) {
|
|
432
|
+
case 'video':
|
|
433
|
+
case 'audio':
|
|
434
|
+
return value.duration;
|
|
435
|
+
case 'timeline':
|
|
436
|
+
return value.duration;
|
|
437
|
+
case 'transition':
|
|
438
|
+
return value.duration;
|
|
439
|
+
case 'text':
|
|
440
|
+
return 3;
|
|
441
|
+
case 'filter':
|
|
442
|
+
case 'shader':
|
|
443
|
+
return 1;
|
|
444
|
+
default:
|
|
445
|
+
return 1;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
export function assertSchedulable(value) {
|
|
449
|
+
if (!isSchedulable(value)) {
|
|
450
|
+
throw new TypeError('Timeline assignment RHS must be a SDK media node (video/text/audio/filter/shader/transition/timeline)');
|
|
451
|
+
}
|
|
452
|
+
}
|
package/dist/ir.d.ts
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IRTimeline contract — mirrors src/types/ir.ts so the SDK can ship standalone.
|
|
3
|
+
* Keep fields in sync with the platform IR; Pass 2 consumes this shape.
|
|
4
|
+
*/
|
|
5
|
+
export interface IRSourceTimespec {
|
|
6
|
+
start: number;
|
|
7
|
+
end: number;
|
|
8
|
+
}
|
|
9
|
+
export interface IRTimeline {
|
|
10
|
+
version: 1;
|
|
11
|
+
width: number;
|
|
12
|
+
height: number;
|
|
13
|
+
fps: number;
|
|
14
|
+
duration: number;
|
|
15
|
+
background: string;
|
|
16
|
+
clips: IRClip[];
|
|
17
|
+
layers: IRLayer[];
|
|
18
|
+
surfaces: IRSurface[];
|
|
19
|
+
effects: IREffect[];
|
|
20
|
+
audio: IRAudioTrack[];
|
|
21
|
+
output: IROutput;
|
|
22
|
+
timelineUses?: IRTimelineUse[];
|
|
23
|
+
}
|
|
24
|
+
export interface IRTimelineUse {
|
|
25
|
+
name: string;
|
|
26
|
+
sourceOffset: number;
|
|
27
|
+
start: number;
|
|
28
|
+
end: number;
|
|
29
|
+
}
|
|
30
|
+
export interface IRClip {
|
|
31
|
+
id: string;
|
|
32
|
+
source: string;
|
|
33
|
+
start: number;
|
|
34
|
+
end: number;
|
|
35
|
+
trimStart: number;
|
|
36
|
+
trimEnd: number;
|
|
37
|
+
speed: number;
|
|
38
|
+
loop: number;
|
|
39
|
+
opacity: number;
|
|
40
|
+
width: number;
|
|
41
|
+
height: number;
|
|
42
|
+
x: number;
|
|
43
|
+
y: number;
|
|
44
|
+
animations?: IRAnimation[];
|
|
45
|
+
motion?: IRMotionTrack[];
|
|
46
|
+
sourceTimespec?: IRSourceTimespec;
|
|
47
|
+
}
|
|
48
|
+
export type IRLayer = IRTextLayer | IRVideoOverlayLayer | IRCompositeLayer;
|
|
49
|
+
export interface IRSurface {
|
|
50
|
+
id: string;
|
|
51
|
+
type: 'text' | 'video' | 'image' | 'mesh' | 'lottie' | string;
|
|
52
|
+
start: number;
|
|
53
|
+
end: number;
|
|
54
|
+
source?: string;
|
|
55
|
+
data: Record<string, unknown>;
|
|
56
|
+
animations?: IRAnimation[];
|
|
57
|
+
motion?: IRMotionTrack[];
|
|
58
|
+
effects?: IREffect[];
|
|
59
|
+
metadata?: Record<string, unknown>;
|
|
60
|
+
}
|
|
61
|
+
export interface IRTextLayer {
|
|
62
|
+
type: 'text';
|
|
63
|
+
id: string;
|
|
64
|
+
content: string;
|
|
65
|
+
start: number;
|
|
66
|
+
end: number;
|
|
67
|
+
style: IRTextStyle;
|
|
68
|
+
animations?: IRAnimation[];
|
|
69
|
+
motion?: IRMotionTrack[];
|
|
70
|
+
effects?: IREffect[];
|
|
71
|
+
sourceTimespec?: IRSourceTimespec;
|
|
72
|
+
}
|
|
73
|
+
export interface IRTextStyle {
|
|
74
|
+
font: string;
|
|
75
|
+
size: number;
|
|
76
|
+
minSize?: number;
|
|
77
|
+
color: string;
|
|
78
|
+
stroke: string;
|
|
79
|
+
strokeWidth: number;
|
|
80
|
+
position: string;
|
|
81
|
+
animation?: string;
|
|
82
|
+
bold: boolean;
|
|
83
|
+
italic: boolean;
|
|
84
|
+
x: number | string;
|
|
85
|
+
y: number | string;
|
|
86
|
+
rotation: number;
|
|
87
|
+
opacity: number;
|
|
88
|
+
align: 'left' | 'center' | 'right';
|
|
89
|
+
lineHeight: number;
|
|
90
|
+
letterSpacing: number;
|
|
91
|
+
shadowColor: string;
|
|
92
|
+
shadowBlur: number;
|
|
93
|
+
shadowOffsetX: number;
|
|
94
|
+
shadowOffsetY: number;
|
|
95
|
+
fit?: 'none' | 'wrap' | 'shrink' | 'wrap-shrink';
|
|
96
|
+
overflow?: 'contain' | 'crop' | 'allow';
|
|
97
|
+
safeArea?: number | string;
|
|
98
|
+
maxWidth?: number | string;
|
|
99
|
+
maxHeight?: number | string;
|
|
100
|
+
maxLines?: number;
|
|
101
|
+
anchor?: 'left' | 'center' | 'right' | 'top-left' | 'top-center' | 'top-right' | 'bottom-left' | 'bottom-center' | 'bottom-right';
|
|
102
|
+
}
|
|
103
|
+
export interface IRAnimation {
|
|
104
|
+
id: string;
|
|
105
|
+
type: string;
|
|
106
|
+
plugin?: string;
|
|
107
|
+
from: Record<string, unknown>;
|
|
108
|
+
to: Record<string, unknown>;
|
|
109
|
+
start: number;
|
|
110
|
+
end: number;
|
|
111
|
+
easing?: string;
|
|
112
|
+
loop?: boolean;
|
|
113
|
+
}
|
|
114
|
+
export type IRMotionValue = number | string | boolean | null | number[] | Record<string, unknown>;
|
|
115
|
+
export interface IRMotionKeyframe {
|
|
116
|
+
time: number;
|
|
117
|
+
value: IRMotionValue;
|
|
118
|
+
easing?: string;
|
|
119
|
+
interpolation?: 'linear' | 'hold';
|
|
120
|
+
}
|
|
121
|
+
export interface IRMotionBehavior {
|
|
122
|
+
type: 'loop' | 'pingPong' | 'spring' | 'wiggle' | 'typewriter' | string;
|
|
123
|
+
params?: Record<string, unknown>;
|
|
124
|
+
}
|
|
125
|
+
export interface IRMotionTrack {
|
|
126
|
+
id: string;
|
|
127
|
+
target: string;
|
|
128
|
+
keyframes: IRMotionKeyframe[];
|
|
129
|
+
behavior?: IRMotionBehavior;
|
|
130
|
+
plugin?: string;
|
|
131
|
+
sourceAnimationId?: string;
|
|
132
|
+
}
|
|
133
|
+
export interface IRVideoOverlayLayer {
|
|
134
|
+
type: 'video_overlay';
|
|
135
|
+
id: string;
|
|
136
|
+
overlayClipId: string;
|
|
137
|
+
targetClipId: string;
|
|
138
|
+
start: number;
|
|
139
|
+
end: number;
|
|
140
|
+
x: number;
|
|
141
|
+
y: number;
|
|
142
|
+
opacity: number;
|
|
143
|
+
effects?: IREffect[];
|
|
144
|
+
sourceTimespec?: IRSourceTimespec;
|
|
145
|
+
}
|
|
146
|
+
export interface IRCompositeLayer {
|
|
147
|
+
type: 'composite';
|
|
148
|
+
id: string;
|
|
149
|
+
targetClipId: string;
|
|
150
|
+
otherClipId: string;
|
|
151
|
+
start: number;
|
|
152
|
+
end: number;
|
|
153
|
+
x: number;
|
|
154
|
+
y: number;
|
|
155
|
+
opacity: number;
|
|
156
|
+
mode: string;
|
|
157
|
+
sourceTimespec?: IRSourceTimespec;
|
|
158
|
+
}
|
|
159
|
+
export type IREffect = IRBuiltinEffect | IRShaderEffect;
|
|
160
|
+
export interface IRBuiltinEffect {
|
|
161
|
+
type: 'builtin';
|
|
162
|
+
id: string;
|
|
163
|
+
name: string;
|
|
164
|
+
start: number;
|
|
165
|
+
end: number;
|
|
166
|
+
params: Record<string, number | string>;
|
|
167
|
+
animations?: IRAnimation[];
|
|
168
|
+
motion?: IRMotionTrack[];
|
|
169
|
+
}
|
|
170
|
+
export interface IRShaderEffect {
|
|
171
|
+
type: 'shader';
|
|
172
|
+
id: string;
|
|
173
|
+
shaderSource: string;
|
|
174
|
+
start: number;
|
|
175
|
+
end: number;
|
|
176
|
+
params: Record<string, number | string>;
|
|
177
|
+
animations?: IRAnimation[];
|
|
178
|
+
motion?: IRMotionTrack[];
|
|
179
|
+
}
|
|
180
|
+
export interface IRAudioTrack {
|
|
181
|
+
id: string;
|
|
182
|
+
source: string;
|
|
183
|
+
start: number;
|
|
184
|
+
duration: number;
|
|
185
|
+
volume: number;
|
|
186
|
+
fadeIn: number;
|
|
187
|
+
fadeOut: number;
|
|
188
|
+
loudnessNormalization?: 'ebu-r128';
|
|
189
|
+
targetLufs?: number;
|
|
190
|
+
truePeakDb?: number;
|
|
191
|
+
loudnessRangeLufs?: number;
|
|
192
|
+
sourceTimespec?: IRSourceTimespec;
|
|
193
|
+
}
|
|
194
|
+
export interface IROutput {
|
|
195
|
+
path: string;
|
|
196
|
+
format: string;
|
|
197
|
+
codec: string;
|
|
198
|
+
bitrate: string;
|
|
199
|
+
resolution: string;
|
|
200
|
+
fps: number;
|
|
201
|
+
}
|
|
202
|
+
export declare function defaultIROutput(): IROutput;
|
|
203
|
+
export declare function defaultIRTimeline(): IRTimeline;
|
|
204
|
+
//# sourceMappingURL=ir.d.ts.map
|
package/dist/ir.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ir.d.ts","sourceRoot":"","sources":["../src/ir.ts"],"names":[],"mappings":"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"}
|
package/dist/ir.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IRTimeline contract — mirrors src/types/ir.ts so the SDK can ship standalone.
|
|
3
|
+
* Keep fields in sync with the platform IR; Pass 2 consumes this shape.
|
|
4
|
+
*/
|
|
5
|
+
export function defaultIROutput() {
|
|
6
|
+
return {
|
|
7
|
+
path: '',
|
|
8
|
+
format: 'mp4',
|
|
9
|
+
codec: 'h264',
|
|
10
|
+
bitrate: '5M',
|
|
11
|
+
resolution: '1080x1920',
|
|
12
|
+
fps: 30,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export function defaultIRTimeline() {
|
|
16
|
+
return {
|
|
17
|
+
version: 1,
|
|
18
|
+
width: 1080,
|
|
19
|
+
height: 1920,
|
|
20
|
+
fps: 30,
|
|
21
|
+
duration: 0,
|
|
22
|
+
background: '#000000',
|
|
23
|
+
clips: [],
|
|
24
|
+
layers: [],
|
|
25
|
+
surfaces: [],
|
|
26
|
+
effects: [],
|
|
27
|
+
audio: [],
|
|
28
|
+
output: defaultIROutput(),
|
|
29
|
+
};
|
|
30
|
+
}
|