@pixerate/editor 0.81.0 → 0.83.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.
Files changed (67) hide show
  1. package/dist/agent/index.cjs +36 -7
  2. package/dist/agent/index.cjs.map +1 -1
  3. package/dist/agent/index.d.cts +5 -3
  4. package/dist/agent/index.d.ts +5 -3
  5. package/dist/agent/index.js +43 -14
  6. package/dist/agent/index.js.map +1 -1
  7. package/dist/animation-editor/index.d.cts +1 -1
  8. package/dist/animation-editor/index.d.ts +1 -1
  9. package/dist/bridge/index.d.cts +3 -3
  10. package/dist/bridge/index.d.ts +3 -3
  11. package/dist/{bridge-client-C5dRjrz5.d.ts → bridge-client-CMGfnjTl.d.ts} +1 -1
  12. package/dist/{bridge-client-C5OziCRK.d.cts → bridge-client-VpnICVxP.d.cts} +1 -1
  13. package/dist/canvas/index.cjs +235 -104
  14. package/dist/canvas/index.cjs.map +1 -1
  15. package/dist/canvas/index.d.cts +59 -1
  16. package/dist/canvas/index.d.ts +59 -1
  17. package/dist/canvas/index.js +234 -103
  18. package/dist/canvas/index.js.map +1 -1
  19. package/dist/capture-DFEMFmVt.d.cts +133 -0
  20. package/dist/capture-wwNGaW05.d.ts +133 -0
  21. package/dist/chart/index.d.cts +1 -1
  22. package/dist/chart/index.d.ts +1 -1
  23. package/dist/{chunk-K73CKYUM.cjs → chunk-EI2MOVQ3.cjs} +198 -3
  24. package/dist/chunk-EI2MOVQ3.cjs.map +1 -0
  25. package/dist/chunk-FURT6ZFZ.cjs +1 -0
  26. package/dist/chunk-FURT6ZFZ.cjs.map +1 -0
  27. package/dist/{chunk-GPWNYQ7R.js → chunk-O2W2SP3C.js} +197 -2
  28. package/dist/chunk-O2W2SP3C.js.map +1 -0
  29. package/dist/chunk-REOJJIY3.js +201 -0
  30. package/dist/chunk-REOJJIY3.js.map +1 -0
  31. package/dist/chunk-RJ2BFKEN.js +1 -0
  32. package/dist/chunk-RJ2BFKEN.js.map +1 -0
  33. package/dist/chunk-VJUVNERT.cjs +201 -0
  34. package/dist/chunk-VJUVNERT.cjs.map +1 -0
  35. package/dist/commands/index.d.cts +1 -1
  36. package/dist/commands/index.d.ts +1 -1
  37. package/dist/diagram/index.d.cts +1 -1
  38. package/dist/diagram/index.d.ts +1 -1
  39. package/dist/dom-capture-7Wvf6Tyg.d.ts +59 -0
  40. package/dist/dom-capture-GyYuE-zq.d.cts +59 -0
  41. package/dist/generation/index.d.cts +2 -2
  42. package/dist/generation/index.d.ts +2 -2
  43. package/dist/image-editor/index.cjs +97 -1
  44. package/dist/image-editor/index.cjs.map +1 -1
  45. package/dist/image-editor/index.d.cts +24 -2
  46. package/dist/image-editor/index.d.ts +24 -2
  47. package/dist/image-editor/index.js +96 -0
  48. package/dist/image-editor/index.js.map +1 -1
  49. package/dist/{registry-DIpIaCkH.d.cts → registry-BqA1AZt0.d.cts} +1 -1
  50. package/dist/{registry-7AZFuand.d.ts → registry-D-4fit9C.d.ts} +1 -1
  51. package/dist/tools/index.cjs +33 -4
  52. package/dist/tools/index.cjs.map +1 -1
  53. package/dist/tools/index.d.cts +4 -2
  54. package/dist/tools/index.d.ts +4 -2
  55. package/dist/tools/index.js +43 -14
  56. package/dist/video-editor/index.cjs +557 -99
  57. package/dist/video-editor/index.cjs.map +1 -1
  58. package/dist/video-editor/index.d.cts +211 -6
  59. package/dist/video-editor/index.d.ts +211 -6
  60. package/dist/video-editor/index.js +493 -35
  61. package/dist/video-editor/index.js.map +1 -1
  62. package/package.json +1 -1
  63. package/skills/pixerate-canvas/SKILL.md +1 -0
  64. package/skills/pixerate-image-editor/SKILL.md +1 -0
  65. package/skills/pixerate-video-editor/SKILL.md +24 -6
  66. package/dist/chunk-GPWNYQ7R.js.map +0 -1
  67. package/dist/chunk-K73CKYUM.cjs.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import { c as AnimationPlayer, C as Clock, b as AnimationLoopMode } from '../player-DrcP2xqj.cjs';
2
2
  import { H as HistoryManager } from '../HistoryManager-DeQQMBCj.cjs';
3
- import { A as AgentToolProvider } from '../registry-DIpIaCkH.cjs';
3
+ import { a as AgentToolProvider } from '../registry-BqA1AZt0.cjs';
4
4
  import '../easing-lM0Xo9Ni.cjs';
5
5
  import '../types-DsiXGmjo.cjs';
6
6
  import '../schema-Di0CS6Pe.cjs';
@@ -179,6 +179,17 @@ interface VideoClipBase {
179
179
  /** Transition from the clip before (see `VideoTransition`). */
180
180
  transition?: VideoTransition;
181
181
  }
182
+ /**
183
+ * The shape of a sound fade, the same curves ffmpeg's `afade` draws, so previews and exports agree.
184
+ * With `x` running 0→1 through a fade in (1→0 through a fade out), the gain is:
185
+ * - `linear`: x (ffmpeg `tri`). Dips in loudness in the middle of a crossfade.
186
+ * - `equal-power`: sin(x·π/2) (`qsin`). Keeps loudness steady; the usual choice for crossfades.
187
+ * - `s-curve`: (1 − cos(x·π))/2 (`hsin`). Gentle at both ends.
188
+ * - `exponential`: x³ (`cub`). Slow start; a natural-sounding fade in from silence.
189
+ * - `logarithmic`: 1 − (1 − x)² (`ipar`). Fast start, slow finish.
190
+ */
191
+ type VideoFadeCurve = 'linear' | 'equal-power' | 's-curve' | 'exponential' | 'logarithmic';
192
+ declare const VIDEO_FADE_CURVES: readonly ["linear", "equal-power", "s-curve", "exponential", "logarithmic"];
182
193
  /** A stretch of an asset. */
183
194
  interface VideoMediaClip extends VideoClipBase {
184
195
  type: 'media';
@@ -191,6 +202,10 @@ interface VideoMediaClip extends VideoClipBase {
191
202
  volume?: VideoAnimatable;
192
203
  /** Silences this clip. */
193
204
  muted?: boolean;
205
+ /** Shape of the sound's fade in (default linear). The picture always fades linearly. */
206
+ fadeInCurve?: VideoFadeCurve;
207
+ /** Shape of the sound's fade out (default linear). */
208
+ fadeOutCurve?: VideoFadeCurve;
194
209
  }
195
210
  /** A title. */
196
211
  interface VideoTextClip extends VideoClipBase {
@@ -302,10 +317,28 @@ declare const videoFrameDuration: (fps: number) => number;
302
317
  declare function snapToVideoFrame(time: number, fps: number): number;
303
318
  /** Whole frames in `time` at `fps` (rounded). */
304
319
  declare const videoFrames: (time: number, fps: number) => number;
305
- /** Non-drop SMPTE timecode `HH:MM:SS:FF` for a time (ms). */
306
- declare function formatVideoTimecode(time: number, fps: number): string;
320
+ /**
321
+ * Whether `fps` is an NTSC rate that SMPTE counts in drop-frame timecode: 29.97 (30000/1001) or
322
+ * 59.94 (60000/1001). Other fractional rates (23.976) have no drop-frame form.
323
+ */
324
+ declare function isVideoDropFrameRate(fps: number): boolean;
325
+ /** Frames elapsed in `time` (ms), counted at the exact rate behind a rounded NTSC rate. */
326
+ declare const videoTimecodeFrames: (time: number, fps: number) => number;
327
+ /**
328
+ * SMPTE timecode for a time (ms): `HH:MM:SS:FF`, or `HH:MM:SS;FF` in drop-frame, which skips frame
329
+ * numbers 0 and 1 (0–3 at 59.94) at the start of every minute except each tenth, so the clock keeps
330
+ * up with real time at NTSC rates. `dropFrame` defaults to on at 29.97 and 59.94 and is ignored at
331
+ * rates without a drop-frame form.
332
+ */
333
+ declare function formatVideoTimecode(time: number, fps: number, dropFrame?: boolean): string;
334
+ /** SMPTE timecode for a frame count (see `formatVideoTimecode`). */
335
+ declare function formatVideoTimecodeFrames(frames: number, fps: number, dropFrame?: boolean): string;
336
+ /** Frames up to timecode `01:00:00:00` (`;00` in drop-frame), where record timecode usually starts. */
337
+ declare const videoHourFrames: (fps: number, dropFrame?: boolean) => number;
307
338
  /** Readable time for messages: `2.50 s`. */
308
339
  declare const formatVideoSeconds: (time: number) => string;
340
+ /** Whether an asset carries sound: audio, or video not marked `hasAudio: false`. */
341
+ declare const videoAssetHasSound: (asset: VideoAsset | undefined) => boolean;
309
342
  declare function videoAssetMap(project: VideoProject): Map<string, VideoAsset>;
310
343
  /** A track's clips in timeline order. */
311
344
  declare function sortedVideoClips(track: VideoTrack): VideoClip[];
@@ -677,6 +710,13 @@ declare function videoTextStyle(clip: VideoTextClip): NonNullable<VideoLayer['te
677
710
  * transforms without them, and moves the image itself).
678
711
  */
679
712
  declare function videoTitleFrame(project: VideoProject, clip: VideoTextClip, clipTime?: number): VideoFrame;
713
+ /** 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. */
714
+ declare function videoFadeCurveGain(curve: VideoFadeCurve | undefined, x: number): number;
715
+ /**
716
+ * A media clip's own gain at clip time `clipTime` (ms): its volume (or volume keyframes) times its
717
+ * shaped fades. Leaves out track volume and transitions, which depend on the timeline around it.
718
+ */
719
+ declare function videoClipSoundGain(clip: VideoClip, clipTime: number): number;
680
720
  /**
681
721
  * What plays at `time` (ms): the pictures to draw, back to front, with their placement, opacity
682
722
  * and the moment of source each shows, and the sounds with their gain. A pure function of the
@@ -684,6 +724,110 @@ declare function videoTitleFrame(project: VideoProject, clip: VideoTextClip, cli
684
724
  */
685
725
  declare function videoFrameAt(project: VideoProject, time: number): VideoFrame;
686
726
 
727
+ /**
728
+ * Sound levels of a piece of audio, small enough to keep for every asset: a pyramid of min / max
729
+ * sample values. Level 0 holds one min / max pair per `blockSize` samples; each level above merges
730
+ * four blocks of the one below, so the min / max of any stretch costs a handful of reads at any
731
+ * zoom. Channels are folded together (the loudest of them counts). Plain data: hosts can compute
732
+ * it once (`buildVideoAudioPeaks`) and store it.
733
+ */
734
+ interface VideoAudioPeaks {
735
+ /** Samples per second of the decoded audio. */
736
+ sampleRate: number;
737
+ /** Samples in the audio (per channel). */
738
+ length: number;
739
+ /** Samples per level-0 block. */
740
+ blockSize: number;
741
+ /** `levels[k]` is `[min, max, min, max, …]`, one pair per block of `blockSize × 4^k` samples. */
742
+ levels: Float32Array[];
743
+ }
744
+ /** Samples per level-0 block (well under a millisecond at common rates). */
745
+ declare const VIDEO_PEAK_BLOCK = 32;
746
+ /** Builds the peak pyramid for decoded audio (one `Float32Array` of samples per channel). */
747
+ declare function buildVideoAudioPeaks(channels: readonly Float32Array[], sampleRate: number, blockSize?: number): VideoAudioPeaks;
748
+ /** Length of the audio (ms). */
749
+ declare const videoAudioPeaksDuration: (peaks: VideoAudioPeaks) => number;
750
+ /**
751
+ * The lowest and highest sample between two times (ms) in the audio, to the nearest block (so a
752
+ * stretch can read up to a block wider). `{ min: 0, max: 0 }` outside the audio.
753
+ */
754
+ declare function videoAudioPeakRange(peaks: VideoAudioPeaks, from: number, to: number): {
755
+ min: number;
756
+ max: number;
757
+ };
758
+ /** `columns` min / max pairs (`[min, max, …]`) evenly across `from`..`to` ms, e.g. one per pixel. */
759
+ declare function videoAudioPeakSpans(peaks: VideoAudioPeaks, from: number, to: number, columns: number): Float32Array;
760
+ /**
761
+ * What a media clip plays as `columns` min / max pairs across its length: each column reads the
762
+ * stretch of source under it (through the in point and speed) and is scaled by the clip's volume and
763
+ * fades, so the waveform shows what is heard.
764
+ */
765
+ declare function videoClipWaveform(clip: VideoMediaClip, peaks: VideoAudioPeaks, columns: number): Float32Array;
766
+ /**
767
+ * An SVG path (`d`) of a waveform filling `width` × `height`: the top edge along the maxima, back
768
+ * along the minima. Values are clamped to ±1, so anything louder than full scale touches the edge.
769
+ */
770
+ declare function videoWaveformPath(spans: Float32Array, width: number, height: number): string;
771
+ /**
772
+ * The SVG path of a media clip's waveform drawn `width` × `height` pixels (one column per 2 px), as
773
+ * `videoClipWaveform` reads it: what timelines draw inside an audio clip.
774
+ */
775
+ declare function videoClipWaveformPath(clip: VideoMediaClip, peaks: VideoAudioPeaks, width: number, height: number): string;
776
+ /** A sample value as dBFS, floored at -100 (silence). */
777
+ declare const videoPeakDb: (value: number) => number;
778
+ interface VideoAudioLevel {
779
+ /** Start of the bucket (ms, in the clock the caller asked in). */
780
+ start: number;
781
+ end: number;
782
+ /** Peak level in dBFS (0 = full scale, -100 = silence). */
783
+ peakDb: number;
784
+ }
785
+ /** Peak level in `buckets` equal stretches of `from`..`to` ms of the audio. */
786
+ declare function videoAudioLevels(peaks: VideoAudioPeaks, from: number, to: number, buckets: number): VideoAudioLevel[];
787
+ interface VideoSilenceOptions {
788
+ /** Quieter than this peak level counts as silence (dBFS, default -40). */
789
+ thresholdDb?: number;
790
+ /** Shortest silence to report (ms, default 300). */
791
+ minDuration?: number;
792
+ /** Resolution of the scan (ms, default 10). */
793
+ resolution?: number;
794
+ }
795
+ /** Stretches of `from`..`to` ms of the audio that stay below a level, at least `minDuration` long. */
796
+ declare function findVideoAudioSilences(peaks: VideoAudioPeaks, from: number, to: number, options?: VideoSilenceOptions): {
797
+ start: number;
798
+ end: number;
799
+ }[];
800
+ /** Fetches and decodes a media file's sound into peaks, in a browser (Web Audio). */
801
+ declare function decodeVideoAudioPeaks(src: string, options?: {
802
+ signal?: AbortSignal;
803
+ }): Promise<VideoAudioPeaks>;
804
+ /** Loads the peaks of an asset's sound. */
805
+ type VideoAudioPeaksLoader = (asset: VideoAsset) => Promise<VideoAudioPeaks>;
806
+ /**
807
+ * Peaks per asset, loaded once each (by `src`) and shared by the timeline and agent tools.
808
+ * `get` returns what is ready and starts loading the rest; `subscribe` hears when more is ready.
809
+ */
810
+ declare class VideoAudioPeaksCache {
811
+ private readonly loader;
812
+ private readonly ready;
813
+ private readonly pending;
814
+ private readonly failed;
815
+ private readonly listeners;
816
+ constructor(loader?: VideoAudioPeaksLoader);
817
+ /** The peaks if ready, without starting to load them. */
818
+ peek(asset: VideoAsset): VideoAudioPeaks | undefined;
819
+ /** The peaks if ready; otherwise `undefined`, and loading starts (once) unless it failed. */
820
+ get(asset: VideoAsset): VideoAudioPeaks | undefined;
821
+ /** Why loading an asset's peaks failed, if it did. */
822
+ error(asset: VideoAsset): string | undefined;
823
+ /** The peaks, loading them if needed. Rejects with a readable error. */
824
+ load(asset: VideoAsset): Promise<VideoAudioPeaks>;
825
+ /** Uses peaks the host already has (computed earlier or stored). */
826
+ set(src: string, peaks: VideoAudioPeaks): void;
827
+ subscribe(fn: () => void): () => void;
828
+ private emit;
829
+ }
830
+
687
831
  /** The part of a rect a wipe shows. */
688
832
  declare function videoWipeRect(rect: VideoRect, wipe: NonNullable<VideoLayer['wipe']>): VideoRect;
689
833
  interface VideoSvgOptions {
@@ -725,14 +869,16 @@ declare function drawVideoFrame(ctx: VideoCanvasContext, frame: VideoFrame, sour
725
869
  interface VideoEdlOptions {
726
870
  /** Track to export (default: the bottom video track, V1 in most NLEs). */
727
871
  track?: string;
728
- /** Record timecode of the timeline's start (ms, default 1 hour, the usual 01:00:00:00). */
872
+ /** Record timecode of the timeline's start (ms; default timecode 01:00:00:00, the usual start). */
729
873
  recordStart?: number;
730
874
  /** Title line (default: the project's name). */
731
875
  title?: string;
876
+ /** Drop-frame timecode (default on at 29.97 and 59.94 fps, where it is the norm; ignored at other rates). */
877
+ dropFrame?: boolean;
732
878
  }
733
879
  /**
734
880
  * 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
881
+ * 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
882
  * wipes (`W001`), `M2` lines for speed changes, and `* FROM CLIP NAME` comments. Titles and colour
737
883
  * clips become black (`BL`) events.
738
884
  */
@@ -760,7 +906,42 @@ interface VideoFfmpegOptions {
760
906
  width: number;
761
907
  height: number;
762
908
  }) => string;
909
+ /** Normalise the mix's loudness with ffmpeg's `loudnorm` (EBU R128). */
910
+ loudness?: VideoLoudnessTarget;
763
911
  }
912
+ /** A loudness to normalise the mix to (`loudnorm`'s I, TP and LRA). */
913
+ interface VideoLoudnessTarget {
914
+ /** Integrated loudness, in LUFS (default -14, as streaming services play; -16 for podcasts, -23 for EBU R128 broadcast). */
915
+ integrated?: number;
916
+ /** Highest true peak, in dBTP (default -1). */
917
+ truePeak?: number;
918
+ /** Loudness range, in LU (default 11). */
919
+ range?: number;
920
+ /**
921
+ * The mix as a first pass measured it (`toVideoLoudnessMeasure` then
922
+ * `parseVideoLoudnessMeasurement`). With it the second pass applies one fixed gain where it can
923
+ * (linear), so the dynamics are kept; without it `loudnorm` adjusts as it goes in one pass.
924
+ */
925
+ measured?: VideoLoudnessMeasurement;
926
+ }
927
+ /** What a measuring pass found (`loudnorm`'s input_i, input_tp, input_lra, input_thresh and target_offset). */
928
+ interface VideoLoudnessMeasurement {
929
+ /** Integrated loudness (LUFS). */
930
+ integrated: number;
931
+ /** True peak (dBTP). */
932
+ truePeak: number;
933
+ /** Loudness range (LU). */
934
+ range: number;
935
+ /** Gating threshold (LUFS). */
936
+ threshold: number;
937
+ /** Offset for the second pass (LU). */
938
+ offset: number;
939
+ }
940
+ /**
941
+ * Reads the loudness a measuring pass printed (the JSON `loudnorm` writes to stderr at the end of
942
+ * `toVideoLoudnessMeasure`'s command). Throws when there is none, or when the mix is silent.
943
+ */
944
+ declare function parseVideoLoudnessMeasurement(output: string): VideoLoudnessMeasurement;
764
945
  interface VideoFfmpegExport {
765
946
  /** Arguments after `ffmpeg` (pass to `spawn('ffmpeg', args)`; no shell quoting needed). */
766
947
  args: string[];
@@ -782,6 +963,13 @@ declare const ffmpegFilterValue: (s: string) => string;
782
963
  * mixed and trimmed to the project's length. Render on a server or with ffmpeg.wasm.
783
964
  */
784
965
  declare function toVideoFfmpeg(project: VideoProject, options?: VideoFfmpegOptions): VideoFfmpegExport;
966
+ /**
967
+ * The first pass of a two-pass loudness normalisation: an ffmpeg command that mixes only the sound,
968
+ * as `toVideoFfmpeg` would, and prints its loudness as JSON on stderr instead of writing a file.
969
+ * Read it with `parseVideoLoudnessMeasurement` and pass it as `loudness.measured` to
970
+ * `toVideoFfmpeg`. Throws when nothing on the timeline makes a sound.
971
+ */
972
+ declare function toVideoLoudnessMeasure(project: VideoProject, options?: Pick<VideoFfmpegOptions, 'resolve' | 'loudness'>): VideoFfmpegExport;
785
973
 
786
974
  /** What a preview follows: a `VideoEditorController` fits. */
787
975
  interface VideoPreviewSource {
@@ -872,6 +1060,11 @@ interface VideoEditorOptions {
872
1060
  readOnly?: boolean;
873
1061
  /** Called after every change to the project (not on playback or selection). */
874
1062
  onChange?: (project: VideoProject) => void;
1063
+ /**
1064
+ * Where sound levels for waveforms and `get_video_audio_levels` come from: a shared cache, or a
1065
+ * loader for one (default: fetch and decode each asset's `src` with Web Audio, in a browser).
1066
+ */
1067
+ audioPeaks?: VideoAudioPeaksCache | VideoAudioPeaksLoader;
875
1068
  }
876
1069
  /** A snapshot of the editor. The same object is returned until something changes. */
877
1070
  interface VideoEditorState {
@@ -909,6 +1102,8 @@ interface VideoEditorState {
909
1102
  declare class VideoEditorController {
910
1103
  readonly history: HistoryManager;
911
1104
  readonly player: AnimationPlayer;
1105
+ /** Sound levels per asset, loaded on demand for waveforms and agents. */
1106
+ readonly audioPeaks: VideoAudioPeaksCache;
912
1107
  private project;
913
1108
  private issues;
914
1109
  private selection;
@@ -985,6 +1180,8 @@ declare class VideoEditorController {
985
1180
  toSvg(time?: number, options?: VideoSvgOptions): string;
986
1181
  /** The project as an ffmpeg command. */
987
1182
  toFfmpeg(options?: VideoFfmpegOptions): VideoFfmpegExport;
1183
+ /** The ffmpeg command that measures the mix's loudness (see `toVideoLoudnessMeasure`). */
1184
+ toLoudnessMeasure(options?: Pick<VideoFfmpegOptions, 'resolve' | 'loudness'>): VideoFfmpegExport;
988
1185
  /** One track as a CMX 3600 EDL. */
989
1186
  toEdl(options?: VideoEdlOptions): string;
990
1187
  }
@@ -1024,6 +1221,8 @@ declare function describeVideoProject(project: VideoProject): {
1024
1221
  speed?: number;
1025
1222
  volume?: VideoAnimatable;
1026
1223
  muted?: boolean;
1224
+ fadeInCurve?: VideoFadeCurve;
1225
+ fadeOutCurve?: VideoFadeCurve;
1027
1226
  id: string;
1028
1227
  name?: string;
1029
1228
  start: number;
@@ -1116,6 +1315,12 @@ interface VideoRulerTick {
1116
1315
  /** Ruler ticks for `[0, duration]` at `pxPerSecond`: a major tick at least every ~80 px, labelled with timecode. */
1117
1316
  declare function videoRulerTicks(duration: number, pxPerSecond: number, fps: number): VideoRulerTick[];
1118
1317
  /** Fill colour a timeline uses for a clip, by what it is. */
1318
+ /** Which clips a timeline draws waveforms in: audio files only (default), anything with sound, or none. */
1319
+ type VideoWaveformMode = 'audio' | 'all' | 'none';
1320
+ /** Whether a timeline in `mode` draws a waveform in this clip. */
1321
+ declare function videoClipShowsWaveform(clip: VideoClip, asset: VideoAsset | undefined, mode?: VideoWaveformMode): asset is VideoAsset;
1322
+ /** Names for the sound fade curves, for menus. */
1323
+ declare const VIDEO_FADE_CURVE_LABELS: Readonly<Record<VideoFadeCurve, string>>;
1119
1324
  declare function videoClipTint(clip: VideoClip, asset?: VideoAsset): string;
1120
1325
  /** A short label for a clip on the timeline. */
1121
1326
  declare function videoClipLabel(clip: VideoClip, asset?: VideoAsset): string;
@@ -1211,4 +1416,4 @@ declare function videoKeyframeValueEdit(project: VideoProject, clipId: string, p
1211
1416
  */
1212
1417
  declare function videoKeyframeToggleEdit(project: VideoProject, clipId: string, property: VideoKeyframeProperty, time: number): VideoEdit | null;
1213
1418
 
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 };
1419
+ export { type CreateVideoProjectOptions, type NewVideoClip, 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_ISSUE_CODES, VIDEO_KEYFRAME_LIMITS, VIDEO_KEYFRAME_PROPERTIES, VIDEO_PEAK_BLOCK, VIDEO_PLACEMENT_MODES, VIDEO_TIME_EPSILON, VIDEO_TRANSFORM_PROPERTIES, VIDEO_TRANSITION_TYPES, VIDEO_WIPE_DIRECTIONS, type VideoAnimatable, type VideoAsset, type VideoAssetKind, type VideoAudioLevel, type VideoAudioPeaks, VideoAudioPeaksCache, type VideoAudioPeaksLoader, 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 VideoFadeCurve, 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 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, buildVideoAudioPeaks, checkVideoProject, createVideoEditorToolProvider, createVideoProject, decodeVideoAudioPeaks, describeVideoProject, drawVideoFrame, ffmpegFilterValue, findVideoAudioSilences, findVideoClip, findVideoGaps, formatVideoSeconds, formatVideoTimecode, formatVideoTimecodeFrames, isVideoDropFrameRate, isVideoKeyframes, nextFreeVideoSlot, parseVideoAnimatable, parseVideoAsset, parseVideoClip, 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, videoClipBefore, videoClipEnd, videoClipHandles, videoClipKeyframes, videoClipLabel, videoClipOverhang, videoClipShowsWaveform, videoClipSoundGain, videoClipSourceRange, videoClipSpeed, videoClipTint, videoClipWaveform, videoClipWaveformPath, videoClipsAt, videoContactSheetSvg, videoDragLabel, videoDropTracks, videoEaseBezier, videoEaseProgress, videoFadeCurveGain, videoFrameAt, videoFrameDuration, videoFrameToSvg, videoFrames, videoHourFrames, videoIssueKey, videoKeyframeBreakpoints, videoKeyframeFfmpegExpr, videoKeyframeRows, videoKeyframeToggleEdit, videoKeyframeValueEdit, videoKeysOf, videoOverlap, videoPeakDb, videoProjectDuration, videoProjectSvg, videoRulerTicks, videoSnapPoints, videoTextStyle, videoTimecodeFrames, videoTitleFrame, videoTrackSyncLocked, videoTransformAt, videoValueAt, videoWaveformPath, videoWipeRect };