@pixerate/editor 0.230.0 → 0.231.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/{chunk-A57ZQDNN.cjs → chunk-5T3H7CGG.cjs} +14 -4
- package/dist/{chunk-ONNNNGNS.js → chunk-CSM5T6SE.js} +13 -3
- 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
|
@@ -155,11 +155,20 @@ var withEase = (key, ease) => {
|
|
|
155
155
|
const { ease: _old, ...rest } = key;
|
|
156
156
|
return ease === void 0 || ease === "linear" ? rest : { ...rest, ease };
|
|
157
157
|
};
|
|
158
|
-
function sortVideoKeys(keys) {
|
|
158
|
+
function sortVideoKeys(keys, options = {}) {
|
|
159
159
|
const sorted = [...keys].sort((a, b) => a.t - b.t);
|
|
160
|
-
|
|
160
|
+
const problem = videoKeyTimesProblem(sorted, options.jumps !== false);
|
|
161
|
+
if (problem) throw new Error(problem);
|
|
161
162
|
return sorted;
|
|
162
163
|
}
|
|
164
|
+
function videoKeyTimesProblem(keys, jumps = true) {
|
|
165
|
+
for (let i = 1; i < keys.length; i++) {
|
|
166
|
+
if (Math.abs(keys[i].t - keys[i - 1].t) >= 1e-6) continue;
|
|
167
|
+
if (!jumps) return `Two keys are at ${keys[i].t} ms; give each key its own time.`;
|
|
168
|
+
if (i >= 2 && Math.abs(keys[i].t - keys[i - 2].t) < 1e-6) return `Three keys are at ${keys[i].t} ms; a time takes one key, or two for a jump (the value just before, then the value after).`;
|
|
169
|
+
}
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
163
172
|
function setVideoKey(prop, key, fallback) {
|
|
164
173
|
const keys = isVideoKeyframes(prop) ? prop.keys.filter((k) => Math.abs(k.t - key.t) >= 1e-6) : [];
|
|
165
174
|
if (!isVideoKeyframes(prop)) {
|
|
@@ -207,7 +216,7 @@ function videoKeyframeFfmpegExpr(prop, time, fallback, step) {
|
|
|
207
216
|
for (let i = points.length - 2; i >= 0; i--) {
|
|
208
217
|
const [t0, v0] = points[i];
|
|
209
218
|
const [t1, v1] = points[i + 1];
|
|
210
|
-
const seg = holds.has(i) || v0 === v1 ? fmt(v0) : `${fmt(v0)}${signed((v1 - v0) / (t1 - t0))}*(${time}${signed(-t0)})`;
|
|
219
|
+
const seg = holds.has(i) || v0 === v1 || t1 <= t0 ? fmt(v0) : `${fmt(v0)}${signed((v1 - v0) / (t1 - t0))}*(${time}${signed(-t0)})`;
|
|
211
220
|
expr = `if(lt(${time},${fmt(t1)}),${seg},${expr})`;
|
|
212
221
|
}
|
|
213
222
|
return `if(lt(${time},${fmt(points[0][0])}),${fmt(points[0][1])},${expr})`;
|
|
@@ -2610,4 +2619,5 @@ function buildFfmpeg(project, options, measure) {
|
|
|
2610
2619
|
|
|
2611
2620
|
|
|
2612
2621
|
|
|
2613
|
-
|
|
2622
|
+
|
|
2623
|
+
exports.VIDEO_FITS = VIDEO_FITS; exports.VIDEO_TRANSITION_TYPES = VIDEO_TRANSITION_TYPES; exports.VIDEO_WIPE_DIRECTIONS = VIDEO_WIPE_DIRECTIONS; exports.videoTransitionAudioCurve = videoTransitionAudioCurve; exports.VIDEO_BLEND_MODES = VIDEO_BLEND_MODES; exports.VIDEO_CLIP_ANIMATION_EFFECTS = VIDEO_CLIP_ANIMATION_EFFECTS; exports.VIDEO_MASK_SHAPES = VIDEO_MASK_SHAPES; exports.VIDEO_FADE_CURVES = VIDEO_FADE_CURVES; exports.VIDEO_ADJUSTMENT_SCOPES = VIDEO_ADJUSTMENT_SCOPES; exports.VIDEO_PLACEMENT_MODES = VIDEO_PLACEMENT_MODES; exports.VIDEO_CLIP_TYPES = VIDEO_CLIP_TYPES; exports.VIDEO_EASE_NAMES = VIDEO_EASE_NAMES; exports.VIDEO_KEYFRAME_PROPERTIES = VIDEO_KEYFRAME_PROPERTIES; exports.VIDEO_TRANSFORM_PROPERTIES = VIDEO_TRANSFORM_PROPERTIES; exports.VIDEO_KEYFRAME_LIMITS = VIDEO_KEYFRAME_LIMITS; exports.isVideoKeyframes = isVideoKeyframes; exports.videoEaseBezier = videoEaseBezier; exports.videoEaseProgress = videoEaseProgress; exports.videoValueAt = videoValueAt; exports.videoKeysOf = videoKeysOf; exports.retimeVideoAnimatable = retimeVideoAnimatable; exports.splitVideoAnimatable = splitVideoAnimatable; exports.sortVideoKeys = sortVideoKeys; exports.videoKeyTimesProblem = videoKeyTimesProblem; exports.setVideoKey = setVideoKey; exports.removeVideoKey = removeVideoKey; exports.videoKeyframeBreakpoints = videoKeyframeBreakpoints; exports.videoKeyframeFfmpegExpr = videoKeyframeFfmpegExpr; exports.VIDEO_LUT_MAX_SIZE = VIDEO_LUT_MAX_SIZE; exports.parseVideoCubeLut = parseVideoCubeLut; exports.videoLutFromFunction = videoLutFromFunction; exports.videoLutToCube = videoLutToCube; exports.applyVideoLut = applyVideoLut; exports.videoSkinToneWeight = videoSkinToneWeight; exports.applyVideoLutToPixels = applyVideoLutToPixels; exports.videoLutSvgApproximation = videoLutSvgApproximation; exports.VideoLutCache = VideoLutCache; exports.VIDEO_GRADE_CONTROLS = VIDEO_GRADE_CONTROLS; exports.VIDEO_GRADE_PRESETS = VIDEO_GRADE_PRESETS; exports.VIDEO_GRADE_PRESET_NAMES = VIDEO_GRADE_PRESET_NAMES; exports.normalizeVideoGradeLut = normalizeVideoGradeLut; exports.normalizeVideoGrade = normalizeVideoGrade; exports.videoGradePreset = videoGradePreset; exports.videoGradeLook = videoGradeLook; exports.videoGradeSteps = videoGradeSteps; exports.videoGradeStepMatrix = videoGradeStepMatrix; exports.applyVideoGrade = applyVideoGrade; exports.videoGradeStepSvgValues = videoGradeStepSvgValues; exports.videoLutSvgPrimitives = videoLutSvgPrimitives; exports.videoGradeSvgFilter = videoGradeSvgFilter; exports.videoGradeGainsFilterId = videoGradeGainsFilterId; exports.videoGradeCssFilter = videoGradeCssFilter; exports.videoGradeSvgDefs = videoGradeSvgDefs; exports.videoGradeFfmpegFilters = videoGradeFfmpegFilters; exports.videoClipSourceTime = videoClipSourceTime; exports.videoClipSpeedAt = videoClipSpeedAt; exports.videoSpeedRampKeys = videoSpeedRampKeys; exports.checkVideoTimeRemap = checkVideoTimeRemap; exports.videoTimeRemapSpan = videoTimeRemapSpan; exports.videoTimeRemapBreakpoints = videoTimeRemapBreakpoints; exports.videoSpeedRampEdit = videoSpeedRampEdit; exports.videoFreezeFrameEdit = videoFreezeFrameEdit; exports.videoSlowMotionRamp = videoSlowMotionRamp; exports.VIDEO_TIME_EPSILON = VIDEO_TIME_EPSILON; exports.videoClipEnd = videoClipEnd; exports.videoClipTypeLabel = videoClipTypeLabel; exports.videoTrackSyncLocked = videoTrackSyncLocked; exports.videoClipSpeed = videoClipSpeed; exports.videoClipSourceRange = videoClipSourceRange; exports.videoFrameDuration = videoFrameDuration; exports.snapToVideoFrame = snapToVideoFrame; exports.videoFrames = videoFrames; exports.isVideoDropFrameRate = isVideoDropFrameRate; exports.videoTimecodeFrames = videoTimecodeFrames; exports.formatVideoTimecode = formatVideoTimecode; exports.formatVideoTimecodeFrames = formatVideoTimecodeFrames; exports.videoHourFrames = videoHourFrames; exports.formatVideoSeconds = formatVideoSeconds; exports.videoAssetHasSound = videoAssetHasSound; exports.videoAssetMap = videoAssetMap; exports.videoSequenceMap = videoSequenceMap; exports.videoSequenceDuration = videoSequenceDuration; exports.videoSequenceChildren = videoSequenceChildren; exports.findVideoSequenceCycle = findVideoSequenceCycle; exports.allVideoTracks = allVideoTracks; exports.sortedVideoClips = sortedVideoClips; exports.findVideoClip = findVideoClip; exports.allVideoClipIds = allVideoClipIds; exports.findVideoSequenceClip = findVideoSequenceClip; exports.videoProjectDuration = videoProjectDuration; exports.videoClipBefore = videoClipBefore; exports.videoClipAfter = videoClipAfter; exports.videoClipHandles = videoClipHandles; exports.videoClipOverhang = videoClipOverhang; exports.videoSnapPoints = videoSnapPoints; exports.snapVideoTime = snapVideoTime; exports.findVideoGaps = findVideoGaps; exports.videoOverlap = videoOverlap; exports.nextFreeVideoSlot = nextFreeVideoSlot; exports.videoClipsAt = videoClipsAt; exports.VIDEO_CLIP_ANIMATION_DURATION = VIDEO_CLIP_ANIMATION_DURATION; exports.videoClipAnimationProperties = videoClipAnimationProperties; exports.videoClipAnimationSpans = videoClipAnimationSpans; exports.videoClipAnimated = videoClipAnimated; exports.VIDEO_MASK_DEFAULTS = VIDEO_MASK_DEFAULTS; exports.normalizeVideoClipMask = normalizeVideoClipMask; exports.videoMaskPolygon = videoMaskPolygon; exports.videoLayerMask = videoLayerMask; exports.videoMaskSvgPath = videoMaskSvgPath; exports.videoMaskContains = videoMaskContains; exports.videoEffectValuesAt = videoEffectValuesAt; exports.videoTransformAt = videoTransformAt; exports.placeVideoRect = placeVideoRect; exports.videoTextStyle = videoTextStyle; exports.videoTitleFrame = videoTitleFrame; exports.videoTransitionEase = videoTransitionEase; exports.videoFadeCurveGain = videoFadeCurveGain; exports.videoClipSoundGain = videoClipSoundGain; exports.videoFrameAt = videoFrameAt; exports.videoLayersWithoutTransitionEffects = videoLayersWithoutTransitionEffects; exports.videoFrameLeafLayers = videoFrameLeafLayers; exports.videoProjectEffects = videoProjectEffects; exports.videoClipEffectUses = videoClipEffectUses; exports.videoLayersUseEffects = videoLayersUseEffects; exports.videoEffectFrameTime = videoEffectFrameTime; exports.videoEffectLayerKey = videoEffectLayerKey; exports.mixEffectPixels = mixEffectPixels; exports.overEffectPixels = overEffectPixels; exports.VideoEffectsEngine = VideoEffectsEngine; exports.VIDEO_EFFECT_PLACES = VIDEO_EFFECT_PLACES; exports.checkVideoEffectPlace = checkVideoEffectPlace; exports.checkVideoEffectValues = checkVideoEffectValues; exports.videoIrisRadius = videoIrisRadius; exports.videoWipeRect = videoWipeRect; exports.videoFrameToSvg = videoFrameToSvg; exports.videoProjectSvg = videoProjectSvg; exports.videoContactSheetSvg = videoContactSheetSvg; exports.drawVideoFrame = drawVideoFrame; exports.renderVideoFrameExact = renderVideoFrameExact; exports.toVideoEdl = toVideoEdl; exports.videoFfmpegUnsupportedEffects = videoFfmpegUnsupportedEffects; exports.videoFfmpegUnsupportedFeatures = videoFfmpegUnsupportedFeatures; exports.parseVideoLoudnessMeasurement = parseVideoLoudnessMeasurement; exports.ffmpegFilterValue = ffmpegFilterValue; exports.videoShellQuote = videoShellQuote; exports.toVideoFfmpeg = toVideoFfmpeg; exports.toVideoLoudnessMeasure = toVideoLoudnessMeasure;
|
|
@@ -155,11 +155,20 @@ var withEase = (key, ease) => {
|
|
|
155
155
|
const { ease: _old, ...rest } = key;
|
|
156
156
|
return ease === void 0 || ease === "linear" ? rest : { ...rest, ease };
|
|
157
157
|
};
|
|
158
|
-
function sortVideoKeys(keys) {
|
|
158
|
+
function sortVideoKeys(keys, options = {}) {
|
|
159
159
|
const sorted = [...keys].sort((a, b) => a.t - b.t);
|
|
160
|
-
|
|
160
|
+
const problem = videoKeyTimesProblem(sorted, options.jumps !== false);
|
|
161
|
+
if (problem) throw new Error(problem);
|
|
161
162
|
return sorted;
|
|
162
163
|
}
|
|
164
|
+
function videoKeyTimesProblem(keys, jumps = true) {
|
|
165
|
+
for (let i = 1; i < keys.length; i++) {
|
|
166
|
+
if (Math.abs(keys[i].t - keys[i - 1].t) >= 1e-6) continue;
|
|
167
|
+
if (!jumps) return `Two keys are at ${keys[i].t} ms; give each key its own time.`;
|
|
168
|
+
if (i >= 2 && Math.abs(keys[i].t - keys[i - 2].t) < 1e-6) return `Three keys are at ${keys[i].t} ms; a time takes one key, or two for a jump (the value just before, then the value after).`;
|
|
169
|
+
}
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
163
172
|
function setVideoKey(prop, key, fallback) {
|
|
164
173
|
const keys = isVideoKeyframes(prop) ? prop.keys.filter((k) => Math.abs(k.t - key.t) >= 1e-6) : [];
|
|
165
174
|
if (!isVideoKeyframes(prop)) {
|
|
@@ -207,7 +216,7 @@ function videoKeyframeFfmpegExpr(prop, time, fallback, step) {
|
|
|
207
216
|
for (let i = points.length - 2; i >= 0; i--) {
|
|
208
217
|
const [t0, v0] = points[i];
|
|
209
218
|
const [t1, v1] = points[i + 1];
|
|
210
|
-
const seg = holds.has(i) || v0 === v1 ? fmt(v0) : `${fmt(v0)}${signed((v1 - v0) / (t1 - t0))}*(${time}${signed(-t0)})`;
|
|
219
|
+
const seg = holds.has(i) || v0 === v1 || t1 <= t0 ? fmt(v0) : `${fmt(v0)}${signed((v1 - v0) / (t1 - t0))}*(${time}${signed(-t0)})`;
|
|
211
220
|
expr = `if(lt(${time},${fmt(t1)}),${seg},${expr})`;
|
|
212
221
|
}
|
|
213
222
|
return `if(lt(${time},${fmt(points[0][0])}),${fmt(points[0][1])},${expr})`;
|
|
@@ -2487,6 +2496,7 @@ export {
|
|
|
2487
2496
|
retimeVideoAnimatable,
|
|
2488
2497
|
splitVideoAnimatable,
|
|
2489
2498
|
sortVideoKeys,
|
|
2499
|
+
videoKeyTimesProblem,
|
|
2490
2500
|
setVideoKey,
|
|
2491
2501
|
removeVideoKey,
|
|
2492
2502
|
videoKeyframeBreakpoints,
|
|
@@ -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';
|