@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.
@@ -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
- for (let i = 1; i < sorted.length; i++) if (Math.abs(sorted[i].t - sorted[i - 1].t) < 1e-6) throw new Error(`Two keys are at ${sorted[i].t} ms; give each key its own time.`);
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
- 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.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;
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
- for (let i = 1; i < sorted.length; i++) if (Math.abs(sorted[i].t - sorted[i - 1].t) < 1e-6) throw new Error(`Two keys are at ${sorted[i].t} ms; give each key its own time.`);
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 _chunkA57ZQDNNcjs = require('../chunk-A57ZQDNN.cjs');
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: _chunkA57ZQDNNcjs.toVideoFfmpeg.call(void 0, video, { output: "timelapse.mp4" }), durationMs };
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)))));
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  toVideoFfmpeg
3
- } from "../chunk-ONNNNGNS.js";
3
+ } from "../chunk-CSM5T6SE.js";
4
4
  import {
5
5
  deserializeLayers,
6
6
  exportPsd,
@@ -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 type { EffectDescription, EffectProvider, EffectValue } from '../effects/types.cjs';
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 type { EffectDescription, EffectProvider, EffectValue } from '../effects/types.js';
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';