@remotion/studio 4.0.527 → 4.0.528

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/dist/components/AgentPrompt.js +1 -2
  2. package/dist/components/AudioWaveform.d.ts +1 -0
  3. package/dist/components/AudioWaveform.js +10 -14
  4. package/dist/components/CodeFrame.js +1 -1
  5. package/dist/components/ColorPicker/checker.d.ts +1 -1
  6. package/dist/components/CurrentAsset.js +3 -2
  7. package/dist/components/EditorRuler/Ruler.js +6 -3
  8. package/dist/components/EffectPickerModal.js +69 -43
  9. package/dist/components/ElementInstallConfirmation.js +3 -3
  10. package/dist/components/ElementLibrariesSettings.d.ts +2 -0
  11. package/dist/components/ElementLibrariesSettings.js +200 -0
  12. package/dist/components/InitialCompositionLoader.js +3 -1
  13. package/dist/components/InspectorOpenInEditor.js +13 -0
  14. package/dist/components/InspectorPanel/AlignmentControls.js +28 -9
  15. package/dist/components/InspectorPanel/CollapsibleInspectorSectionHeader.js +1 -1
  16. package/dist/components/InspectorPanel/EasingInspector.js +6 -2
  17. package/dist/components/InspectorPanel/ElementLibraryButton.js +1 -1
  18. package/dist/components/InspectorPanel/KeyframeEasingNavigator.js +1 -1
  19. package/dist/components/InspectorPanel/KeyframeInspector.js +28 -24
  20. package/dist/components/InspectorPanel/MultiSequenceNumberField.js +1 -1
  21. package/dist/components/InspectorPanel/SequenceInspectorHeader.d.ts +3 -1
  22. package/dist/components/InspectorPanel/SequenceSelectionInspector.js +30 -2
  23. package/dist/components/InspectorPanel/SequenceWrapAction.d.ts +8 -0
  24. package/dist/components/InspectorPanel/SequenceWrapAction.js +151 -0
  25. package/dist/components/InspectorPanel/easing-inspector-selection.d.ts +2 -1
  26. package/dist/components/InspectorPanel/easing-inspector-selection.js +4 -3
  27. package/dist/components/InspectorPanel/keyframe-inspector-frame.d.ts +2 -1
  28. package/dist/components/InspectorPanel/keyframe-inspector-frame.js +2 -2
  29. package/dist/components/InspectorSequenceSection.d.ts +1 -0
  30. package/dist/components/InspectorSequenceSection.js +7 -5
  31. package/dist/components/KeyboardShortcutsSettings.js +1 -1
  32. package/dist/components/Menu/styles.d.ts +2 -2
  33. package/dist/components/Modals.js +7 -6
  34. package/dist/components/ModelManager.js +10 -9
  35. package/dist/components/NewComposition/CancelButton.js +10 -4
  36. package/dist/components/NewComposition/InputDragger.d.ts +3 -1
  37. package/dist/components/NewComposition/InputDragger.js +28 -9
  38. package/dist/components/NewComposition/NewComposition.js +7 -6
  39. package/dist/components/NewComposition/RemInput.d.ts +1 -1
  40. package/dist/components/NewComposition/menu-typeahead.js +1 -1
  41. package/dist/components/Preview.js +3 -2
  42. package/dist/components/RenderModal/SchemaEditor/create-zod-values.js +1 -2
  43. package/dist/components/RenderModal/WebRenderModalPicture.js +1 -2
  44. package/dist/components/RenderQueue/CaptionQueueItem.js +14 -5
  45. package/dist/components/RenderQueue/CaptionQueueProcessor.js +30 -7
  46. package/dist/components/RenderQueue/QueueJobError.d.ts +8 -0
  47. package/dist/components/RenderQueue/QueueJobError.js +24 -0
  48. package/dist/components/RenderQueue/QueueJobErrorModal.d.ts +8 -0
  49. package/dist/components/RenderQueue/QueueJobErrorModal.js +63 -0
  50. package/dist/components/RenderQueue/RenderQueueItemCancelButton.d.ts +3 -1
  51. package/dist/components/RenderQueue/RenderQueueItemCancelButton.js +11 -4
  52. package/dist/components/RenderQueue/RenderQueueRepeat.d.ts +3 -1
  53. package/dist/components/RenderQueue/RenderQueueRepeat.js +20 -3
  54. package/dist/components/RenderQueue/VideoMattingQueueItem.js +24 -27
  55. package/dist/components/RenderQueue/VideoMattingQueueProcessor.js +68 -28
  56. package/dist/components/RenderQueue/caption-job-types.d.ts +3 -1
  57. package/dist/components/RenderQueue/context.d.ts +4 -0
  58. package/dist/components/RenderQueue/context.js +58 -8
  59. package/dist/components/RenderQueue/index.js +2 -3
  60. package/dist/components/RenderQueue/load-model-for-job.d.ts +2 -1
  61. package/dist/components/RenderQueue/load-model-for-job.js +5 -1
  62. package/dist/components/RenderQueue/video-matting-job-types.d.ts +13 -6
  63. package/dist/components/SelectedOutlineCropControls.js +2 -1
  64. package/dist/components/SelectedOutlineEditingHandles.js +9 -2
  65. package/dist/components/SelectedOutlineElement.js +9 -3
  66. package/dist/components/SelectedOutlineKeyboardControls.d.ts +2 -4
  67. package/dist/components/SelectedOutlineKeyboardControls.js +4 -22
  68. package/dist/components/SelectedOutlineOverlay.js +152 -106
  69. package/dist/components/SelectedOutlinePathPoints.d.ts +8 -0
  70. package/dist/components/SelectedOutlinePathPoints.js +433 -0
  71. package/dist/components/SelectedOutlinePolygon.js +21 -46
  72. package/dist/components/SelectedOutlineRenderer.d.ts +3 -5
  73. package/dist/components/SelectedOutlineRenderer.js +32 -136
  74. package/dist/components/SelectedOutlineTransformOriginHandle.js +3 -2
  75. package/dist/components/SelectedOutlineUvControls.js +12 -7
  76. package/dist/components/SettingsModal.js +30 -3
  77. package/dist/components/SettingsModalFooter.d.ts +1 -0
  78. package/dist/components/SettingsModalFooter.js +7 -3
  79. package/dist/components/ShowOutlinesProvider.js +1 -1
  80. package/dist/components/SkillsSettings.d.ts +0 -1
  81. package/dist/components/SkillsSettings.js +13 -14
  82. package/dist/components/Splitter/SplitterElement.js +1 -2
  83. package/dist/components/TimeValue.js +1 -1
  84. package/dist/components/Timeline/LoopedTimelineIndicators.d.ts +1 -0
  85. package/dist/components/Timeline/LoopedTimelineIndicators.js +7 -6
  86. package/dist/components/Timeline/TimelineArrayField.js +1 -1
  87. package/dist/components/Timeline/TimelineClipboardKeybindings.js +0 -1
  88. package/dist/components/Timeline/TimelineColorField.js +1 -1
  89. package/dist/components/Timeline/TimelineDragHandler.js +1 -1
  90. package/dist/components/Timeline/TimelineEffectPropItem.d.ts +1 -0
  91. package/dist/components/Timeline/TimelineEffectPropItem.js +12 -5
  92. package/dist/components/Timeline/TimelineExpandedRow.d.ts +1 -0
  93. package/dist/components/Timeline/TimelineExpandedRow.js +5 -4
  94. package/dist/components/Timeline/TimelineExpandedSection.d.ts +1 -0
  95. package/dist/components/Timeline/TimelineExpandedSection.js +2 -2
  96. package/dist/components/Timeline/TimelineExpandedTrackKeyframes.d.ts +1 -0
  97. package/dist/components/Timeline/TimelineExpandedTrackKeyframes.js +3 -1
  98. package/dist/components/Timeline/TimelineFontFamilyField.js +12 -12
  99. package/dist/components/Timeline/TimelineKeyframeControls.d.ts +1 -0
  100. package/dist/components/Timeline/TimelineKeyframeControls.js +39 -28
  101. package/dist/components/Timeline/TimelineLayerChildren.js +1 -1
  102. package/dist/components/Timeline/TimelineList.js +1 -1
  103. package/dist/components/Timeline/TimelineNumberField.js +2 -4
  104. package/dist/components/Timeline/TimelinePrimitiveFieldValue.js +1 -1
  105. package/dist/components/Timeline/TimelineSelection.d.ts +9 -9
  106. package/dist/components/Timeline/TimelineSelection.js +16 -9
  107. package/dist/components/Timeline/TimelineSequence.d.ts +3 -1
  108. package/dist/components/Timeline/TimelineSequence.js +39 -21
  109. package/dist/components/Timeline/TimelineSequenceItem.d.ts +1 -0
  110. package/dist/components/Timeline/TimelineSequenceItem.js +18 -8
  111. package/dist/components/Timeline/TimelineSequencePropItem.d.ts +3 -0
  112. package/dist/components/Timeline/TimelineSequencePropItem.js +262 -25
  113. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.d.ts +11 -13
  114. package/dist/components/Timeline/TimelineSequenceRightEdgeDragHandle.js +98 -77
  115. package/dist/components/Timeline/TimelineTextContentField.js +27 -4
  116. package/dist/components/Timeline/TimelineTimeIndicators.js +10 -5
  117. package/dist/components/Timeline/TimelineTrack.js +1 -1
  118. package/dist/components/Timeline/TimelineTrimTooltip.d.ts +11 -0
  119. package/dist/components/Timeline/TimelineTrimTooltip.js +41 -0
  120. package/dist/components/Timeline/TimelineVideoInfo.d.ts +1 -0
  121. package/dist/components/Timeline/TimelineVideoInfo.js +13 -10
  122. package/dist/components/Timeline/delete-selected-keyframe.js +22 -8
  123. package/dist/components/Timeline/delete-selected-timeline-item.d.ts +1 -5
  124. package/dist/components/Timeline/delete-selected-timeline-item.js +7 -93
  125. package/dist/components/Timeline/get-animation-item-selection-for-frame.d.ts +2 -1
  126. package/dist/components/Timeline/get-animation-item-selection-for-frame.js +7 -5
  127. package/dist/components/Timeline/get-keyframed-sequence-drag-targets.d.ts +23 -0
  128. package/dist/components/Timeline/get-keyframed-sequence-drag-targets.js +57 -0
  129. package/dist/components/Timeline/get-node-keyframes.d.ts +2 -1
  130. package/dist/components/Timeline/get-node-keyframes.js +6 -4
  131. package/dist/components/Timeline/get-playback-rate-keyframe-changes.d.ts +21 -0
  132. package/dist/components/Timeline/get-playback-rate-keyframe-changes.js +142 -0
  133. package/dist/components/Timeline/get-timeline-keyframes.d.ts +15 -2
  134. package/dist/components/Timeline/get-timeline-keyframes.js +44 -6
  135. package/dist/components/Timeline/keyframe-clipboard.js +17 -3
  136. package/dist/components/Timeline/split-selected-timeline-item.js +4 -1
  137. package/dist/components/Timeline/timeline-field-display-utils.js +1 -0
  138. package/dist/components/Timeline/timeline-field-row-layout.js +1 -0
  139. package/dist/components/Timeline/use-delete-timeline-items.js +17 -11
  140. package/dist/components/Timeline/use-expanded-track-keyframe-rows.d.ts +2 -1
  141. package/dist/components/Timeline/use-expanded-track-keyframe-rows.js +3 -1
  142. package/dist/components/Timeline/use-sequence-freeze-frame-menu-item.js +7 -3
  143. package/dist/components/Timeline/use-timeline-keyframe-drag.js +28 -19
  144. package/dist/components/Transcription/Models.js +1 -1
  145. package/dist/components/Transcription/TranscriptionModal.js +3 -1
  146. package/dist/components/Transcription/resample-media-to-16-khz.d.ts +2 -1
  147. package/dist/components/Transcription/resample-media-to-16-khz.js +20 -2
  148. package/dist/components/UpdatesSettings.js +2 -0
  149. package/dist/components/VideoMatting/Models.js +1 -1
  150. package/dist/components/VideoMatting/VideoMattingModal.js +30 -47
  151. package/dist/components/VideoMatting/VideoMattingModalWithOptionalPackage.js +1 -1
  152. package/dist/components/WebMcp.js +22 -40
  153. package/dist/components/composition-drop-preview.js +1 -0
  154. package/dist/components/effect-drag-and-drop.d.ts +13 -5
  155. package/dist/components/effect-drag-and-drop.js +19 -4
  156. package/dist/components/get-open-in-menu-items.d.ts +2 -1
  157. package/dist/components/get-open-in-menu-items.js +17 -1
  158. package/dist/components/selected-outline-drag.d.ts +1 -6
  159. package/dist/components/selected-outline-drag.js +22 -6
  160. package/dist/components/selected-outline-geometry.d.ts +2 -18
  161. package/dist/components/selected-outline-measurement.d.ts +23 -41
  162. package/dist/components/selected-outline-measurement.js +14 -252
  163. package/dist/components/selected-outline-order.d.ts +4 -11
  164. package/dist/components/selected-outline-order.js +2 -254
  165. package/dist/components/selected-outline-snap.d.ts +1 -1
  166. package/dist/components/selected-outline-snap.js +2 -1
  167. package/dist/components/selected-outline-types.d.ts +18 -28
  168. package/dist/components/selected-outline-uv.d.ts +4 -4
  169. package/dist/components/selected-outline-uv.js +6 -111
  170. package/dist/components/sequence-props-api.js +0 -10
  171. package/dist/components/use-selected-outline-control-target.js +12 -21
  172. package/dist/components/wrap-jsx-node-api.d.ts +2 -0
  173. package/dist/components/wrap-jsx-node-api.js +13 -0
  174. package/dist/error-overlay/remotion-overlay/OpenInEditor.js +45 -2
  175. package/dist/error-overlay/remotion-overlay/StackFrame.js +32 -3
  176. package/dist/esm/{CaptionQueueProcessor-npa6szn1.mjs → CaptionQueueProcessor-nr7hjcga.mjs} +63 -17
  177. package/dist/esm/LazyModels-ajkn7fs3.mjs +12 -0
  178. package/dist/esm/LazyModels-g1g7cf4e.mjs +12 -0
  179. package/dist/esm/{TranscriptionModal-79m5wgcj.mjs → TranscriptionModal-e18bzbkb.mjs} +15 -15
  180. package/dist/esm/{VideoMattingModal-31pew0xj.mjs → VideoMattingModal-5bz2s4rs.mjs} +47 -65
  181. package/dist/esm/{VideoMattingQueueProcessor-t1hgm2rm.mjs → VideoMattingQueueProcessor-4tkj0f4k.mjs} +69 -26
  182. package/dist/esm/{index-v4tr1bft.mjs → index-09txs1bj.mjs} +5 -0
  183. package/dist/esm/{index-n5gmcvhz.mjs → index-5ycb9e9q.mjs} +2 -4
  184. package/dist/esm/{index-5t2dwxsk.mjs → index-890dd9b3.mjs} +259 -21
  185. package/dist/esm/{index-ac5550e7.mjs → index-8nt6a0mw.mjs} +3 -3
  186. package/dist/esm/{index-614tdz2q.mjs → index-9q9w8v9p.mjs} +3 -3
  187. package/dist/esm/{index-s7qa3xbw.mjs → index-c2wabcdt.mjs} +6 -6
  188. package/dist/esm/{index-r1gr3j3a.mjs → index-dfy1t576.mjs} +50 -1
  189. package/dist/esm/{index-21hxsfaa.mjs → index-dh3zk2hv.mjs} +6 -25
  190. package/dist/esm/{index-4zen9prq.mjs → index-dpyss74p.mjs} +6563 -5485
  191. package/dist/esm/{index-9x6e1dq0.mjs → index-hqxc6tzp.mjs} +40 -6
  192. package/dist/esm/{index-9xxg6218.mjs → index-qve7mdfp.mjs} +19 -1
  193. package/dist/esm/{index-e855w59j.mjs → index-s6qya2gg.mjs} +3 -5
  194. package/dist/esm/index-t7tbt980.mjs +103 -0
  195. package/dist/esm/{index-r0ejh5sy.mjs → index-t7xnxdf8.mjs} +44 -26
  196. package/dist/esm/index-wqc43mw0.mjs +158 -0
  197. package/dist/esm/{index-ppspzgn9.mjs → index-x6r9bn12.mjs} +4026 -4761
  198. package/dist/esm/{index-vxwg66ar.mjs → index-xac20sv4.mjs} +44 -57
  199. package/dist/esm/index.mjs +4 -5
  200. package/dist/esm/internals.mjs +13 -13
  201. package/dist/esm/previewEntry.mjs +18 -15
  202. package/dist/esm/renderEntry.mjs +5 -1
  203. package/dist/helpers/calculate-timeline.d.ts +5 -1
  204. package/dist/helpers/calculate-timeline.js +1 -1
  205. package/dist/helpers/checkerboard-background.d.ts +2 -2
  206. package/dist/helpers/colors.d.ts +132 -112
  207. package/dist/helpers/colors.js +117 -95
  208. package/dist/helpers/create-folder-tree.js +2 -1
  209. package/dist/helpers/editor-guide-selection.d.ts +1 -1
  210. package/dist/helpers/editor-ruler.js +23 -12
  211. package/dist/helpers/get-connected-compositions.d.ts +6 -1
  212. package/dist/helpers/get-connected-compositions.js +1 -1
  213. package/dist/helpers/get-sequence-double-click-action.js +1 -1
  214. package/dist/helpers/get-sequence-visible-range.d.ts +1 -1
  215. package/dist/helpers/get-sequence-visible-range.js +2 -5
  216. package/dist/helpers/get-timeline-nestedness.d.ts +1 -1
  217. package/dist/helpers/get-timeline-nestedness.js +1 -1
  218. package/dist/helpers/get-timeline-sequence-sort-key.d.ts +1 -1
  219. package/dist/helpers/get-timeline-sequence-sort-key.js +1 -1
  220. package/dist/helpers/hoverable.js +4 -4
  221. package/dist/helpers/inject-css.js +5 -7
  222. package/dist/helpers/prism-vsc-dark-plus.d.ts +1 -1
  223. package/dist/helpers/prism-vsc-dark-plus.js +52 -51
  224. package/dist/helpers/resolve-studio-color.d.ts +1 -0
  225. package/dist/helpers/resolve-studio-color.js +11 -0
  226. package/dist/helpers/studio-css-variables.d.ts +1 -0
  227. package/dist/helpers/studio-css-variables.js +105 -0
  228. package/dist/helpers/studio-pixel-ratio.d.ts +1 -0
  229. package/dist/helpers/studio-pixel-ratio.js +7 -0
  230. package/dist/helpers/timeline-node-path-key.d.ts +1 -1
  231. package/dist/helpers/timeline-node-path-key.js +2 -2
  232. package/dist/helpers/use-runtime-values.js +2 -28
  233. package/dist/hot-middleware-client/client.js +5 -3
  234. package/dist/icons/align-center-horizontal.js +2 -1
  235. package/dist/icons/align-left.js +2 -1
  236. package/dist/icons/align-right.js +2 -1
  237. package/dist/icons/{separation.d.ts → background-removal.d.ts} +1 -1
  238. package/dist/icons/background-removal.js +9 -0
  239. package/dist/icons/wrap.d.ts +4 -0
  240. package/dist/icons/wrap.js +10 -0
  241. package/dist/previewEntry.js +2 -0
  242. package/dist/renderEntry.js +2 -0
  243. package/dist/state/modals.d.ts +15 -1
  244. package/dist/state/timeline-sequence-hover.d.ts +6 -16
  245. package/dist/state/timeline-sequence-hover.js +6 -67
  246. package/package.json +20 -19
  247. package/dist/components/Timeline/get-easing-selection-after-keyframe-delete.d.ts +0 -15
  248. package/dist/components/Timeline/get-easing-selection-after-keyframe-delete.js +0 -31
  249. package/dist/esm/LazyModels-nh3c8h9p.mjs +0 -12
  250. package/dist/esm/LazyModels-rr5v8h5y.mjs +0 -12
  251. package/dist/esm/index-cw0pnpg5.mjs +0 -50
  252. package/dist/esm/index-k426ye99.mjs +0 -139
  253. package/dist/helpers/get-box-quads-polyfill-internals.d.ts +0 -82
  254. package/dist/helpers/get-box-quads-polyfill-internals.js +0 -2403
  255. package/dist/helpers/get-box-quads-ponyfill.d.ts +0 -10
  256. package/dist/helpers/get-box-quads-ponyfill.js +0 -23
  257. package/dist/icons/separation.js +0 -7
  258. /package/dist/esm/{resolve-composition-component-location-qrp05g62.mjs → resolve-composition-component-location-2hgf6g0a.mjs} +0 -0
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPlaybackRateKeyframeChanges = void 0;
4
+ const studio_shared_1 = require("@remotion/studio-shared");
5
+ const get_keyframed_sequence_drag_targets_1 = require("./get-keyframed-sequence-drag-targets");
6
+ const getPlaybackRateKeyframeChanges = ({ nodePath, sequences, overrideIdsToNodePaths, propStatuses, previousPlaybackRate, playbackRate, }) => {
7
+ var _a;
8
+ var _b;
9
+ const sequenceKeyframes = [];
10
+ const effectKeyframes = [];
11
+ const previews = [];
12
+ if (previousPlaybackRate === playbackRate ||
13
+ !Number.isFinite(previousPlaybackRate) ||
14
+ previousPlaybackRate <= 0 ||
15
+ !Number.isFinite(playbackRate) ||
16
+ playbackRate <= 0) {
17
+ return { sequenceKeyframes, effectKeyframes, previews };
18
+ }
19
+ const key = (0, studio_shared_1.stringifySequenceSubscriptionKey)(nodePath);
20
+ const root = sequences.find((sequence) => {
21
+ var _a;
22
+ const overrideId = (_a = sequence.controls) === null || _a === void 0 ? void 0 : _a.overrideId;
23
+ const path = overrideId ? overrideIdsToNodePaths[overrideId] : undefined;
24
+ return path && (0, studio_shared_1.stringifySequenceSubscriptionKey)(path) === key;
25
+ });
26
+ if (!root) {
27
+ return { sequenceKeyframes, effectKeyframes, previews };
28
+ }
29
+ const sequencesById = new Map(sequences.map((sequence) => [sequence.id, sequence]));
30
+ const ratio = previousPlaybackRate / playbackRate;
31
+ const includedNodePaths = new Set();
32
+ for (const sequence of sequences) {
33
+ let ancestorId = sequence.id;
34
+ let belongsToRoot = false;
35
+ let descendantOffset = 0;
36
+ while (ancestorId !== null) {
37
+ if (ancestorId === root.id) {
38
+ belongsToRoot = true;
39
+ break;
40
+ }
41
+ const ancestor = sequencesById.get(ancestorId);
42
+ if (!ancestor) {
43
+ break;
44
+ }
45
+ descendantOffset += ancestor.from - ((_b = ancestor.trimBefore) !== null && _b !== void 0 ? _b : 0);
46
+ ancestorId = ancestor.parent;
47
+ }
48
+ if (!belongsToRoot) {
49
+ continue;
50
+ }
51
+ const overrideId = (_a = sequence.controls) === null || _a === void 0 ? void 0 : _a.overrideId;
52
+ const descendantNodePath = overrideId
53
+ ? overrideIdsToNodePaths[overrideId]
54
+ : undefined;
55
+ if (!descendantNodePath) {
56
+ continue;
57
+ }
58
+ const descendantKey = (0, studio_shared_1.stringifySequenceSubscriptionKey)(descendantNodePath);
59
+ if (includedNodePaths.has(descendantKey)) {
60
+ continue;
61
+ }
62
+ includedNodePaths.add(descendantKey);
63
+ // Local-clock descendant keyframes already follow their parent's rate.
64
+ // The shared collector includes only outer-clock descendants.
65
+ const targets = (0, get_keyframed_sequence_drag_targets_1.getKeyframedSequenceDragTargets)({
66
+ nodePath: descendantNodePath,
67
+ sequence,
68
+ sequences,
69
+ propStatuses,
70
+ isDescendant: sequence.id !== root.id,
71
+ });
72
+ const addMoves = (target, effectIndex) => {
73
+ var _a;
74
+ const adjustment = (_a = target.status.keyframeDisplayOffsetAdjustment) !== null && _a !== void 0 ? _a : 0;
75
+ // The adjustment includes the timing offsets between this element and
76
+ // the useCurrentFrame() binding. Remove the descendant offsets to find
77
+ // the edited element's start in that binding's source clock.
78
+ const anchor = sequence.id === root.id
79
+ ? root.from - adjustment
80
+ : -adjustment - descendantOffset;
81
+ if (!Number.isFinite(anchor)) {
82
+ return;
83
+ }
84
+ const nextKeyframes = target.status.keyframes.map((keyframe) => {
85
+ const frame = anchor + (keyframe.frame - anchor) * ratio;
86
+ const nearestInteger = Math.round(frame);
87
+ return {
88
+ ...keyframe,
89
+ frame: Math.abs(frame - nearestInteger) <=
90
+ Number.EPSILON * Math.max(1, Math.abs(frame)) * 2
91
+ ? nearestInteger
92
+ : frame,
93
+ };
94
+ });
95
+ if (nextKeyframes.some((keyframe) => !Number.isFinite(keyframe.frame)) ||
96
+ new Set(nextKeyframes.map((keyframe) => keyframe.frame)).size !==
97
+ nextKeyframes.length) {
98
+ return;
99
+ }
100
+ const moves = target.status.keyframes.flatMap((keyframe, index) => {
101
+ var _a;
102
+ const toFrame = (_a = nextKeyframes[index]) === null || _a === void 0 ? void 0 : _a.frame;
103
+ if (toFrame === undefined || toFrame === keyframe.frame) {
104
+ return [];
105
+ }
106
+ return [
107
+ {
108
+ fileName: target.fileName,
109
+ nodePath: target.nodePath,
110
+ fieldKey: target.fieldKey,
111
+ fromFrame: keyframe.frame,
112
+ toFrame,
113
+ schema: target.schema,
114
+ },
115
+ ];
116
+ });
117
+ if (moves.length === 0) {
118
+ return;
119
+ }
120
+ previews.push({
121
+ nodePath: target.nodePath,
122
+ fieldKey: target.fieldKey,
123
+ effectIndex,
124
+ status: { ...target.status, keyframes: nextKeyframes },
125
+ });
126
+ if (effectIndex === null) {
127
+ sequenceKeyframes.push(...moves);
128
+ }
129
+ else {
130
+ effectKeyframes.push(...moves.map((move) => ({ ...move, effectIndex })));
131
+ }
132
+ };
133
+ for (const target of targets.sequenceKeyframes) {
134
+ addMoves(target, null);
135
+ }
136
+ for (const target of targets.effectKeyframes) {
137
+ addMoves(target, target.effectIndex);
138
+ }
139
+ }
140
+ return { sequenceKeyframes, effectKeyframes, previews };
141
+ };
142
+ exports.getPlaybackRateKeyframeChanges = getPlaybackRateKeyframeChanges;
@@ -1,9 +1,22 @@
1
1
  import type { CanUpdateSequencePropStatus } from 'remotion';
2
- export declare const getTimelineKeyframes: (propStatus: CanUpdateSequencePropStatus | null | undefined, keyframeDisplayOffset?: number) => {
2
+ export type KeyframeSourceFrame = number | {
3
+ readonly displayFrame: number;
4
+ readonly keyframeDisplayOffset: number;
5
+ readonly keyframePlaybackRate: number;
6
+ };
7
+ export declare const getKeyframeSourceFrame: ({ displayFrame, keyframeDisplayOffset, keyframePlaybackRate, propStatus, }: {
8
+ displayFrame: number;
9
+ keyframeDisplayOffset: number;
10
+ keyframePlaybackRate: number;
11
+ propStatus: CanUpdateSequencePropStatus | null;
12
+ }) => number;
13
+ export declare const resolveKeyframeSourceFrame: (sourceFrame: KeyframeSourceFrame, propStatus: CanUpdateSequencePropStatus | null) => number;
14
+ export declare const getTimelineKeyframes: (propStatus: CanUpdateSequencePropStatus | null | undefined, keyframeDisplayOffset?: number, keyframePlaybackRate?: number) => {
3
15
  frame: number;
4
16
  value: unknown;
5
17
  }[];
6
- export declare const getKeyframeDisplayOffset: ({ propStatus, keyframeDisplayOffset, }: {
18
+ export declare const getKeyframeDisplayOffset: ({ propStatus, keyframeDisplayOffset, keyframePlaybackRate, }: {
7
19
  propStatus: CanUpdateSequencePropStatus | null | undefined;
8
20
  keyframeDisplayOffset: number;
21
+ keyframePlaybackRate: number;
9
22
  }) => number;
@@ -1,7 +1,44 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getKeyframeDisplayOffset = exports.getTimelineKeyframes = void 0;
4
- const getTimelineKeyframes = (propStatus, keyframeDisplayOffset = 0) => {
3
+ exports.getKeyframeDisplayOffset = exports.getTimelineKeyframes = exports.resolveKeyframeSourceFrame = exports.getKeyframeSourceFrame = void 0;
4
+ const getKeyframeSourceFrame = ({ displayFrame, keyframeDisplayOffset, keyframePlaybackRate, propStatus, }) => {
5
+ const sourceFrame = (displayFrame - keyframeDisplayOffset) * keyframePlaybackRate;
6
+ if ((propStatus === null || propStatus === void 0 ? void 0 : propStatus.status) !== 'keyframed') {
7
+ return sourceFrame;
8
+ }
9
+ // Converting a displayed keyframe back to source frames may introduce rounding
10
+ // error. Resolve its original frame so edits keep the existing keyframe identity,
11
+ // including when source keyframes themselves have fractional frames.
12
+ const tolerance = Number.EPSILON *
13
+ Math.max(1, Math.abs(displayFrame), Math.abs(keyframeDisplayOffset)) *
14
+ keyframePlaybackRate *
15
+ 8;
16
+ let closestFrame = sourceFrame;
17
+ let closestDistance = Infinity;
18
+ for (const keyframe of propStatus.keyframes) {
19
+ const distance = Math.abs(keyframe.frame - sourceFrame);
20
+ if (distance <= tolerance && distance < closestDistance) {
21
+ closestFrame = keyframe.frame;
22
+ closestDistance = distance;
23
+ }
24
+ }
25
+ return closestFrame;
26
+ };
27
+ exports.getKeyframeSourceFrame = getKeyframeSourceFrame;
28
+ const resolveKeyframeSourceFrame = (sourceFrame, propStatus) => {
29
+ return (0, exports.getKeyframeSourceFrame)({
30
+ ...(typeof sourceFrame === 'number'
31
+ ? {
32
+ displayFrame: sourceFrame,
33
+ keyframeDisplayOffset: 0,
34
+ keyframePlaybackRate: 1,
35
+ }
36
+ : sourceFrame),
37
+ propStatus,
38
+ });
39
+ };
40
+ exports.resolveKeyframeSourceFrame = resolveKeyframeSourceFrame;
41
+ const getTimelineKeyframes = (propStatus, keyframeDisplayOffset = 0, keyframePlaybackRate = 1) => {
5
42
  if (!propStatus) {
6
43
  return [];
7
44
  }
@@ -12,22 +49,23 @@ const getTimelineKeyframes = (propStatus, keyframeDisplayOffset = 0) => {
12
49
  const resolvedKeyframeDisplayOffset = (0, exports.getKeyframeDisplayOffset)({
13
50
  propStatus,
14
51
  keyframeDisplayOffset,
52
+ keyframePlaybackRate,
15
53
  });
16
- if (resolvedKeyframeDisplayOffset === 0) {
54
+ if (resolvedKeyframeDisplayOffset === 0 && keyframePlaybackRate === 1) {
17
55
  return keyframes;
18
56
  }
19
57
  return keyframes.map((keyframe) => ({
20
58
  ...keyframe,
21
- frame: keyframe.frame + resolvedKeyframeDisplayOffset,
59
+ frame: keyframe.frame / keyframePlaybackRate + resolvedKeyframeDisplayOffset,
22
60
  }));
23
61
  };
24
62
  exports.getTimelineKeyframes = getTimelineKeyframes;
25
- const getKeyframeDisplayOffset = ({ propStatus, keyframeDisplayOffset, }) => {
63
+ const getKeyframeDisplayOffset = ({ propStatus, keyframeDisplayOffset, keyframePlaybackRate, }) => {
26
64
  return (keyframeDisplayOffset +
27
65
  ((propStatus === null || propStatus === void 0 ? void 0 : propStatus.status) === 'keyframed' || (propStatus === null || propStatus === void 0 ? void 0 : propStatus.status) === 'static'
28
66
  ? propStatus.keyframeDisplayOffsetAdjustment === null
29
67
  ? 0
30
- : propStatus.keyframeDisplayOffsetAdjustment
68
+ : propStatus.keyframeDisplayOffsetAdjustment / keyframePlaybackRate
31
69
  : 0));
32
70
  };
33
71
  exports.getKeyframeDisplayOffset = getKeyframeDisplayOffset;
@@ -69,9 +69,11 @@ const resolveKeyframeField = ({ selection, sequences, overrideIdsToNodePaths, pr
69
69
  fieldKey: identity.fieldKey,
70
70
  }),
71
71
  propStatus: sequencePropStatus,
72
+ keyframePlaybackRate: track.keyframePlaybackRate,
72
73
  keyframeDisplayOffset: (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
73
74
  propStatus: sequencePropStatus,
74
75
  keyframeDisplayOffset: track.keyframeDisplayOffset,
76
+ keyframePlaybackRate: track.keyframePlaybackRate,
75
77
  }),
76
78
  };
77
79
  }
@@ -97,9 +99,11 @@ const resolveKeyframeField = ({ selection, sequences, overrideIdsToNodePaths, pr
97
99
  fieldKey: identity.fieldKey,
98
100
  }),
99
101
  propStatus: effectPropStatus,
102
+ keyframePlaybackRate: track.keyframePlaybackRate,
100
103
  keyframeDisplayOffset: (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
101
104
  propStatus: effectPropStatus,
102
105
  keyframeDisplayOffset: track.keyframeDisplayOffset,
106
+ keyframePlaybackRate: track.keyframePlaybackRate,
103
107
  }),
104
108
  };
105
109
  };
@@ -147,7 +151,12 @@ const getKeyframeClipboardDataFromSelections = ({ selections, sequences, overrid
147
151
  }
148
152
  const keyframes = [];
149
153
  for (const { selection } of resolvedFields) {
150
- const sourceFrame = selection.frame - firstResolved.keyframeDisplayOffset;
154
+ const sourceFrame = (0, get_timeline_keyframes_1.getKeyframeSourceFrame)({
155
+ displayFrame: selection.frame,
156
+ keyframeDisplayOffset: firstResolved.keyframeDisplayOffset,
157
+ keyframePlaybackRate: firstResolved.keyframePlaybackRate,
158
+ propStatus: keyframedPropStatus,
159
+ });
151
160
  const keyframe = keyframedPropStatus.keyframes.find((item) => item.frame === sourceFrame);
152
161
  if (keyframe === undefined ||
153
162
  JSON.stringify(keyframe.value) === undefined) {
@@ -195,7 +204,7 @@ const getKeyframeClipboardDataFromSelections = ({ selections, sequences, overrid
195
204
  },
196
205
  keyframes: keyframes.map((keyframe) => {
197
206
  return {
198
- frameOffset: keyframe.frame - firstFrame,
207
+ frameOffset: (keyframe.frame - firstFrame) / firstResolved.keyframePlaybackRate,
199
208
  value: keyframe.value,
200
209
  };
201
210
  }),
@@ -260,7 +269,12 @@ const getPasteKeyframeTarget = ({ selectedItems, payload, timelinePosition, sequ
260
269
  return { type: 'multiple' };
261
270
  }
262
271
  const keyframes = payload.keyframes.map((keyframe) => ({
263
- sourceFrame: timelinePosition - resolved.keyframeDisplayOffset + keyframe.frameOffset,
272
+ sourceFrame: (0, get_timeline_keyframes_1.getKeyframeSourceFrame)({
273
+ displayFrame: timelinePosition + keyframe.frameOffset,
274
+ keyframeDisplayOffset: resolved.keyframeDisplayOffset,
275
+ keyframePlaybackRate: resolved.keyframePlaybackRate,
276
+ propStatus: resolved.propStatus,
277
+ }),
264
278
  value: keyframe.value,
265
279
  }));
266
280
  const firstFrame = (_b = keyframes[0]) === null || _b === void 0 ? void 0 : _b.sourceFrame;
@@ -147,7 +147,10 @@ const splitSelectedTimelineItems = ({ selections, sequences, overrideIdsToNodePa
147
147
  if (eligibility.canSplit) {
148
148
  eligible.push({
149
149
  nodePathInfo: eligibility.nodePathInfo,
150
- splitFrame,
150
+ splitFrame: track
151
+ ? (splitFrame - track.keyframeDisplayOffset) *
152
+ track.keyframePlaybackRate
153
+ : splitFrame,
151
154
  });
152
155
  }
153
156
  else {
@@ -240,6 +240,7 @@ const formatTimelineFieldValueForDisplay = ({ fieldSchema, value, }) => {
240
240
  case 'uv-coordinate':
241
241
  return ((_e = formatUvCoordinateTimelineFieldValueForDisplay({ fieldSchema, value })) !== null && _e !== void 0 ? _e : formatUnknownTimelineValueForDisplay(value));
242
242
  case 'text-content':
243
+ case 'svg-path':
243
244
  return String(value);
244
245
  case 'asset':
245
246
  case 'array':
@@ -6,6 +6,7 @@ const timeline_row_layout_1 = require("./timeline-row-layout");
6
6
  exports.TIMELINE_STACKED_FIELD_HEADER_HEIGHT = 14;
7
7
  const isTimelineFieldStacked = ({ field, transform3DMode, }) => {
8
8
  return (field.typeName === 'text-content' ||
9
+ field.typeName === 'svg-path' ||
9
10
  (transform3DMode &&
10
11
  (field.typeName === 'translate' ||
11
12
  field.typeName === 'rotation-css' ||
@@ -55,17 +55,9 @@ const useDeleteTimelineItems = () => {
55
55
  timelinePosition,
56
56
  });
57
57
  if (deletePromise !== null) {
58
- deletePromise
59
- .then((deleted) => {
60
- if (!deleted) {
61
- return;
62
- }
58
+ const updateSelectionAfterDeletion = () => {
63
59
  const nextSelection = (0, delete_selected_timeline_item_1.getTimelineSelectionAfterDeletingItems)({
64
60
  selections: selectedItems,
65
- sequences,
66
- overrideIdsToNodePaths: overrideIdToNodePathMappings,
67
- propStatuses,
68
- timelinePosition,
69
61
  });
70
62
  if (nextSelection.length === 0) {
71
63
  clearSelection();
@@ -73,8 +65,22 @@ const useDeleteTimelineItems = () => {
73
65
  else {
74
66
  selectItems(nextSelection);
75
67
  }
76
- })
77
- .catch(() => undefined);
68
+ };
69
+ if (selectedItems.some((item) => item.type === 'keyframe')) {
70
+ // Keyframes are removed optimistically. Update selection in the same
71
+ // event so easing segments cannot inherit the deleted segments' indices.
72
+ updateSelectionAfterDeletion();
73
+ deletePromise.catch(() => undefined);
74
+ }
75
+ else {
76
+ deletePromise
77
+ .then((deleted) => {
78
+ if (deleted) {
79
+ updateSelectionAfterDeletion();
80
+ }
81
+ })
82
+ .catch(() => undefined);
83
+ }
78
84
  return;
79
85
  }
80
86
  const easingSelections = (0, update_selected_easing_1.getEasingSelections)(selectedItems);
@@ -8,10 +8,11 @@ export type ExpandedTrackKeyframeRow = {
8
8
  readonly nodePathInfo: SequenceNodePathInfo;
9
9
  readonly rowKey: string;
10
10
  };
11
- export declare const useExpandedTrackKeyframeRows: ({ sequence, nodePathInfo, keyframeDisplayOffset, }: {
11
+ export declare const useExpandedTrackKeyframeRows: ({ sequence, nodePathInfo, keyframeDisplayOffset, keyframePlaybackRate, }: {
12
12
  sequence: TSequence;
13
13
  nodePathInfo: SequenceNodePathInfo;
14
14
  keyframeDisplayOffset: number;
15
+ keyframePlaybackRate: number;
15
16
  }) => {
16
17
  readonly rows: ExpandedTrackKeyframeRow[];
17
18
  readonly expandedHeight: number;
@@ -62,7 +62,7 @@ const getNodeCanEditEasing = ({ node, nodePath, propStatuses, }) => {
62
62
  return ((effectPropStatus === null || effectPropStatus === void 0 ? void 0 : effectPropStatus.status) === 'keyframed' &&
63
63
  (0, studio_shared_1.canEditEasingForInterpolationFunction)(effectPropStatus.interpolationFunction));
64
64
  };
65
- const useExpandedTrackKeyframeRows = ({ sequence, nodePathInfo, keyframeDisplayOffset, }) => {
65
+ const useExpandedTrackKeyframeRows = ({ sequence, nodePathInfo, keyframeDisplayOffset, keyframePlaybackRate, }) => {
66
66
  const { getIsExpanded } = (0, react_1.useContext)(ExpandedTracksProvider_1.ExpandedTracksGetterContext);
67
67
  const { propStatuses } = (0, react_1.useContext)(remotion_1.Internals.VisualModePropStatusesContext);
68
68
  const { getDragOverrides, getEffectDragOverrides } = (0, react_1.useContext)(remotion_1.Internals.VisualModeDragOverridesContext);
@@ -123,6 +123,7 @@ const useExpandedTrackKeyframeRows = ({ sequence, nodePathInfo, keyframeDisplayO
123
123
  nodePath: nodePathInfo.sequenceSubscriptionKey,
124
124
  propStatuses,
125
125
  keyframeDisplayOffset,
126
+ keyframePlaybackRate,
126
127
  getDragOverrides,
127
128
  getEffectDragOverrides,
128
129
  timelinePosition: (0, imperative_state_1.getCurrentFrame)(),
@@ -132,6 +133,7 @@ const useExpandedTrackKeyframeRows = ({ sequence, nodePathInfo, keyframeDisplayO
132
133
  getDragOverrides,
133
134
  getEffectDragOverrides,
134
135
  keyframeDisplayOffset,
136
+ keyframePlaybackRate,
135
137
  nodePathInfo.sequenceSubscriptionKey,
136
138
  propStatuses,
137
139
  ]);
@@ -12,10 +12,14 @@ const isSequenceVisibleAtTimelinePosition = ({ sequence, timelinePosition, }) =>
12
12
  };
13
13
  exports.isSequenceVisibleAtTimelinePosition = isSequenceVisibleAtTimelinePosition;
14
14
  const calculateSequenceFreezeFrame = ({ sequence, sequenceFrameOffset, timelinePosition, }) => {
15
- const rawFreezeFrame = Math.round(timelinePosition - sequence.from + sequenceFrameOffset);
16
- const minFrame = sequenceFrameOffset;
15
+ const rawFreezeFrame = (timelinePosition - sequence.from) * sequence.sequencePlaybackRate +
16
+ sequenceFrameOffset;
17
+ const minFrame = (Math.ceil(sequence.from) - sequence.from) * sequence.sequencePlaybackRate +
18
+ sequenceFrameOffset;
17
19
  const maxFrame = Number.isFinite(sequence.duration)
18
- ? Math.max(minFrame, sequence.duration + sequenceFrameOffset - 1)
20
+ ? Math.max(minFrame, (Math.ceil(sequence.from + sequence.duration) - 1 - sequence.from) *
21
+ sequence.sequencePlaybackRate +
22
+ sequenceFrameOffset)
19
23
  : Infinity;
20
24
  return Math.min(Math.max(minFrame, rawFreezeFrame), maxFrame);
21
25
  };
@@ -102,7 +102,7 @@ const getTimelineSelectionsAfterEasingKeyframeDrag = ({ delta, selections, targe
102
102
  exports.getTimelineSelectionsAfterEasingKeyframeDrag = getTimelineSelectionsAfterEasingKeyframeDrag;
103
103
  const getCodeValueForTarget = ({ propStatuses, nodePath, }) => propStatuses[remotion_1.Internals.makeSequencePropsSubscriptionKey(nodePath)];
104
104
  const getTimelineKeyframeDragTarget = ({ propStatuses, displayFrame, nodePathInfo, overrideIdsToNodePaths, sequences, }) => {
105
- var _a, _b, _c;
105
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
106
106
  const field = (0, parse_keyframe_field_from_node_path_1.parseKeyframeFieldFromNodePath)(nodePathInfo.auxiliaryKeys);
107
107
  if (field === null) {
108
108
  return null;
@@ -132,11 +132,16 @@ const getTimelineKeyframeDragTarget = ({ propStatuses, displayFrame, nodePathInf
132
132
  if ((effectPropStatus === null || effectPropStatus === void 0 ? void 0 : effectPropStatus.status) !== 'keyframed') {
133
133
  return null;
134
134
  }
135
- const effectSourceFrame = displayFrame -
136
- (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
135
+ const effectSourceFrame = (0, get_timeline_keyframes_1.getKeyframeSourceFrame)({
136
+ displayFrame,
137
+ propStatus: effectPropStatus,
138
+ keyframeDisplayOffset: (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
137
139
  propStatus: effectPropStatus,
138
140
  keyframeDisplayOffset: (_b = track === null || track === void 0 ? void 0 : track.keyframeDisplayOffset) !== null && _b !== void 0 ? _b : 0,
139
- });
141
+ keyframePlaybackRate: (_c = track === null || track === void 0 ? void 0 : track.keyframePlaybackRate) !== null && _c !== void 0 ? _c : 1,
142
+ }),
143
+ keyframePlaybackRate: (_d = track === null || track === void 0 ? void 0 : track.keyframePlaybackRate) !== null && _d !== void 0 ? _d : 1,
144
+ });
140
145
  if (!effectPropStatus.keyframes.some((keyframe) => keyframe.frame === effectSourceFrame)) {
141
146
  return null;
142
147
  }
@@ -151,17 +156,23 @@ const getTimelineKeyframeDragTarget = ({ propStatuses, displayFrame, nodePathInf
151
156
  propStatus: effectPropStatus,
152
157
  schema: effect.schema,
153
158
  sourceFrame: effectSourceFrame,
159
+ keyframePlaybackRate: (_e = track === null || track === void 0 ? void 0 : track.keyframePlaybackRate) !== null && _e !== void 0 ? _e : 1,
154
160
  };
155
161
  }
156
162
  const sequencePropStatus = sequenceStatus.props[field.fieldKey];
157
163
  if ((sequencePropStatus === null || sequencePropStatus === void 0 ? void 0 : sequencePropStatus.status) !== 'keyframed') {
158
164
  return null;
159
165
  }
160
- const sourceFrame = displayFrame -
161
- (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
166
+ const sourceFrame = (0, get_timeline_keyframes_1.getKeyframeSourceFrame)({
167
+ displayFrame,
168
+ propStatus: sequencePropStatus,
169
+ keyframeDisplayOffset: (0, get_timeline_keyframes_1.getKeyframeDisplayOffset)({
162
170
  propStatus: sequencePropStatus,
163
- keyframeDisplayOffset: (_c = track === null || track === void 0 ? void 0 : track.keyframeDisplayOffset) !== null && _c !== void 0 ? _c : 0,
164
- });
171
+ keyframeDisplayOffset: (_f = track === null || track === void 0 ? void 0 : track.keyframeDisplayOffset) !== null && _f !== void 0 ? _f : 0,
172
+ keyframePlaybackRate: (_g = track === null || track === void 0 ? void 0 : track.keyframePlaybackRate) !== null && _g !== void 0 ? _g : 1,
173
+ }),
174
+ keyframePlaybackRate: (_h = track === null || track === void 0 ? void 0 : track.keyframePlaybackRate) !== null && _h !== void 0 ? _h : 1,
175
+ });
165
176
  if (!sequencePropStatus.keyframes.some((keyframe) => keyframe.frame === sourceFrame)) {
166
177
  return null;
167
178
  }
@@ -175,6 +186,7 @@ const getTimelineKeyframeDragTarget = ({ propStatuses, displayFrame, nodePathInf
175
186
  propStatus: sequencePropStatus,
176
187
  schema: sequence.controls.schema,
177
188
  sourceFrame,
189
+ keyframePlaybackRate: (_j = track === null || track === void 0 ? void 0 : track.keyframePlaybackRate) !== null && _j !== void 0 ? _j : 1,
178
190
  };
179
191
  };
180
192
  const getTargetGroupKey = (target) => {
@@ -196,10 +208,11 @@ const groupTargets = (targets) => {
196
208
  }
197
209
  return [...groups.values()];
198
210
  };
199
- const getMovesForGroup = ({ group, delta, }) => group.map((target) => ({
211
+ const getMoveForTarget = (target, delta) => ({
200
212
  fromFrame: target.sourceFrame,
201
- toFrame: target.sourceFrame + delta,
202
- }));
213
+ toFrame: (0, get_timeline_keyframes_1.resolveKeyframeSourceFrame)(target.sourceFrame + delta * target.keyframePlaybackRate, target.propStatus),
214
+ });
215
+ const getMovesForGroup = ({ group, delta, }) => group.map((target) => getMoveForTarget(target, delta));
203
216
  const canMoveTimelineKeyframeDragTargets = ({ targets, delta, }) => groupTargets(targets).every((group) => {
204
217
  const [first] = group;
205
218
  if (!first) {
@@ -422,8 +435,7 @@ const useTimelineKeyframeDrag = ({ frame, nodePathInfo, onSelect, selectable, se
422
435
  fileName: target.fileName,
423
436
  nodePath: target.nodePath,
424
437
  fieldKey: target.fieldKey,
425
- fromFrame: target.sourceFrame,
426
- toFrame: target.sourceFrame + lastDelta,
438
+ ...getMoveForTarget(target, lastDelta),
427
439
  schema: target.schema,
428
440
  })),
429
441
  effectKeyframes: targets
@@ -433,8 +445,7 @@ const useTimelineKeyframeDrag = ({ frame, nodePathInfo, onSelect, selectable, se
433
445
  nodePath: target.nodePath,
434
446
  effectIndex: target.effectIndex,
435
447
  fieldKey: target.fieldKey,
436
- fromFrame: target.sourceFrame,
437
- toFrame: target.sourceFrame + lastDelta,
448
+ ...getMoveForTarget(target, lastDelta),
438
449
  schema: target.schema,
439
450
  })),
440
451
  setPropStatuses,
@@ -629,8 +640,7 @@ const useTimelineEasingKeyframeDrag = ({ onSelect, selectable, selected, selecti
629
640
  fileName: target.fileName,
630
641
  nodePath: target.nodePath,
631
642
  fieldKey: target.fieldKey,
632
- fromFrame: target.sourceFrame,
633
- toFrame: target.sourceFrame + lastDelta,
643
+ ...getMoveForTarget(target, lastDelta),
634
644
  schema: target.schema,
635
645
  })),
636
646
  effectKeyframes: targets
@@ -640,8 +650,7 @@ const useTimelineEasingKeyframeDrag = ({ onSelect, selectable, selected, selecti
640
650
  nodePath: target.nodePath,
641
651
  effectIndex: target.effectIndex,
642
652
  fieldKey: target.fieldKey,
643
- fromFrame: target.sourceFrame,
644
- toFrame: target.sourceFrame + lastDelta,
653
+ ...getMoveForTarget(target, lastDelta),
645
654
  schema: target.schema,
646
655
  })),
647
656
  setPropStatuses,
@@ -8,7 +8,7 @@ const ModelManager_1 = require("../ModelManager");
8
8
  const AVAILABLE_MODELS = (0, whisper_webgpu_1.getAvailableModels)();
9
9
  const Models = ({ description, indent, visible }) => {
10
10
  const isModelCached = (0, react_1.useCallback)((model) => (0, whisper_webgpu_1.isWhisperModelCached)({ model }), []);
11
- const loadModel = (0, react_1.useCallback)((model, onProgress) => (0, whisper_webgpu_1.loadWhisperModel)({
11
+ const loadModel = (0, react_1.useCallback)((model, onProgress) => (0, whisper_webgpu_1.downloadWhisperModel)({
12
12
  model,
13
13
  onProgress: (progress) => onProgress(progress.progress),
14
14
  }), []);
@@ -324,7 +324,9 @@ const TranscriptionModal = ({ audioStreamIndex, displayName, requestInit, src, t
324
324
  }, []);
325
325
  const normalizedOutName = outName.normalize('NFC').toLowerCase();
326
326
  const queuedOutputExists = captionJobs.some((job) => job.target === null &&
327
- (job.status === 'idle' || job.status === 'running') &&
327
+ (job.status === 'idle' ||
328
+ job.status === 'running' ||
329
+ job.status === 'saving') &&
328
330
  job.outName.normalize('NFC').toLowerCase() === normalizedOutName);
329
331
  const outputValidationMessage = target === null
330
332
  ? ((_a = (0, caption_output_name_1.validateCaptionOutputName)(outName)) !== null && _a !== void 0 ? _a : (queuedOutputExists
@@ -1,6 +1,7 @@
1
- export declare const resampleMediaTo16Khz: ({ src, audioStreamIndex, requestInit, onProgress, }: {
1
+ export declare const resampleMediaTo16Khz: ({ src, audioStreamIndex, requestInit, onProgress, signal, }: {
2
2
  readonly src: string;
3
3
  readonly audioStreamIndex: number | null;
4
4
  readonly requestInit: Omit<RequestInit, "signal"> | null;
5
5
  readonly onProgress: (progress: number) => void;
6
+ readonly signal: AbortSignal;
6
7
  }) => Promise<Float32Array<ArrayBufferLike>>;
@@ -3,13 +3,22 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resampleMediaTo16Khz = void 0;
4
4
  const whisper_webgpu_1 = require("@remotion/whisper-webgpu");
5
5
  const mediabunny_1 = require("mediabunny");
6
- const resampleMediaTo16Khz = async ({ src, audioStreamIndex, requestInit, onProgress, }) => {
6
+ const resampleMediaTo16Khz = async ({ src, audioStreamIndex, requestInit, onProgress, signal, }) => {
7
7
  var _a, _b;
8
+ signal.throwIfAborted();
8
9
  const input = new mediabunny_1.Input({
9
10
  formats: mediabunny_1.ALL_FORMATS,
10
11
  source: new mediabunny_1.UrlSource(src, requestInit === null ? {} : { requestInit }),
11
12
  });
12
13
  const waveformChunks = [];
14
+ let conversion = null;
15
+ let cancellation = null;
16
+ const onAbort = () => {
17
+ var _a;
18
+ cancellation = (_a = conversion === null || conversion === void 0 ? void 0 : conversion.cancel().catch(() => undefined)) !== null && _a !== void 0 ? _a : null;
19
+ input.dispose();
20
+ };
21
+ signal.addEventListener('abort', onAbort, { once: true });
13
22
  try {
14
23
  onProgress(0);
15
24
  const audioTracks = await input.getAudioTracks();
@@ -29,7 +38,8 @@ const resampleMediaTo16Khz = async ({ src, audioStreamIndex, requestInit, onProg
29
38
  format: new mediabunny_1.WavOutputFormat(),
30
39
  target: new mediabunny_1.NullTarget(),
31
40
  });
32
- const conversion = await mediabunny_1.Conversion.init({
41
+ signal.throwIfAborted();
42
+ conversion = await mediabunny_1.Conversion.init({
33
43
  input,
34
44
  output,
35
45
  tracks: 'all',
@@ -43,6 +53,7 @@ const resampleMediaTo16Khz = async ({ src, audioStreamIndex, requestInit, onProg
43
53
  forceTranscode: true,
44
54
  numberOfChannels: 1,
45
55
  process: (sample) => {
56
+ signal.throwIfAborted();
46
57
  const floats = new Float32Array(sample.allocationSize({ format: 'f32', planeIndex: 0 }) /
47
58
  Float32Array.BYTES_PER_ELEMENT);
48
59
  sample.copyTo(floats, { format: 'f32', planeIndex: 0 });
@@ -57,14 +68,21 @@ const resampleMediaTo16Khz = async ({ src, audioStreamIndex, requestInit, onProg
57
68
  };
58
69
  },
59
70
  });
71
+ signal.throwIfAborted();
60
72
  if (!conversion.isValid) {
61
73
  throw new Error('The audio track cannot be decoded in this browser. Try converting the media to WAV first.');
62
74
  }
63
75
  conversion.onProgress = (progress) => onProgress(progress);
64
76
  await conversion.execute();
77
+ signal.throwIfAborted();
65
78
  onProgress(1);
66
79
  }
67
80
  finally {
81
+ signal.removeEventListener('abort', onAbort);
82
+ await cancellation;
83
+ if (signal.aborted && conversion && cancellation === null) {
84
+ await conversion.cancel().catch(() => undefined);
85
+ }
68
86
  input.dispose();
69
87
  }
70
88
  const waveformLength = waveformChunks.reduce((maximum, chunk) => Math.max(maximum, chunk.startFrame + chunk.waveform.length), 0);