@pixerate/editor 0.123.0 → 0.124.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/index.cjs +2 -2
- package/dist/agent/index.cjs.map +1 -1
- package/dist/agent/index.js +3 -3
- package/dist/animation/index.d.cts +2 -1
- package/dist/animation/index.d.ts +2 -1
- package/dist/animation-editor/index.cjs.map +1 -1
- package/dist/animation-editor/index.d.cts +11 -733
- package/dist/animation-editor/index.d.ts +11 -733
- package/dist/animation-editor/index.js.map +1 -1
- package/dist/{bezier-C-W9LFyD.d.cts → bezier-CBzKKDjl.d.cts} +2 -66
- package/dist/{bezier-DQZE5dxA.d.ts → bezier-CWv6LQal.d.ts} +2 -66
- package/dist/{brushstrokeRender-M4S65DHT.cjs → brushstrokeRender-EELTV7U4.cjs} +8 -8
- package/dist/{brushstrokeRender-M4S65DHT.cjs.map → brushstrokeRender-EELTV7U4.cjs.map} +1 -1
- package/dist/{brushstrokeRender-CDDRSV2W.js → brushstrokeRender-LRV7GXGD.js} +3 -3
- package/dist/canvas/index.cjs +6 -6
- package/dist/canvas/index.d.cts +10 -6
- package/dist/canvas/index.d.ts +10 -6
- package/dist/canvas/index.js +1 -1
- package/dist/{chunk-TVXFHE4T.js → chunk-64PYNEHJ.js} +45 -12
- package/dist/chunk-64PYNEHJ.js.map +1 -0
- package/dist/{chunk-2IW3BWRT.cjs → chunk-7LQO6OHH.cjs} +2 -2
- package/dist/{chunk-2IW3BWRT.cjs.map → chunk-7LQO6OHH.cjs.map} +1 -1
- package/dist/chunk-IOXKXQNW.cjs +178 -0
- package/dist/chunk-IOXKXQNW.cjs.map +1 -0
- package/dist/{chunk-SMJGE7HM.cjs → chunk-IWSMDQE5.cjs} +523 -39
- package/dist/chunk-IWSMDQE5.cjs.map +1 -0
- package/dist/{chunk-KMBC4HNV.js → chunk-J67OLQUQ.js} +2 -2
- package/dist/{chunk-6CJRDJCU.cjs → chunk-PEHYWUVV.cjs} +176 -111
- package/dist/chunk-PEHYWUVV.cjs.map +1 -0
- package/dist/chunk-TGKT5QAB.js +178 -0
- package/dist/chunk-TGKT5QAB.js.map +1 -0
- package/dist/chunk-TK53AB4Q.cjs +215 -0
- package/dist/chunk-TK53AB4Q.cjs.map +1 -0
- package/dist/chunk-VFAKN46Z.js +215 -0
- package/dist/chunk-VFAKN46Z.js.map +1 -0
- package/dist/{chunk-6ZBR4J62.js → chunk-WATAQ2Z2.js} +79 -14
- package/dist/chunk-WATAQ2Z2.js.map +1 -0
- package/dist/{chunk-IPFRWILU.js → chunk-YVVSTD3B.js} +499 -15
- package/dist/chunk-YVVSTD3B.js.map +1 -0
- package/dist/{chunk-RLRUAPBJ.cjs → chunk-Z6OUCS2K.cjs} +47 -14
- package/dist/chunk-Z6OUCS2K.cjs.map +1 -0
- package/dist/effects/index.cjs +588 -0
- package/dist/effects/index.cjs.map +1 -0
- package/dist/effects/index.d.cts +131 -0
- package/dist/effects/index.d.ts +131 -0
- package/dist/effects/index.js +588 -0
- package/dist/effects/index.js.map +1 -0
- package/dist/evaluate-2S3vSPLy.d.cts +55 -0
- package/dist/evaluate-CfmT6xA3.d.ts +55 -0
- package/dist/{export-DfjzHAJI.d.ts → export-8RnlngAv.d.ts} +534 -128
- package/dist/{export-Dv0-ZVrV.d.ts → export-BzSRXyH6.d.cts} +390 -5
- package/dist/{export-Dv0-ZVrV.d.cts → export-DM3h7QEI.d.ts} +390 -5
- package/dist/{export-lU5qSpHE.d.cts → export-TqXMOlDt.d.cts} +534 -128
- package/dist/flair-CxB3fOcU.d.ts +739 -0
- package/dist/flair-D7BxyBwL.d.cts +739 -0
- package/dist/gradient-KDfCvhuj.d.cts +66 -0
- package/dist/gradient-KDfCvhuj.d.ts +66 -0
- package/dist/helpers-777mC6dc.d.cts +253 -0
- package/dist/helpers-DX2_7L5t.d.ts +253 -0
- package/dist/image-editor/index.cjs +1307 -805
- package/dist/image-editor/index.cjs.map +1 -1
- package/dist/image-editor/index.d.cts +39 -182
- package/dist/image-editor/index.d.ts +39 -182
- package/dist/image-editor/index.js +508 -6
- package/dist/image-editor/index.js.map +1 -1
- package/dist/{opentype-p8Xxf-Wh.d.ts → opentype-14PDI5D2.d.ts} +1 -1
- package/dist/{opentype-BV7wWatY.d.cts → opentype-D80AVmMu.d.cts} +1 -1
- package/dist/paint/index.cjs +2 -2
- package/dist/paint/index.d.cts +32 -10
- package/dist/paint/index.d.ts +32 -10
- package/dist/paint/index.js +1 -1
- package/dist/paint-editor/index.cjs +10 -8
- package/dist/paint-editor/index.cjs.map +1 -1
- package/dist/paint-editor/index.d.cts +11 -5
- package/dist/paint-editor/index.d.ts +11 -5
- package/dist/paint-editor/index.js +4 -2
- package/dist/paint-editor/index.js.map +1 -1
- package/dist/parameters/index.d.cts +4 -184
- package/dist/parameters/index.d.ts +4 -184
- package/dist/{pathfinder-IxcyhO00.d.cts → pathfinder-C0UoFypx.d.cts} +1 -1
- package/dist/{pathfinder-StVChJOT.d.ts → pathfinder-DjISxkUv.d.ts} +1 -1
- package/dist/{player-DrcP2xqj.d.cts → player-CBtEoU2x.d.cts} +2 -54
- package/dist/{player-DV4Jujdq.d.ts → player-cGLrngL_.d.ts} +2 -54
- package/dist/{svg-BtND4TJu.d.cts → svg-BDrjRnL1.d.cts} +3 -2
- package/dist/{svg-BfVXG7hL.d.ts → svg-C-vZ3q50.d.ts} +3 -2
- package/dist/tools/index.cjs +2 -2
- package/dist/tools/index.cjs.map +1 -1
- package/dist/tools/index.js +3 -3
- package/dist/tools-C7JtLYzo.d.ts +126 -0
- package/dist/tools-DHKGHiSK.d.cts +126 -0
- package/dist/{types-fuXEme9j.d.ts → types-BcX7sCsn.d.ts} +2 -2
- package/dist/{types-DJF3Ghn5.d.cts → types-CznabG7m.d.cts} +2 -2
- package/dist/types-D3-J3TFf.d.ts +185 -0
- package/dist/types-DMcf_z4J.d.cts +185 -0
- package/dist/vector/index.d.cts +10 -10
- package/dist/vector/index.d.ts +10 -10
- package/dist/video-editor/index.cjs +749 -277
- package/dist/video-editor/index.cjs.map +1 -1
- package/dist/video-editor/index.d.cts +265 -138
- package/dist/video-editor/index.d.ts +265 -138
- package/dist/video-editor/index.js +490 -18
- package/dist/video-editor/index.js.map +1 -1
- package/dist/{warp-BjmAgQwq.d.cts → warp-CH9MM435.d.cts} +1 -1
- package/dist/{warp-Ca5fedzS.d.ts → warp-k_PdtXOG.d.ts} +1 -1
- package/package.json +6 -1
- package/skills/pixerate-image-editor/SKILL.md +7 -0
- package/skills/pixerate-image-editor/references/provider-effects.md +35 -0
- package/skills/pixerate-video-editor/SKILL.md +39 -1
- package/dist/chunk-6CJRDJCU.cjs.map +0 -1
- package/dist/chunk-6ZBR4J62.js.map +0 -1
- package/dist/chunk-IPFRWILU.js.map +0 -1
- package/dist/chunk-RLRUAPBJ.cjs.map +0 -1
- package/dist/chunk-SMJGE7HM.cjs.map +0 -1
- package/dist/chunk-TVXFHE4T.js.map +0 -1
- /package/dist/{brushstrokeRender-CDDRSV2W.js.map → brushstrokeRender-LRV7GXGD.js.map} +0 -0
- /package/dist/{chunk-KMBC4HNV.js.map → chunk-J67OLQUQ.js.map} +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { d as EffectValue, v as EffectsSlot, f as EffectPixels, E as EffectProvider, e as EffectDescription } from './helpers-777mC6dc.cjs';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Keyframes for a clip's opacity, volume and transform. A property is either a plain number or
|
|
3
5
|
* `{ keys }`: values at clip-relative times (ms from the clip's start), each with the easing of the
|
|
@@ -165,9 +167,37 @@ declare const VIDEO_FITS: readonly ["contain", "cover", "fill", "none"];
|
|
|
165
167
|
* - `push`: this clip slides in, pushing the one before out.
|
|
166
168
|
* - `slide`: this clip slides in over the one before, which stays put.
|
|
167
169
|
* - `iris`: a circle opens from the centre, revealing this clip.
|
|
170
|
+
* - `effect`: a transition effect from the editor's effects provider (`VideoTransition.effect`).
|
|
171
|
+
*/
|
|
172
|
+
type VideoTransitionType = 'crossfade' | 'dip' | 'wipe' | 'push' | 'slide' | 'iris' | 'effect';
|
|
173
|
+
declare const VIDEO_TRANSITION_TYPES: readonly ["crossfade", "dip", "wipe", "push", "slide", "iris", "effect"];
|
|
174
|
+
/**
|
|
175
|
+
* Values of a provider effect's controls (see `@pixerate/editor/effects`): plain values, or
|
|
176
|
+
* keyframes (clip-relative ms) for numeric controls.
|
|
168
177
|
*/
|
|
169
|
-
type
|
|
170
|
-
|
|
178
|
+
type VideoEffectValues = Record<string, EffectValue | VideoKeyframes>;
|
|
179
|
+
/** A provider effect used by a transition or an effect clip. Kept in the project even without a provider. */
|
|
180
|
+
interface VideoEffectRef {
|
|
181
|
+
/** The provider's effect id. */
|
|
182
|
+
effect: string;
|
|
183
|
+
/** The provider it was applied with (its `id`). */
|
|
184
|
+
provider?: string;
|
|
185
|
+
/** The effect's name when it was applied, shown where no provider can draw it. */
|
|
186
|
+
name?: string;
|
|
187
|
+
values?: VideoEffectValues;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* A provider effect on a clip's picture (see `VideoClipBase.effects`). Effects run in order on the
|
|
191
|
+
* picture as it comes from the source, before the clip's grade, placement, opacity and blend.
|
|
192
|
+
*/
|
|
193
|
+
interface VideoClipEffect extends VideoEffectRef {
|
|
194
|
+
/** Unique within the clip (e.g. `fx1`). */
|
|
195
|
+
id: string;
|
|
196
|
+
/** Default true. */
|
|
197
|
+
enabled?: boolean;
|
|
198
|
+
/** How much of the effect's result shows over its input, 0–1 (default 1), or keyframes. */
|
|
199
|
+
opacity?: VideoAnimatable;
|
|
200
|
+
}
|
|
171
201
|
type VideoWipeDirection = 'left' | 'right' | 'up' | 'down';
|
|
172
202
|
declare const VIDEO_WIPE_DIRECTIONS: readonly ["left", "right", "up", "down"];
|
|
173
203
|
/**
|
|
@@ -183,6 +213,8 @@ interface VideoTransition {
|
|
|
183
213
|
color?: string;
|
|
184
214
|
/** For wipe, push and slide: the way the edge or picture travels (default right: in from the left). */
|
|
185
215
|
direction?: VideoWipeDirection;
|
|
216
|
+
/** For effect: the provider's transition effect and its values (plain values only). */
|
|
217
|
+
effect?: VideoEffectRef;
|
|
186
218
|
/**
|
|
187
219
|
* Shape of the sound's fades through the transition (see `VideoFadeCurve`). Default
|
|
188
220
|
* `equal-power` for crossfades and wipes, where two sounds overlap and a linear mix dips in
|
|
@@ -267,6 +299,8 @@ interface VideoClipBase {
|
|
|
267
299
|
fadeOut?: number;
|
|
268
300
|
/** Transition from the clip before (see `VideoTransition`). */
|
|
269
301
|
transition?: VideoTransition;
|
|
302
|
+
/** Provider effects on the picture, applied in order (see `VideoClipEffect`). */
|
|
303
|
+
effects?: VideoClipEffect[];
|
|
270
304
|
}
|
|
271
305
|
/**
|
|
272
306
|
* The shape of a sound fade, the same curves ffmpeg's `afade` draws, so previews and exports agree.
|
|
@@ -344,7 +378,14 @@ interface VideoSequenceClip extends VideoClipBase {
|
|
|
344
378
|
/** Shape of the sound's fade out (default linear). */
|
|
345
379
|
fadeOutCurve?: VideoFadeCurve;
|
|
346
380
|
}
|
|
347
|
-
|
|
381
|
+
/**
|
|
382
|
+
* A picture drawn by a provider effect (a generator, title or overlay), filling the frame. Without
|
|
383
|
+
* a provider it shows as a placeholder and keeps its effect id and values.
|
|
384
|
+
*/
|
|
385
|
+
interface VideoEffectClip extends VideoClipBase, VideoEffectRef {
|
|
386
|
+
type: 'effect';
|
|
387
|
+
}
|
|
388
|
+
type VideoClip = VideoMediaClip | VideoTextClip | VideoColorClip | VideoSequenceClip | VideoEffectClip;
|
|
348
389
|
type VideoClipType = VideoClip['type'];
|
|
349
390
|
/**
|
|
350
391
|
* How a clip is placed where others already are: `refuse` an overlap (the default), `overwrite`
|
|
@@ -353,7 +394,7 @@ type VideoClipType = VideoClip['type'];
|
|
|
353
394
|
*/
|
|
354
395
|
type VideoPlacementMode = 'refuse' | 'overwrite' | 'insert';
|
|
355
396
|
declare const VIDEO_PLACEMENT_MODES: readonly ["refuse", "overwrite", "insert"];
|
|
356
|
-
declare const VIDEO_CLIP_TYPES: readonly ["media", "text", "color", "sequence"];
|
|
397
|
+
declare const VIDEO_CLIP_TYPES: readonly ["media", "text", "color", "sequence", "effect"];
|
|
357
398
|
interface VideoMarker {
|
|
358
399
|
id: string;
|
|
359
400
|
time: number;
|
|
@@ -389,6 +430,336 @@ interface VideoProject {
|
|
|
389
430
|
markers?: VideoMarker[];
|
|
390
431
|
}
|
|
391
432
|
|
|
433
|
+
/** A rectangle in frame pixels. */
|
|
434
|
+
interface VideoRect {
|
|
435
|
+
x: number;
|
|
436
|
+
y: number;
|
|
437
|
+
width: number;
|
|
438
|
+
height: number;
|
|
439
|
+
}
|
|
440
|
+
/** One picture in a frame, in draw order (first is at the back). */
|
|
441
|
+
interface VideoLayer {
|
|
442
|
+
/**
|
|
443
|
+
* The clip it comes from, or `transition:<clip>` for a dip's colour. Inside a compound clip it is
|
|
444
|
+
* the path of clip ids from the project's own track (`compound/inner`), so the same sequence
|
|
445
|
+
* played twice gives distinct layers.
|
|
446
|
+
*/
|
|
447
|
+
clip: string;
|
|
448
|
+
/** The track it is on (inside a compound: the sequence's track). */
|
|
449
|
+
track: string;
|
|
450
|
+
type: VideoClip['type'];
|
|
451
|
+
/** For media: the asset, its kind and `src`, and the moment of the source to show (ms). */
|
|
452
|
+
asset?: string;
|
|
453
|
+
assetKind?: VideoAsset['kind'];
|
|
454
|
+
src?: string;
|
|
455
|
+
/** For media: the moment of the source to show (ms); for a compound: the moment of its sequence. */
|
|
456
|
+
sourceTime?: number;
|
|
457
|
+
/** For a compound: the sequence it plays. */
|
|
458
|
+
sequence?: string;
|
|
459
|
+
/**
|
|
460
|
+
* For a compound: the sequence's frame at `sourceTime`, back to front in the sequence's own frame
|
|
461
|
+
* (the project's size, transparent where nothing covers it). They are drawn together as one
|
|
462
|
+
* picture, which this layer's rect, rotation, opacity, blend, grade, wipe and iris then apply to.
|
|
463
|
+
*/
|
|
464
|
+
layers?: VideoLayer[];
|
|
465
|
+
/** 0–1, after fades and transitions. */
|
|
466
|
+
opacity: number;
|
|
467
|
+
/** Where the fitted picture sits before rotation (its centre is the rotation centre). */
|
|
468
|
+
rect: VideoRect;
|
|
469
|
+
/** Degrees clockwise about the rect's centre. */
|
|
470
|
+
rotation: number;
|
|
471
|
+
/** For a wipe: the part shown is the `progress` (0–1) of the rect from the edge opposite `direction`. */
|
|
472
|
+
wipe?: {
|
|
473
|
+
direction: VideoWipeDirection;
|
|
474
|
+
progress: number;
|
|
475
|
+
};
|
|
476
|
+
/** For an iris: only a circle on the frame's centre shows, its radius `progress` (0–1) of the way to the frame's corners. */
|
|
477
|
+
iris?: {
|
|
478
|
+
progress: number;
|
|
479
|
+
};
|
|
480
|
+
/** For text: what to draw. */
|
|
481
|
+
text?: {
|
|
482
|
+
text: string;
|
|
483
|
+
color: string;
|
|
484
|
+
fontSize: number;
|
|
485
|
+
fontFamily: string;
|
|
486
|
+
fontWeight: number;
|
|
487
|
+
background?: string;
|
|
488
|
+
};
|
|
489
|
+
/** For colour clips and dips. */
|
|
490
|
+
color?: string;
|
|
491
|
+
/** How it mixes with the layers beneath (absent = normal). */
|
|
492
|
+
blend?: VideoBlendMode;
|
|
493
|
+
/** Colour correction (absent = none). */
|
|
494
|
+
grade?: VideoGrade;
|
|
495
|
+
/** The clip's enabled provider effects, in order, with values at this moment (see `VideoClipEffect`). */
|
|
496
|
+
effects?: VideoLayerEffect[];
|
|
497
|
+
/** For an effect clip: the provider effect drawing the picture, at `time` ms into the clip. */
|
|
498
|
+
generator?: {
|
|
499
|
+
effect: string;
|
|
500
|
+
name?: string;
|
|
501
|
+
values: Record<string, EffectValue>;
|
|
502
|
+
time: number;
|
|
503
|
+
};
|
|
504
|
+
/**
|
|
505
|
+
* For a clip coming in through an effect transition: the provider transition from the outgoing
|
|
506
|
+
* clip's layer (`from`, drawn in its place) to this one, `progress` (0–1) and `time` ms through it.
|
|
507
|
+
*/
|
|
508
|
+
transitionEffect?: {
|
|
509
|
+
effect: string;
|
|
510
|
+
name?: string;
|
|
511
|
+
values: Record<string, EffectValue>;
|
|
512
|
+
progress: number;
|
|
513
|
+
time: number;
|
|
514
|
+
from: VideoLayer | null;
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
/** One provider effect on a layer at a moment. */
|
|
518
|
+
interface VideoLayerEffect {
|
|
519
|
+
/** The effect's id within its clip. */
|
|
520
|
+
id: string;
|
|
521
|
+
effect: string;
|
|
522
|
+
name?: string;
|
|
523
|
+
/** 0–1 after keyframes. */
|
|
524
|
+
opacity: number;
|
|
525
|
+
values: Record<string, EffectValue>;
|
|
526
|
+
/** Ms into the clip. */
|
|
527
|
+
time: number;
|
|
528
|
+
}
|
|
529
|
+
/** Effect values at clip-relative `clipTime` (ms): keyframed numbers resolved. */
|
|
530
|
+
declare function videoEffectValuesAt(values: VideoEffectValues | undefined, clipTime: number): Record<string, EffectValue>;
|
|
531
|
+
/** One sound playing at a moment. */
|
|
532
|
+
interface VideoAudioSource {
|
|
533
|
+
/** The clip it comes from (inside a compound: the path of clip ids, `compound/inner`). */
|
|
534
|
+
clip: string;
|
|
535
|
+
/** The track it is on (inside a compound: the sequence's track). */
|
|
536
|
+
track: string;
|
|
537
|
+
asset: string;
|
|
538
|
+
src: string;
|
|
539
|
+
/** The moment of the source playing (ms). */
|
|
540
|
+
sourceTime: number;
|
|
541
|
+
/** Gain after clip and track volume, fades and transitions, and those of any compound it plays in (0 = silent). */
|
|
542
|
+
gain: number;
|
|
543
|
+
speed: number;
|
|
544
|
+
}
|
|
545
|
+
interface VideoFrame {
|
|
546
|
+
time: number;
|
|
547
|
+
width: number;
|
|
548
|
+
height: number;
|
|
549
|
+
background: string;
|
|
550
|
+
layers: VideoLayer[];
|
|
551
|
+
audio: VideoAudioSource[];
|
|
552
|
+
}
|
|
553
|
+
/** A transform's values at clip-relative time `clipTime` (ms), keyframes resolved and defaults filled in. */
|
|
554
|
+
declare function videoTransformAt(transform: VideoClip['transform'], clipTime?: number): {
|
|
555
|
+
x: number;
|
|
556
|
+
y: number;
|
|
557
|
+
scale: number;
|
|
558
|
+
rotation: number;
|
|
559
|
+
};
|
|
560
|
+
/** Places a picture of `size` in the frame by `fit`, then the clip's transform at clip-relative `clipTime` (ms). */
|
|
561
|
+
declare function placeVideoRect(frame: {
|
|
562
|
+
width: number;
|
|
563
|
+
height: number;
|
|
564
|
+
}, size: {
|
|
565
|
+
width: number;
|
|
566
|
+
height: number;
|
|
567
|
+
}, fit?: VideoFit, transform?: VideoClip['transform'], clipTime?: number): VideoRect;
|
|
568
|
+
/** A title's text and style with the defaults filled in. */
|
|
569
|
+
declare function videoTextStyle(clip: VideoTextClip): NonNullable<VideoLayer['text']>;
|
|
570
|
+
/**
|
|
571
|
+
* A frame holding only one title, fully opaque on a transparent background, placed as the preview
|
|
572
|
+
* places it: draw it with `drawVideoFrame` and save the canvas as a PNG to give the ffmpeg export
|
|
573
|
+
* titles without `drawtext` (`VideoFfmpegOptions.titleImage`). Fades and opacity are left to the export.
|
|
574
|
+
* A keyframed transform is placed as it is at `clipTime` (the export passes titles with keyframed
|
|
575
|
+
* transforms without them, and moves the image itself).
|
|
576
|
+
*/
|
|
577
|
+
declare function videoTitleFrame(project: VideoProject, clip: VideoTextClip, clipTime?: number): VideoFrame;
|
|
578
|
+
/** How far a push or slide has moved at `progress` (0–1): eased in and out, (1 − cos πp) / 2. */
|
|
579
|
+
declare const videoTransitionEase: (progress: number) => number;
|
|
580
|
+
/** Gain of a fade shape `x` of the way up (0–1); a fade out uses the time left, so it mirrors the fade in. */
|
|
581
|
+
declare function videoFadeCurveGain(curve: VideoFadeCurve | undefined, x: number): number;
|
|
582
|
+
/**
|
|
583
|
+
* A media or compound clip's own gain at clip time `clipTime` (ms): its volume (or volume keyframes) times its
|
|
584
|
+
* shaped fades. Leaves out track volume and transitions, which depend on the timeline around it.
|
|
585
|
+
*/
|
|
586
|
+
declare function videoClipSoundGain(clip: VideoClip, clipTime: number): number;
|
|
587
|
+
/**
|
|
588
|
+
* What plays at `time` (ms): the pictures to draw, back to front, with their placement, opacity
|
|
589
|
+
* and the moment of source each shows, and the sounds with their gain. A pure function of the
|
|
590
|
+
* project and the time, so previews, exporters and agents all agree on every frame. A compound
|
|
591
|
+
* clip is one layer holding its sequence's frame (`layers`), and its sounds are mixed in with the
|
|
592
|
+
* compound's volume, fades and transitions.
|
|
593
|
+
*/
|
|
594
|
+
declare function videoFrameAt(project: VideoProject, time: number): VideoFrame;
|
|
595
|
+
/**
|
|
596
|
+
* Layers as drawn without an effects provider: an effect transition becomes a crossfade (the
|
|
597
|
+
* outgoing layer, then this one faded up by the progress). Clip effects are left on the layers,
|
|
598
|
+
* where they are simply not drawn.
|
|
599
|
+
*/
|
|
600
|
+
declare function videoLayersWithoutTransitionEffects(layers: readonly VideoLayer[]): VideoLayer[];
|
|
601
|
+
/**
|
|
602
|
+
* Every layer of a frame that draws a picture of its own, compounds opened up (each compound's
|
|
603
|
+
* layers in place of it), back to front. Hosts use it to find the media a frame needs.
|
|
604
|
+
*/
|
|
605
|
+
declare function videoFrameLeafLayers(layers: readonly VideoLayer[]): VideoLayer[];
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Provider effects in the video editor (see `@pixerate/editor/effects`): the per-frame cache of
|
|
609
|
+
* rendered effect pictures the preview and frame-exact exports draw from, and helpers to find the
|
|
610
|
+
* effects a project uses.
|
|
611
|
+
*
|
|
612
|
+
* Effects render asynchronously. The canvas drawing (`drawVideoFrame`) is synchronous, so it asks
|
|
613
|
+
* the engine for a picture by key: a cached one is drawn at once, and a missing one is requested
|
|
614
|
+
* and the layer drawn without its effects meanwhile (the frame counts as incomplete). When the
|
|
615
|
+
* render lands, subscribers redraw. `renderVideoFrameExact` repeats this until every effect of the
|
|
616
|
+
* frame is in, which is what exports use.
|
|
617
|
+
*/
|
|
618
|
+
|
|
619
|
+
/** Where a project uses a provider effect. */
|
|
620
|
+
interface VideoEffectUse {
|
|
621
|
+
/** The clip it is on (for a transition: the clip it leads into). */
|
|
622
|
+
clip: string;
|
|
623
|
+
/** `clip`: in the clip's effect stack (`instance` is its id); `transition`: an effect transition; `generator`: an effect clip. */
|
|
624
|
+
kind: 'clip' | 'transition' | 'generator';
|
|
625
|
+
instance?: string;
|
|
626
|
+
effect: string;
|
|
627
|
+
name?: string;
|
|
628
|
+
provider?: string;
|
|
629
|
+
enabled: boolean;
|
|
630
|
+
}
|
|
631
|
+
/** Every provider effect in a project, sequences included, in track and clip order. */
|
|
632
|
+
declare function videoProjectEffects(project: VideoProject): VideoEffectUse[];
|
|
633
|
+
/** The provider effects of one clip: its effect clip picture, its transition and its effect stack. */
|
|
634
|
+
declare function videoClipEffectUses(clip: VideoClip): VideoEffectUse[];
|
|
635
|
+
/** True when drawing the layers needs an effects provider. */
|
|
636
|
+
declare const videoLayersUseEffects: (layers: readonly VideoLayer[]) => boolean;
|
|
637
|
+
/** The start of the frame `time` falls in (ms), on the project's frame grid. Effects render once per frame. */
|
|
638
|
+
declare const videoEffectFrameTime: (time: number, fps: number) => number;
|
|
639
|
+
/** What to render for one layer. */
|
|
640
|
+
type VideoEffectJob =
|
|
641
|
+
/** A clip's effect stack over its unprocessed picture. */
|
|
642
|
+
{
|
|
643
|
+
kind: 'stack';
|
|
644
|
+
input: EffectPixels;
|
|
645
|
+
effects: readonly VideoLayerEffect[];
|
|
646
|
+
}
|
|
647
|
+
/** An effect clip: the generator at `time`, then the clip's effect stack. */
|
|
648
|
+
| {
|
|
649
|
+
kind: 'generator';
|
|
650
|
+
width: number;
|
|
651
|
+
height: number;
|
|
652
|
+
effect: string;
|
|
653
|
+
values: Record<string, EffectValue>;
|
|
654
|
+
time: number;
|
|
655
|
+
effects: readonly VideoLayerEffect[];
|
|
656
|
+
}
|
|
657
|
+
/** An effect transition between two whole-frame pictures. */
|
|
658
|
+
| {
|
|
659
|
+
kind: 'transition';
|
|
660
|
+
effect: string;
|
|
661
|
+
values: Record<string, EffectValue>;
|
|
662
|
+
progress: number;
|
|
663
|
+
time: number;
|
|
664
|
+
from: EffectPixels;
|
|
665
|
+
to: EffectPixels;
|
|
666
|
+
};
|
|
667
|
+
/**
|
|
668
|
+
* The cache key of a layer's processed picture at a canvas size: everything that changes the
|
|
669
|
+
* picture before placement (its content, the moment of source, the effects and their values),
|
|
670
|
+
* not where it is placed. A transition's key covers both of its pictures, placement included.
|
|
671
|
+
*/
|
|
672
|
+
declare function videoEffectLayerKey(layer: VideoLayer, width: number, height: number): string;
|
|
673
|
+
/** `a` mixed towards `b` by `k` (0–1), as a new picture. */
|
|
674
|
+
declare function mixEffectPixels(a: EffectPixels, b: EffectPixels, k: number): EffectPixels;
|
|
675
|
+
/** `top` laid over `base` (straight alpha, source-over) at `opacity`, as a new picture. */
|
|
676
|
+
declare function overEffectPixels(base: EffectPixels, top: EffectPixels, opacity?: number): EffectPixels;
|
|
677
|
+
interface VideoEffectsEngineOptions {
|
|
678
|
+
/** The provider slot to follow (a controller passes its own). Default: a new one. */
|
|
679
|
+
slot?: EffectsSlot;
|
|
680
|
+
/** Rendered pictures kept (default 120, a few seconds of one layer). */
|
|
681
|
+
maxEntries?: number;
|
|
682
|
+
/**
|
|
683
|
+
* Turns rendered pixels into something `drawImage` takes. Default: an `OffscreenCanvas` (or a
|
|
684
|
+
* `<canvas>`) holding them; `null` where neither exists.
|
|
685
|
+
*/
|
|
686
|
+
toImage?: (pixels: EffectPixels) => CanvasImageSource | null;
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Renders and caches provider effect pictures for one editor. It follows the editor's provider
|
|
690
|
+
* slot: with no provider it renders nothing (`available` is false), and a new provider clears the
|
|
691
|
+
* cache and disposes the old renderers.
|
|
692
|
+
*/
|
|
693
|
+
declare class VideoEffectsEngine {
|
|
694
|
+
readonly slot: EffectsSlot;
|
|
695
|
+
private readonly cache;
|
|
696
|
+
private readonly pending;
|
|
697
|
+
private readonly failures;
|
|
698
|
+
private readonly renderers;
|
|
699
|
+
private readonly descriptions;
|
|
700
|
+
private readonly listeners;
|
|
701
|
+
private readonly maxEntries;
|
|
702
|
+
private readonly toImage;
|
|
703
|
+
private generation;
|
|
704
|
+
private readonly detach;
|
|
705
|
+
constructor(options?: VideoEffectsEngineOptions);
|
|
706
|
+
get provider(): EffectProvider | null;
|
|
707
|
+
/** True when a provider is registered, so effects can be drawn. */
|
|
708
|
+
get available(): boolean;
|
|
709
|
+
/** The drawable picture for `key`, or `undefined` when it is not rendered (yet). */
|
|
710
|
+
get(key: string): CanvasImageSource | null | undefined;
|
|
711
|
+
/** The rendered pixels for `key`. */
|
|
712
|
+
pixels(key: string): EffectPixels | undefined;
|
|
713
|
+
/** Why the render for `key` failed, if it did (it is not retried until the cache is cleared). */
|
|
714
|
+
failure(key: string): Error | undefined;
|
|
715
|
+
/** Every failure so far, newest last. */
|
|
716
|
+
failuresList(): {
|
|
717
|
+
key: string;
|
|
718
|
+
error: Error;
|
|
719
|
+
}[];
|
|
720
|
+
/** Whether `key` is being rendered. */
|
|
721
|
+
isPending(key: string): boolean;
|
|
722
|
+
/**
|
|
723
|
+
* Starts rendering `job` into `key` unless it is cached, pending or failed. Returns true while
|
|
724
|
+
* the picture is on its way (so the frame is waiting for it).
|
|
725
|
+
*/
|
|
726
|
+
request(key: string, job: VideoEffectJob): boolean;
|
|
727
|
+
/** Resolves when nothing is being rendered. */
|
|
728
|
+
idle(): Promise<void>;
|
|
729
|
+
/** Renders a job now, without the cache. Rejects with the provider's error. */
|
|
730
|
+
run(job: VideoEffectJob): Promise<EffectPixels>;
|
|
731
|
+
private stack;
|
|
732
|
+
/** The provider's description of an effect, fetched once. */
|
|
733
|
+
describe(provider: EffectProvider, id: string): Promise<EffectDescription>;
|
|
734
|
+
/** Renders on a renderer kept per effect and size, one render at a time per renderer. */
|
|
735
|
+
private render;
|
|
736
|
+
/** Forgets every picture and failure and disposes the renderers (e.g. after the provider changes). */
|
|
737
|
+
reset(): void;
|
|
738
|
+
subscribe(listener: () => void): () => void;
|
|
739
|
+
private notify;
|
|
740
|
+
destroy(): void;
|
|
741
|
+
}
|
|
742
|
+
/** Which uses each place accepts. */
|
|
743
|
+
declare const VIDEO_EFFECT_PLACES: {
|
|
744
|
+
/** A clip's effect stack: filters change the picture, overlays draw over it. */
|
|
745
|
+
readonly clip: readonly ["filter", "overlay"];
|
|
746
|
+
readonly transition: readonly ["transition"];
|
|
747
|
+
/** An effect clip's picture. */
|
|
748
|
+
readonly generator: readonly ["generator", "title", "overlay"];
|
|
749
|
+
};
|
|
750
|
+
type VideoEffectPlace = keyof typeof VIDEO_EFFECT_PLACES;
|
|
751
|
+
/** Refuses an effect that cannot go in `place`, with what to use instead. */
|
|
752
|
+
declare function checkVideoEffectPlace(d: EffectDescription, place: VideoEffectPlace): void;
|
|
753
|
+
/**
|
|
754
|
+
* Checks values (plain, or keyframes for numeric controls when `keyframes`) against an effect's
|
|
755
|
+
* controls and returns them over `base` (default the effect's defaults). Throws
|
|
756
|
+
* `EffectControlError` naming every bad control.
|
|
757
|
+
*/
|
|
758
|
+
declare function checkVideoEffectValues(d: EffectDescription, values: VideoEffectValues | undefined, options?: {
|
|
759
|
+
base?: VideoEffectValues;
|
|
760
|
+
keyframes?: boolean;
|
|
761
|
+
}): VideoEffectValues;
|
|
762
|
+
|
|
392
763
|
interface VideoEdlOptions {
|
|
393
764
|
/** Track to export (default: the bottom video track, V1 in most NLEs). */
|
|
394
765
|
track?: string;
|
|
@@ -433,7 +804,21 @@ interface VideoFfmpegOptions {
|
|
|
433
804
|
}) => string;
|
|
434
805
|
/** Normalise the mix's loudness with ffmpeg's `loudnorm` (EBU R128). */
|
|
435
806
|
loudness?: VideoLoudnessTarget;
|
|
807
|
+
/**
|
|
808
|
+
* The picture as frames the host rendered, instead of ffmpeg's filters: one per frame of the
|
|
809
|
+
* project's frame grid from 0, each the project's size rounded up to even numbers, drawn with
|
|
810
|
+
* `renderVideoFrameExact` (the preview's own drawing, provider effects included). `input` is an
|
|
811
|
+
* image sequence pattern (`frames/%06d.png`, format `image2`, the default) or raw RGBA on a
|
|
812
|
+
* pipe (`pipe:0`, format `rawvideo`). The sound is still mixed by ffmpeg. Projects that use
|
|
813
|
+
* provider effects need this: ffmpeg cannot draw them, so without it the export is refused.
|
|
814
|
+
*/
|
|
815
|
+
frames?: {
|
|
816
|
+
input: string;
|
|
817
|
+
format?: 'image2' | 'rawvideo';
|
|
818
|
+
};
|
|
436
819
|
}
|
|
820
|
+
/** The provider effects in a project's video tracks that ffmpeg's filters cannot draw. */
|
|
821
|
+
declare function videoFfmpegUnsupportedEffects(project: VideoProject): VideoEffectUse[];
|
|
437
822
|
/** A loudness to normalise the mix to (`loudnorm`'s I, TP and LRA). */
|
|
438
823
|
interface VideoLoudnessTarget {
|
|
439
824
|
/** Integrated loudness, in LUFS (default -14, as streaming services play; -16 for podcasts, -23 for EBU R128 broadcast). */
|
|
@@ -498,4 +883,4 @@ declare function toVideoFfmpeg(project: VideoProject, options?: VideoFfmpegOptio
|
|
|
498
883
|
*/
|
|
499
884
|
declare function toVideoLoudnessMeasure(project: VideoProject, options?: Pick<VideoFfmpegOptions, 'resolve' | 'loudness'>): VideoFfmpegExport;
|
|
500
885
|
|
|
501
|
-
export {
|
|
886
|
+
export { type VideoColorClip as $, type VideoRect as A, type VideoEffectPlace as B, type VideoFfmpegOptions as C, type VideoFfmpegExport as D, type VideoEdlOptions as E, type VideoFadeCurve as F, type VideoFit as G, type VideoBlendMode as H, type VideoAssetKind as I, type VideoClipAnimationEffect as J, type VideoTransitionType as K, VIDEO_BLEND_MODES as L, VIDEO_CLIP_ANIMATION_EFFECTS as M, VIDEO_CLIP_TYPES as N, VIDEO_EASE_NAMES as O, VIDEO_EFFECT_PLACES as P, VIDEO_FADE_CURVES as Q, VIDEO_FITS as R, VIDEO_KEYFRAME_LIMITS as S, VIDEO_KEYFRAME_PROPERTIES as T, VIDEO_PLACEMENT_MODES as U, type VideoProject as V, VIDEO_TRANSFORM_PROPERTIES as W, VIDEO_TRANSITION_TYPES as X, VIDEO_WIPE_DIRECTIONS as Y, type VideoAudioSource as Z, type VideoClipType as _, type VideoAnimatable as a, type VideoEase as a0, type VideoEffectClip as a1, type VideoEffectJob as a2, type VideoEffectUse as a3, type VideoEffectsEngineOptions as a4, type VideoLayerEffect as a5, type VideoLoudnessMeasurement as a6, type VideoLoudnessTarget as a7, type VideoSequenceClip as a8, type VideoTextClip as a9, videoFrameAt as aA, videoFrameLeafLayers as aB, videoKeyframeBreakpoints as aC, videoKeyframeFfmpegExpr as aD, videoLayersUseEffects as aE, videoLayersWithoutTransitionEffects as aF, videoProjectEffects as aG, videoShellQuote as aH, videoTextStyle as aI, videoTitleFrame as aJ, videoTransformAt as aK, videoTransitionAudioCurve as aL, videoTransitionEase as aM, videoValueAt as aN, type VideoWipeDirection as aa, checkVideoEffectPlace as ab, checkVideoEffectValues as ac, ffmpegFilterValue as ad, isVideoKeyframes as ae, mixEffectPixels as af, overEffectPixels as ag, parseVideoLoudnessMeasurement as ah, placeVideoRect as ai, removeVideoKey as aj, retimeVideoAnimatable as ak, setVideoKey as al, sortVideoKeys as am, splitVideoAnimatable as an, toVideoEdl as ao, toVideoFfmpeg as ap, toVideoLoudnessMeasure as aq, videoClipEffectUses as ar, videoClipSoundGain as as, videoEaseBezier as at, videoEaseProgress as au, videoEffectFrameTime as av, videoEffectLayerKey as aw, videoEffectValuesAt as ax, videoFadeCurveGain as ay, videoFfmpegUnsupportedEffects as az, type VideoAsset as b, type VideoAssetProxy as c, type VideoClip as d, type VideoClipAnimation as e, type VideoClipEffect as f, type VideoEffectRef as g, type VideoEffectValues as h, type VideoGrade as i, type VideoGradeLut as j, type VideoKeyframes as k, type VideoMarker as l, type VideoSequence as m, type VideoTrack as n, type VideoTranscriptWord as o, type VideoTransform as p, type VideoTransition as q, type VideoTrackKind as r, type VideoPlacementMode as s, type VideoKeyframeProperty as t, type VideoKey as u, videoKeysOf as v, type VideoMediaClip as w, VideoEffectsEngine as x, type VideoLayer as y, type VideoFrame as z };
|