@pixerate/editor 0.82.0 → 0.84.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 +1054 -130
- package/dist/video-editor/index.cjs.map +1 -1
- package/dist/video-editor/index.d.cts +456 -12
- package/dist/video-editor/index.d.ts +456 -12
- package/dist/video-editor/index.js +992 -68
- package/dist/video-editor/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/pixerate-video-editor/SKILL.md +46 -10
|
@@ -142,8 +142,16 @@ interface VideoTransform {
|
|
|
142
142
|
/** How a picture is fitted to the frame before its transform: like CSS `object-fit`. */
|
|
143
143
|
type VideoFit = 'contain' | 'cover' | 'fill' | 'none';
|
|
144
144
|
declare const VIDEO_FITS: readonly ["contain", "cover", "fill", "none"];
|
|
145
|
-
|
|
146
|
-
|
|
145
|
+
/**
|
|
146
|
+
* - `crossfade`: this clip fades up over the one before.
|
|
147
|
+
* - `dip`: down into a colour and up out of it.
|
|
148
|
+
* - `wipe`: an edge travels across, revealing this clip.
|
|
149
|
+
* - `push`: this clip slides in, pushing the one before out.
|
|
150
|
+
* - `slide`: this clip slides in over the one before, which stays put.
|
|
151
|
+
* - `iris`: a circle opens from the centre, revealing this clip.
|
|
152
|
+
*/
|
|
153
|
+
type VideoTransitionType = 'crossfade' | 'dip' | 'wipe' | 'push' | 'slide' | 'iris';
|
|
154
|
+
declare const VIDEO_TRANSITION_TYPES: readonly ["crossfade", "dip", "wipe", "push", "slide", "iris"];
|
|
147
155
|
type VideoWipeDirection = 'left' | 'right' | 'up' | 'down';
|
|
148
156
|
declare const VIDEO_WIPE_DIRECTIONS: readonly ["left", "right", "up", "down"];
|
|
149
157
|
/**
|
|
@@ -157,8 +165,54 @@ interface VideoTransition {
|
|
|
157
165
|
duration: number;
|
|
158
166
|
/** For dip: the colour passed through (default black). */
|
|
159
167
|
color?: string;
|
|
160
|
-
/** For wipe: the way the edge travels (default right
|
|
168
|
+
/** For wipe, push and slide: the way the edge or picture travels (default right: in from the left). */
|
|
161
169
|
direction?: VideoWipeDirection;
|
|
170
|
+
/**
|
|
171
|
+
* Shape of the sound's fades through the transition (see `VideoFadeCurve`). Default
|
|
172
|
+
* `equal-power` for crossfades and wipes, where two sounds overlap and a linear mix dips in
|
|
173
|
+
* loudness halfway; `linear` for dips, where one sound fades out before the other fades in.
|
|
174
|
+
*/
|
|
175
|
+
audioCurve?: VideoFadeCurve;
|
|
176
|
+
}
|
|
177
|
+
/** The curve a transition's sound fades follow (its `audioCurve`, else the default for its type). */
|
|
178
|
+
declare const videoTransitionAudioCurve: (t: VideoTransition) => VideoFadeCurve;
|
|
179
|
+
/**
|
|
180
|
+
* How a clip's picture mixes with what is beneath it, as in CSS `mix-blend-mode` (`add` sums the
|
|
181
|
+
* colours, `plus-lighter` in CSS). These are the modes the canvas preview, SVG frames and ffmpeg's
|
|
182
|
+
* `blend` filter all share.
|
|
183
|
+
*/
|
|
184
|
+
type VideoBlendMode = 'normal' | 'multiply' | 'screen' | 'overlay' | 'darken' | 'lighten' | 'color-dodge' | 'color-burn' | 'hard-light' | 'soft-light' | 'difference' | 'exclusion' | 'add';
|
|
185
|
+
declare const VIDEO_BLEND_MODES: readonly ["normal", "multiply", "screen", "overlay", "darken", "lighten", "color-dodge", "color-burn", "hard-light", "soft-light", "difference", "exclusion", "add"];
|
|
186
|
+
/**
|
|
187
|
+
* Colour correction for a clip's picture (see `VIDEO_GRADE_CONTROLS` for ranges). Applied in a fixed
|
|
188
|
+
* order: exposure, contrast, saturation, hue, then white balance (temperature and tint).
|
|
189
|
+
*/
|
|
190
|
+
interface VideoGrade {
|
|
191
|
+
/** Stops: +1 doubles every channel (default 0). */
|
|
192
|
+
exposure?: number;
|
|
193
|
+
/** -1 (flat grey) to 1 (twice as steep), around mid grey (default 0). */
|
|
194
|
+
contrast?: number;
|
|
195
|
+
/** -1 (black and white) to 1 (twice as saturated); default 0. */
|
|
196
|
+
saturation?: number;
|
|
197
|
+
/** Hue rotation in degrees (default 0). */
|
|
198
|
+
hue?: number;
|
|
199
|
+
/** -1 (cool) to 1 (warm); default 0. */
|
|
200
|
+
temperature?: number;
|
|
201
|
+
/** -1 (green) to 1 (magenta); default 0. */
|
|
202
|
+
tint?: number;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* How a clip enters or leaves: `fade`; `rise` (up into place) or `drop` (down into place);
|
|
206
|
+
* `slide-left` / `slide-right` (in moving that way); `zoom` (grows into place); `pop` (grows past its
|
|
207
|
+
* size and settles). Each also fades. An exit plays the same movement backwards.
|
|
208
|
+
*/
|
|
209
|
+
type VideoClipAnimationEffect = 'fade' | 'rise' | 'drop' | 'slide-left' | 'slide-right' | 'zoom' | 'pop';
|
|
210
|
+
declare const VIDEO_CLIP_ANIMATION_EFFECTS: readonly ["fade", "rise", "drop", "slide-left", "slide-right", "zoom", "pop"];
|
|
211
|
+
/** An entrance or exit animation (see `VideoClipAnimationEffect`). */
|
|
212
|
+
interface VideoClipAnimation {
|
|
213
|
+
effect: VideoClipAnimationEffect;
|
|
214
|
+
/** Length (ms, default 500). */
|
|
215
|
+
duration?: number;
|
|
162
216
|
}
|
|
163
217
|
interface VideoClipBase {
|
|
164
218
|
id: string;
|
|
@@ -172,6 +226,14 @@ interface VideoClipBase {
|
|
|
172
226
|
transform?: VideoTransform;
|
|
173
227
|
/** Default contain. */
|
|
174
228
|
fit?: VideoFit;
|
|
229
|
+
/** How the picture mixes with what is beneath it (default normal). */
|
|
230
|
+
blend?: VideoBlendMode;
|
|
231
|
+
/** Colour correction of the picture. */
|
|
232
|
+
grade?: VideoGrade;
|
|
233
|
+
/** How the picture enters, from the clip's start (on top of any fade in). */
|
|
234
|
+
animateIn?: VideoClipAnimation;
|
|
235
|
+
/** How the picture leaves, up to the clip's end. */
|
|
236
|
+
animateOut?: VideoClipAnimation;
|
|
175
237
|
/** Fade in from nothing over this long (ms), pictures and sound. */
|
|
176
238
|
fadeIn?: number;
|
|
177
239
|
/** Fade out over this long (ms). */
|
|
@@ -179,6 +241,17 @@ interface VideoClipBase {
|
|
|
179
241
|
/** Transition from the clip before (see `VideoTransition`). */
|
|
180
242
|
transition?: VideoTransition;
|
|
181
243
|
}
|
|
244
|
+
/**
|
|
245
|
+
* The shape of a sound fade, the same curves ffmpeg's `afade` draws, so previews and exports agree.
|
|
246
|
+
* With `x` running 0→1 through a fade in (1→0 through a fade out), the gain is:
|
|
247
|
+
* - `linear`: x (ffmpeg `tri`). Dips in loudness in the middle of a crossfade.
|
|
248
|
+
* - `equal-power`: sin(x·π/2) (`qsin`). Keeps loudness steady; the usual choice for crossfades.
|
|
249
|
+
* - `s-curve`: (1 − cos(x·π))/2 (`hsin`). Gentle at both ends.
|
|
250
|
+
* - `exponential`: x³ (`cub`). Slow start; a natural-sounding fade in from silence.
|
|
251
|
+
* - `logarithmic`: 1 − (1 − x)² (`ipar`). Fast start, slow finish.
|
|
252
|
+
*/
|
|
253
|
+
type VideoFadeCurve = 'linear' | 'equal-power' | 's-curve' | 'exponential' | 'logarithmic';
|
|
254
|
+
declare const VIDEO_FADE_CURVES: readonly ["linear", "equal-power", "s-curve", "exponential", "logarithmic"];
|
|
182
255
|
/** A stretch of an asset. */
|
|
183
256
|
interface VideoMediaClip extends VideoClipBase {
|
|
184
257
|
type: 'media';
|
|
@@ -191,6 +264,10 @@ interface VideoMediaClip extends VideoClipBase {
|
|
|
191
264
|
volume?: VideoAnimatable;
|
|
192
265
|
/** Silences this clip. */
|
|
193
266
|
muted?: boolean;
|
|
267
|
+
/** Shape of the sound's fade in (default linear). The picture always fades linearly. */
|
|
268
|
+
fadeInCurve?: VideoFadeCurve;
|
|
269
|
+
/** Shape of the sound's fade out (default linear). */
|
|
270
|
+
fadeOutCurve?: VideoFadeCurve;
|
|
194
271
|
}
|
|
195
272
|
/** A title. */
|
|
196
273
|
interface VideoTextClip extends VideoClipBase {
|
|
@@ -259,6 +336,8 @@ declare function parseVideoAnimatable(v: unknown, path: string, range?: {
|
|
|
259
336
|
optional?: boolean;
|
|
260
337
|
}): VideoAnimatable | undefined;
|
|
261
338
|
declare function parseVideoTransform(v: unknown, path: string): VideoTransform | undefined;
|
|
339
|
+
declare function parseVideoClipAnimation(v: unknown, path: string): VideoClipAnimation | undefined;
|
|
340
|
+
declare function parseVideoGrade(v: unknown, path: string): VideoGrade | undefined;
|
|
262
341
|
declare function parseVideoTransition(v: unknown, path: string): VideoTransition | undefined;
|
|
263
342
|
declare function parseVideoAsset(v: unknown, path?: string): VideoAsset;
|
|
264
343
|
declare function parseVideoClip(v: unknown, path?: string): VideoClip;
|
|
@@ -302,10 +381,28 @@ declare const videoFrameDuration: (fps: number) => number;
|
|
|
302
381
|
declare function snapToVideoFrame(time: number, fps: number): number;
|
|
303
382
|
/** Whole frames in `time` at `fps` (rounded). */
|
|
304
383
|
declare const videoFrames: (time: number, fps: number) => number;
|
|
305
|
-
/**
|
|
306
|
-
|
|
384
|
+
/**
|
|
385
|
+
* Whether `fps` is an NTSC rate that SMPTE counts in drop-frame timecode: 29.97 (30000/1001) or
|
|
386
|
+
* 59.94 (60000/1001). Other fractional rates (23.976) have no drop-frame form.
|
|
387
|
+
*/
|
|
388
|
+
declare function isVideoDropFrameRate(fps: number): boolean;
|
|
389
|
+
/** Frames elapsed in `time` (ms), counted at the exact rate behind a rounded NTSC rate. */
|
|
390
|
+
declare const videoTimecodeFrames: (time: number, fps: number) => number;
|
|
391
|
+
/**
|
|
392
|
+
* SMPTE timecode for a time (ms): `HH:MM:SS:FF`, or `HH:MM:SS;FF` in drop-frame, which skips frame
|
|
393
|
+
* numbers 0 and 1 (0–3 at 59.94) at the start of every minute except each tenth, so the clock keeps
|
|
394
|
+
* up with real time at NTSC rates. `dropFrame` defaults to on at 29.97 and 59.94 and is ignored at
|
|
395
|
+
* rates without a drop-frame form.
|
|
396
|
+
*/
|
|
397
|
+
declare function formatVideoTimecode(time: number, fps: number, dropFrame?: boolean): string;
|
|
398
|
+
/** SMPTE timecode for a frame count (see `formatVideoTimecode`). */
|
|
399
|
+
declare function formatVideoTimecodeFrames(frames: number, fps: number, dropFrame?: boolean): string;
|
|
400
|
+
/** Frames up to timecode `01:00:00:00` (`;00` in drop-frame), where record timecode usually starts. */
|
|
401
|
+
declare const videoHourFrames: (fps: number, dropFrame?: boolean) => number;
|
|
307
402
|
/** Readable time for messages: `2.50 s`. */
|
|
308
403
|
declare const formatVideoSeconds: (time: number) => string;
|
|
404
|
+
/** Whether an asset carries sound: audio, or video not marked `hasAudio: false`. */
|
|
405
|
+
declare const videoAssetHasSound: (asset: VideoAsset | undefined) => boolean;
|
|
309
406
|
declare function videoAssetMap(project: VideoProject): Map<string, VideoAsset>;
|
|
310
407
|
/** A track's clips in timeline order. */
|
|
311
408
|
declare function sortedVideoClips(track: VideoTrack): VideoClip[];
|
|
@@ -377,7 +474,7 @@ declare function videoClipKeyframes(clip: VideoClip): {
|
|
|
377
474
|
keys: ReturnType<typeof videoKeysOf>;
|
|
378
475
|
}[];
|
|
379
476
|
type VideoIssueSeverity = 'error' | 'warning' | 'note';
|
|
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"];
|
|
477
|
+
declare const VIDEO_ISSUE_CODES: readonly ["missing-asset", "wrong-track", "overlap", "source-overrun", "transition-without-cut", "transition-too-long", "transition-handles", "fades-too-long", "animations-too-long", "animation-keyed", "keyframes-outside-clip", "unknown-duration", "unused-asset", "marker-past-end", "empty"];
|
|
381
478
|
type VideoIssueCode = (typeof VIDEO_ISSUE_CODES)[number];
|
|
382
479
|
interface VideoIssue {
|
|
383
480
|
code: VideoIssueCode;
|
|
@@ -620,6 +717,10 @@ interface VideoLayer {
|
|
|
620
717
|
direction: VideoWipeDirection;
|
|
621
718
|
progress: number;
|
|
622
719
|
};
|
|
720
|
+
/** 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. */
|
|
721
|
+
iris?: {
|
|
722
|
+
progress: number;
|
|
723
|
+
};
|
|
623
724
|
/** For text: what to draw. */
|
|
624
725
|
text?: {
|
|
625
726
|
text: string;
|
|
@@ -631,6 +732,10 @@ interface VideoLayer {
|
|
|
631
732
|
};
|
|
632
733
|
/** For colour clips and dips. */
|
|
633
734
|
color?: string;
|
|
735
|
+
/** How it mixes with the layers beneath (absent = normal). */
|
|
736
|
+
blend?: VideoBlendMode;
|
|
737
|
+
/** Colour correction (absent = none). */
|
|
738
|
+
grade?: VideoGrade;
|
|
634
739
|
}
|
|
635
740
|
/** One sound playing at a moment. */
|
|
636
741
|
interface VideoAudioSource {
|
|
@@ -677,6 +782,15 @@ declare function videoTextStyle(clip: VideoTextClip): NonNullable<VideoLayer['te
|
|
|
677
782
|
* transforms without them, and moves the image itself).
|
|
678
783
|
*/
|
|
679
784
|
declare function videoTitleFrame(project: VideoProject, clip: VideoTextClip, clipTime?: number): VideoFrame;
|
|
785
|
+
/** How far a push or slide has moved at `progress` (0–1): eased in and out, (1 − cos πp) / 2. */
|
|
786
|
+
declare const videoTransitionEase: (progress: number) => number;
|
|
787
|
+
/** 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. */
|
|
788
|
+
declare function videoFadeCurveGain(curve: VideoFadeCurve | undefined, x: number): number;
|
|
789
|
+
/**
|
|
790
|
+
* A media clip's own gain at clip time `clipTime` (ms): its volume (or volume keyframes) times its
|
|
791
|
+
* shaped fades. Leaves out track volume and transitions, which depend on the timeline around it.
|
|
792
|
+
*/
|
|
793
|
+
declare function videoClipSoundGain(clip: VideoClip, clipTime: number): number;
|
|
680
794
|
/**
|
|
681
795
|
* What plays at `time` (ms): the pictures to draw, back to front, with their placement, opacity
|
|
682
796
|
* and the moment of source each shows, and the sounds with their gain. A pure function of the
|
|
@@ -684,6 +798,241 @@ declare function videoTitleFrame(project: VideoProject, clip: VideoTextClip, cli
|
|
|
684
798
|
*/
|
|
685
799
|
declare function videoFrameAt(project: VideoProject, time: number): VideoFrame;
|
|
686
800
|
|
|
801
|
+
/**
|
|
802
|
+
* Sound levels of a piece of audio, small enough to keep for every asset: a pyramid of min / max
|
|
803
|
+
* sample values. Level 0 holds one min / max pair per `blockSize` samples; each level above merges
|
|
804
|
+
* four blocks of the one below, so the min / max of any stretch costs a handful of reads at any
|
|
805
|
+
* zoom. Channels are folded together (the loudest of them counts). Plain data: hosts can compute
|
|
806
|
+
* it once (`buildVideoAudioPeaks`) and store it.
|
|
807
|
+
*/
|
|
808
|
+
interface VideoAudioPeaks {
|
|
809
|
+
/** Samples per second of the decoded audio. */
|
|
810
|
+
sampleRate: number;
|
|
811
|
+
/** Samples in the audio (per channel). */
|
|
812
|
+
length: number;
|
|
813
|
+
/** Samples per level-0 block. */
|
|
814
|
+
blockSize: number;
|
|
815
|
+
/** `levels[k]` is `[min, max, min, max, …]`, one pair per block of `blockSize × 4^k` samples. */
|
|
816
|
+
levels: Float32Array[];
|
|
817
|
+
}
|
|
818
|
+
/** Samples per level-0 block (well under a millisecond at common rates). */
|
|
819
|
+
declare const VIDEO_PEAK_BLOCK = 32;
|
|
820
|
+
/** Builds the peak pyramid for decoded audio (one `Float32Array` of samples per channel). */
|
|
821
|
+
declare function buildVideoAudioPeaks(channels: readonly Float32Array[], sampleRate: number, blockSize?: number): VideoAudioPeaks;
|
|
822
|
+
/** Length of the audio (ms). */
|
|
823
|
+
declare const videoAudioPeaksDuration: (peaks: VideoAudioPeaks) => number;
|
|
824
|
+
/**
|
|
825
|
+
* The lowest and highest sample between two times (ms) in the audio, to the nearest block (so a
|
|
826
|
+
* stretch can read up to a block wider). `{ min: 0, max: 0 }` outside the audio.
|
|
827
|
+
*/
|
|
828
|
+
declare function videoAudioPeakRange(peaks: VideoAudioPeaks, from: number, to: number): {
|
|
829
|
+
min: number;
|
|
830
|
+
max: number;
|
|
831
|
+
};
|
|
832
|
+
/** `columns` min / max pairs (`[min, max, …]`) evenly across `from`..`to` ms, e.g. one per pixel. */
|
|
833
|
+
declare function videoAudioPeakSpans(peaks: VideoAudioPeaks, from: number, to: number, columns: number): Float32Array;
|
|
834
|
+
/**
|
|
835
|
+
* What a media clip plays as `columns` min / max pairs across its length: each column reads the
|
|
836
|
+
* stretch of source under it (through the in point and speed) and is scaled by the clip's volume and
|
|
837
|
+
* fades, so the waveform shows what is heard.
|
|
838
|
+
*/
|
|
839
|
+
declare function videoClipWaveform(clip: VideoMediaClip, peaks: VideoAudioPeaks, columns: number): Float32Array;
|
|
840
|
+
/**
|
|
841
|
+
* An SVG path (`d`) of a waveform filling `width` × `height`: the top edge along the maxima, back
|
|
842
|
+
* along the minima. Values are clamped to ±1, so anything louder than full scale touches the edge.
|
|
843
|
+
*/
|
|
844
|
+
declare function videoWaveformPath(spans: Float32Array, width: number, height: number): string;
|
|
845
|
+
/**
|
|
846
|
+
* The SVG path of a media clip's waveform drawn `width` × `height` pixels (one column per 2 px), as
|
|
847
|
+
* `videoClipWaveform` reads it: what timelines draw inside an audio clip.
|
|
848
|
+
*/
|
|
849
|
+
declare function videoClipWaveformPath(clip: VideoMediaClip, peaks: VideoAudioPeaks, width: number, height: number): string;
|
|
850
|
+
/** A sample value as dBFS, floored at -100 (silence). */
|
|
851
|
+
declare const videoPeakDb: (value: number) => number;
|
|
852
|
+
interface VideoAudioLevel {
|
|
853
|
+
/** Start of the bucket (ms, in the clock the caller asked in). */
|
|
854
|
+
start: number;
|
|
855
|
+
end: number;
|
|
856
|
+
/** Peak level in dBFS (0 = full scale, -100 = silence). */
|
|
857
|
+
peakDb: number;
|
|
858
|
+
}
|
|
859
|
+
/** Peak level in `buckets` equal stretches of `from`..`to` ms of the audio. */
|
|
860
|
+
declare function videoAudioLevels(peaks: VideoAudioPeaks, from: number, to: number, buckets: number): VideoAudioLevel[];
|
|
861
|
+
interface VideoSilenceOptions {
|
|
862
|
+
/** Quieter than this peak level counts as silence (dBFS, default -40). */
|
|
863
|
+
thresholdDb?: number;
|
|
864
|
+
/** Shortest silence to report (ms, default 300). */
|
|
865
|
+
minDuration?: number;
|
|
866
|
+
/** Resolution of the scan (ms, default 10). */
|
|
867
|
+
resolution?: number;
|
|
868
|
+
}
|
|
869
|
+
/** Stretches of `from`..`to` ms of the audio that stay below a level, at least `minDuration` long. */
|
|
870
|
+
declare function findVideoAudioSilences(peaks: VideoAudioPeaks, from: number, to: number, options?: VideoSilenceOptions): {
|
|
871
|
+
start: number;
|
|
872
|
+
end: number;
|
|
873
|
+
}[];
|
|
874
|
+
/** Fetches and decodes a media file's sound into peaks, in a browser (Web Audio). */
|
|
875
|
+
declare function decodeVideoAudioPeaks(src: string, options?: {
|
|
876
|
+
signal?: AbortSignal;
|
|
877
|
+
}): Promise<VideoAudioPeaks>;
|
|
878
|
+
/** Loads the peaks of an asset's sound. */
|
|
879
|
+
type VideoAudioPeaksLoader = (asset: VideoAsset) => Promise<VideoAudioPeaks>;
|
|
880
|
+
/**
|
|
881
|
+
* Peaks per asset, loaded once each (by `src`) and shared by the timeline and agent tools.
|
|
882
|
+
* `get` returns what is ready and starts loading the rest; `subscribe` hears when more is ready.
|
|
883
|
+
*/
|
|
884
|
+
declare class VideoAudioPeaksCache {
|
|
885
|
+
private readonly loader;
|
|
886
|
+
private readonly ready;
|
|
887
|
+
private readonly pending;
|
|
888
|
+
private readonly failed;
|
|
889
|
+
private readonly listeners;
|
|
890
|
+
constructor(loader?: VideoAudioPeaksLoader);
|
|
891
|
+
/** The peaks if ready, without starting to load them. */
|
|
892
|
+
peek(asset: VideoAsset): VideoAudioPeaks | undefined;
|
|
893
|
+
/** The peaks if ready; otherwise `undefined`, and loading starts (once) unless it failed. */
|
|
894
|
+
get(asset: VideoAsset): VideoAudioPeaks | undefined;
|
|
895
|
+
/** Why loading an asset's peaks failed, if it did. */
|
|
896
|
+
error(asset: VideoAsset): string | undefined;
|
|
897
|
+
/** The peaks, loading them if needed. Rejects with a readable error. */
|
|
898
|
+
load(asset: VideoAsset): Promise<VideoAudioPeaks>;
|
|
899
|
+
/** Uses peaks the host already has (computed earlier or stored). */
|
|
900
|
+
set(src: string, peaks: VideoAudioPeaks): void;
|
|
901
|
+
subscribe(fn: () => void): () => void;
|
|
902
|
+
private emit;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
/**
|
|
906
|
+
* Colour correction as a fixed series of colour-matrix steps on gamma-encoded sRGB, each clamped
|
|
907
|
+
* to 0–1, in the same order everywhere: exposure, contrast, saturation, hue, then white balance.
|
|
908
|
+
* Every step is one the browser has (CSS `brightness`, `contrast`, `saturate`, `hue-rotate`; white
|
|
909
|
+
* balance as an SVG `feColorMatrix`) and ffmpeg has (`lutrgb`, `colorchannelmixer`), with the same
|
|
910
|
+
* formulas, so the preview, SVG frames and the export agree.
|
|
911
|
+
*/
|
|
912
|
+
/** One slider of a grade: its range, default and step, for schemas, inspectors and clamping. */
|
|
913
|
+
interface VideoGradeControl {
|
|
914
|
+
key: keyof VideoGrade;
|
|
915
|
+
label: string;
|
|
916
|
+
min: number;
|
|
917
|
+
max: number;
|
|
918
|
+
step: number;
|
|
919
|
+
/** What the number means, for tool descriptions. */
|
|
920
|
+
description: string;
|
|
921
|
+
}
|
|
922
|
+
declare const VIDEO_GRADE_CONTROLS: readonly VideoGradeControl[];
|
|
923
|
+
/** Named looks. Apply them at a strength with `videoGradePreset`. */
|
|
924
|
+
declare const VIDEO_GRADE_PRESETS: {
|
|
925
|
+
readonly warm: {
|
|
926
|
+
readonly temperature: 0.4;
|
|
927
|
+
readonly saturation: 0.1;
|
|
928
|
+
};
|
|
929
|
+
readonly cool: {
|
|
930
|
+
readonly temperature: -0.4;
|
|
931
|
+
readonly tint: -0.05;
|
|
932
|
+
};
|
|
933
|
+
readonly punchy: {
|
|
934
|
+
readonly contrast: 0.25;
|
|
935
|
+
readonly saturation: 0.3;
|
|
936
|
+
};
|
|
937
|
+
readonly faded: {
|
|
938
|
+
readonly exposure: 0.15;
|
|
939
|
+
readonly contrast: -0.3;
|
|
940
|
+
readonly saturation: -0.3;
|
|
941
|
+
};
|
|
942
|
+
readonly 'black-and-white': {
|
|
943
|
+
readonly saturation: -1;
|
|
944
|
+
readonly contrast: 0.15;
|
|
945
|
+
};
|
|
946
|
+
readonly 'bleach-bypass': {
|
|
947
|
+
readonly saturation: -0.6;
|
|
948
|
+
readonly contrast: 0.4;
|
|
949
|
+
};
|
|
950
|
+
readonly 'day-for-night': {
|
|
951
|
+
readonly exposure: -1.5;
|
|
952
|
+
readonly saturation: -0.4;
|
|
953
|
+
readonly temperature: -0.6;
|
|
954
|
+
};
|
|
955
|
+
};
|
|
956
|
+
type VideoGradePreset = keyof typeof VIDEO_GRADE_PRESETS;
|
|
957
|
+
declare const VIDEO_GRADE_PRESET_NAMES: VideoGradePreset[];
|
|
958
|
+
/** A grade with every value clamped to its range and zero values left out; `undefined` when nothing is left. */
|
|
959
|
+
declare function normalizeVideoGrade(grade: VideoGrade | undefined): VideoGrade | undefined;
|
|
960
|
+
/** A preset at `amount` (0–1, default 1) of its strength. */
|
|
961
|
+
declare function videoGradePreset(name: VideoGradePreset, amount?: number): VideoGrade | undefined;
|
|
962
|
+
/** One step of a grade. */
|
|
963
|
+
type VideoGradeStep = {
|
|
964
|
+
kind: 'brightness';
|
|
965
|
+
amount: number;
|
|
966
|
+
} | {
|
|
967
|
+
kind: 'contrast';
|
|
968
|
+
amount: number;
|
|
969
|
+
} | {
|
|
970
|
+
kind: 'saturate';
|
|
971
|
+
amount: number;
|
|
972
|
+
} | {
|
|
973
|
+
kind: 'hue-rotate';
|
|
974
|
+
degrees: number;
|
|
975
|
+
} | {
|
|
976
|
+
kind: 'gains';
|
|
977
|
+
r: number;
|
|
978
|
+
g: number;
|
|
979
|
+
b: number;
|
|
980
|
+
};
|
|
981
|
+
/** The steps a grade applies, in order, leaving out those that change nothing. */
|
|
982
|
+
declare function videoGradeSteps(grade: VideoGrade | undefined): VideoGradeStep[];
|
|
983
|
+
/**
|
|
984
|
+
* A step as a 3 × 4 matrix (rows r, g, b; columns r, g, b, offset), with the coefficients the CSS
|
|
985
|
+
* Filter Effects spec gives for `saturate` and `hue-rotate`.
|
|
986
|
+
*/
|
|
987
|
+
declare function videoGradeStepMatrix(step: VideoGradeStep): number[][];
|
|
988
|
+
/** An RGB colour (0–255 each) through a grade, as the preview and export draw it. */
|
|
989
|
+
declare function applyVideoGrade(grade: VideoGrade | undefined, rgb: readonly [number, number, number]): [number, number, number];
|
|
990
|
+
/** The `values` of an SVG `feColorMatrix type="matrix"` for a step. */
|
|
991
|
+
declare function videoGradeStepSvgValues(step: VideoGradeStep): string;
|
|
992
|
+
/** An SVG `<filter>` applying a grade, steps in order (each clamps, as CSS filters do). */
|
|
993
|
+
declare function videoGradeSvgFilter(id: string, grade: VideoGrade | undefined): string;
|
|
994
|
+
/** Id of the SVG filter for a white-balance step: the same gains always get the same id. */
|
|
995
|
+
declare const videoGradeGainsFilterId: (step: Extract<VideoGradeStep, {
|
|
996
|
+
kind: "gains";
|
|
997
|
+
}>) => string;
|
|
998
|
+
/**
|
|
999
|
+
* A grade as a CSS / canvas `filter`: CSS functions for every step, and `url(#id)` for white balance,
|
|
1000
|
+
* which CSS has no function for (see `videoGradeGainsFilterId`; the host puts that filter in the page).
|
|
1001
|
+
* `''` when the grade changes nothing.
|
|
1002
|
+
*/
|
|
1003
|
+
declare function videoGradeCssFilter(grade: VideoGrade | undefined): string;
|
|
1004
|
+
/** The white-balance SVG filters a grade's CSS filter refers to, as `{ id, markup }`. */
|
|
1005
|
+
declare function videoGradeSvgDefs(grade: VideoGrade | undefined): {
|
|
1006
|
+
id: string;
|
|
1007
|
+
markup: string;
|
|
1008
|
+
}[];
|
|
1009
|
+
/** A grade as ffmpeg filters on RGB, in order: `lutrgb` for exposure and contrast, `colorchannelmixer` for the rest. */
|
|
1010
|
+
declare function videoGradeFfmpegFilters(grade: VideoGrade | undefined): string[];
|
|
1011
|
+
|
|
1012
|
+
/** Default length of an entrance or exit animation (ms). */
|
|
1013
|
+
declare const VIDEO_CLIP_ANIMATION_DURATION = 500;
|
|
1014
|
+
declare const PROPS: readonly ["opacity", "x", "y", "scale"];
|
|
1015
|
+
type Prop = (typeof PROPS)[number];
|
|
1016
|
+
/** The properties an animation moves (each also fades: opacity is always one). */
|
|
1017
|
+
declare function videoClipAnimationProperties(animation: VideoClipAnimation): Prop[];
|
|
1018
|
+
/** Entrance and exit lengths (ms), shortened in proportion when together they are longer than the clip. */
|
|
1019
|
+
declare function videoClipAnimationSpans(clip: VideoClip): {
|
|
1020
|
+
in: number;
|
|
1021
|
+
out: number;
|
|
1022
|
+
};
|
|
1023
|
+
/**
|
|
1024
|
+
* The clip with its entrance and exit animations written out as keyframes on opacity, x, y and
|
|
1025
|
+
* scale, so previews, SVG frames and the ffmpeg export all play them the same way. A property the
|
|
1026
|
+
* clip already keys itself is left alone (`checkVideoProject` notes it). Returns the clip unchanged
|
|
1027
|
+
* when it has no animations.
|
|
1028
|
+
*/
|
|
1029
|
+
declare function videoClipAnimated(clip: VideoClip, project: Pick<VideoProject, 'width' | 'height'>): VideoClip;
|
|
1030
|
+
|
|
1031
|
+
/** Radius of an iris `progress` (0–1) open: from nothing to the frame's corners. */
|
|
1032
|
+
declare const videoIrisRadius: (frame: {
|
|
1033
|
+
width: number;
|
|
1034
|
+
height: number;
|
|
1035
|
+
}, progress: number) => number;
|
|
687
1036
|
/** The part of a rect a wipe shows. */
|
|
688
1037
|
declare function videoWipeRect(rect: VideoRect, wipe: NonNullable<VideoLayer['wipe']>): VideoRect;
|
|
689
1038
|
interface VideoSvgOptions {
|
|
@@ -705,8 +1054,10 @@ declare function videoContactSheetSvg(project: VideoProject, times: readonly num
|
|
|
705
1054
|
width?: number;
|
|
706
1055
|
}): string;
|
|
707
1056
|
/** The subset of `CanvasRenderingContext2D` `drawVideoFrame` uses (so tests and workers can pass their own). */
|
|
708
|
-
type VideoCanvasContext = Pick<CanvasRenderingContext2D, 'save' | 'restore' | 'fillRect' | 'drawImage' | 'translate' | 'rotate' | 'beginPath' | 'rect' | 'clip' | 'fillText' | 'measureText' | 'setTransform'> & {
|
|
1057
|
+
type VideoCanvasContext = Pick<CanvasRenderingContext2D, 'save' | 'restore' | 'fillRect' | 'drawImage' | 'translate' | 'rotate' | 'beginPath' | 'rect' | 'arc' | 'clip' | 'fillText' | 'measureText' | 'setTransform'> & {
|
|
709
1058
|
globalAlpha: number;
|
|
1059
|
+
globalCompositeOperation: GlobalCompositeOperation;
|
|
1060
|
+
filter?: string;
|
|
710
1061
|
fillStyle: string | CanvasGradient | CanvasPattern;
|
|
711
1062
|
font: string;
|
|
712
1063
|
textAlign: CanvasTextAlign;
|
|
@@ -718,21 +1069,27 @@ type VideoCanvasContext = Pick<CanvasRenderingContext2D, 'save' | 'restore' | 'f
|
|
|
718
1069
|
/**
|
|
719
1070
|
* Draws a frame on a 2D canvas scaled by `scale` (canvas pixels per frame pixel). `sourceFor`
|
|
720
1071
|
* returns what to draw for a media layer (a `<video>` seeked to `layer.sourceTime`, an `<img>`,
|
|
721
|
-
* an `ImageBitmap`…) or `null` for a placeholder box.
|
|
1072
|
+
* an `ImageBitmap`…) or `null` for a placeholder box. Grades become the context's `filter`; white
|
|
1073
|
+
* balance there refers to an SVG filter, which `options.defineSvgFilter` is given to put in the page
|
|
1074
|
+
* (without it, white balance is left out of the canvas).
|
|
722
1075
|
*/
|
|
723
|
-
declare function drawVideoFrame(ctx: VideoCanvasContext, frame: VideoFrame, sourceFor: (layer: VideoLayer) => CanvasImageSource | null, scale?: number
|
|
1076
|
+
declare function drawVideoFrame(ctx: VideoCanvasContext, frame: VideoFrame, sourceFor: (layer: VideoLayer) => CanvasImageSource | null, scale?: number, options?: {
|
|
1077
|
+
defineSvgFilter?: (id: string, markup: string) => void;
|
|
1078
|
+
}): void;
|
|
724
1079
|
|
|
725
1080
|
interface VideoEdlOptions {
|
|
726
1081
|
/** Track to export (default: the bottom video track, V1 in most NLEs). */
|
|
727
1082
|
track?: string;
|
|
728
|
-
/** Record timecode of the timeline's start (ms
|
|
1083
|
+
/** Record timecode of the timeline's start (ms; default timecode 01:00:00:00, the usual start). */
|
|
729
1084
|
recordStart?: number;
|
|
730
1085
|
/** Title line (default: the project's name). */
|
|
731
1086
|
title?: string;
|
|
1087
|
+
/** Drop-frame timecode (default on at 29.97 and 59.94 fps, where it is the norm; ignored at other rates). */
|
|
1088
|
+
dropFrame?: boolean;
|
|
732
1089
|
}
|
|
733
1090
|
/**
|
|
734
1091
|
* One track as a CMX 3600 edit decision list, for conforming in another NLE: an event per clip with
|
|
735
|
-
* source and record timecode at the project's frame rate, dissolves (`D`) for crossfades, dips and
|
|
1092
|
+
* source and record timecode at the project's frame rate (drop-frame at 29.97 and 59.94), dissolves (`D`) for crossfades, dips and
|
|
736
1093
|
* wipes (`W001`), `M2` lines for speed changes, and `* FROM CLIP NAME` comments. Titles and colour
|
|
737
1094
|
* clips become black (`BL`) events.
|
|
738
1095
|
*/
|
|
@@ -760,7 +1117,42 @@ interface VideoFfmpegOptions {
|
|
|
760
1117
|
width: number;
|
|
761
1118
|
height: number;
|
|
762
1119
|
}) => string;
|
|
1120
|
+
/** Normalise the mix's loudness with ffmpeg's `loudnorm` (EBU R128). */
|
|
1121
|
+
loudness?: VideoLoudnessTarget;
|
|
763
1122
|
}
|
|
1123
|
+
/** A loudness to normalise the mix to (`loudnorm`'s I, TP and LRA). */
|
|
1124
|
+
interface VideoLoudnessTarget {
|
|
1125
|
+
/** Integrated loudness, in LUFS (default -14, as streaming services play; -16 for podcasts, -23 for EBU R128 broadcast). */
|
|
1126
|
+
integrated?: number;
|
|
1127
|
+
/** Highest true peak, in dBTP (default -1). */
|
|
1128
|
+
truePeak?: number;
|
|
1129
|
+
/** Loudness range, in LU (default 11). */
|
|
1130
|
+
range?: number;
|
|
1131
|
+
/**
|
|
1132
|
+
* The mix as a first pass measured it (`toVideoLoudnessMeasure` then
|
|
1133
|
+
* `parseVideoLoudnessMeasurement`). With it the second pass applies one fixed gain where it can
|
|
1134
|
+
* (linear), so the dynamics are kept; without it `loudnorm` adjusts as it goes in one pass.
|
|
1135
|
+
*/
|
|
1136
|
+
measured?: VideoLoudnessMeasurement;
|
|
1137
|
+
}
|
|
1138
|
+
/** What a measuring pass found (`loudnorm`'s input_i, input_tp, input_lra, input_thresh and target_offset). */
|
|
1139
|
+
interface VideoLoudnessMeasurement {
|
|
1140
|
+
/** Integrated loudness (LUFS). */
|
|
1141
|
+
integrated: number;
|
|
1142
|
+
/** True peak (dBTP). */
|
|
1143
|
+
truePeak: number;
|
|
1144
|
+
/** Loudness range (LU). */
|
|
1145
|
+
range: number;
|
|
1146
|
+
/** Gating threshold (LUFS). */
|
|
1147
|
+
threshold: number;
|
|
1148
|
+
/** Offset for the second pass (LU). */
|
|
1149
|
+
offset: number;
|
|
1150
|
+
}
|
|
1151
|
+
/**
|
|
1152
|
+
* Reads the loudness a measuring pass printed (the JSON `loudnorm` writes to stderr at the end of
|
|
1153
|
+
* `toVideoLoudnessMeasure`'s command). Throws when there is none, or when the mix is silent.
|
|
1154
|
+
*/
|
|
1155
|
+
declare function parseVideoLoudnessMeasurement(output: string): VideoLoudnessMeasurement;
|
|
764
1156
|
interface VideoFfmpegExport {
|
|
765
1157
|
/** Arguments after `ffmpeg` (pass to `spawn('ffmpeg', args)`; no shell quoting needed). */
|
|
766
1158
|
args: string[];
|
|
@@ -782,6 +1174,13 @@ declare const ffmpegFilterValue: (s: string) => string;
|
|
|
782
1174
|
* mixed and trimmed to the project's length. Render on a server or with ffmpeg.wasm.
|
|
783
1175
|
*/
|
|
784
1176
|
declare function toVideoFfmpeg(project: VideoProject, options?: VideoFfmpegOptions): VideoFfmpegExport;
|
|
1177
|
+
/**
|
|
1178
|
+
* The first pass of a two-pass loudness normalisation: an ffmpeg command that mixes only the sound,
|
|
1179
|
+
* as `toVideoFfmpeg` would, and prints its loudness as JSON on stderr instead of writing a file.
|
|
1180
|
+
* Read it with `parseVideoLoudnessMeasurement` and pass it as `loudness.measured` to
|
|
1181
|
+
* `toVideoFfmpeg`. Throws when nothing on the timeline makes a sound.
|
|
1182
|
+
*/
|
|
1183
|
+
declare function toVideoLoudnessMeasure(project: VideoProject, options?: Pick<VideoFfmpegOptions, 'resolve' | 'loudness'>): VideoFfmpegExport;
|
|
785
1184
|
|
|
786
1185
|
/** What a preview follows: a `VideoEditorController` fits. */
|
|
787
1186
|
interface VideoPreviewSource {
|
|
@@ -826,6 +1225,11 @@ interface VideoPreviewOptions {
|
|
|
826
1225
|
context?: VideoCanvasContext | null;
|
|
827
1226
|
/** Called after each frame is drawn. */
|
|
828
1227
|
onFrame?: (frame: VideoFrame) => void;
|
|
1228
|
+
/**
|
|
1229
|
+
* Puts an SVG filter (white balance in a grade) where the canvas's `filter: url(#id)` can find
|
|
1230
|
+
* it. Default: a hidden `<svg>` added to `document.body`. `null` leaves white balance out.
|
|
1231
|
+
*/
|
|
1232
|
+
defineSvgFilter?: ((id: string, markup: string) => void) | null;
|
|
829
1233
|
}
|
|
830
1234
|
/**
|
|
831
1235
|
* Plays a project in the browser: keeps one `<video>` or `<audio>` element per playing clip in step
|
|
@@ -843,6 +1247,8 @@ declare class VideoPreviewEngine {
|
|
|
843
1247
|
private readonly unsubscribe;
|
|
844
1248
|
private scheduled;
|
|
845
1249
|
private destroyed;
|
|
1250
|
+
private filterHost;
|
|
1251
|
+
private readonly filters;
|
|
846
1252
|
constructor(source: VideoPreviewSource, canvas: {
|
|
847
1253
|
width: number;
|
|
848
1254
|
height: number;
|
|
@@ -858,6 +1264,7 @@ declare class VideoPreviewEngine {
|
|
|
858
1264
|
private redraw;
|
|
859
1265
|
private sourceFor;
|
|
860
1266
|
private draw;
|
|
1267
|
+
private readonly defineSvgFilter;
|
|
861
1268
|
/** Stops following the editor and releases every media element. */
|
|
862
1269
|
destroy(): void;
|
|
863
1270
|
}
|
|
@@ -872,6 +1279,11 @@ interface VideoEditorOptions {
|
|
|
872
1279
|
readOnly?: boolean;
|
|
873
1280
|
/** Called after every change to the project (not on playback or selection). */
|
|
874
1281
|
onChange?: (project: VideoProject) => void;
|
|
1282
|
+
/**
|
|
1283
|
+
* Where sound levels for waveforms and `get_video_audio_levels` come from: a shared cache, or a
|
|
1284
|
+
* loader for one (default: fetch and decode each asset's `src` with Web Audio, in a browser).
|
|
1285
|
+
*/
|
|
1286
|
+
audioPeaks?: VideoAudioPeaksCache | VideoAudioPeaksLoader;
|
|
875
1287
|
}
|
|
876
1288
|
/** A snapshot of the editor. The same object is returned until something changes. */
|
|
877
1289
|
interface VideoEditorState {
|
|
@@ -909,6 +1321,8 @@ interface VideoEditorState {
|
|
|
909
1321
|
declare class VideoEditorController {
|
|
910
1322
|
readonly history: HistoryManager;
|
|
911
1323
|
readonly player: AnimationPlayer;
|
|
1324
|
+
/** Sound levels per asset, loaded on demand for waveforms and agents. */
|
|
1325
|
+
readonly audioPeaks: VideoAudioPeaksCache;
|
|
912
1326
|
private project;
|
|
913
1327
|
private issues;
|
|
914
1328
|
private selection;
|
|
@@ -985,6 +1399,8 @@ declare class VideoEditorController {
|
|
|
985
1399
|
toSvg(time?: number, options?: VideoSvgOptions): string;
|
|
986
1400
|
/** The project as an ffmpeg command. */
|
|
987
1401
|
toFfmpeg(options?: VideoFfmpegOptions): VideoFfmpegExport;
|
|
1402
|
+
/** The ffmpeg command that measures the mix's loudness (see `toVideoLoudnessMeasure`). */
|
|
1403
|
+
toLoudnessMeasure(options?: Pick<VideoFfmpegOptions, 'resolve' | 'loudness'>): VideoFfmpegExport;
|
|
988
1404
|
/** One track as a CMX 3600 EDL. */
|
|
989
1405
|
toEdl(options?: VideoEdlOptions): string;
|
|
990
1406
|
}
|
|
@@ -1024,6 +1440,8 @@ declare function describeVideoProject(project: VideoProject): {
|
|
|
1024
1440
|
speed?: number;
|
|
1025
1441
|
volume?: VideoAnimatable;
|
|
1026
1442
|
muted?: boolean;
|
|
1443
|
+
fadeInCurve?: VideoFadeCurve;
|
|
1444
|
+
fadeOutCurve?: VideoFadeCurve;
|
|
1027
1445
|
id: string;
|
|
1028
1446
|
name?: string;
|
|
1029
1447
|
start: number;
|
|
@@ -1031,6 +1449,10 @@ declare function describeVideoProject(project: VideoProject): {
|
|
|
1031
1449
|
opacity?: VideoAnimatable;
|
|
1032
1450
|
transform?: VideoTransform;
|
|
1033
1451
|
fit?: VideoFit;
|
|
1452
|
+
blend?: VideoBlendMode;
|
|
1453
|
+
grade?: VideoGrade;
|
|
1454
|
+
animateIn?: VideoClipAnimation;
|
|
1455
|
+
animateOut?: VideoClipAnimation;
|
|
1034
1456
|
fadeIn?: number;
|
|
1035
1457
|
fadeOut?: number;
|
|
1036
1458
|
transition?: VideoTransition;
|
|
@@ -1054,6 +1476,10 @@ declare function describeVideoProject(project: VideoProject): {
|
|
|
1054
1476
|
opacity?: VideoAnimatable;
|
|
1055
1477
|
transform?: VideoTransform;
|
|
1056
1478
|
fit?: VideoFit;
|
|
1479
|
+
blend?: VideoBlendMode;
|
|
1480
|
+
grade?: VideoGrade;
|
|
1481
|
+
animateIn?: VideoClipAnimation;
|
|
1482
|
+
animateOut?: VideoClipAnimation;
|
|
1057
1483
|
fadeIn?: number;
|
|
1058
1484
|
fadeOut?: number;
|
|
1059
1485
|
transition?: VideoTransition;
|
|
@@ -1072,6 +1498,10 @@ declare function describeVideoProject(project: VideoProject): {
|
|
|
1072
1498
|
opacity?: VideoAnimatable;
|
|
1073
1499
|
transform?: VideoTransform;
|
|
1074
1500
|
fit?: VideoFit;
|
|
1501
|
+
blend?: VideoBlendMode;
|
|
1502
|
+
grade?: VideoGrade;
|
|
1503
|
+
animateIn?: VideoClipAnimation;
|
|
1504
|
+
animateOut?: VideoClipAnimation;
|
|
1075
1505
|
fadeIn?: number;
|
|
1076
1506
|
fadeOut?: number;
|
|
1077
1507
|
transition?: VideoTransition;
|
|
@@ -1116,6 +1546,20 @@ interface VideoRulerTick {
|
|
|
1116
1546
|
/** Ruler ticks for `[0, duration]` at `pxPerSecond`: a major tick at least every ~80 px, labelled with timecode. */
|
|
1117
1547
|
declare function videoRulerTicks(duration: number, pxPerSecond: number, fps: number): VideoRulerTick[];
|
|
1118
1548
|
/** Fill colour a timeline uses for a clip, by what it is. */
|
|
1549
|
+
/** Which clips a timeline draws waveforms in: audio files only (default), anything with sound, or none. */
|
|
1550
|
+
type VideoWaveformMode = 'audio' | 'all' | 'none';
|
|
1551
|
+
/** Whether a timeline in `mode` draws a waveform in this clip. */
|
|
1552
|
+
declare function videoClipShowsWaveform(clip: VideoClip, asset: VideoAsset | undefined, mode?: VideoWaveformMode): asset is VideoAsset;
|
|
1553
|
+
/** Names for the entrance and exit animations, for menus. */
|
|
1554
|
+
declare const VIDEO_CLIP_ANIMATION_LABELS: Readonly<Record<VideoClipAnimationEffect, string>>;
|
|
1555
|
+
/** Names for the transitions, for menus. */
|
|
1556
|
+
declare const VIDEO_TRANSITION_LABELS: Readonly<Record<VideoTransitionType, string>>;
|
|
1557
|
+
/** Whether a transition type takes a `direction`. */
|
|
1558
|
+
declare const videoTransitionHasDirection: (type: VideoTransitionType) => boolean;
|
|
1559
|
+
/** Names for the blend modes, for menus. */
|
|
1560
|
+
declare const VIDEO_BLEND_MODE_LABELS: Readonly<Record<VideoBlendMode, string>>;
|
|
1561
|
+
/** Names for the sound fade curves, for menus. */
|
|
1562
|
+
declare const VIDEO_FADE_CURVE_LABELS: Readonly<Record<VideoFadeCurve, string>>;
|
|
1119
1563
|
declare function videoClipTint(clip: VideoClip, asset?: VideoAsset): string;
|
|
1120
1564
|
/** A short label for a clip on the timeline. */
|
|
1121
1565
|
declare function videoClipLabel(clip: VideoClip, asset?: VideoAsset): string;
|
|
@@ -1211,4 +1655,4 @@ declare function videoKeyframeValueEdit(project: VideoProject, clipId: string, p
|
|
|
1211
1655
|
*/
|
|
1212
1656
|
declare function videoKeyframeToggleEdit(project: VideoProject, clipId: string, property: VideoKeyframeProperty, time: number): VideoEdit | null;
|
|
1213
1657
|
|
|
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 };
|
|
1658
|
+
export { type CreateVideoProjectOptions, type NewVideoClip, VIDEO_BLEND_MODES, VIDEO_BLEND_MODE_LABELS, VIDEO_CLIP_ANIMATION_DURATION, VIDEO_CLIP_ANIMATION_EFFECTS, VIDEO_CLIP_ANIMATION_LABELS, VIDEO_CLIP_TYPES, VIDEO_DEFAULT_STILL_DURATION, VIDEO_DEFAULT_TITLE_DURATION, VIDEO_EASE_NAMES, VIDEO_EDIT_OPS, VIDEO_FADE_CURVES, VIDEO_FADE_CURVE_LABELS, VIDEO_FITS, VIDEO_GRADE_CONTROLS, VIDEO_GRADE_PRESETS, VIDEO_GRADE_PRESET_NAMES, VIDEO_ISSUE_CODES, VIDEO_KEYFRAME_LIMITS, VIDEO_KEYFRAME_PROPERTIES, VIDEO_PEAK_BLOCK, VIDEO_PLACEMENT_MODES, VIDEO_TIME_EPSILON, VIDEO_TRANSFORM_PROPERTIES, VIDEO_TRANSITION_LABELS, VIDEO_TRANSITION_TYPES, VIDEO_WIPE_DIRECTIONS, type VideoAnimatable, type VideoAsset, type VideoAssetKind, type VideoAudioLevel, type VideoAudioPeaks, VideoAudioPeaksCache, type VideoAudioPeaksLoader, type VideoAudioSource, type VideoBlendMode, type VideoCanvasContext, type VideoClip, type VideoClipAnimation, type VideoClipAnimationEffect, 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 VideoFadeCurve, type VideoFfmpegExport, type VideoFfmpegOptions, type VideoFit, type VideoFrame, type VideoGap, type VideoGrade, type VideoGradeControl, type VideoGradePreset, type VideoGradeStep, type VideoIssue, type VideoIssueCode, type VideoIssueSeverity, type VideoKey, type VideoKeyframeProperty, type VideoKeyframeRow, type VideoKeyframes, type VideoLayer, type VideoLoudnessMeasurement, type VideoLoudnessTarget, type VideoMarker, type VideoMediaClip, type VideoMediaProbe, type VideoPlacementMode, VideoPreviewEngine, type VideoPreviewImage, type VideoPreviewMedia, type VideoPreviewOptions, type VideoPreviewSource, type VideoProject, type VideoRect, type VideoRulerTick, type VideoSilenceOptions, type VideoSnapOptions, type VideoSvgOptions, type VideoTextClip, type VideoTrack, type VideoTrackKind, type VideoTransform, type VideoTransition, type VideoTransitionType, type VideoWaveformMode, type VideoWipeDirection, allVideoClipIds, applyVideoEdits, applyVideoGrade, buildVideoAudioPeaks, checkVideoProject, createVideoEditorToolProvider, createVideoProject, decodeVideoAudioPeaks, describeVideoProject, drawVideoFrame, ffmpegFilterValue, findVideoAudioSilences, findVideoClip, findVideoGaps, formatVideoSeconds, formatVideoTimecode, formatVideoTimecodeFrames, isVideoDropFrameRate, isVideoKeyframes, nextFreeVideoSlot, normalizeVideoGrade, parseVideoAnimatable, parseVideoAsset, parseVideoClip, parseVideoClipAnimation, parseVideoGrade, parseVideoKeyframes, parseVideoLoudnessMeasurement, parseVideoMarker, parseVideoProject, parseVideoTrack, parseVideoTransform, parseVideoTransition, placeVideoRect, planVideoClipDrag, probeVideoMedia, removeVideoKey, retimeVideoAnimatable, setVideoKey, snapToVideoFrame, snapVideoTime, sortVideoKeys, sortedVideoClips, splitVideoAnimatable, toVideoEdl, toVideoFfmpeg, toVideoLoudnessMeasure, videoAssetDropEdit, videoAssetHasSound, videoAssetKindOf, videoAssetMap, videoAudioLevels, videoAudioPeakRange, videoAudioPeakSpans, videoAudioPeaksDuration, videoClipAfter, videoClipAnimated, videoClipAnimationProperties, videoClipAnimationSpans, videoClipBefore, videoClipEnd, videoClipHandles, videoClipKeyframes, videoClipLabel, videoClipOverhang, videoClipShowsWaveform, videoClipSoundGain, videoClipSourceRange, videoClipSpeed, videoClipTint, videoClipWaveform, videoClipWaveformPath, videoClipsAt, videoContactSheetSvg, videoDragLabel, videoDropTracks, videoEaseBezier, videoEaseProgress, videoFadeCurveGain, videoFrameAt, videoFrameDuration, videoFrameToSvg, videoFrames, videoGradeCssFilter, videoGradeFfmpegFilters, videoGradeGainsFilterId, videoGradePreset, videoGradeStepMatrix, videoGradeStepSvgValues, videoGradeSteps, videoGradeSvgDefs, videoGradeSvgFilter, videoHourFrames, videoIrisRadius, videoIssueKey, videoKeyframeBreakpoints, videoKeyframeFfmpegExpr, videoKeyframeRows, videoKeyframeToggleEdit, videoKeyframeValueEdit, videoKeysOf, videoOverlap, videoPeakDb, videoProjectDuration, videoProjectSvg, videoRulerTicks, videoSnapPoints, videoTextStyle, videoTimecodeFrames, videoTitleFrame, videoTrackSyncLocked, videoTransformAt, videoTransitionAudioCurve, videoTransitionEase, videoTransitionHasDirection, videoValueAt, videoWaveformPath, videoWipeRect };
|