@pixerate/editor 0.230.0 → 0.231.1
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/{chunk-A57ZQDNN.cjs → chunk-5T3H7CGG.cjs} +14 -4
- package/dist/{chunk-ONNNNGNS.js → chunk-CSM5T6SE.js} +13 -3
- package/dist/image-editor/controller.d.cts +12 -0
- package/dist/image-editor/controller.d.ts +12 -0
- package/dist/image-editor/index.cjs +176 -131
- package/dist/image-editor/index.js +47 -2
- package/dist/paint-editor/index.cjs +2 -2
- package/dist/paint-editor/index.js +1 -1
- package/dist/video-editor/camera-tools.d.cts +10 -0
- package/dist/video-editor/camera-tools.d.ts +10 -0
- package/dist/video-editor/camera.d.cts +47 -0
- package/dist/video-editor/camera.d.ts +47 -0
- package/dist/video-editor/check.d.cts +1 -1
- package/dist/video-editor/check.d.ts +1 -1
- package/dist/video-editor/controller.d.cts +37 -2
- package/dist/video-editor/controller.d.ts +37 -2
- package/dist/video-editor/effect-tools.d.cts +2 -1
- package/dist/video-editor/effect-tools.d.ts +2 -1
- package/dist/video-editor/index.cjs +690 -375
- package/dist/video-editor/index.d.cts +2 -0
- package/dist/video-editor/index.d.ts +2 -0
- package/dist/video-editor/index.js +331 -16
- package/dist/video-editor/keyframes.d.cts +10 -3
- package/dist/video-editor/keyframes.d.ts +10 -3
- package/dist/video-editor/parse.d.cts +5 -3
- package/dist/video-editor/parse.d.ts +5 -3
- package/dist/video-editor/tools.d.cts +18 -0
- package/dist/video-editor/tools.d.ts +18 -0
- package/dist/video-editor/types.d.cts +37 -1
- package/dist/video-editor/types.d.ts +37 -1
- package/package.json +1 -1
|
@@ -7141,6 +7141,50 @@ var ImageEditorController = class {
|
|
|
7141
7141
|
const enc = encodeSurface(surface);
|
|
7142
7142
|
return enc ? enc.url : null;
|
|
7143
7143
|
}
|
|
7144
|
+
maskedImageCache = /* @__PURE__ */ new WeakMap();
|
|
7145
|
+
/**
|
|
7146
|
+
* A pixel layer's own pixels with its raster and vector masks applied, cropped to what shows: a
|
|
7147
|
+
* PNG data URL and its document bounds, or `null` for an unknown or non-pixel layer, or when
|
|
7148
|
+
* nothing shows. Opacity, blending, filters and effects are left out, as in `getLayerDataURL`.
|
|
7149
|
+
* Use it for a masked layer, whose stored pixels (a whole copy, for Separate Subject's subject)
|
|
7150
|
+
* are not what it shows.
|
|
7151
|
+
*/
|
|
7152
|
+
getMaskedLayerImage(id) {
|
|
7153
|
+
const layer = this.getLayer(id);
|
|
7154
|
+
if (!layer || layer.type !== "pixel") return null;
|
|
7155
|
+
const surface = this.surfaceOf(layer);
|
|
7156
|
+
const cached = this.maskedImageCache.get(layer);
|
|
7157
|
+
if (cached && cached.surface === surface) return cached.image;
|
|
7158
|
+
const b = this.getLayerBounds(id);
|
|
7159
|
+
let image = null;
|
|
7160
|
+
if (b) {
|
|
7161
|
+
const content = { ...layer, visible: true, opacity: 1, blend: "normal" };
|
|
7162
|
+
delete content.clipped;
|
|
7163
|
+
delete content.fillOpacity;
|
|
7164
|
+
delete content.effects;
|
|
7165
|
+
delete content.filters;
|
|
7166
|
+
const data = this.compositor.composite([content], b, this.compositorSources());
|
|
7167
|
+
let x0 = b.width, y0 = b.height, x1 = -1, y1 = -1;
|
|
7168
|
+
for (let y = 0; y < b.height; y++) {
|
|
7169
|
+
for (let x = 0; x < b.width; x++) {
|
|
7170
|
+
if (!data[(y * b.width + x) * 4 + 3]) continue;
|
|
7171
|
+
if (x < x0) x0 = x;
|
|
7172
|
+
if (x > x1) x1 = x;
|
|
7173
|
+
if (y < y0) y0 = y;
|
|
7174
|
+
if (y > y1) y1 = y;
|
|
7175
|
+
}
|
|
7176
|
+
}
|
|
7177
|
+
if (x1 >= 0) {
|
|
7178
|
+
const w = x1 - x0 + 1;
|
|
7179
|
+
const h = y1 - y0 + 1;
|
|
7180
|
+
const out = new Uint8ClampedArray(w * h * 4);
|
|
7181
|
+
for (let y = 0; y < h; y++) out.set(data.subarray(((y0 + y) * b.width + x0) * 4, ((y0 + y) * b.width + x0 + w) * 4), y * w * 4);
|
|
7182
|
+
image = { url: pngDataUrl(w, h, out, 4), bounds: { x: b.x + x0, y: b.y + y0, width: w, height: h } };
|
|
7183
|
+
}
|
|
7184
|
+
}
|
|
7185
|
+
this.maskedImageCache.set(layer, { surface, image });
|
|
7186
|
+
return image;
|
|
7187
|
+
}
|
|
7144
7188
|
/**
|
|
7145
7189
|
* Composites the layer stack in document space without a canvas (annotation layers need one
|
|
7146
7190
|
* and are left out): `rect` (default: the canvas) as RGBA, straight alpha. Crop, rotation and
|
|
@@ -20820,7 +20864,8 @@ function extractNormalizedLayerItems(controller, fallbackImageUrl = "") {
|
|
|
20820
20864
|
const imgW = state.imageDimensions?.width || 1;
|
|
20821
20865
|
const imgH = state.imageDimensions?.height || 1;
|
|
20822
20866
|
return ctrlLayers.map((l) => {
|
|
20823
|
-
const
|
|
20867
|
+
const masked = l.type === "pixel" && (l.mask || l.vectorMask) ? controller.getMaskedLayerImage(l.id) : null;
|
|
20868
|
+
const bounds = masked?.bounds || controller.getLayerBounds(l.id) || {
|
|
20824
20869
|
x: 0,
|
|
20825
20870
|
y: 0,
|
|
20826
20871
|
width: imgW,
|
|
@@ -20828,7 +20873,7 @@ function extractNormalizedLayerItems(controller, fallbackImageUrl = "") {
|
|
|
20828
20873
|
};
|
|
20829
20874
|
const sLayer = sLayerMap.get(l.id);
|
|
20830
20875
|
const assetKey = sLayer?.asset;
|
|
20831
|
-
const layerDataUrl = assetKey && assets[assetKey] || assets[l.id] || (sLayer?.source === "document" ? fallbackImageUrl : "");
|
|
20876
|
+
const layerDataUrl = masked?.url || assetKey && assets[assetKey] || assets[l.id] || (sLayer?.source === "document" ? fallbackImageUrl : "");
|
|
20832
20877
|
return {
|
|
20833
20878
|
id: l.id,
|
|
20834
20879
|
name: l.name || "Untitled Layer",
|
|
@@ -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
|
|
3
|
+
var _chunk5T3H7CGGcjs = require('../chunk-5T3H7CGG.cjs');
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
@@ -3213,7 +3213,7 @@ function timeLapseVideo(frameCount, width, height, fps, holdMs, name = "Time-lap
|
|
|
3213
3213
|
}
|
|
3214
3214
|
const video = { version: 1, name, width: w, height: h, fps, background: "#000000", assets, tracks: [{ id: "v1", kind: "video", clips }] };
|
|
3215
3215
|
const durationMs = frameCount ? clips[clips.length - 1].start + clips[clips.length - 1].duration : 0;
|
|
3216
|
-
return { video, ffmpeg:
|
|
3216
|
+
return { video, ffmpeg: _chunk5T3H7CGGcjs.toVideoFfmpeg.call(void 0, video, { output: "timelapse.mp4" }), durationMs };
|
|
3217
3217
|
}
|
|
3218
3218
|
async function buildTimeLapse(source, target, options = {}) {
|
|
3219
3219
|
const maxSide = Math.max(32, Math.min(4096, Math.round(_nullishCoalesce(options.maxSide, () => ( 720)))));
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent tools for provider camera moves on video clips (see `VideoClipCamera`): list the moves
|
|
3
|
+
* by role, set one on a clip (baked into its transform keys) and clear it. They ride on the video
|
|
4
|
+
* effects tool provider (`createVideoEffectsToolProvider`).
|
|
5
|
+
*/
|
|
6
|
+
import type { EffectToolContext } from '../effects/tools.cjs';
|
|
7
|
+
import type { AgentTool } from '../tools/registry.cjs';
|
|
8
|
+
import type { VideoEditorController } from './controller.cjs';
|
|
9
|
+
/** The video camera move tools (see the module comment). */
|
|
10
|
+
export declare function videoCameraMoveTools(controller: VideoEditorController, ctx: EffectToolContext): AgentTool[];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent tools for provider camera moves on video clips (see `VideoClipCamera`): list the moves
|
|
3
|
+
* by role, set one on a clip (baked into its transform keys) and clear it. They ride on the video
|
|
4
|
+
* effects tool provider (`createVideoEffectsToolProvider`).
|
|
5
|
+
*/
|
|
6
|
+
import type { EffectToolContext } from '../effects/tools.js';
|
|
7
|
+
import type { AgentTool } from '../tools/registry.js';
|
|
8
|
+
import type { VideoEditorController } from './controller.js';
|
|
9
|
+
/** The video camera move tools (see the module comment). */
|
|
10
|
+
export declare function videoCameraMoveTools(controller: VideoEditorController, ctx: EffectToolContext): AgentTool[];
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider camera moves on video clips (see `VideoClipCamera` and `@pixerate/editor/effects`).
|
|
3
|
+
* A clip is the shot: a `transition` move (`in`) moves the camera from `from` to `framing` from
|
|
4
|
+
* the clip's start, and a `hold` move (`during`) plays across the rest of the clip. The moves are
|
|
5
|
+
* baked into the clip's x, y, scale and rotation keys with `sampleEffectCameraMove` at the
|
|
6
|
+
* project's frame rate, keeping a cut's two keys (a jump), so nothing downstream needs the
|
|
7
|
+
* provider. The camera looks at the clip's picture as its own transform places it.
|
|
8
|
+
*/
|
|
9
|
+
import type { CameraMoveRole, CameraMoveSpec, CameraStage, CameraView, EffectProvider } from '../effects/types.cjs';
|
|
10
|
+
import type { VideoCameraFraming, VideoClip, VideoClipCamera, VideoProject, VideoTransform } from './types.cjs';
|
|
11
|
+
/** The view that shows `framing` of a `stage`-sized frame (see `VideoCameraFraming`). */
|
|
12
|
+
export declare function videoCameraView(framing: VideoCameraFraming | undefined, stage: CameraStage): CameraView;
|
|
13
|
+
/**
|
|
14
|
+
* The clip transform that shows `view` of a picture placed by `base`: the picture's centre goes
|
|
15
|
+
* where the camera puts it (turned by the view's roll round the frame's centre), its scale times
|
|
16
|
+
* the zoom, its rotation plus the roll. Tilt, turn and blur have no place in a clip transform.
|
|
17
|
+
*/
|
|
18
|
+
export declare function videoTransformOfView(view: CameraView, base: VideoClipCamera['base'], stage: CameraStage): Required<VideoClipCamera['base']>;
|
|
19
|
+
/** What baking a clip's camera moves gave: its transform with the keys, and notes on what could not be kept. */
|
|
20
|
+
export interface VideoCameraBake {
|
|
21
|
+
transform: VideoTransform;
|
|
22
|
+
/** Ms from the clip's start of each move's cut, when it has one. */
|
|
23
|
+
cuts: number[];
|
|
24
|
+
/** When each move plays (clip ms). */
|
|
25
|
+
windows: {
|
|
26
|
+
in?: {
|
|
27
|
+
start: number;
|
|
28
|
+
end: number;
|
|
29
|
+
};
|
|
30
|
+
during?: {
|
|
31
|
+
start: number;
|
|
32
|
+
end: number;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
notes: string[];
|
|
36
|
+
}
|
|
37
|
+
/** The clip's transform as plain numbers, for a camera's `base` (refusing keyed fields, which a camera would replace). */
|
|
38
|
+
export declare function videoCameraBase(clip: VideoClip): VideoClipCamera['base'];
|
|
39
|
+
/**
|
|
40
|
+
* Bakes a clip's camera moves (its `camera`) into transform keys at the project's frame rate:
|
|
41
|
+
* `in` from the clip's start over its `ms` (default the move's `durationMs`), then `during`
|
|
42
|
+
* across the rest of the clip. Keys are linear, one per frame, with both keys of a cut kept.
|
|
43
|
+
* Async: the provider samples the moves (`sampleEffectCameraMove`).
|
|
44
|
+
*/
|
|
45
|
+
export declare function bakeVideoClipCamera(clip: VideoClip, camera: VideoClipCamera, project: Pick<VideoProject, 'width' | 'height' | 'fps'>, provider: EffectProvider): Promise<VideoCameraBake>;
|
|
46
|
+
/** A clip's camera move for a role as its parts, or undefined. */
|
|
47
|
+
export declare function videoClipCameraMove(clip: Pick<VideoClip, 'camera'> | undefined, role: CameraMoveRole): Exclude<CameraMoveSpec, string> | undefined;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider camera moves on video clips (see `VideoClipCamera` and `@pixerate/editor/effects`).
|
|
3
|
+
* A clip is the shot: a `transition` move (`in`) moves the camera from `from` to `framing` from
|
|
4
|
+
* the clip's start, and a `hold` move (`during`) plays across the rest of the clip. The moves are
|
|
5
|
+
* baked into the clip's x, y, scale and rotation keys with `sampleEffectCameraMove` at the
|
|
6
|
+
* project's frame rate, keeping a cut's two keys (a jump), so nothing downstream needs the
|
|
7
|
+
* provider. The camera looks at the clip's picture as its own transform places it.
|
|
8
|
+
*/
|
|
9
|
+
import type { CameraMoveRole, CameraMoveSpec, CameraStage, CameraView, EffectProvider } from '../effects/types.js';
|
|
10
|
+
import type { VideoCameraFraming, VideoClip, VideoClipCamera, VideoProject, VideoTransform } from './types.js';
|
|
11
|
+
/** The view that shows `framing` of a `stage`-sized frame (see `VideoCameraFraming`). */
|
|
12
|
+
export declare function videoCameraView(framing: VideoCameraFraming | undefined, stage: CameraStage): CameraView;
|
|
13
|
+
/**
|
|
14
|
+
* The clip transform that shows `view` of a picture placed by `base`: the picture's centre goes
|
|
15
|
+
* where the camera puts it (turned by the view's roll round the frame's centre), its scale times
|
|
16
|
+
* the zoom, its rotation plus the roll. Tilt, turn and blur have no place in a clip transform.
|
|
17
|
+
*/
|
|
18
|
+
export declare function videoTransformOfView(view: CameraView, base: VideoClipCamera['base'], stage: CameraStage): Required<VideoClipCamera['base']>;
|
|
19
|
+
/** What baking a clip's camera moves gave: its transform with the keys, and notes on what could not be kept. */
|
|
20
|
+
export interface VideoCameraBake {
|
|
21
|
+
transform: VideoTransform;
|
|
22
|
+
/** Ms from the clip's start of each move's cut, when it has one. */
|
|
23
|
+
cuts: number[];
|
|
24
|
+
/** When each move plays (clip ms). */
|
|
25
|
+
windows: {
|
|
26
|
+
in?: {
|
|
27
|
+
start: number;
|
|
28
|
+
end: number;
|
|
29
|
+
};
|
|
30
|
+
during?: {
|
|
31
|
+
start: number;
|
|
32
|
+
end: number;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
notes: string[];
|
|
36
|
+
}
|
|
37
|
+
/** The clip's transform as plain numbers, for a camera's `base` (refusing keyed fields, which a camera would replace). */
|
|
38
|
+
export declare function videoCameraBase(clip: VideoClip): VideoClipCamera['base'];
|
|
39
|
+
/**
|
|
40
|
+
* Bakes a clip's camera moves (its `camera`) into transform keys at the project's frame rate:
|
|
41
|
+
* `in` from the clip's start over its `ms` (default the move's `durationMs`), then `during`
|
|
42
|
+
* across the rest of the clip. Keys are linear, one per frame, with both keys of a cut kept.
|
|
43
|
+
* Async: the provider samples the moves (`sampleEffectCameraMove`).
|
|
44
|
+
*/
|
|
45
|
+
export declare function bakeVideoClipCamera(clip: VideoClip, camera: VideoClipCamera, project: Pick<VideoProject, 'width' | 'height' | 'fps'>, provider: EffectProvider): Promise<VideoCameraBake>;
|
|
46
|
+
/** A clip's camera move for a role as its parts, or undefined. */
|
|
47
|
+
export declare function videoClipCameraMove(clip: Pick<VideoClip, 'camera'> | undefined, role: CameraMoveRole): Exclude<CameraMoveSpec, string> | undefined;
|
|
@@ -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", "missing-target-track", "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", "camera-stale", "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", "missing-target-track", "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", "camera-stale", "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;
|
|
@@ -12,9 +12,10 @@ import { VideoPreviewPixels } from './scopes.cjs';
|
|
|
12
12
|
import type { VideoPreviewScale } from './proxy.cjs';
|
|
13
13
|
import type { VideoFrameCache } from './frame-cache.cjs';
|
|
14
14
|
import { type VideoSvgOptions } from './render.cjs';
|
|
15
|
-
import type { VideoClipEffect, VideoEffectValues, VideoPlacementMode, VideoProject } from './types.cjs';
|
|
15
|
+
import type { VideoCameraFraming, VideoClipCamera, VideoClipEffect, VideoEffectValues, VideoPlacementMode, VideoProject } from './types.cjs';
|
|
16
16
|
import { EffectsSlot } from '../effects/helpers.cjs';
|
|
17
|
-
import
|
|
17
|
+
import { type VideoCameraBake } from './camera.cjs';
|
|
18
|
+
import type { CameraMoveRole, CameraMoveSpec, EffectDescription, EffectProvider, EffectSummary, EffectValue } from '../effects/types.cjs';
|
|
18
19
|
import { VideoEffectsEngine, type VideoEffectPlace } from './effects.cjs';
|
|
19
20
|
import { type VideoAnimatable, type VideoKey } from './keyframes.cjs';
|
|
20
21
|
import { type VideoEditPlan, type VideoEditPlanInput } from './plan.cjs';
|
|
@@ -50,6 +51,19 @@ export interface VideoEditorOptions {
|
|
|
50
51
|
effects?: EffectProvider | null;
|
|
51
52
|
}
|
|
52
53
|
/** What `applyClipEffect` and the other effect edits return: the edit result plus what they made or changed. */
|
|
54
|
+
/** What setting or clearing a clip's camera move did: its camera now, the keys baked per property, any cuts and when each move plays (clip ms). */
|
|
55
|
+
export type VideoCameraMoveResult = {
|
|
56
|
+
ok: true;
|
|
57
|
+
clip: string;
|
|
58
|
+
camera: VideoClipCamera | null;
|
|
59
|
+
keys: Record<'x' | 'y' | 'scale' | 'rotation', number>;
|
|
60
|
+
cuts: number[];
|
|
61
|
+
windows: VideoCameraBake['windows'];
|
|
62
|
+
notes: string[];
|
|
63
|
+
} | {
|
|
64
|
+
ok: false;
|
|
65
|
+
error: string;
|
|
66
|
+
};
|
|
53
67
|
export type VideoEffectEditResult = (VideoEditResult & {
|
|
54
68
|
ok: true;
|
|
55
69
|
clip: string;
|
|
@@ -272,6 +286,27 @@ export declare class VideoEditorController {
|
|
|
272
286
|
}, options?: {
|
|
273
287
|
merge?: string;
|
|
274
288
|
}): Promise<VideoEffectEditResult>;
|
|
289
|
+
/** The provider's camera moves for a role (`transition` into a clip, `hold` while it plays), or all of them. Empty without camera support. */
|
|
290
|
+
cameraMoves(role?: CameraMoveRole): Promise<EffectSummary[]>;
|
|
291
|
+
private cameraClip;
|
|
292
|
+
private cameraEdit;
|
|
293
|
+
/**
|
|
294
|
+
* Sets the camera move a clip plays into (`transition`: from `from` to `framing` from the
|
|
295
|
+
* clip's start) or while it holds (`hold`: across the rest of the clip at `framing`), and bakes
|
|
296
|
+
* the clip's moves into its x, y, scale and rotation keys at the project's frame rate, keeping a
|
|
297
|
+
* cut's two keys. The move is checked first (role, preset, values; a preset's values and a move
|
|
298
|
+
* in's length are written out). A clip whose transform is keyed by hand is refused. One undo step.
|
|
299
|
+
*/
|
|
300
|
+
setClipCameraMove(clip: string, role: CameraMoveRole, spec: CameraMoveSpec, options?: {
|
|
301
|
+
from?: VideoCameraFraming | null;
|
|
302
|
+
framing?: VideoCameraFraming | null;
|
|
303
|
+
merge?: string;
|
|
304
|
+
}): Promise<VideoCameraMoveResult>;
|
|
305
|
+
/**
|
|
306
|
+
* Removes a clip's camera move for a role and bakes what is left (which needs the provider);
|
|
307
|
+
* with no move left the transform goes back to what it was before the moves. One undo step.
|
|
308
|
+
*/
|
|
309
|
+
clearClipCameraMove(clip: string, role: CameraMoveRole): Promise<VideoCameraMoveResult>;
|
|
275
310
|
/** Removes an effect from a clip's stack (works without a provider, so placeholders can be cleared). One undo step. */
|
|
276
311
|
removeClipEffect(clip: string, instance: string): VideoEffectEditResult;
|
|
277
312
|
/**
|
|
@@ -12,9 +12,10 @@ import { VideoPreviewPixels } from './scopes.js';
|
|
|
12
12
|
import type { VideoPreviewScale } from './proxy.js';
|
|
13
13
|
import type { VideoFrameCache } from './frame-cache.js';
|
|
14
14
|
import { type VideoSvgOptions } from './render.js';
|
|
15
|
-
import type { VideoClipEffect, VideoEffectValues, VideoPlacementMode, VideoProject } from './types.js';
|
|
15
|
+
import type { VideoCameraFraming, VideoClipCamera, VideoClipEffect, VideoEffectValues, VideoPlacementMode, VideoProject } from './types.js';
|
|
16
16
|
import { EffectsSlot } from '../effects/helpers.js';
|
|
17
|
-
import
|
|
17
|
+
import { type VideoCameraBake } from './camera.js';
|
|
18
|
+
import type { CameraMoveRole, CameraMoveSpec, EffectDescription, EffectProvider, EffectSummary, EffectValue } from '../effects/types.js';
|
|
18
19
|
import { VideoEffectsEngine, type VideoEffectPlace } from './effects.js';
|
|
19
20
|
import { type VideoAnimatable, type VideoKey } from './keyframes.js';
|
|
20
21
|
import { type VideoEditPlan, type VideoEditPlanInput } from './plan.js';
|
|
@@ -50,6 +51,19 @@ export interface VideoEditorOptions {
|
|
|
50
51
|
effects?: EffectProvider | null;
|
|
51
52
|
}
|
|
52
53
|
/** What `applyClipEffect` and the other effect edits return: the edit result plus what they made or changed. */
|
|
54
|
+
/** What setting or clearing a clip's camera move did: its camera now, the keys baked per property, any cuts and when each move plays (clip ms). */
|
|
55
|
+
export type VideoCameraMoveResult = {
|
|
56
|
+
ok: true;
|
|
57
|
+
clip: string;
|
|
58
|
+
camera: VideoClipCamera | null;
|
|
59
|
+
keys: Record<'x' | 'y' | 'scale' | 'rotation', number>;
|
|
60
|
+
cuts: number[];
|
|
61
|
+
windows: VideoCameraBake['windows'];
|
|
62
|
+
notes: string[];
|
|
63
|
+
} | {
|
|
64
|
+
ok: false;
|
|
65
|
+
error: string;
|
|
66
|
+
};
|
|
53
67
|
export type VideoEffectEditResult = (VideoEditResult & {
|
|
54
68
|
ok: true;
|
|
55
69
|
clip: string;
|
|
@@ -272,6 +286,27 @@ export declare class VideoEditorController {
|
|
|
272
286
|
}, options?: {
|
|
273
287
|
merge?: string;
|
|
274
288
|
}): Promise<VideoEffectEditResult>;
|
|
289
|
+
/** The provider's camera moves for a role (`transition` into a clip, `hold` while it plays), or all of them. Empty without camera support. */
|
|
290
|
+
cameraMoves(role?: CameraMoveRole): Promise<EffectSummary[]>;
|
|
291
|
+
private cameraClip;
|
|
292
|
+
private cameraEdit;
|
|
293
|
+
/**
|
|
294
|
+
* Sets the camera move a clip plays into (`transition`: from `from` to `framing` from the
|
|
295
|
+
* clip's start) or while it holds (`hold`: across the rest of the clip at `framing`), and bakes
|
|
296
|
+
* the clip's moves into its x, y, scale and rotation keys at the project's frame rate, keeping a
|
|
297
|
+
* cut's two keys. The move is checked first (role, preset, values; a preset's values and a move
|
|
298
|
+
* in's length are written out). A clip whose transform is keyed by hand is refused. One undo step.
|
|
299
|
+
*/
|
|
300
|
+
setClipCameraMove(clip: string, role: CameraMoveRole, spec: CameraMoveSpec, options?: {
|
|
301
|
+
from?: VideoCameraFraming | null;
|
|
302
|
+
framing?: VideoCameraFraming | null;
|
|
303
|
+
merge?: string;
|
|
304
|
+
}): Promise<VideoCameraMoveResult>;
|
|
305
|
+
/**
|
|
306
|
+
* Removes a clip's camera move for a role and bakes what is left (which needs the provider);
|
|
307
|
+
* with no move left the transform goes back to what it was before the moves. One undo step.
|
|
308
|
+
*/
|
|
309
|
+
clearClipCameraMove(clip: string, role: CameraMoveRole): Promise<VideoCameraMoveResult>;
|
|
275
310
|
/** Removes an effect from a clip's stack (works without a provider, so placeholders can be cleared). One undo step. */
|
|
276
311
|
removeClipEffect(clip: string, instance: string): VideoEffectEditResult;
|
|
277
312
|
/**
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* Agent tools for provider effects in the video editor: the shared effect tools
|
|
3
3
|
* (`search_effects`, `describe_effect`, `list_applied_effects`, `apply_effect`, `update_effect`,
|
|
4
4
|
* `remove_effect`) on clips, plus `add_video_effect_clip`, `set_video_effect_transition` and
|
|
5
|
-
* `set_video_effect_keyframes
|
|
5
|
+
* `set_video_effect_keyframes`, and the camera move tools (`list_video_camera_moves`,
|
|
6
|
+
* `set_clip_camera_move`, `clear_clip_camera_move`).
|
|
6
7
|
*/
|
|
7
8
|
import { type AppliedEffectInfo } from '../effects/tools.cjs';
|
|
8
9
|
import type { AgentToolProvider } from '../tools/registry.cjs';
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* Agent tools for provider effects in the video editor: the shared effect tools
|
|
3
3
|
* (`search_effects`, `describe_effect`, `list_applied_effects`, `apply_effect`, `update_effect`,
|
|
4
4
|
* `remove_effect`) on clips, plus `add_video_effect_clip`, `set_video_effect_transition` and
|
|
5
|
-
* `set_video_effect_keyframes
|
|
5
|
+
* `set_video_effect_keyframes`, and the camera move tools (`list_video_camera_moves`,
|
|
6
|
+
* `set_clip_camera_move`, `clear_clip_camera_move`).
|
|
6
7
|
*/
|
|
7
8
|
import { type AppliedEffectInfo } from '../effects/tools.js';
|
|
8
9
|
import type { AgentToolProvider } from '../tools/registry.js';
|