@pixerate/editor 0.160.0 → 0.161.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 (57) hide show
  1. package/dist/{chunk-VKF3PWKR.cjs → chunk-3OSXHLIT.cjs} +259 -28
  2. package/dist/chunk-6DM3PUQD.cjs +767 -0
  3. package/dist/{chunk-IQ6KKXOU.js → chunk-YN4AYYBJ.js} +243 -12
  4. package/dist/chunk-ZGOHKS3X.js +767 -0
  5. package/dist/effects/index.cjs +16 -767
  6. package/dist/effects/index.js +5 -756
  7. package/dist/paint-editor/index.cjs +2 -2
  8. package/dist/paint-editor/index.js +1 -1
  9. package/dist/video-editor/audio.d.cts +9 -0
  10. package/dist/video-editor/audio.d.ts +9 -0
  11. package/dist/video-editor/check.d.cts +1 -1
  12. package/dist/video-editor/check.d.ts +1 -1
  13. package/dist/video-editor/controller.d.cts +47 -0
  14. package/dist/video-editor/controller.d.ts +47 -0
  15. package/dist/video-editor/dialogue-tools.d.cts +19 -0
  16. package/dist/video-editor/dialogue-tools.d.ts +19 -0
  17. package/dist/video-editor/effect-authoring.d.cts +54 -0
  18. package/dist/video-editor/effect-authoring.d.ts +54 -0
  19. package/dist/video-editor/evaluate.d.cts +11 -0
  20. package/dist/video-editor/evaluate.d.ts +11 -0
  21. package/dist/video-editor/export.d.cts +7 -1
  22. package/dist/video-editor/export.d.ts +7 -1
  23. package/dist/video-editor/index.cjs +1853 -528
  24. package/dist/video-editor/index.d.cts +7 -0
  25. package/dist/video-editor/index.d.ts +7 -0
  26. package/dist/video-editor/index.js +1512 -187
  27. package/dist/video-editor/lut.d.cts +12 -2
  28. package/dist/video-editor/lut.d.ts +12 -2
  29. package/dist/video-editor/mask.d.cts +48 -0
  30. package/dist/video-editor/mask.d.ts +48 -0
  31. package/dist/video-editor/mix.d.cts +107 -0
  32. package/dist/video-editor/mix.d.ts +107 -0
  33. package/dist/video-editor/music-tools.d.cts +19 -0
  34. package/dist/video-editor/music-tools.d.ts +19 -0
  35. package/dist/video-editor/parse.d.cts +3 -1
  36. package/dist/video-editor/parse.d.ts +3 -1
  37. package/dist/video-editor/plan.d.cts +75 -0
  38. package/dist/video-editor/plan.d.ts +75 -0
  39. package/dist/video-editor/render.d.cts +1 -1
  40. package/dist/video-editor/render.d.ts +1 -1
  41. package/dist/video-editor/timeline.d.cts +2 -0
  42. package/dist/video-editor/timeline.d.ts +2 -0
  43. package/dist/video-editor/tools.d.cts +90 -0
  44. package/dist/video-editor/tools.d.ts +90 -0
  45. package/dist/video-editor/transcript-controller.d.cts +106 -0
  46. package/dist/video-editor/transcript-controller.d.ts +106 -0
  47. package/dist/video-editor/transcript.d.cts +40 -0
  48. package/dist/video-editor/transcript.d.ts +40 -0
  49. package/dist/video-editor/types.d.cts +62 -2
  50. package/dist/video-editor/types.d.ts +62 -2
  51. package/dist/video-editor/ui.d.cts +21 -1
  52. package/dist/video-editor/ui.d.ts +21 -1
  53. package/package.json +1 -1
  54. package/skills/README.md +2 -0
  55. package/skills/pixerate-bgm-alignment/SKILL.md +82 -0
  56. package/skills/pixerate-talking-head-edit/SKILL.md +80 -0
  57. package/skills/pixerate-video-editor/SKILL.md +40 -2
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7; var _class8; var _class9; var _class10; var _class11; var _class12;
2
2
 
3
- var _chunkVKF3PWKRcjs = require('../chunk-VKF3PWKR.cjs');
3
+ var _chunk3OSXHLITcjs = require('../chunk-3OSXHLIT.cjs');
4
4
 
5
5
 
6
6
 
@@ -3155,7 +3155,7 @@ function timeLapseVideo(frameCount, width, height, fps, holdMs, name = "Time-lap
3155
3155
  }
3156
3156
  const video = { version: 1, name, width: w, height: h, fps, background: "#000000", assets, tracks: [{ id: "v1", kind: "video", clips }] };
3157
3157
  const durationMs = frameCount ? clips[clips.length - 1].start + clips[clips.length - 1].duration : 0;
3158
- return { video, ffmpeg: _chunkVKF3PWKRcjs.toVideoFfmpeg.call(void 0, video, { output: "timelapse.mp4" }), durationMs };
3158
+ return { video, ffmpeg: _chunk3OSXHLITcjs.toVideoFfmpeg.call(void 0, video, { output: "timelapse.mp4" }), durationMs };
3159
3159
  }
3160
3160
  async function buildTimeLapse(source, target, options = {}) {
3161
3161
  const maxSide = Math.max(32, Math.min(4096, Math.round(_nullishCoalesce(options.maxSide, () => ( 720)))));
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  toVideoFfmpeg
3
- } from "../chunk-IQ6KKXOU.js";
3
+ } from "../chunk-YN4AYYBJ.js";
4
4
  import {
5
5
  deserializeLayers,
6
6
  exportPsd,
@@ -15,6 +15,15 @@ export interface VideoAudioPeaks {
15
15
  blockSize: number;
16
16
  /** `levels[k]` is `[min, max, min, max, …]`, one pair per block of `blockSize × 4^k` samples. */
17
17
  levels: Float32Array[];
18
+ /**
19
+ * Loudness as ITU-R BS.1770 measures it: the K-weighted mean square of the channels, summed,
20
+ * per `hop` ms of audio (100 ms). `videoAudioLoudness` gates it into LUFS for any stretch.
21
+ * Absent from peaks built before it existed; `buildVideoAudioPeaks` always adds it.
22
+ */
23
+ loudness?: {
24
+ hop: number;
25
+ energy: Float32Array;
26
+ };
18
27
  }
19
28
  /** Samples per level-0 block (well under a millisecond at common rates). */
20
29
  export declare const VIDEO_PEAK_BLOCK = 32;
@@ -15,6 +15,15 @@ export interface VideoAudioPeaks {
15
15
  blockSize: number;
16
16
  /** `levels[k]` is `[min, max, min, max, …]`, one pair per block of `blockSize × 4^k` samples. */
17
17
  levels: Float32Array[];
18
+ /**
19
+ * Loudness as ITU-R BS.1770 measures it: the K-weighted mean square of the channels, summed,
20
+ * per `hop` ms of audio (100 ms). `videoAudioLoudness` gates it into LUFS for any stretch.
21
+ * Absent from peaks built before it existed; `buildVideoAudioPeaks` always adds it.
22
+ */
23
+ loudness?: {
24
+ hop: number;
25
+ energy: Float32Array;
26
+ };
18
27
  }
19
28
  /** Samples per level-0 block (well under a millisecond at common rates). */
20
29
  export declare const VIDEO_PEAK_BLOCK = 32;
@@ -6,7 +6,7 @@ export declare function videoClipKeyframes(clip: VideoClip): {
6
6
  keys: ReturnType<typeof videoKeysOf>;
7
7
  }[];
8
8
  export type VideoIssueSeverity = 'error' | 'warning' | 'note';
9
- export declare const VIDEO_ISSUE_CODES: readonly ["missing-asset", "missing-sequence", "sequence-cycle", "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", "unused-sequence", "marker-past-end", "empty"];
9
+ export declare const VIDEO_ISSUE_CODES: readonly ["missing-asset", "missing-sequence", "sequence-cycle", "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", "unused-sequence", "marker-past-end", "missing-target-track", "empty"];
10
10
  export type VideoIssueCode = (typeof VIDEO_ISSUE_CODES)[number];
11
11
  export interface VideoIssue {
12
12
  code: VideoIssueCode;
@@ -6,7 +6,7 @@ export declare function videoClipKeyframes(clip: VideoClip): {
6
6
  keys: ReturnType<typeof videoKeysOf>;
7
7
  }[];
8
8
  export type VideoIssueSeverity = 'error' | 'warning' | 'note';
9
- export declare const VIDEO_ISSUE_CODES: readonly ["missing-asset", "missing-sequence", "sequence-cycle", "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", "unused-sequence", "marker-past-end", "empty"];
9
+ export declare const VIDEO_ISSUE_CODES: readonly ["missing-asset", "missing-sequence", "sequence-cycle", "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", "unused-sequence", "marker-past-end", "missing-target-track", "empty"];
10
10
  export type VideoIssueCode = (typeof VIDEO_ISSUE_CODES)[number];
11
11
  export interface VideoIssue {
12
12
  code: VideoIssueCode;
@@ -17,6 +17,7 @@ import { EffectsSlot } from '../effects/helpers.cjs';
17
17
  import type { EffectDescription, EffectProvider, EffectValue } from '../effects/types.cjs';
18
18
  import { VideoEffectsEngine, type VideoEffectPlace } from './effects.cjs';
19
19
  import { type VideoAnimatable, type VideoKey } from './keyframes.cjs';
20
+ import { type VideoEditPlan, type VideoEditPlanInput } from './plan.cjs';
20
21
  export interface VideoEditorOptions {
21
22
  /** The project to open (default: an empty 1920 × 1080, 30 fps project with tracks v1 and a1). */
22
23
  project?: VideoProject;
@@ -83,9 +84,20 @@ export interface VideoEditorState {
83
84
  previewScale: VideoPreviewScale;
84
85
  /** The registered effects provider, or `null` (effects are then drawn as placeholders and cannot be added). */
85
86
  effectsProvider: EffectProvider | null;
87
+ /** Proposed edit plans waiting for review, oldest first (see `proposePlan`). Not part of the project or its undo history. */
88
+ plans: readonly VideoEditPlan[];
86
89
  /** Bumped on every change. */
87
90
  revision: number;
88
91
  }
92
+ /** What `applyPlan` returns: the edit result, the plan applied and whether the project had changed since it was made. */
93
+ export type VideoPlanApplyResult = (VideoEditResult & {
94
+ ok: true;
95
+ plan: VideoEditPlan;
96
+ stale: boolean;
97
+ }) | {
98
+ ok: false;
99
+ error: string;
100
+ };
89
101
  /**
90
102
  * Headless non-linear video editor: a `VideoProject` of assets and tracks of clips, edited with
91
103
  * undoable, all-or-nothing edits (insert, ripple, trim, split, move, transitions), played on an
@@ -121,6 +133,10 @@ export declare class VideoEditorController {
121
133
  private readonly listeners;
122
134
  private readonly unsubscribers;
123
135
  private state;
136
+ private plans;
137
+ /** The project each open plan was worked out against. */
138
+ private readonly planBasis;
139
+ private planCount;
124
140
  constructor(options?: VideoEditorOptions);
125
141
  private connect;
126
142
  /** Pauses and stops listening to the player and history. Subscribing again reconnects (React StrictMode). */
@@ -145,6 +161,37 @@ export declare class VideoEditorController {
145
161
  dryRun?: boolean;
146
162
  merge?: string;
147
163
  }): VideoEditResult;
164
+ /** Most plans kept open at once; proposing another drops the oldest. */
165
+ static readonly MAX_PLANS = 20;
166
+ /**
167
+ * Works out a batch of edits without applying it and keeps it for review (see `VideoEditPlan`):
168
+ * the result says what it would do. Allowed while read-only (nothing changes); applying is not.
169
+ * A plan with the id of an open one replaces it.
170
+ */
171
+ proposePlan(input: VideoEditPlanInput): {
172
+ ok: true;
173
+ plan: VideoEditPlan;
174
+ } | {
175
+ ok: false;
176
+ error: string;
177
+ };
178
+ /** An open plan, or `undefined`. */
179
+ getPlan(id: string): VideoEditPlan | undefined;
180
+ /** Whether the project changed since a plan was made (its summary may then be out of date). */
181
+ isPlanStale(id: string): boolean;
182
+ /** The project as an open plan would leave it, worked out against the current project; `null` when it no longer applies. */
183
+ planPreview(id: string): VideoProject | null;
184
+ /**
185
+ * Applies an open plan as one undo step labelled with its title and closes it. If the project
186
+ * changed since it was made, its edits are checked again against the project as it is now and
187
+ * refused (the plan stays open) when they no longer apply.
188
+ */
189
+ applyPlan(id: string): VideoPlanApplyResult;
190
+ /** Closes an open plan without applying it. False when there is no such plan. */
191
+ discardPlan(id: string): boolean;
192
+ /** Closes every open plan. */
193
+ discardPlans(): void;
194
+ private dropPlan;
148
195
  /** Opens a project (JSON or object). `clearHistory` drops the undo stack (opening a file); otherwise it is one undo step. */
149
196
  load(project: VideoProject | string, options?: {
150
197
  clearHistory?: boolean;
@@ -17,6 +17,7 @@ import { EffectsSlot } from '../effects/helpers.js';
17
17
  import type { EffectDescription, EffectProvider, EffectValue } from '../effects/types.js';
18
18
  import { VideoEffectsEngine, type VideoEffectPlace } from './effects.js';
19
19
  import { type VideoAnimatable, type VideoKey } from './keyframes.js';
20
+ import { type VideoEditPlan, type VideoEditPlanInput } from './plan.js';
20
21
  export interface VideoEditorOptions {
21
22
  /** The project to open (default: an empty 1920 × 1080, 30 fps project with tracks v1 and a1). */
22
23
  project?: VideoProject;
@@ -83,9 +84,20 @@ export interface VideoEditorState {
83
84
  previewScale: VideoPreviewScale;
84
85
  /** The registered effects provider, or `null` (effects are then drawn as placeholders and cannot be added). */
85
86
  effectsProvider: EffectProvider | null;
87
+ /** Proposed edit plans waiting for review, oldest first (see `proposePlan`). Not part of the project or its undo history. */
88
+ plans: readonly VideoEditPlan[];
86
89
  /** Bumped on every change. */
87
90
  revision: number;
88
91
  }
92
+ /** What `applyPlan` returns: the edit result, the plan applied and whether the project had changed since it was made. */
93
+ export type VideoPlanApplyResult = (VideoEditResult & {
94
+ ok: true;
95
+ plan: VideoEditPlan;
96
+ stale: boolean;
97
+ }) | {
98
+ ok: false;
99
+ error: string;
100
+ };
89
101
  /**
90
102
  * Headless non-linear video editor: a `VideoProject` of assets and tracks of clips, edited with
91
103
  * undoable, all-or-nothing edits (insert, ripple, trim, split, move, transitions), played on an
@@ -121,6 +133,10 @@ export declare class VideoEditorController {
121
133
  private readonly listeners;
122
134
  private readonly unsubscribers;
123
135
  private state;
136
+ private plans;
137
+ /** The project each open plan was worked out against. */
138
+ private readonly planBasis;
139
+ private planCount;
124
140
  constructor(options?: VideoEditorOptions);
125
141
  private connect;
126
142
  /** Pauses and stops listening to the player and history. Subscribing again reconnects (React StrictMode). */
@@ -145,6 +161,37 @@ export declare class VideoEditorController {
145
161
  dryRun?: boolean;
146
162
  merge?: string;
147
163
  }): VideoEditResult;
164
+ /** Most plans kept open at once; proposing another drops the oldest. */
165
+ static readonly MAX_PLANS = 20;
166
+ /**
167
+ * Works out a batch of edits without applying it and keeps it for review (see `VideoEditPlan`):
168
+ * the result says what it would do. Allowed while read-only (nothing changes); applying is not.
169
+ * A plan with the id of an open one replaces it.
170
+ */
171
+ proposePlan(input: VideoEditPlanInput): {
172
+ ok: true;
173
+ plan: VideoEditPlan;
174
+ } | {
175
+ ok: false;
176
+ error: string;
177
+ };
178
+ /** An open plan, or `undefined`. */
179
+ getPlan(id: string): VideoEditPlan | undefined;
180
+ /** Whether the project changed since a plan was made (its summary may then be out of date). */
181
+ isPlanStale(id: string): boolean;
182
+ /** The project as an open plan would leave it, worked out against the current project; `null` when it no longer applies. */
183
+ planPreview(id: string): VideoProject | null;
184
+ /**
185
+ * Applies an open plan as one undo step labelled with its title and closes it. If the project
186
+ * changed since it was made, its edits are checked again against the project as it is now and
187
+ * refused (the plan stays open) when they no longer apply.
188
+ */
189
+ applyPlan(id: string): VideoPlanApplyResult;
190
+ /** Closes an open plan without applying it. False when there is no such plan. */
191
+ discardPlan(id: string): boolean;
192
+ /** Closes every open plan. */
193
+ discardPlans(): void;
194
+ private dropPlan;
148
195
  /** Opens a project (JSON or object). `clearHistory` drops the undo stack (opening a file); otherwise it is one undo step. */
149
196
  load(project: VideoProject | string, options?: {
150
197
  clearHistory?: boolean;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Agent tools for talking-head cleanup: find fillers, long pauses and stutters in one pass, and
3
+ * propose cutting them as one plan for review (plan first, then `apply_video_edit_plan`). Skill:
4
+ * `pixerate-talking-head-edit`.
5
+ */
6
+ import type { AgentToolProvider } from '../tools/registry.cjs';
7
+ import type { VideoEditorController } from './controller.cjs';
8
+ export interface VideoDialogueToolProviderOptions {
9
+ /** Provider id (unique per registry). Default `video-dialogue`. */
10
+ id?: string;
11
+ /** Tool-name prefix (`<namespace>__<name>`); defaults to the provider id, `''` for bare names. */
12
+ namespace?: string;
13
+ /** The project cannot be edited: the planning tool is hidden. A string is the reason. */
14
+ readOnly?: boolean | string | (() => boolean | string);
15
+ /** The agent playback surface its calls are acted out on (default `video`). */
16
+ playbackSurface?: string;
17
+ }
18
+ /** The talking-head cleanup tools for a video editor (see the module comment). */
19
+ export declare function createVideoDialogueToolProvider(controller: VideoEditorController, options?: VideoDialogueToolProviderOptions): AgentToolProvider;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Agent tools for talking-head cleanup: find fillers, long pauses and stutters in one pass, and
3
+ * propose cutting them as one plan for review (plan first, then `apply_video_edit_plan`). Skill:
4
+ * `pixerate-talking-head-edit`.
5
+ */
6
+ import type { AgentToolProvider } from '../tools/registry.js';
7
+ import type { VideoEditorController } from './controller.js';
8
+ export interface VideoDialogueToolProviderOptions {
9
+ /** Provider id (unique per registry). Default `video-dialogue`. */
10
+ id?: string;
11
+ /** Tool-name prefix (`<namespace>__<name>`); defaults to the provider id, `''` for bare names. */
12
+ namespace?: string;
13
+ /** The project cannot be edited: the planning tool is hidden. A string is the reason. */
14
+ readOnly?: boolean | string | (() => boolean | string);
15
+ /** The agent playback surface its calls are acted out on (default `video`). */
16
+ playbackSurface?: string;
17
+ }
18
+ /** The talking-head cleanup tools for a video editor (see the module comment). */
19
+ export declare function createVideoDialogueToolProvider(controller: VideoEditorController, options?: VideoDialogueToolProviderOptions): AgentToolProvider;
@@ -0,0 +1,54 @@
1
+ import { type AnimationEasing } from '../animation/easing.cjs';
2
+ import { type GenericAuthoringOptions } from '../effects/authoring-session.cjs';
3
+ import type { EffectAuthoringDocument, EffectAuthoringSession } from '../effects/authoring.cjs';
4
+ import type { EffectValue } from '../effects/types.cjs';
5
+ import type { VideoEditorController, VideoEffectEditResult } from './controller.cjs';
6
+ import { type VideoEase, type VideoKeyframes } from './keyframes.cjs';
7
+ import type { VideoClip, VideoClipEffect } from './types.cjs';
8
+ /**
9
+ * One keyframe model for clip effects and the effect authoring editor: a clip effect's values
10
+ * (plain values, or `{ keys }` in clip ms) open as an `EffectAuthoringDocument` (values and
11
+ * keyframe tracks in ms from the effect's start, which is the clip's start), are tuned and
12
+ * keyframed in an `EffectAuthoringSession` / `<EffectAuthoringEditor>`, and are written back to the
13
+ * clip as one undo step. Adjustment clips use this to tune the effects they apply to the pictures
14
+ * beneath them.
15
+ */
16
+ /** A video ease as an animation easing (they share CSS cubic-bezier semantics). */
17
+ export declare function videoEaseToAnimationEasing(ease: VideoEase | undefined): AnimationEasing;
18
+ /**
19
+ * An animation easing as a video ease, or `null` when video keyframes cannot hold it (springs,
20
+ * elastics): those segments are sampled into several keys instead (see `videoEffectValuesFromDocument`).
21
+ */
22
+ export declare function animationEasingToVideoEase(easing: AnimationEasing | undefined): VideoEase | null;
23
+ /** A clip effect as an authoring document (values, keyframe tracks, the clip's length as the timeline). */
24
+ export declare function videoClipEffectDocument(clip: VideoClip, instance: string, providerId: string): EffectAuthoringDocument;
25
+ /**
26
+ * An authoring document's values and tracks as clip effect values: numeric tracks become `{ keys }`
27
+ * (springs and elastics sampled into several keys), other tracks keep their value at the start
28
+ * (video keyframes are numbers only). `notes` says what was sampled or dropped.
29
+ */
30
+ export declare function videoEffectValuesFromDocument(doc: Pick<EffectAuthoringDocument, 'values' | 'tracks'>): {
31
+ values: Record<string, EffectValue | VideoKeyframes>;
32
+ notes: string[];
33
+ };
34
+ /** An effect authoring session opened on a clip effect, and the way to write it back. */
35
+ export interface VideoClipEffectAuthoring {
36
+ readonly clip: string;
37
+ readonly instance: string;
38
+ readonly session: EffectAuthoringSession;
39
+ /** Writes the session's values and keyframes back to the clip effect as one undo step. */
40
+ commit(): Promise<VideoEffectEditResult & {
41
+ notes?: string[];
42
+ }>;
43
+ /** Closes the session without writing back. */
44
+ dispose(): void;
45
+ }
46
+ /**
47
+ * Opens a clip's effect (on any clip, adjustment clips included) in an `EffectAuthoringSession`
48
+ * using the editor's effects provider, with the clip's length as the timeline and its keyframes as
49
+ * tracks, so `<EffectAuthoringEditor>` can tune and keyframe it. Nothing changes on the clip until
50
+ * `commit`. Rejects with a readable error for an unknown clip or effect, or without a provider.
51
+ */
52
+ export declare function openVideoClipEffectAuthoring(controller: VideoEditorController, clip: string, instance: string, options?: Omit<GenericAuthoringOptions, 'provider'>): Promise<VideoClipEffectAuthoring>;
53
+ /** The effects of a clip a host can open for authoring (enabled or not). */
54
+ export declare const videoAuthorableEffects: (clip: VideoClip) => readonly VideoClipEffect[];
@@ -0,0 +1,54 @@
1
+ import { type AnimationEasing } from '../animation/easing.js';
2
+ import { type GenericAuthoringOptions } from '../effects/authoring-session.js';
3
+ import type { EffectAuthoringDocument, EffectAuthoringSession } from '../effects/authoring.js';
4
+ import type { EffectValue } from '../effects/types.js';
5
+ import type { VideoEditorController, VideoEffectEditResult } from './controller.js';
6
+ import { type VideoEase, type VideoKeyframes } from './keyframes.js';
7
+ import type { VideoClip, VideoClipEffect } from './types.js';
8
+ /**
9
+ * One keyframe model for clip effects and the effect authoring editor: a clip effect's values
10
+ * (plain values, or `{ keys }` in clip ms) open as an `EffectAuthoringDocument` (values and
11
+ * keyframe tracks in ms from the effect's start, which is the clip's start), are tuned and
12
+ * keyframed in an `EffectAuthoringSession` / `<EffectAuthoringEditor>`, and are written back to the
13
+ * clip as one undo step. Adjustment clips use this to tune the effects they apply to the pictures
14
+ * beneath them.
15
+ */
16
+ /** A video ease as an animation easing (they share CSS cubic-bezier semantics). */
17
+ export declare function videoEaseToAnimationEasing(ease: VideoEase | undefined): AnimationEasing;
18
+ /**
19
+ * An animation easing as a video ease, or `null` when video keyframes cannot hold it (springs,
20
+ * elastics): those segments are sampled into several keys instead (see `videoEffectValuesFromDocument`).
21
+ */
22
+ export declare function animationEasingToVideoEase(easing: AnimationEasing | undefined): VideoEase | null;
23
+ /** A clip effect as an authoring document (values, keyframe tracks, the clip's length as the timeline). */
24
+ export declare function videoClipEffectDocument(clip: VideoClip, instance: string, providerId: string): EffectAuthoringDocument;
25
+ /**
26
+ * An authoring document's values and tracks as clip effect values: numeric tracks become `{ keys }`
27
+ * (springs and elastics sampled into several keys), other tracks keep their value at the start
28
+ * (video keyframes are numbers only). `notes` says what was sampled or dropped.
29
+ */
30
+ export declare function videoEffectValuesFromDocument(doc: Pick<EffectAuthoringDocument, 'values' | 'tracks'>): {
31
+ values: Record<string, EffectValue | VideoKeyframes>;
32
+ notes: string[];
33
+ };
34
+ /** An effect authoring session opened on a clip effect, and the way to write it back. */
35
+ export interface VideoClipEffectAuthoring {
36
+ readonly clip: string;
37
+ readonly instance: string;
38
+ readonly session: EffectAuthoringSession;
39
+ /** Writes the session's values and keyframes back to the clip effect as one undo step. */
40
+ commit(): Promise<VideoEffectEditResult & {
41
+ notes?: string[];
42
+ }>;
43
+ /** Closes the session without writing back. */
44
+ dispose(): void;
45
+ }
46
+ /**
47
+ * Opens a clip's effect (on any clip, adjustment clips included) in an `EffectAuthoringSession`
48
+ * using the editor's effects provider, with the clip's length as the timeline and its keyframes as
49
+ * tracks, so `<EffectAuthoringEditor>` can tune and keyframe it. Nothing changes on the clip until
50
+ * `commit`. Rejects with a readable error for an unknown clip or effect, or without a provider.
51
+ */
52
+ export declare function openVideoClipEffectAuthoring(controller: VideoEditorController, clip: string, instance: string, options?: Omit<GenericAuthoringOptions, 'provider'>): Promise<VideoClipEffectAuthoring>;
53
+ /** The effects of a clip a host can open for authoring (enabled or not). */
54
+ export declare const videoAuthorableEffects: (clip: VideoClip) => readonly VideoClipEffect[];
@@ -1,3 +1,4 @@
1
+ import { type VideoLayerMask } from './mask.cjs';
1
2
  import type { EffectValue } from '../effects/types.cjs';
2
3
  import type { VideoEffectValues } from './types.cjs';
3
4
  import type { VideoAsset, VideoBlendMode, VideoGrade, VideoClip, VideoFadeCurve, VideoFit, VideoProject, VideoTextClip, VideoWipeDirection } from './types.cjs';
@@ -65,6 +66,16 @@ export interface VideoLayer {
65
66
  grade?: VideoGrade;
66
67
  /** The clip's enabled provider effects, in order, with values at this moment (see `VideoClipEffect`). */
67
68
  effects?: VideoLayerEffect[];
69
+ /** The clip's mask, resolved to an outline in frame pixels (before `rotation`): only what it keeps shows. */
70
+ mask?: VideoLayerMask;
71
+ /**
72
+ * For an adjustment clip: the scope it changed (`layers` holds the pictures it changed, drawn as
73
+ * one picture like a compound's, which its grade, effects and mask then apply to).
74
+ */
75
+ adjustment?: {
76
+ scope: 'underneath' | 'all' | 'track';
77
+ track?: string;
78
+ };
68
79
  /** For an effect clip: the provider effect drawing the picture, at `time` ms into the clip. */
69
80
  generator?: {
70
81
  effect: string;
@@ -1,3 +1,4 @@
1
+ import { type VideoLayerMask } from './mask.js';
1
2
  import type { EffectValue } from '../effects/types.js';
2
3
  import type { VideoEffectValues } from './types.js';
3
4
  import type { VideoAsset, VideoBlendMode, VideoGrade, VideoClip, VideoFadeCurve, VideoFit, VideoProject, VideoTextClip, VideoWipeDirection } from './types.js';
@@ -65,6 +66,16 @@ export interface VideoLayer {
65
66
  grade?: VideoGrade;
66
67
  /** The clip's enabled provider effects, in order, with values at this moment (see `VideoClipEffect`). */
67
68
  effects?: VideoLayerEffect[];
69
+ /** The clip's mask, resolved to an outline in frame pixels (before `rotation`): only what it keeps shows. */
70
+ mask?: VideoLayerMask;
71
+ /**
72
+ * For an adjustment clip: the scope it changed (`layers` holds the pictures it changed, drawn as
73
+ * one picture like a compound's, which its grade, effects and mask then apply to).
74
+ */
75
+ adjustment?: {
76
+ scope: 'underneath' | 'all' | 'track';
77
+ track?: string;
78
+ };
68
79
  /** For an effect clip: the provider effect drawing the picture, at `time` ms into the clip. */
69
80
  generator?: {
70
81
  effect: string;
@@ -14,7 +14,7 @@ export interface VideoEdlOptions {
14
14
  * One track as a CMX 3600 edit decision list, for conforming in another NLE: an event per clip with
15
15
  * source and record timecode at the project's frame rate (drop-frame at 29.97 and 59.94), dissolves (`D`) for crossfades, dips and
16
16
  * wipes (`W001`), `M2` lines for speed changes, and `* FROM CLIP NAME` comments. Titles, colour
17
- * clips and compound clips (not flattened yet) become black (`BL`) events.
17
+ * clips and compound clips (not flattened yet) become black (`BL`) events; adjustment clips are left out.
18
18
  */
19
19
  export declare function toVideoEdl(project: VideoProject, options?: VideoEdlOptions): string;
20
20
  export interface VideoFfmpegOptions {
@@ -59,6 +59,12 @@ export interface VideoFfmpegOptions {
59
59
  }
60
60
  /** The provider effects in a project's video tracks that ffmpeg's filters cannot draw. */
61
61
  export declare function videoFfmpegUnsupportedEffects(project: VideoProject): VideoEffectUse[];
62
+ /**
63
+ * What ffmpeg's filters cannot draw besides provider effects: clip masks, and adjustment clips
64
+ * other than a plain grade (and LUT at full strength) over what is underneath or the whole frame
65
+ * at full opacity. Each is one sentence naming the clip. Exports refuse them unless given `frames`.
66
+ */
67
+ export declare function videoFfmpegUnsupportedFeatures(project: VideoProject): string[];
62
68
  /** A loudness to normalise the mix to (`loudnorm`'s I, TP and LRA). */
63
69
  export interface VideoLoudnessTarget {
64
70
  /** Integrated loudness, in LUFS (default -14, as streaming services play; -16 for podcasts, -23 for EBU R128 broadcast). */
@@ -14,7 +14,7 @@ export interface VideoEdlOptions {
14
14
  * One track as a CMX 3600 edit decision list, for conforming in another NLE: an event per clip with
15
15
  * source and record timecode at the project's frame rate (drop-frame at 29.97 and 59.94), dissolves (`D`) for crossfades, dips and
16
16
  * wipes (`W001`), `M2` lines for speed changes, and `* FROM CLIP NAME` comments. Titles, colour
17
- * clips and compound clips (not flattened yet) become black (`BL`) events.
17
+ * clips and compound clips (not flattened yet) become black (`BL`) events; adjustment clips are left out.
18
18
  */
19
19
  export declare function toVideoEdl(project: VideoProject, options?: VideoEdlOptions): string;
20
20
  export interface VideoFfmpegOptions {
@@ -59,6 +59,12 @@ export interface VideoFfmpegOptions {
59
59
  }
60
60
  /** The provider effects in a project's video tracks that ffmpeg's filters cannot draw. */
61
61
  export declare function videoFfmpegUnsupportedEffects(project: VideoProject): VideoEffectUse[];
62
+ /**
63
+ * What ffmpeg's filters cannot draw besides provider effects: clip masks, and adjustment clips
64
+ * other than a plain grade (and LUT at full strength) over what is underneath or the whole frame
65
+ * at full opacity. Each is one sentence naming the clip. Exports refuse them unless given `frames`.
66
+ */
67
+ export declare function videoFfmpegUnsupportedFeatures(project: VideoProject): string[];
62
68
  /** A loudness to normalise the mix to (`loudnorm`'s I, TP and LRA). */
63
69
  export interface VideoLoudnessTarget {
64
70
  /** Integrated loudness, in LUFS (default -14, as streaming services play; -16 for podcasts, -23 for EBU R128 broadcast). */