@scenerok/sdk 0.9.0 → 0.10.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 +63 -1
- package/dist/describe.d.ts +87 -0
- package/dist/describe.d.ts.map +1 -0
- package/dist/describe.js +210 -0
- package/dist/duration.d.ts +9 -3
- package/dist/duration.d.ts.map +1 -1
- package/dist/duration.js +22 -5
- package/dist/frame-rate.d.ts +30 -0
- package/dist/frame-rate.d.ts.map +1 -0
- package/dist/frame-rate.js +73 -0
- package/dist/index.d.ts +9 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -4
- package/dist/ir-builder.d.ts +61 -8
- package/dist/ir-builder.d.ts.map +1 -1
- package/dist/ir-builder.js +714 -256
- package/dist/ir.d.ts +203 -2
- package/dist/ir.d.ts.map +1 -1
- package/dist/ir.js +4 -2
- package/dist/media.d.ts +49 -5
- package/dist/media.d.ts.map +1 -1
- package/dist/media.js +223 -33
- package/dist/motion-tracks.d.ts +10 -0
- package/dist/motion-tracks.d.ts.map +1 -0
- package/dist/motion-tracks.js +150 -0
- package/dist/motion.d.ts +34 -0
- package/dist/motion.d.ts.map +1 -1
- package/dist/motion.js +51 -11
- package/dist/plugins/invoke.d.ts.map +1 -1
- package/dist/plugins/invoke.js +5 -2
- package/dist/timeline.d.ts +3 -0
- package/dist/timeline.d.ts.map +1 -1
- package/dist/timeline.js +101 -41
- package/dist/types.d.ts +214 -28
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +8 -9
- package/package.json +2 -2
- package/skills/scenerok/SKILL.md +5 -2
- package/skills/scenerok/references/catalog-index.json +1 -1
- package/skills/scenerok/references/sdk-guide.md +149 -49
- package/skills/scenerok/references/vidscript-guide.md +45 -12
package/README.md
CHANGED
|
@@ -55,7 +55,7 @@ JavaScript has no `t[0, end]` dual key (comma operator). Use:
|
|
|
55
55
|
| `t.range(start, end, value)` | Explicit call |
|
|
56
56
|
| `t['-'] = value` / `t.push(value)` | Auto-append at playhead |
|
|
57
57
|
|
|
58
|
-
`start` / `end` accept numbers (seconds), `s(3)` / `ms(300)`, or strings (`'3s'`, `'1:30'`). Full JS arithmetic works: `clip.duration + 0.5`.
|
|
58
|
+
`start` / `end` accept numbers (seconds), `s(3)` / `ms(300)`, `t.frames(48)`, or strings (`'3s'`, `'1:30'`, `'48f'`, `'01:00:00:00'`). Full JS arithmetic works: `clip.duration + 0.5`. Windows snap to the timeline's frame grid, as VidScript blocks do; NTSC rates (`fps: 23.976`) are exact.
|
|
59
59
|
|
|
60
60
|
No `video` / `text` keywords after `=` — the RHS type is inferred from factories.
|
|
61
61
|
|
|
@@ -65,6 +65,7 @@ No `video` / `text` keywords after `=` — the RHS type is inferred from factori
|
|
|
65
65
|
|-----|----------|
|
|
66
66
|
| Short promos, human edits, templates | VidScript (`.vid`) |
|
|
67
67
|
| Loops, branches, computed timing, agents | TypeScript + `@scenerok/sdk` |
|
|
68
|
+
| An edit with one data-driven part | VidScript importing a `.ts` module (below) |
|
|
68
69
|
|
|
69
70
|
## AI plugins
|
|
70
71
|
|
|
@@ -116,6 +117,67 @@ t[5.6][10] = video('./b.mp4', { duration: 4.4 })
|
|
|
116
117
|
|
|
117
118
|
Same 29 shaders as VidScript. `toIR()` binds neighboring clips automatically.
|
|
118
119
|
|
|
120
|
+
## Values, methods, and placement
|
|
121
|
+
|
|
122
|
+
The SDK speaks the current VidScript language and lowers to the same IR:
|
|
123
|
+
|
|
124
|
+
```ts
|
|
125
|
+
import { timeline, video, image, text, audio, solid, gap, marker, fadeIn, volumeRamp } from '@scenerok/sdk'
|
|
126
|
+
|
|
127
|
+
const t = timeline({ width: 1920, height: 1080, fps: 30 })
|
|
128
|
+
const beach = video('./beach.mp4', { duration: 60 })
|
|
129
|
+
const vo = audio('./vo.mp3', { duration: 9 })
|
|
130
|
+
|
|
131
|
+
t[0][6] = beach.trim(10, 20).speed(1.5).crop(0, 0, 1280, 720) // methods return copies
|
|
132
|
+
t[0][6] = video('./flare.mp4', { blend: 'screen', opacity: 0.6 }) // blend over what is below
|
|
133
|
+
t[1][4] = image('./logo.png', { width: 240, height: 240, x: 60, y: 60, radius: 120 })
|
|
134
|
+
t[6][9] = beach.trim(30, 33).mask(solid('#fff', { width: 800, height: 800, x: 560, y: 140, radius: 400 }))
|
|
135
|
+
t.push(gap(), 1)
|
|
136
|
+
t[4][4] = marker('act 2')
|
|
137
|
+
t[0][9] = vo
|
|
138
|
+
t[0][9] = audio('./bed.mp3', { duration: 60, volume: 0.4, duckUnder: vo, animate: volumeRamp(0, 0.4, 2) })
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Values: `video`, `imageSequence`, `image`, `text`, `audio`, `solid`, `gap`, `marker`, `filter`, `shader`. Methods: `trim`, `speed`, `loop`, `resize`, `opacity`, `filter`, `crop`, `mask`, `animate`, `with`. Placement options on every picture: `x`, `y`, `width`, `height`, `area`, `opacity`, `rotation`, `radius`, `corners`, `blend`, `motionBlur`, `enabled`, `animate`.
|
|
142
|
+
|
|
143
|
+
A timeline is a value too. Placed bare its items join the parent; `place(opts)`, `opacity`, `resize`, `filter`, `crop`, or `mask` draw it as one group:
|
|
144
|
+
|
|
145
|
+
```ts
|
|
146
|
+
const card = timeline({ name: 'card' })
|
|
147
|
+
card[0][3] = solid('#101820', { height: 200, y: 880 })
|
|
148
|
+
card[0][3] = text('Konkan Day 1', { y: '88%' }).animate(fadeIn(0.3))
|
|
149
|
+
|
|
150
|
+
t[2][5] = card // flat
|
|
151
|
+
t[6][9] = card.opacity(0.8).place({ x: 40 }) // one group
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Use TypeScript from VidScript
|
|
155
|
+
|
|
156
|
+
A `.vid` can import a module and place its exports as VidScript values:
|
|
157
|
+
|
|
158
|
+
```ts
|
|
159
|
+
// kit.ts
|
|
160
|
+
import { video, text, timeline, solid } from '@scenerok/sdk'
|
|
161
|
+
export const hero = video('beach.mp4', { duration: 12 }).trim(2, 8)
|
|
162
|
+
export const title = text('Konkan Day 1', { size: 72, area: 'title' })
|
|
163
|
+
export function lowerThird(name: string, opts: { color?: string } = {}) {
|
|
164
|
+
const t = timeline()
|
|
165
|
+
t[0][3] = solid(opts.color ?? '#101820', { height: 160, y: 880 })
|
|
166
|
+
t[0][3] = text(name, { y: '88%' })
|
|
167
|
+
return t
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
```
|
|
172
|
+
import kit from "./kit.ts"
|
|
173
|
+
[0s .. 6s] = kit.hero
|
|
174
|
+
[1s .. 4s] = kit.title
|
|
175
|
+
[3s .. 6s] = kit.lowerThird("Nidheesh", color: "#ff5500")
|
|
176
|
+
output to "reel.mp4", resolution: "1920x1080"
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
A `timeline()` without a size takes the importing script's canvas. `describeValue(value)` is the bridge the host uses; you do not call it yourself.
|
|
180
|
+
|
|
119
181
|
## Validate / render
|
|
120
182
|
|
|
121
183
|
```bash
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plain-data descriptors of SDK values, for hosts that place them as VidScript
|
|
3
|
+
* values (`import kit from "./kit.ts"` then `[0s .. 3s] = kit.title`).
|
|
4
|
+
*
|
|
5
|
+
* A descriptor is JSON — it crosses a VM boundary — and its params use
|
|
6
|
+
* VidScript's property names (`stroke_width`, `fade_in`, …), so the compiler
|
|
7
|
+
* places it exactly like the VidScript spelling of the same value.
|
|
8
|
+
*/
|
|
9
|
+
import type { IRCrop, IREffect, IRMaskMode, IRTimeline } from './ir.js';
|
|
10
|
+
export type DescriptorParams = Record<string, unknown>;
|
|
11
|
+
export interface MaskDescriptor {
|
|
12
|
+
matte: SdkValueDescriptor;
|
|
13
|
+
mode: IRMaskMode;
|
|
14
|
+
}
|
|
15
|
+
export type SdkValueDescriptor = {
|
|
16
|
+
kind: 'video' | 'image';
|
|
17
|
+
source: string;
|
|
18
|
+
/** Media length in seconds, when known. */
|
|
19
|
+
duration?: number;
|
|
20
|
+
/** Frame rate to interpret the footage at. */
|
|
21
|
+
rate?: number;
|
|
22
|
+
sequence?: {
|
|
23
|
+
first: number;
|
|
24
|
+
count: number;
|
|
25
|
+
rate?: number;
|
|
26
|
+
};
|
|
27
|
+
/** The clip's own sound comes along when placed. */
|
|
28
|
+
nativeAudio?: boolean;
|
|
29
|
+
edits: {
|
|
30
|
+
trimStart?: number;
|
|
31
|
+
trimEnd?: number;
|
|
32
|
+
speed?: number;
|
|
33
|
+
loop?: number;
|
|
34
|
+
opacity?: number;
|
|
35
|
+
width?: number;
|
|
36
|
+
height?: number;
|
|
37
|
+
effects?: IREffect[];
|
|
38
|
+
crop?: IRCrop;
|
|
39
|
+
mask?: MaskDescriptor;
|
|
40
|
+
};
|
|
41
|
+
props: DescriptorParams;
|
|
42
|
+
} | {
|
|
43
|
+
kind: 'text';
|
|
44
|
+
content: string;
|
|
45
|
+
params: DescriptorParams;
|
|
46
|
+
} | {
|
|
47
|
+
kind: 'audio';
|
|
48
|
+
source: string;
|
|
49
|
+
duration?: number;
|
|
50
|
+
trimEnd?: number;
|
|
51
|
+
params: DescriptorParams;
|
|
52
|
+
} | {
|
|
53
|
+
kind: 'solid';
|
|
54
|
+
color: string;
|
|
55
|
+
props: DescriptorParams;
|
|
56
|
+
} | {
|
|
57
|
+
kind: 'gap';
|
|
58
|
+
} | {
|
|
59
|
+
kind: 'marker';
|
|
60
|
+
name: string;
|
|
61
|
+
metadata?: Record<string, unknown>;
|
|
62
|
+
} | {
|
|
63
|
+
kind: 'timeline';
|
|
64
|
+
name: string;
|
|
65
|
+
/** Lowered on the host canvas, in timeline-local time (0 is the placement start). */
|
|
66
|
+
ir: IRTimeline;
|
|
67
|
+
props: DescriptorParams;
|
|
68
|
+
effects: IREffect[];
|
|
69
|
+
crop?: IRCrop;
|
|
70
|
+
mask?: MaskDescriptor;
|
|
71
|
+
}
|
|
72
|
+
/** Plain data: numbers (Durations as seconds), strings, booleans, arrays, objects. */
|
|
73
|
+
| {
|
|
74
|
+
kind: 'data';
|
|
75
|
+
value: unknown;
|
|
76
|
+
}
|
|
77
|
+
/** A value with no VidScript placement (filters, shaders, transitions as values). */
|
|
78
|
+
| {
|
|
79
|
+
kind: 'unsupported';
|
|
80
|
+
sdkKind: string;
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Describe any SDK value — or plain data — as JSON a host can place. Timelines
|
|
84
|
+
* lower on the host canvas (`globalThis.__scenerokCanvas`).
|
|
85
|
+
*/
|
|
86
|
+
export declare function describeValue(value: unknown): SdkValueDescriptor;
|
|
87
|
+
//# sourceMappingURL=describe.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"describe.d.ts","sourceRoot":"","sources":["../src/describe.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAexE,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEvD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,IAAI,EAAE,UAAU,CAAC;CAClB;AAED,MAAM,MAAM,kBAAkB,GAC1B;IACA,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D,oDAAoD;IACpD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,KAAK,EAAE;QACL,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,QAAQ,EAAE,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,cAAc,CAAC;KACvB,CAAC;IACF,KAAK,EAAE,gBAAgB,CAAC;CACzB,GACC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,GAChG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,gBAAgB,CAAA;CAAE,GACzD;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,GACf;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GACpE;IACA,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,qFAAqF;IACrF,EAAE,EAAE,UAAU,CAAC;IACf,KAAK,EAAE,gBAAgB,CAAC;IACxB,OAAO,EAAE,QAAQ,EAAE,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,cAAc,CAAC;CACvB;AACD,sFAAsF;GACpF;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE;AAClC,qFAAqF;GACnF;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AA2K7C;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,CAyBhE"}
|
package/dist/describe.js
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plain-data descriptors of SDK values, for hosts that place them as VidScript
|
|
3
|
+
* values (`import kit from "./kit.ts"` then `[0s .. 3s] = kit.title`).
|
|
4
|
+
*
|
|
5
|
+
* A descriptor is JSON — it crosses a VM boundary — and its params use
|
|
6
|
+
* VidScript's property names (`stroke_width`, `fade_in`, …), so the compiler
|
|
7
|
+
* places it exactly like the VidScript spelling of the same value.
|
|
8
|
+
*/
|
|
9
|
+
import { Duration, toSeconds } from './duration.js';
|
|
10
|
+
import { bindTransitions, hostCanvas, lowerTimeline, timelineRecordOf } from './ir-builder.js';
|
|
11
|
+
import { isSdkNode } from './types.js';
|
|
12
|
+
function defined(entries) {
|
|
13
|
+
const out = {};
|
|
14
|
+
for (const [key, value] of Object.entries(entries)) {
|
|
15
|
+
if (value !== undefined)
|
|
16
|
+
out[key] = value;
|
|
17
|
+
}
|
|
18
|
+
return out;
|
|
19
|
+
}
|
|
20
|
+
function animateParam(animate) {
|
|
21
|
+
if (!animate)
|
|
22
|
+
return undefined;
|
|
23
|
+
const list = Array.isArray(animate) ? animate : [animate];
|
|
24
|
+
if (list.length === 0)
|
|
25
|
+
return undefined;
|
|
26
|
+
return list.map(({ type, from, to, duration, align, easing, loop, plugin }) => defined({ type, from, to, duration, align, easing, loop, plugin }));
|
|
27
|
+
}
|
|
28
|
+
/** Placement options in VidScript's property names. */
|
|
29
|
+
function placementParams(opts) {
|
|
30
|
+
return defined({
|
|
31
|
+
x: opts.x,
|
|
32
|
+
y: opts.y,
|
|
33
|
+
width: opts.width,
|
|
34
|
+
height: opts.height,
|
|
35
|
+
opacity: opts.opacity,
|
|
36
|
+
rotation: opts.rotation,
|
|
37
|
+
radius: opts.radius,
|
|
38
|
+
corners: opts.corners,
|
|
39
|
+
area: opts.area,
|
|
40
|
+
blend: opts.blend,
|
|
41
|
+
motion_blur: opts.motionBlur,
|
|
42
|
+
enabled: opts.enabled,
|
|
43
|
+
animate: animateParam(opts.animate),
|
|
44
|
+
input_colorspace: opts.inputColorspace,
|
|
45
|
+
output_colorspace: opts.outputColorspace,
|
|
46
|
+
volume: opts.volume,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function describeMask(mask) {
|
|
50
|
+
if (!mask)
|
|
51
|
+
return undefined;
|
|
52
|
+
return { matte: describeValue(mask.matte), mode: mask.mode };
|
|
53
|
+
}
|
|
54
|
+
function describeMedia(node) {
|
|
55
|
+
const { trimStart, trimEnd, speed, loop, opacity, width, height, effects, crop, mask } = node.edits;
|
|
56
|
+
const video = node.kind === 'video' ? node : null;
|
|
57
|
+
return {
|
|
58
|
+
kind: node.kind,
|
|
59
|
+
source: node.source,
|
|
60
|
+
...(video?.mediaDuration !== undefined ? { duration: video.mediaDuration } : {}),
|
|
61
|
+
...(video?.options.rate !== undefined && !video.sequence ? { rate: video.options.rate } : {}),
|
|
62
|
+
...(video?.sequence ? { sequence: video.sequence } : {}),
|
|
63
|
+
...(video?.options.nativeAudio ? { nativeAudio: true } : {}),
|
|
64
|
+
edits: defined({
|
|
65
|
+
trimStart, trimEnd, speed, loop, opacity, width, height,
|
|
66
|
+
effects: effects?.length ? effects : undefined,
|
|
67
|
+
crop,
|
|
68
|
+
mask: describeMask(mask),
|
|
69
|
+
}),
|
|
70
|
+
props: placementParams(node.options),
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function describeText(node) {
|
|
74
|
+
const o = node.options;
|
|
75
|
+
return {
|
|
76
|
+
kind: 'text',
|
|
77
|
+
content: node.content,
|
|
78
|
+
params: defined({
|
|
79
|
+
font: o.font,
|
|
80
|
+
size: o.size,
|
|
81
|
+
min_size: o.minSize,
|
|
82
|
+
color: o.color,
|
|
83
|
+
stroke: o.stroke,
|
|
84
|
+
stroke_width: o.strokeWidth,
|
|
85
|
+
position: o.position,
|
|
86
|
+
bold: o.bold,
|
|
87
|
+
italic: o.italic,
|
|
88
|
+
x: o.x,
|
|
89
|
+
y: o.y,
|
|
90
|
+
rotation: o.rotation,
|
|
91
|
+
opacity: o.opacity,
|
|
92
|
+
align: o.align,
|
|
93
|
+
line_height: o.lineHeight,
|
|
94
|
+
letter_spacing: o.letterSpacing,
|
|
95
|
+
shadow_color: o.shadowColor,
|
|
96
|
+
shadow_blur: o.shadowBlur,
|
|
97
|
+
shadow_offset_x: o.shadowOffsetX,
|
|
98
|
+
shadow_offset_y: o.shadowOffsetY,
|
|
99
|
+
fit: o.fit,
|
|
100
|
+
overflow: o.overflow,
|
|
101
|
+
safe_area: o.safeArea,
|
|
102
|
+
max_width: o.maxWidth,
|
|
103
|
+
max_height: o.maxHeight,
|
|
104
|
+
max_lines: o.maxLines,
|
|
105
|
+
anchor: o.anchor,
|
|
106
|
+
area: o.area,
|
|
107
|
+
stagger: o.stagger,
|
|
108
|
+
blend: o.blend,
|
|
109
|
+
animate: animateParam(node.animations),
|
|
110
|
+
}),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
function describeAudio(node) {
|
|
114
|
+
const o = node.options;
|
|
115
|
+
const ebu = o.loudness === 'ebu-r128' || o.loudnessNormalization === 'ebu-r128';
|
|
116
|
+
const duck = typeof o.duckUnder === 'string' ? o.duckUnder : o.duckUnder?.source;
|
|
117
|
+
return {
|
|
118
|
+
kind: 'audio',
|
|
119
|
+
source: node.source,
|
|
120
|
+
...(node.mediaDuration !== undefined ? { duration: node.mediaDuration } : {}),
|
|
121
|
+
params: defined({
|
|
122
|
+
volume: o.volume,
|
|
123
|
+
fade_in: o.fadeIn !== undefined ? toSeconds(o.fadeIn) : undefined,
|
|
124
|
+
fade_out: o.fadeOut !== undefined ? toSeconds(o.fadeOut) : undefined,
|
|
125
|
+
trim_start: o.trimStart !== undefined && toSeconds(o.trimStart) > 0 ? toSeconds(o.trimStart) : undefined,
|
|
126
|
+
pan: o.pan,
|
|
127
|
+
duck_under: duck,
|
|
128
|
+
loudness: ebu ? 'ebu-r128' : undefined,
|
|
129
|
+
animate: animateParam(o.animate),
|
|
130
|
+
}),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function describeSolid(node) {
|
|
134
|
+
return { kind: 'solid', color: node.color, props: placementParams(node.options) };
|
|
135
|
+
}
|
|
136
|
+
function lowerForHost(timeline) {
|
|
137
|
+
const state = lowerTimeline(timelineRecordOf(timeline), hostCanvas());
|
|
138
|
+
bindTransitions(state.ir);
|
|
139
|
+
return JSON.parse(JSON.stringify(state.ir));
|
|
140
|
+
}
|
|
141
|
+
function describeTimeline(value) {
|
|
142
|
+
const view = 'placement' in value ? value : null;
|
|
143
|
+
const timeline = view ? view.timeline : value;
|
|
144
|
+
return {
|
|
145
|
+
kind: 'timeline',
|
|
146
|
+
name: timeline.options.name ?? 'timeline',
|
|
147
|
+
ir: lowerForHost(timeline),
|
|
148
|
+
props: view ? placementParams(view.placement) : {},
|
|
149
|
+
effects: view ? view.effects : [],
|
|
150
|
+
...(view?.cropRect ? { crop: view.cropRect } : {}),
|
|
151
|
+
...(view?.maskSpec ? { mask: describeMask(view.maskSpec) } : {}),
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
function plainData(value, seen) {
|
|
155
|
+
if (value === null || typeof value === 'string' || typeof value === 'boolean')
|
|
156
|
+
return value;
|
|
157
|
+
if (typeof value === 'number')
|
|
158
|
+
return Number.isFinite(value) ? value : null;
|
|
159
|
+
if (Duration.isDuration(value))
|
|
160
|
+
return value.seconds;
|
|
161
|
+
if (typeof value !== 'object')
|
|
162
|
+
return undefined;
|
|
163
|
+
if (seen.has(value))
|
|
164
|
+
throw new TypeError('Cannot describe a value that refers to itself');
|
|
165
|
+
seen.add(value);
|
|
166
|
+
try {
|
|
167
|
+
if (Array.isArray(value))
|
|
168
|
+
return value.map((item) => plainData(item, seen));
|
|
169
|
+
const out = {};
|
|
170
|
+
for (const [key, item] of Object.entries(value)) {
|
|
171
|
+
const data = plainData(item, seen);
|
|
172
|
+
if (data !== undefined)
|
|
173
|
+
out[key] = data;
|
|
174
|
+
}
|
|
175
|
+
return out;
|
|
176
|
+
}
|
|
177
|
+
finally {
|
|
178
|
+
seen.delete(value);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Describe any SDK value — or plain data — as JSON a host can place. Timelines
|
|
183
|
+
* lower on the host canvas (`globalThis.__scenerokCanvas`).
|
|
184
|
+
*/
|
|
185
|
+
export function describeValue(value) {
|
|
186
|
+
if (isSdkNode(value)) {
|
|
187
|
+
switch (value.kind) {
|
|
188
|
+
case 'video':
|
|
189
|
+
case 'image':
|
|
190
|
+
return describeMedia(value);
|
|
191
|
+
case 'text':
|
|
192
|
+
return describeText(value);
|
|
193
|
+
case 'audio':
|
|
194
|
+
return describeAudio(value);
|
|
195
|
+
case 'solid':
|
|
196
|
+
return describeSolid(value);
|
|
197
|
+
case 'gap':
|
|
198
|
+
return { kind: 'gap' };
|
|
199
|
+
case 'marker': {
|
|
200
|
+
const marker = value;
|
|
201
|
+
return { kind: 'marker', name: marker.name, ...(marker.metadata ? { metadata: marker.metadata } : {}) };
|
|
202
|
+
}
|
|
203
|
+
case 'timeline':
|
|
204
|
+
return describeTimeline(value);
|
|
205
|
+
default:
|
|
206
|
+
return { kind: 'unsupported', sdkKind: value.kind };
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return { kind: 'data', value: plainData(value, new Set()) ?? null };
|
|
210
|
+
}
|
package/dist/duration.d.ts
CHANGED
|
@@ -17,13 +17,19 @@ export declare class Duration {
|
|
|
17
17
|
export declare function s(seconds: number): Duration;
|
|
18
18
|
/** Milliseconds helper: `ms(300)` → 0.3s. */
|
|
19
19
|
export declare function ms(milliseconds: number): Duration;
|
|
20
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* A frame count at `fps` (exact for NTSC: `frames(24, 23.976)` is `24 * 1001 / 24000`).
|
|
22
|
+
* To count frames of the timeline's own rate, use `t.frames(n)` or the string `'48f'`.
|
|
23
|
+
*/
|
|
21
24
|
export declare function frames(count: number, fps?: number): Duration;
|
|
22
25
|
/**
|
|
23
26
|
* Parse a time value to seconds.
|
|
24
|
-
* Accepts numbers (already seconds), Duration, or strings like `3s`, `300ms`,
|
|
27
|
+
* Accepts numbers (already seconds), Duration, or strings like `3s`, `300ms`,
|
|
28
|
+
* `1:30`, `0:01:30`, frame counts `48f`, and timecodes `01:00:00:00@24`.
|
|
29
|
+
* Frame counts and timecodes without `@rate` count frames of `fps` — a
|
|
30
|
+
* timeline passes its own — and throw without one.
|
|
25
31
|
*/
|
|
26
|
-
export declare function toSeconds(value: TimeInput): number;
|
|
32
|
+
export declare function toSeconds(value: TimeInput, fps?: number): number;
|
|
27
33
|
export declare function isAutoPlayheadKey(key: PropertyKey): boolean;
|
|
28
34
|
export {};
|
|
29
35
|
//# sourceMappingURL=duration.d.ts.map
|
package/dist/duration.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"duration.d.ts","sourceRoot":"","sources":["../src/duration.ts"],"names":[],"mappings":"AAAA,qEAAqE;
|
|
1
|
+
{"version":3,"file":"duration.d.ts","sourceRoot":"","sources":["../src/duration.ts"],"names":[],"mappings":"AAAA,qEAAqE;AAIrE,QAAA,MAAM,cAAc,eAAkC,CAAC;AAEvD,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEnD,qBAAa,QAAQ;IACnB,QAAQ,CAAC,CAAC,cAAc,CAAC,EAAG,IAAI,CAAU;IAC1C,yBAAyB;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEb,OAAO,EAAE,MAAM;IAO3B,OAAO,IAAI,MAAM;IAIjB,QAAQ,IAAI,MAAM;IAIlB,GAAG,CAAC,KAAK,EAAE,SAAS,GAAG,QAAQ;IAI/B,GAAG,CAAC,KAAK,EAAE,SAAS,GAAG,QAAQ;IAI/B,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ;IAI7B,MAAM,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ;CAOrD;AAED,mCAAmC;AACnC,wBAAgB,CAAC,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAE3C;AAED,6CAA6C;AAC7C,wBAAgB,EAAE,CAAC,YAAY,EAAE,MAAM,GAAG,QAAQ,CAEjD;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,SAAK,GAAG,QAAQ,CAGxD;AAOD;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAoChE;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAE3D"}
|
package/dist/duration.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/** Duration helpers — seconds as the canonical unit (matches IR). */
|
|
2
|
+
import { exactFpsOf, isTimecodeString, timecodeToSeconds } from './frame-rate.js';
|
|
2
3
|
const DURATION_BRAND = Symbol.for('scenerok.Duration');
|
|
3
4
|
export class Duration {
|
|
4
5
|
[DURATION_BRAND] = true;
|
|
@@ -39,18 +40,25 @@ export function s(seconds) {
|
|
|
39
40
|
export function ms(milliseconds) {
|
|
40
41
|
return new Duration(milliseconds / 1000);
|
|
41
42
|
}
|
|
42
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* A frame count at `fps` (exact for NTSC: `frames(24, 23.976)` is `24 * 1001 / 24000`).
|
|
45
|
+
* To count frames of the timeline's own rate, use `t.frames(n)` or the string `'48f'`.
|
|
46
|
+
*/
|
|
43
47
|
export function frames(count, fps = 30) {
|
|
44
48
|
if (fps <= 0)
|
|
45
49
|
throw new TypeError('fps must be positive');
|
|
46
|
-
return new Duration(count / fps);
|
|
50
|
+
return new Duration(count / exactFpsOf(fps));
|
|
47
51
|
}
|
|
52
|
+
const FRAME_STRING_RE = /^(\d+)\s*(?:f|frame|frames)$/i;
|
|
48
53
|
const TIME_STRING_RE = /^(?:(?<h>\d+):(?<m>\d{2}):(?<s>\d{2}(?:\.\d+)?))$|^(?:(?<mm>\d+):(?<ss>\d{2}(?:\.\d+)?))$|^(?<num>\d+(?:\.\d+)?)\s*(?<unit>s|sec|secs|seconds|ms|milliseconds)?$/i;
|
|
49
54
|
/**
|
|
50
55
|
* Parse a time value to seconds.
|
|
51
|
-
* Accepts numbers (already seconds), Duration, or strings like `3s`, `300ms`,
|
|
56
|
+
* Accepts numbers (already seconds), Duration, or strings like `3s`, `300ms`,
|
|
57
|
+
* `1:30`, `0:01:30`, frame counts `48f`, and timecodes `01:00:00:00@24`.
|
|
58
|
+
* Frame counts and timecodes without `@rate` count frames of `fps` — a
|
|
59
|
+
* timeline passes its own — and throw without one.
|
|
52
60
|
*/
|
|
53
|
-
export function toSeconds(value) {
|
|
61
|
+
export function toSeconds(value, fps) {
|
|
54
62
|
if (typeof value === 'number') {
|
|
55
63
|
if (!Number.isFinite(value))
|
|
56
64
|
throw new TypeError(`Invalid time number: ${value}`);
|
|
@@ -63,6 +71,15 @@ export function toSeconds(value) {
|
|
|
63
71
|
if (trimmed === '-' || trimmed === '') {
|
|
64
72
|
throw new TypeError(`Cannot convert auto-playhead marker '${value}' via toSeconds; use timeline.push / t['-']`);
|
|
65
73
|
}
|
|
74
|
+
if (isTimecodeString(trimmed))
|
|
75
|
+
return timecodeToSeconds(trimmed, fps);
|
|
76
|
+
const frameMatch = FRAME_STRING_RE.exec(trimmed);
|
|
77
|
+
if (frameMatch) {
|
|
78
|
+
if (fps === undefined) {
|
|
79
|
+
throw new TypeError(`Frame time '${value}' needs a frame rate; schedule it on a timeline or use frames(n, fps)`);
|
|
80
|
+
}
|
|
81
|
+
return Number(frameMatch[1]) / exactFpsOf(fps);
|
|
82
|
+
}
|
|
66
83
|
const match = TIME_STRING_RE.exec(trimmed);
|
|
67
84
|
if (!match || !match.groups) {
|
|
68
85
|
throw new TypeError(`Unrecognized time string: ${JSON.stringify(value)}`);
|
|
@@ -83,5 +100,5 @@ export function toSeconds(value) {
|
|
|
83
100
|
throw new TypeError(`Unsupported time input: ${String(value)}`);
|
|
84
101
|
}
|
|
85
102
|
export function isAutoPlayheadKey(key) {
|
|
86
|
-
return key === '-'
|
|
103
|
+
return key === '-';
|
|
87
104
|
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rational frame rates — the SDK's copy of the platform's `src/lib/time/frame-rate.ts`.
|
|
3
|
+
*
|
|
4
|
+
* IR times stay float seconds. A frame is `num / den` seconds, so 23.976 is
|
|
5
|
+
* `1001 / 24000` rather than a rounded float, exactly as VidScript computes it.
|
|
6
|
+
*/
|
|
7
|
+
/** Frame duration in seconds: `num / den`. */
|
|
8
|
+
export interface TimeBase {
|
|
9
|
+
num: number;
|
|
10
|
+
den: number;
|
|
11
|
+
}
|
|
12
|
+
/** Frame digits a timecode counts per second: 23.976 counts 24. */
|
|
13
|
+
export declare function nominalFps(fps: number): number;
|
|
14
|
+
/** `{ 1001, nominal * 1000 }` for NTSC rates (23.976, 29.97, …), `{ 1, fps }` otherwise. */
|
|
15
|
+
export declare function frameRateOf(fps: number): TimeBase;
|
|
16
|
+
/** True for the NTSC family (a time base that is not `1 / integer`). */
|
|
17
|
+
export declare function isFractionalTimeBase(timeBase: TimeBase): boolean;
|
|
18
|
+
/** The exact frames per second: `24000 / 1001` for 23.976. */
|
|
19
|
+
export declare function exactFpsOf(fps: number): number;
|
|
20
|
+
/** Round seconds to the nearest frame boundary (ties up). */
|
|
21
|
+
export declare function snapToFrame(seconds: number, timeBase: TimeBase): number;
|
|
22
|
+
/** True for an `HH:MM:SS:FF` (optionally `@rate`) string. */
|
|
23
|
+
export declare function isTimecodeString(value: string): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* `HH:MM:SS:FF[@rate]` in seconds. Non-drop-frame only; FF must be below the
|
|
26
|
+
* nominal rate and hours run 0-23. Without `@rate`, `fps` is the rate; with
|
|
27
|
+
* neither the timecode has no meaning and this throws.
|
|
28
|
+
*/
|
|
29
|
+
export declare function timecodeToSeconds(value: string, fps?: number, label?: string): number;
|
|
30
|
+
//# sourceMappingURL=frame-rate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frame-rate.d.ts","sourceRoot":"","sources":["../src/frame-rate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,8CAA8C;AAC9C,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAKD,mEAAmE;AACnE,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,4FAA4F;AAC5F,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,CAMjD;AAED,wEAAwE;AACxE,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAEhE;AAED,8DAA8D;AAC9D,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG9C;AAED,6DAA6D;AAC7D,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAIvE;AAID,6DAA6D;AAC7D,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,KAAK,SAAa,GAAG,MAAM,CAsBzF"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rational frame rates — the SDK's copy of the platform's `src/lib/time/frame-rate.ts`.
|
|
3
|
+
*
|
|
4
|
+
* IR times stay float seconds. A frame is `num / den` seconds, so 23.976 is
|
|
5
|
+
* `1001 / 24000` rather than a rounded float, exactly as VidScript computes it.
|
|
6
|
+
*/
|
|
7
|
+
const NTSC_TOLERANCE = 0.001;
|
|
8
|
+
const NTSC_NOMINAL = [24, 30, 48, 60, 120];
|
|
9
|
+
/** Frame digits a timecode counts per second: 23.976 counts 24. */
|
|
10
|
+
export function nominalFps(fps) {
|
|
11
|
+
return Math.max(1, Math.round(fps));
|
|
12
|
+
}
|
|
13
|
+
/** `{ 1001, nominal * 1000 }` for NTSC rates (23.976, 29.97, …), `{ 1, fps }` otherwise. */
|
|
14
|
+
export function frameRateOf(fps) {
|
|
15
|
+
for (const nominal of NTSC_NOMINAL) {
|
|
16
|
+
const ntsc = (nominal * 1000) / 1001;
|
|
17
|
+
if (Math.abs(fps - ntsc) <= NTSC_TOLERANCE)
|
|
18
|
+
return { num: 1001, den: nominal * 1000 };
|
|
19
|
+
}
|
|
20
|
+
return { num: 1, den: fps };
|
|
21
|
+
}
|
|
22
|
+
/** True for the NTSC family (a time base that is not `1 / integer`). */
|
|
23
|
+
export function isFractionalTimeBase(timeBase) {
|
|
24
|
+
return timeBase.num !== 1;
|
|
25
|
+
}
|
|
26
|
+
/** The exact frames per second: `24000 / 1001` for 23.976. */
|
|
27
|
+
export function exactFpsOf(fps) {
|
|
28
|
+
const base = frameRateOf(fps);
|
|
29
|
+
return base.den / base.num;
|
|
30
|
+
}
|
|
31
|
+
/** Round seconds to the nearest frame boundary (ties up). */
|
|
32
|
+
export function snapToFrame(seconds, timeBase) {
|
|
33
|
+
if (!Number.isFinite(seconds))
|
|
34
|
+
return seconds;
|
|
35
|
+
const frames = Math.round((seconds * timeBase.den) / timeBase.num);
|
|
36
|
+
return (frames * timeBase.num) / timeBase.den;
|
|
37
|
+
}
|
|
38
|
+
const TIMECODE_RE = /^(\d{2}):(\d{2}):(\d{2})([:;])(\d{2})(?:@(\d+(?:\.\d+)?))?$/;
|
|
39
|
+
/** True for an `HH:MM:SS:FF` (optionally `@rate`) string. */
|
|
40
|
+
export function isTimecodeString(value) {
|
|
41
|
+
return TIMECODE_RE.test(value.trim());
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* `HH:MM:SS:FF[@rate]` in seconds. Non-drop-frame only; FF must be below the
|
|
45
|
+
* nominal rate and hours run 0-23. Without `@rate`, `fps` is the rate; with
|
|
46
|
+
* neither the timecode has no meaning and this throws.
|
|
47
|
+
*/
|
|
48
|
+
export function timecodeToSeconds(value, fps, label = 'timecode') {
|
|
49
|
+
const match = TIMECODE_RE.exec(value.trim());
|
|
50
|
+
if (!match) {
|
|
51
|
+
throw new TypeError(`${label} "${value}" is not HH:MM:SS:FF (two digits each, for example "01:00:00:00")`);
|
|
52
|
+
}
|
|
53
|
+
if (match[4] === ';') {
|
|
54
|
+
throw new TypeError(`${label} "${value}" is drop-frame; only non-drop-frame HH:MM:SS:FF is supported`);
|
|
55
|
+
}
|
|
56
|
+
const rate = match[6] !== undefined ? Number(match[6]) : fps;
|
|
57
|
+
if (rate === undefined || !Number.isFinite(rate) || rate <= 0) {
|
|
58
|
+
throw new TypeError(`${label} "${value}" needs a frame rate: write it as "${value}@24", or schedule it on a timeline`);
|
|
59
|
+
}
|
|
60
|
+
const [hours, minutes, seconds, frames] = [match[1], match[2], match[3], match[5]].map(Number);
|
|
61
|
+
if (hours > 23)
|
|
62
|
+
throw new RangeError(`${label} "${value}" has hours ${hours}; hours run 0-23`);
|
|
63
|
+
if (minutes > 59)
|
|
64
|
+
throw new RangeError(`${label} "${value}" has minutes ${minutes}; minutes run 0-59`);
|
|
65
|
+
if (seconds > 59)
|
|
66
|
+
throw new RangeError(`${label} "${value}" has seconds ${seconds}; seconds run 0-59`);
|
|
67
|
+
const nominal = nominalFps(rate);
|
|
68
|
+
if (frames >= nominal) {
|
|
69
|
+
throw new RangeError(`${label} "${value}" has frame ${frames}, but the rate is ${rate}; frames run 0-${nominal - 1}`);
|
|
70
|
+
}
|
|
71
|
+
const count = ((hours * 60 + minutes) * 60 + seconds) * nominal + frames;
|
|
72
|
+
return snapToFrame(count / exactFpsOf(rate), frameRateOf(rate));
|
|
73
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -4,15 +4,18 @@
|
|
|
4
4
|
* Agents use this for complex, data-driven scenes. Humans keep VidScript for
|
|
5
5
|
* short declarative scripts. Both emit the same IRTimeline for Pass 2.
|
|
6
6
|
*/
|
|
7
|
-
export type { IRTimeline, IRClip, IRLayer, IRTextLayer, IRSurface, IREffect, IRAudioTrack, IROutput, IRAnimation, IRMotionTrack, } from './ir.js';
|
|
7
|
+
export type { IRTimeline, IRClip, IRLayer, IRTextLayer, IRTextStyle, IRSurface, IREffect, IRAudioTrack, IROutput, IRAnimation, IRMotionTrack, IRGroup, IRMarker, IRCrop, IRMaskMode, IRMotionBlur, IRImageSequence, } from './ir.js';
|
|
8
8
|
export { defaultIRTimeline, defaultIROutput } from './ir.js';
|
|
9
9
|
export { Duration, s, ms, frames, toSeconds, type TimeInput, } from './duration.js';
|
|
10
|
-
export
|
|
11
|
-
export {
|
|
12
|
-
export {
|
|
13
|
-
export {
|
|
10
|
+
export { frameRateOf, exactFpsOf, snapToFrame, timecodeToSeconds, type TimeBase } from './frame-rate.js';
|
|
11
|
+
export type { VideoClip, VideoOptions, ImageClip, ImageOptions, ImageSequenceOptions, MediaMethods, ClipEdits, MaskOptions, PlacementOptions, BlendMode, MotionBlurOption, TextLayer, TextOptions, AudioTrack, AudioOptions, SolidNode, SolidOptions, GapNode, MarkerNode, FilterEffect, ShaderEffect, TransitionEffect, TransitionOptions, AnimationDescriptor, PictureNode, Schedulable, OutputOptions, TimelineOptions, TimelineLike, TimelineView, TimelinePlacementOptions, SdkHost, } from './types.js';
|
|
12
|
+
export { isSdkNode, isSchedulable, isPictureNode } from './types.js';
|
|
13
|
+
export { video, loadVideo, image, imageSequence, text, audio, loadAudio, solid, gap, marker, filter, shader, } from './media.js';
|
|
14
|
+
export { animation, fadeIn, fadeOut, slideY, slideX, scale, popIn, riseIn, swingIn, glitchIn, float, typewriter, rotate, volumeRamp, type AnimationOptions, } from './motion.js';
|
|
14
15
|
export { timeline, isTimeline, type Timeline } from './timeline.js';
|
|
15
|
-
export { createIrBuilder, scheduleAt, resetIrBuilderIds, inferAutoDuration, assertSchedulable, bindTransitions, setGrid, type IrBuilderState, } from './ir-builder.js';
|
|
16
|
+
export { createIrBuilder, scheduleAt, resetIrBuilderIds, inferAutoDuration, assertSchedulable, bindTransitions, setGrid, hostCanvas, type Canvas, type IrBuilderState, } from './ir-builder.js';
|
|
17
|
+
export { animationToMotionTracks, animationsToMotionTracks } from './motion-tracks.js';
|
|
18
|
+
export { describeValue, type SdkValueDescriptor, type MaskDescriptor } from './describe.js';
|
|
16
19
|
export { defaultGridSpec, resolveGridAreas, placementFromGridArea, placeInArea, type GridSpec, type GridAreaRect, type GridAreaPlacement, } from './grid.js';
|
|
17
20
|
export { getVideoLength, getAudioLength, getMediaInfo, getDimensions, getFps, getLoudness, hasAudio, mediaKind, grabFrame, grabFrames, grabFrameAtFraction, measureText, fitContain, fitCover, clampTime, parseTime, timecode, beats, type MediaSource, type MediaInfo, type Dimensions, type LoudnessInfo, type FitBox, type GrabFrameOptions, type MeasureTextStyle, type TextMetrics, type StdlibMediaKind, type StdlibHostApi, } from './stdlib.js';
|
|
18
21
|
export { default as xai } from './plugins/xai.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,YAAY,EACV,UAAU,EACV,MAAM,EACN,OAAO,EACP,WAAW,EACX,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,aAAa,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -6,11 +6,14 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export { defaultIRTimeline, defaultIROutput } from './ir.js';
|
|
8
8
|
export { Duration, s, ms, frames, toSeconds, } from './duration.js';
|
|
9
|
-
export {
|
|
10
|
-
export {
|
|
11
|
-
export {
|
|
9
|
+
export { frameRateOf, exactFpsOf, snapToFrame, timecodeToSeconds } from './frame-rate.js';
|
|
10
|
+
export { isSdkNode, isSchedulable, isPictureNode } from './types.js';
|
|
11
|
+
export { video, loadVideo, image, imageSequence, text, audio, loadAudio, solid, gap, marker, filter, shader, } from './media.js';
|
|
12
|
+
export { animation, fadeIn, fadeOut, slideY, slideX, scale, popIn, riseIn, swingIn, glitchIn, float, typewriter, rotate, volumeRamp, } from './motion.js';
|
|
12
13
|
export { timeline, isTimeline } from './timeline.js';
|
|
13
|
-
export { createIrBuilder, scheduleAt, resetIrBuilderIds, inferAutoDuration, assertSchedulable, bindTransitions, setGrid, } from './ir-builder.js';
|
|
14
|
+
export { createIrBuilder, scheduleAt, resetIrBuilderIds, inferAutoDuration, assertSchedulable, bindTransitions, setGrid, hostCanvas, } from './ir-builder.js';
|
|
15
|
+
export { animationToMotionTracks, animationsToMotionTracks } from './motion-tracks.js';
|
|
16
|
+
export { describeValue } from './describe.js';
|
|
14
17
|
export { defaultGridSpec, resolveGridAreas, placementFromGridArea, placeInArea, } from './grid.js';
|
|
15
18
|
// Media stdlib — host-injected at compile time (`@scenerok/stdlib` alias)
|
|
16
19
|
export { getVideoLength, getAudioLength, getMediaInfo, getDimensions, getFps, getLoudness, hasAudio, mediaKind, grabFrame, grabFrames, grabFrameAtFraction, measureText, fitContain, fitCover, clampTime, parseTime, timecode, beats, } from './stdlib.js';
|