@pixerate/editor 0.78.0 → 0.80.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/video-editor/index.cjs +947 -117
- package/dist/video-editor/index.cjs.map +1 -1
- package/dist/video-editor/index.d.cts +231 -20
- package/dist/video-editor/index.d.ts +231 -20
- package/dist/video-editor/index.js +925 -95
- package/dist/video-editor/index.js.map +1 -1
- package/package.json +2 -1
|
@@ -5,6 +5,84 @@ import '../easing-lM0Xo9Ni.js';
|
|
|
5
5
|
import '../types-DsiXGmjo.js';
|
|
6
6
|
import '../schema-Di0CS6Pe.js';
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Keyframes for a clip's opacity, volume and transform. A property is either a plain number or
|
|
10
|
+
* `{ keys }`: values at clip-relative times (ms from the clip's start), each with the easing of the
|
|
11
|
+
* segment that leaves it. Pure functions only, so previews, renders and exports agree.
|
|
12
|
+
*
|
|
13
|
+
* Easing is stored as CSS `cubic-bezier(x1, y1, x2, y2)` control points (named easings are the CSS
|
|
14
|
+
* ones), which is also what After Effects / Lottie speed-and-influence handles convert to exactly.
|
|
15
|
+
*/
|
|
16
|
+
/** How a segment moves from its key to the next: a named curve, `hold` (jump at the next key) or CSS cubic-bezier points. */
|
|
17
|
+
type VideoEase = 'linear' | 'hold' | 'ease-in' | 'ease-out' | 'ease-in-out' | [number, number, number, number];
|
|
18
|
+
declare const VIDEO_EASE_NAMES: readonly ["linear", "hold", "ease-in", "ease-out", "ease-in-out"];
|
|
19
|
+
interface VideoKey {
|
|
20
|
+
/** Clip-relative time (ms from the clip's start). */
|
|
21
|
+
t: number;
|
|
22
|
+
v: number;
|
|
23
|
+
/** The segment from this key to the next (default linear). Ignored on the last key. */
|
|
24
|
+
ease?: VideoEase;
|
|
25
|
+
}
|
|
26
|
+
interface VideoKeyframes {
|
|
27
|
+
/** In time order, at least one. */
|
|
28
|
+
keys: VideoKey[];
|
|
29
|
+
}
|
|
30
|
+
/** A number, or keyframes for it. */
|
|
31
|
+
type VideoAnimatable = number | VideoKeyframes;
|
|
32
|
+
/** The clip properties that can be keyframed: `opacity`, `volume` (media) and the transform's fields. */
|
|
33
|
+
type VideoKeyframeProperty = 'opacity' | 'volume' | 'x' | 'y' | 'scale' | 'rotation';
|
|
34
|
+
declare const VIDEO_KEYFRAME_PROPERTIES: readonly ["opacity", "volume", "x", "y", "scale", "rotation"];
|
|
35
|
+
declare const VIDEO_TRANSFORM_PROPERTIES: readonly ["x", "y", "scale", "rotation"];
|
|
36
|
+
/** Each property's default and allowed range. */
|
|
37
|
+
declare const VIDEO_KEYFRAME_LIMITS: Record<VideoKeyframeProperty, {
|
|
38
|
+
default: number;
|
|
39
|
+
min?: number;
|
|
40
|
+
max?: number;
|
|
41
|
+
}>;
|
|
42
|
+
declare const isVideoKeyframes: (v: unknown) => v is VideoKeyframes;
|
|
43
|
+
/** The cubic-bezier points for an ease (`null` for linear and hold). */
|
|
44
|
+
declare function videoEaseBezier(ease: VideoEase | undefined): [number, number, number, number] | null;
|
|
45
|
+
/** How far (0–1 in, any y out) an ease has got at progress `p` (0–1) through its segment. */
|
|
46
|
+
declare function videoEaseProgress(ease: VideoEase | undefined, p: number): number;
|
|
47
|
+
/**
|
|
48
|
+
* A property's value at clip-relative time `clipTime` (ms): the number itself, or the keys
|
|
49
|
+
* interpolated (held before the first and after the last). `fallback` is used when it is unset.
|
|
50
|
+
*/
|
|
51
|
+
declare function videoValueAt(prop: VideoAnimatable | undefined, clipTime: number, fallback?: number): number;
|
|
52
|
+
/** A property's keys (a plain number or unset gives none). */
|
|
53
|
+
declare const videoKeysOf: (prop: VideoAnimatable | undefined) => VideoKey[];
|
|
54
|
+
/** Shifts every key by `dt` ms (or scales times by `k` first); numbers pass through. */
|
|
55
|
+
declare function retimeVideoAnimatable<T extends VideoAnimatable | undefined>(prop: T, dt: number, k?: number): T;
|
|
56
|
+
/**
|
|
57
|
+
* Splits keyframes at clip time `at`: the keys before it (with a key added at `at`) and the keys
|
|
58
|
+
* after it, moved to start at 0 (with a key added at 0). Eased segments across the cut are split
|
|
59
|
+
* into two curves that trace the same path, so the two halves play exactly as the whole did.
|
|
60
|
+
*/
|
|
61
|
+
declare function splitVideoAnimatable<T extends VideoAnimatable | undefined>(prop: T, at: number): [T, T];
|
|
62
|
+
/** The keys sorted by time, refusing two at the same time. */
|
|
63
|
+
declare function sortVideoKeys(keys: readonly VideoKey[]): VideoKey[];
|
|
64
|
+
/**
|
|
65
|
+
* Keys with one set (or replaced) at `t`: a plain value becomes keys holding it and the new one.
|
|
66
|
+
* For a keyframe toggle or "add key at playhead".
|
|
67
|
+
*/
|
|
68
|
+
declare function setVideoKey(prop: VideoAnimatable | undefined, key: VideoKey, fallback: number): VideoKeyframes;
|
|
69
|
+
/** Keys with the one at `t` removed; the value it then holds when none are left. */
|
|
70
|
+
declare function removeVideoKey(prop: VideoKeyframes, t: number): VideoAnimatable;
|
|
71
|
+
/**
|
|
72
|
+
* Breakpoints `[clipTime, value]` tracing a property as straight lines: linear segments as they
|
|
73
|
+
* are, holds as steps, eased segments sampled every `step` ms (about two frames).
|
|
74
|
+
*/
|
|
75
|
+
declare function videoKeyframeBreakpoints(prop: VideoKeyframes, step: number): {
|
|
76
|
+
points: [number, number][];
|
|
77
|
+
holds: Set<number>;
|
|
78
|
+
};
|
|
79
|
+
/**
|
|
80
|
+
* An ffmpeg expression for a property, given `time`: an expression for the clip-relative time in
|
|
81
|
+
* ms (e.g. `(t*1000-1500)`). Piecewise linear `if(lt(…))` chains; eased segments are baked to
|
|
82
|
+
* breakpoints every `step` ms.
|
|
83
|
+
*/
|
|
84
|
+
declare function videoKeyframeFfmpegExpr(prop: VideoAnimatable | undefined, time: string, fallback: number, step: number): string;
|
|
85
|
+
|
|
8
86
|
/**
|
|
9
87
|
* A video project is plain JSON: the media it uses (assets), tracks of clips placed on a timeline,
|
|
10
88
|
* and markers. Every time is in milliseconds; `fps` sets the frame grid edits snap to and exports use.
|
|
@@ -12,6 +90,7 @@ import '../schema-Di0CS6Pe.js';
|
|
|
12
90
|
* Tracks are listed top to bottom as a timeline shows them: on screen, a clip on an earlier video
|
|
13
91
|
* track draws over one on a later track. Clips on one track never overlap.
|
|
14
92
|
*/
|
|
93
|
+
|
|
15
94
|
type VideoAssetKind = 'video' | 'audio' | 'image';
|
|
16
95
|
/** A piece of source media. The project refers to it by id; `src` is whatever the host can load. */
|
|
17
96
|
interface VideoAsset {
|
|
@@ -41,19 +120,24 @@ interface VideoTrack {
|
|
|
41
120
|
hidden?: boolean;
|
|
42
121
|
/** Refuses edits to the track's clips. */
|
|
43
122
|
locked?: boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Moves with ripple edits made on other sync-locked tracks, so it stays in sync (default true).
|
|
125
|
+
* Turn it off for a track that should stay put while the others ripple (e.g. a music bed).
|
|
126
|
+
*/
|
|
127
|
+
syncLocked?: boolean;
|
|
44
128
|
/** Gain applied to every clip on the track (1 = unchanged, default 1). */
|
|
45
129
|
volume?: number;
|
|
46
130
|
clips: VideoClip[];
|
|
47
131
|
}
|
|
48
|
-
/** Where a picture sits in the frame, after it has been fitted. */
|
|
132
|
+
/** Where a picture sits in the frame, after it has been fitted. Each field may be keyframed. */
|
|
49
133
|
interface VideoTransform {
|
|
50
134
|
/** Offset of the centre from the frame's centre, in pixels (default 0). */
|
|
51
|
-
x?:
|
|
52
|
-
y?:
|
|
135
|
+
x?: VideoAnimatable;
|
|
136
|
+
y?: VideoAnimatable;
|
|
53
137
|
/** 1 = fitted size (default 1). */
|
|
54
|
-
scale?:
|
|
138
|
+
scale?: VideoAnimatable;
|
|
55
139
|
/** Degrees clockwise (default 0). */
|
|
56
|
-
rotation?:
|
|
140
|
+
rotation?: VideoAnimatable;
|
|
57
141
|
}
|
|
58
142
|
/** How a picture is fitted to the frame before its transform: like CSS `object-fit`. */
|
|
59
143
|
type VideoFit = 'contain' | 'cover' | 'fill' | 'none';
|
|
@@ -83,8 +167,8 @@ interface VideoClipBase {
|
|
|
83
167
|
start: number;
|
|
84
168
|
/** How long it lasts on the timeline (ms). */
|
|
85
169
|
duration: number;
|
|
86
|
-
/** 0–1 (default 1). */
|
|
87
|
-
opacity?:
|
|
170
|
+
/** 0–1 (default 1), or keyframes (`{ keys: [{ t, v, ease }] }`, `t` in ms from the clip's start). */
|
|
171
|
+
opacity?: VideoAnimatable;
|
|
88
172
|
transform?: VideoTransform;
|
|
89
173
|
/** Default contain. */
|
|
90
174
|
fit?: VideoFit;
|
|
@@ -103,8 +187,8 @@ interface VideoMediaClip extends VideoClipBase {
|
|
|
103
187
|
in?: number;
|
|
104
188
|
/** Playback speed (default 1): it uses `duration × speed` of the source. */
|
|
105
189
|
speed?: number;
|
|
106
|
-
/** Gain (1 = unchanged, default 1). */
|
|
107
|
-
volume?:
|
|
190
|
+
/** Gain (1 = unchanged, default 1), or keyframes. */
|
|
191
|
+
volume?: VideoAnimatable;
|
|
108
192
|
/** Silences this clip. */
|
|
109
193
|
muted?: boolean;
|
|
110
194
|
}
|
|
@@ -130,6 +214,13 @@ interface VideoColorClip extends VideoClipBase {
|
|
|
130
214
|
}
|
|
131
215
|
type VideoClip = VideoMediaClip | VideoTextClip | VideoColorClip;
|
|
132
216
|
type VideoClipType = VideoClip['type'];
|
|
217
|
+
/**
|
|
218
|
+
* How a clip is placed where others already are: `refuse` an overlap (the default), `overwrite`
|
|
219
|
+
* what is underneath (cutting, trimming or removing it), or `insert` (cut everything across the
|
|
220
|
+
* point and push later material along on every sync-locked track).
|
|
221
|
+
*/
|
|
222
|
+
type VideoPlacementMode = 'refuse' | 'overwrite' | 'insert';
|
|
223
|
+
declare const VIDEO_PLACEMENT_MODES: readonly ["refuse", "overwrite", "insert"];
|
|
133
224
|
declare const VIDEO_CLIP_TYPES: readonly ["media", "text", "color"];
|
|
134
225
|
interface VideoMarker {
|
|
135
226
|
id: string;
|
|
@@ -153,6 +244,20 @@ interface VideoProject {
|
|
|
153
244
|
markers?: VideoMarker[];
|
|
154
245
|
}
|
|
155
246
|
|
|
247
|
+
/**
|
|
248
|
+
* Keyframes `{ keys: [{ t, v, ease }] }`: at least one key, in strictly increasing time (clip-relative
|
|
249
|
+
* ms), each value within `range`.
|
|
250
|
+
*/
|
|
251
|
+
declare function parseVideoKeyframes(v: unknown, path: string, { min, max }?: {
|
|
252
|
+
min?: number;
|
|
253
|
+
max?: number;
|
|
254
|
+
}): VideoKeyframes;
|
|
255
|
+
/** A number within `range`, or keyframes for one. */
|
|
256
|
+
declare function parseVideoAnimatable(v: unknown, path: string, range?: {
|
|
257
|
+
min?: number;
|
|
258
|
+
max?: number;
|
|
259
|
+
optional?: boolean;
|
|
260
|
+
}): VideoAnimatable | undefined;
|
|
156
261
|
declare function parseVideoTransform(v: unknown, path: string): VideoTransform | undefined;
|
|
157
262
|
declare function parseVideoTransition(v: unknown, path: string): VideoTransition | undefined;
|
|
158
263
|
declare function parseVideoAsset(v: unknown, path?: string): VideoAsset;
|
|
@@ -182,6 +287,8 @@ declare function createVideoProject(options?: CreateVideoProjectOptions): VideoP
|
|
|
182
287
|
/** Clip edges closer than this (ms) count as touching: a cut, not a gap. */
|
|
183
288
|
declare const VIDEO_TIME_EPSILON = 0.5;
|
|
184
289
|
declare const videoClipEnd: (clip: VideoClip) => number;
|
|
290
|
+
/** Whether a track moves with ripple edits on other tracks (`syncLocked`, default true). */
|
|
291
|
+
declare const videoTrackSyncLocked: (track: VideoTrack) => boolean;
|
|
185
292
|
/** Playback speed of a clip (1 for titles and colours). */
|
|
186
293
|
declare const videoClipSpeed: (clip: VideoClip) => number;
|
|
187
294
|
/** The stretch of source a media clip plays (ms), or `null` for titles and colours. */
|
|
@@ -264,8 +371,13 @@ declare function videoClipsAt(project: VideoProject, time: number): {
|
|
|
264
371
|
clip: VideoClip;
|
|
265
372
|
}[];
|
|
266
373
|
|
|
374
|
+
/** A clip's keyframed properties (`opacity`, `volume`, `x`…) with their keys. */
|
|
375
|
+
declare function videoClipKeyframes(clip: VideoClip): {
|
|
376
|
+
property: string;
|
|
377
|
+
keys: ReturnType<typeof videoKeysOf>;
|
|
378
|
+
}[];
|
|
267
379
|
type VideoIssueSeverity = 'error' | 'warning' | 'note';
|
|
268
|
-
declare const VIDEO_ISSUE_CODES: readonly ["missing-asset", "wrong-track", "overlap", "source-overrun", "transition-without-cut", "transition-too-long", "transition-handles", "fades-too-long", "unknown-duration", "unused-asset", "marker-past-end", "empty"];
|
|
380
|
+
declare const VIDEO_ISSUE_CODES: readonly ["missing-asset", "wrong-track", "overlap", "source-overrun", "transition-without-cut", "transition-too-long", "transition-handles", "fades-too-long", "keyframes-outside-clip", "unknown-duration", "unused-asset", "marker-past-end", "empty"];
|
|
269
381
|
type VideoIssueCode = (typeof VIDEO_ISSUE_CODES)[number];
|
|
270
382
|
interface VideoIssue {
|
|
271
383
|
code: VideoIssueCode;
|
|
@@ -299,6 +411,7 @@ type TrackFields = {
|
|
|
299
411
|
muted?: boolean;
|
|
300
412
|
hidden?: boolean;
|
|
301
413
|
locked?: boolean;
|
|
414
|
+
syncLocked?: boolean;
|
|
302
415
|
volume?: number;
|
|
303
416
|
};
|
|
304
417
|
/** A clip to add: `id` and `start` are optional (default: a fresh id, the end of the track). */
|
|
@@ -350,12 +463,14 @@ type VideoEdit = ({
|
|
|
350
463
|
op: 'add_clip';
|
|
351
464
|
track: string;
|
|
352
465
|
clip: NewVideoClip;
|
|
466
|
+
mode?: VideoPlacementMode;
|
|
353
467
|
ripple?: boolean;
|
|
354
468
|
} | {
|
|
355
469
|
op: 'move_clip';
|
|
356
470
|
clip: string;
|
|
357
471
|
start?: number;
|
|
358
472
|
track?: string;
|
|
473
|
+
mode?: VideoPlacementMode;
|
|
359
474
|
} | {
|
|
360
475
|
op: 'trim_clip';
|
|
361
476
|
clip: string;
|
|
@@ -380,6 +495,40 @@ type VideoEdit = ({
|
|
|
380
495
|
op: 'set_transition';
|
|
381
496
|
clip: string;
|
|
382
497
|
transition: VideoTransition | null;
|
|
498
|
+
} | {
|
|
499
|
+
op: 'slip_clip';
|
|
500
|
+
clip: string;
|
|
501
|
+
delta: number;
|
|
502
|
+
} | {
|
|
503
|
+
op: 'roll_edit';
|
|
504
|
+
left: string;
|
|
505
|
+
right: string;
|
|
506
|
+
delta: number;
|
|
507
|
+
} | {
|
|
508
|
+
op: 'slide_clip';
|
|
509
|
+
clip: string;
|
|
510
|
+
delta: number;
|
|
511
|
+
} | {
|
|
512
|
+
op: 'lift_range';
|
|
513
|
+
from: number;
|
|
514
|
+
to: number;
|
|
515
|
+
tracks?: string[];
|
|
516
|
+
} | {
|
|
517
|
+
op: 'extract_range';
|
|
518
|
+
from: number;
|
|
519
|
+
to: number;
|
|
520
|
+
tracks?: string[];
|
|
521
|
+
} | {
|
|
522
|
+
op: 'split_at';
|
|
523
|
+
at: number;
|
|
524
|
+
tracks?: string[];
|
|
525
|
+
}
|
|
526
|
+
/** Keys for one property (in any order; clip-relative ms), or null to stop animating it and keep its value at the clip's start. */
|
|
527
|
+
| {
|
|
528
|
+
op: 'set_keyframes';
|
|
529
|
+
clip: string;
|
|
530
|
+
property: VideoKeyframeProperty;
|
|
531
|
+
keys: VideoKey[] | null;
|
|
383
532
|
} | {
|
|
384
533
|
op: 'close_gaps';
|
|
385
534
|
track: string;
|
|
@@ -411,6 +560,16 @@ interface VideoEditOutcome {
|
|
|
411
560
|
track?: string;
|
|
412
561
|
asset?: string;
|
|
413
562
|
marker?: string;
|
|
563
|
+
/** Clips the op made by cutting others (the right-hand parts). */
|
|
564
|
+
created?: string[];
|
|
565
|
+
/** Clips it deleted to make room (overwrite, lift, extract). */
|
|
566
|
+
removed?: string[];
|
|
567
|
+
/** Clips it shortened to make room. */
|
|
568
|
+
trimmed?: string[];
|
|
569
|
+
/** Tracks a ripple moved (the edited ones and every sync-locked one with them). */
|
|
570
|
+
rippled?: string[];
|
|
571
|
+
/** For slip, roll and slide: how far it actually moved (ms), after clamping to what the media allows. */
|
|
572
|
+
delta?: number;
|
|
414
573
|
}
|
|
415
574
|
type VideoEditResult = {
|
|
416
575
|
ok: true;
|
|
@@ -493,22 +652,31 @@ interface VideoFrame {
|
|
|
493
652
|
layers: VideoLayer[];
|
|
494
653
|
audio: VideoAudioSource[];
|
|
495
654
|
}
|
|
496
|
-
/**
|
|
655
|
+
/** A transform's values at clip-relative time `clipTime` (ms), keyframes resolved and defaults filled in. */
|
|
656
|
+
declare function videoTransformAt(transform: VideoClip['transform'], clipTime?: number): {
|
|
657
|
+
x: number;
|
|
658
|
+
y: number;
|
|
659
|
+
scale: number;
|
|
660
|
+
rotation: number;
|
|
661
|
+
};
|
|
662
|
+
/** Places a picture of `size` in the frame by `fit`, then the clip's transform at clip-relative `clipTime` (ms). */
|
|
497
663
|
declare function placeVideoRect(frame: {
|
|
498
664
|
width: number;
|
|
499
665
|
height: number;
|
|
500
666
|
}, size: {
|
|
501
667
|
width: number;
|
|
502
668
|
height: number;
|
|
503
|
-
}, fit?: VideoFit, transform?: VideoClip['transform']): VideoRect;
|
|
669
|
+
}, fit?: VideoFit, transform?: VideoClip['transform'], clipTime?: number): VideoRect;
|
|
504
670
|
/** A title's text and style with the defaults filled in. */
|
|
505
671
|
declare function videoTextStyle(clip: VideoTextClip): NonNullable<VideoLayer['text']>;
|
|
506
672
|
/**
|
|
507
673
|
* A frame holding only one title, fully opaque on a transparent background, placed as the preview
|
|
508
674
|
* places it: draw it with `drawVideoFrame` and save the canvas as a PNG to give the ffmpeg export
|
|
509
675
|
* titles without `drawtext` (`VideoFfmpegOptions.titleImage`). Fades and opacity are left to the export.
|
|
676
|
+
* A keyframed transform is placed as it is at `clipTime` (the export passes titles with keyframed
|
|
677
|
+
* transforms without them, and moves the image itself).
|
|
510
678
|
*/
|
|
511
|
-
declare function videoTitleFrame(project: VideoProject, clip: VideoTextClip): VideoFrame;
|
|
679
|
+
declare function videoTitleFrame(project: VideoProject, clip: VideoTextClip, clipTime?: number): VideoFrame;
|
|
512
680
|
/**
|
|
513
681
|
* What plays at `time` (ms): the pictures to draw, back to front, with their placement, opacity
|
|
514
682
|
* and the moment of source each shows, and the sounds with their gain. A pure function of the
|
|
@@ -854,13 +1022,13 @@ declare function describeVideoProject(project: VideoProject): {
|
|
|
854
1022
|
asset: string;
|
|
855
1023
|
in?: number;
|
|
856
1024
|
speed?: number;
|
|
857
|
-
volume?:
|
|
1025
|
+
volume?: VideoAnimatable;
|
|
858
1026
|
muted?: boolean;
|
|
859
1027
|
id: string;
|
|
860
1028
|
name?: string;
|
|
861
1029
|
start: number;
|
|
862
1030
|
duration: number;
|
|
863
|
-
opacity?:
|
|
1031
|
+
opacity?: VideoAnimatable;
|
|
864
1032
|
transform?: VideoTransform;
|
|
865
1033
|
fit?: VideoFit;
|
|
866
1034
|
fadeIn?: number;
|
|
@@ -883,7 +1051,7 @@ declare function describeVideoProject(project: VideoProject): {
|
|
|
883
1051
|
name?: string;
|
|
884
1052
|
start: number;
|
|
885
1053
|
duration: number;
|
|
886
|
-
opacity?:
|
|
1054
|
+
opacity?: VideoAnimatable;
|
|
887
1055
|
transform?: VideoTransform;
|
|
888
1056
|
fit?: VideoFit;
|
|
889
1057
|
fadeIn?: number;
|
|
@@ -901,7 +1069,7 @@ declare function describeVideoProject(project: VideoProject): {
|
|
|
901
1069
|
name?: string;
|
|
902
1070
|
start: number;
|
|
903
1071
|
duration: number;
|
|
904
|
-
opacity?:
|
|
1072
|
+
opacity?: VideoAnimatable;
|
|
905
1073
|
transform?: VideoTransform;
|
|
906
1074
|
fit?: VideoFit;
|
|
907
1075
|
fadeIn?: number;
|
|
@@ -909,6 +1077,7 @@ declare function describeVideoProject(project: VideoProject): {
|
|
|
909
1077
|
transition?: VideoTransition;
|
|
910
1078
|
})[];
|
|
911
1079
|
volume?: number | undefined;
|
|
1080
|
+
syncLocked?: boolean | undefined;
|
|
912
1081
|
locked?: boolean | undefined;
|
|
913
1082
|
hidden?: boolean | undefined;
|
|
914
1083
|
muted?: boolean | undefined;
|
|
@@ -928,8 +1097,9 @@ declare function describeVideoProject(project: VideoProject): {
|
|
|
928
1097
|
/**
|
|
929
1098
|
* Agent tools for a `VideoEditorController`: read the project (assets, tracks with clips and their
|
|
930
1099
|
* times, gaps, what plays at a moment), check it, render frames, export to ffmpeg or an EDL, and
|
|
931
|
-
* edit it a step at a time (add assets and tracks, add / move / trim / split / delete clips
|
|
932
|
-
*
|
|
1100
|
+
* edit it a step at a time (add assets and tracks, add / move / trim / split / delete clips with
|
|
1101
|
+
* overwrite, insert and sync-locked ripple, slip / roll / slide, lift / extract a range, cut across
|
|
1102
|
+
* tracks, transitions, markers). Every write is checked first (unknown ids with "did you mean", overlaps,
|
|
933
1103
|
* trims past the source, locked tracks), applies as one undo step, and returns what it made and
|
|
934
1104
|
* the resulting length and issues. Write tools are hidden while the project is read-only.
|
|
935
1105
|
*/
|
|
@@ -959,6 +1129,11 @@ interface VideoClipDragInput {
|
|
|
959
1129
|
track?: string;
|
|
960
1130
|
/** Push later clips along instead of refusing overlaps (trims) — hold a modifier for it. */
|
|
961
1131
|
ripple?: boolean;
|
|
1132
|
+
/**
|
|
1133
|
+
* For move: what to do with clips where it lands (default refuse). The timelines use Alt for
|
|
1134
|
+
* insert and Shift for overwrite.
|
|
1135
|
+
*/
|
|
1136
|
+
placement?: VideoPlacementMode;
|
|
962
1137
|
/** Snaps a time (e.g. `controller.snap(t, { exclude: [clip] }).time`); default: none. */
|
|
963
1138
|
snap?: (time: number) => number;
|
|
964
1139
|
}
|
|
@@ -979,11 +1154,14 @@ interface VideoClipDragPlan {
|
|
|
979
1154
|
declare function planVideoClipDrag(project: VideoProject, input: VideoClipDragInput): VideoClipDragPlan | null;
|
|
980
1155
|
/** Tracks a clip may be dragged onto: the same kind as its own, unlocked. */
|
|
981
1156
|
declare function videoDropTracks(project: VideoProject, clipId: string): string[];
|
|
1157
|
+
/** The label for the undo step a drag makes. */
|
|
1158
|
+
declare function videoDragLabel(edit: VideoEdit): string;
|
|
982
1159
|
/** The edit that adds an asset as a clip where the person dropped it (or at the end of the first fitting track). */
|
|
983
1160
|
declare function videoAssetDropEdit(project: VideoProject, assetId: string, options?: {
|
|
984
1161
|
track?: string;
|
|
985
1162
|
start?: number;
|
|
986
1163
|
ripple?: boolean;
|
|
1164
|
+
mode?: VideoPlacementMode;
|
|
987
1165
|
}): VideoEdit | null;
|
|
988
1166
|
/** What `probeVideoMedia` found out about a file. */
|
|
989
1167
|
interface VideoMediaProbe {
|
|
@@ -999,5 +1177,38 @@ declare function videoAssetKindOf(typeOrName: string): VideoAssetKind | null;
|
|
|
999
1177
|
* `<video>`, `<audio>` or `<img>`. Rejects with a readable error when it cannot be loaded.
|
|
1000
1178
|
*/
|
|
1001
1179
|
declare function probeVideoMedia(src: string, kind: VideoAssetKind, timeout?: number): Promise<VideoMediaProbe>;
|
|
1180
|
+
/** One animatable property of a clip as an inspector shows it at the playhead. */
|
|
1181
|
+
interface VideoKeyframeRow {
|
|
1182
|
+
property: VideoKeyframeProperty;
|
|
1183
|
+
label: string;
|
|
1184
|
+
/** Its value at the playhead (the playhead held inside the clip). */
|
|
1185
|
+
value: number;
|
|
1186
|
+
/** Whether it has keyframes. */
|
|
1187
|
+
keyed: boolean;
|
|
1188
|
+
/** How many keys it has. */
|
|
1189
|
+
keys: number;
|
|
1190
|
+
/** Whether a key sits at the playhead. */
|
|
1191
|
+
onKey: boolean;
|
|
1192
|
+
/** The playhead in clip time (ms), where new keys go. */
|
|
1193
|
+
clipTime: number;
|
|
1194
|
+
step: number;
|
|
1195
|
+
min?: number;
|
|
1196
|
+
max?: number;
|
|
1197
|
+
}
|
|
1198
|
+
/**
|
|
1199
|
+
* The clip's animatable properties for an inspector at timeline `time`: opacity and the transform
|
|
1200
|
+
* for pictures, volume for sound, each with its value there and whether it is keyed.
|
|
1201
|
+
*/
|
|
1202
|
+
declare function videoKeyframeRows(project: VideoProject, clipId: string, time: number): VideoKeyframeRow[];
|
|
1203
|
+
/**
|
|
1204
|
+
* Typing a value in an inspector: on a keyed property it sets (or moves) the key at the playhead;
|
|
1205
|
+
* otherwise it sets the plain value (`undefined` resets it).
|
|
1206
|
+
*/
|
|
1207
|
+
declare function videoKeyframeValueEdit(project: VideoProject, clipId: string, property: VideoKeyframeProperty, time: number, value: number | undefined): VideoEdit | null;
|
|
1208
|
+
/**
|
|
1209
|
+
* The keyframe toggle: adds a key at the playhead holding the current value (the first key turns
|
|
1210
|
+
* the plain value into keys), or removes the key there (the last one leaves its value plain).
|
|
1211
|
+
*/
|
|
1212
|
+
declare function videoKeyframeToggleEdit(project: VideoProject, clipId: string, property: VideoKeyframeProperty, time: number): VideoEdit | null;
|
|
1002
1213
|
|
|
1003
|
-
export { type CreateVideoProjectOptions, type NewVideoClip, VIDEO_CLIP_TYPES, VIDEO_DEFAULT_STILL_DURATION, VIDEO_DEFAULT_TITLE_DURATION, VIDEO_EDIT_OPS, VIDEO_FITS, VIDEO_ISSUE_CODES, VIDEO_TIME_EPSILON, VIDEO_TRANSITION_TYPES, VIDEO_WIPE_DIRECTIONS, type VideoAsset, type VideoAssetKind, type VideoAudioSource, type VideoCanvasContext, type VideoClip, type VideoClipDragInput, type VideoClipDragMode, type VideoClipDragPlan, type VideoClipLocation, type VideoClipType, type VideoColorClip, type VideoEdit, type VideoEditOp, type VideoEditOutcome, type VideoEditResult, VideoEditorController, type VideoEditorOptions, type VideoEditorState, type VideoEditorToolProviderOptions, type VideoEdlOptions, type VideoFfmpegExport, type VideoFfmpegOptions, type VideoFit, type VideoFrame, type VideoGap, type VideoIssue, type VideoIssueCode, type VideoIssueSeverity, type VideoLayer, type VideoMarker, type VideoMediaClip, type VideoMediaProbe, VideoPreviewEngine, type VideoPreviewImage, type VideoPreviewMedia, type VideoPreviewOptions, type VideoPreviewSource, type VideoProject, type VideoRect, type VideoRulerTick, type VideoSnapOptions, type VideoSvgOptions, type VideoTextClip, type VideoTrack, type VideoTrackKind, type VideoTransform, type VideoTransition, type VideoTransitionType, type VideoWipeDirection, allVideoClipIds, applyVideoEdits, checkVideoProject, createVideoEditorToolProvider, createVideoProject, describeVideoProject, drawVideoFrame, ffmpegFilterValue, findVideoClip, findVideoGaps, formatVideoSeconds, formatVideoTimecode, nextFreeVideoSlot, parseVideoAsset, parseVideoClip, parseVideoMarker, parseVideoProject, parseVideoTrack, parseVideoTransform, parseVideoTransition, placeVideoRect, planVideoClipDrag, probeVideoMedia, snapToVideoFrame, snapVideoTime, sortedVideoClips, toVideoEdl, toVideoFfmpeg, videoAssetDropEdit, videoAssetKindOf, videoAssetMap, videoClipAfter, videoClipBefore, videoClipEnd, videoClipHandles, videoClipLabel, videoClipOverhang, videoClipSourceRange, videoClipSpeed, videoClipTint, videoClipsAt, videoContactSheetSvg, videoDropTracks, videoFrameAt, videoFrameDuration, videoFrameToSvg, videoFrames, videoIssueKey, videoOverlap, videoProjectDuration, videoProjectSvg, videoRulerTicks, videoSnapPoints, videoTextStyle, videoTitleFrame, videoWipeRect };
|
|
1214
|
+
export { type CreateVideoProjectOptions, type NewVideoClip, VIDEO_CLIP_TYPES, VIDEO_DEFAULT_STILL_DURATION, VIDEO_DEFAULT_TITLE_DURATION, VIDEO_EASE_NAMES, VIDEO_EDIT_OPS, VIDEO_FITS, VIDEO_ISSUE_CODES, VIDEO_KEYFRAME_LIMITS, VIDEO_KEYFRAME_PROPERTIES, VIDEO_PLACEMENT_MODES, VIDEO_TIME_EPSILON, VIDEO_TRANSFORM_PROPERTIES, VIDEO_TRANSITION_TYPES, VIDEO_WIPE_DIRECTIONS, type VideoAnimatable, type VideoAsset, type VideoAssetKind, type VideoAudioSource, type VideoCanvasContext, type VideoClip, type VideoClipDragInput, type VideoClipDragMode, type VideoClipDragPlan, type VideoClipLocation, type VideoClipType, type VideoColorClip, type VideoEase, type VideoEdit, type VideoEditOp, type VideoEditOutcome, type VideoEditResult, VideoEditorController, type VideoEditorOptions, type VideoEditorState, type VideoEditorToolProviderOptions, type VideoEdlOptions, type VideoFfmpegExport, type VideoFfmpegOptions, type VideoFit, type VideoFrame, type VideoGap, type VideoIssue, type VideoIssueCode, type VideoIssueSeverity, type VideoKey, type VideoKeyframeProperty, type VideoKeyframeRow, type VideoKeyframes, type VideoLayer, type VideoMarker, type VideoMediaClip, type VideoMediaProbe, type VideoPlacementMode, VideoPreviewEngine, type VideoPreviewImage, type VideoPreviewMedia, type VideoPreviewOptions, type VideoPreviewSource, type VideoProject, type VideoRect, type VideoRulerTick, type VideoSnapOptions, type VideoSvgOptions, type VideoTextClip, type VideoTrack, type VideoTrackKind, type VideoTransform, type VideoTransition, type VideoTransitionType, type VideoWipeDirection, allVideoClipIds, applyVideoEdits, checkVideoProject, createVideoEditorToolProvider, createVideoProject, describeVideoProject, drawVideoFrame, ffmpegFilterValue, findVideoClip, findVideoGaps, formatVideoSeconds, formatVideoTimecode, isVideoKeyframes, nextFreeVideoSlot, parseVideoAnimatable, parseVideoAsset, parseVideoClip, parseVideoKeyframes, parseVideoMarker, parseVideoProject, parseVideoTrack, parseVideoTransform, parseVideoTransition, placeVideoRect, planVideoClipDrag, probeVideoMedia, removeVideoKey, retimeVideoAnimatable, setVideoKey, snapToVideoFrame, snapVideoTime, sortVideoKeys, sortedVideoClips, splitVideoAnimatable, toVideoEdl, toVideoFfmpeg, videoAssetDropEdit, videoAssetKindOf, videoAssetMap, videoClipAfter, videoClipBefore, videoClipEnd, videoClipHandles, videoClipKeyframes, videoClipLabel, videoClipOverhang, videoClipSourceRange, videoClipSpeed, videoClipTint, videoClipsAt, videoContactSheetSvg, videoDragLabel, videoDropTracks, videoEaseBezier, videoEaseProgress, videoFrameAt, videoFrameDuration, videoFrameToSvg, videoFrames, videoIssueKey, videoKeyframeBreakpoints, videoKeyframeFfmpegExpr, videoKeyframeRows, videoKeyframeToggleEdit, videoKeyframeValueEdit, videoKeysOf, videoOverlap, videoProjectDuration, videoProjectSvg, videoRulerTicks, videoSnapPoints, videoTextStyle, videoTitleFrame, videoTrackSyncLocked, videoTransformAt, videoValueAt, videoWipeRect };
|