remotion 4.0.536 → 4.0.538

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 (172) hide show
  1. package/dist/cjs/AbsoluteFill.d.ts +62 -62
  2. package/dist/cjs/AbsoluteFill.js +3 -3
  3. package/dist/cjs/AbsoluteFillElement.d.ts +1 -1
  4. package/dist/cjs/AbsoluteFillElement.js +36 -3
  5. package/dist/cjs/CanUseRemotionHooks.js +1 -1
  6. package/dist/cjs/Composition.js +5 -11
  7. package/dist/cjs/CompositionErrorBoundary.js +5 -2
  8. package/dist/cjs/CompositionManager.d.ts +1 -0
  9. package/dist/cjs/CompositionManagerContext.d.ts +3 -0
  10. package/dist/cjs/CompositionManagerContext.js +5 -3
  11. package/dist/cjs/CompositionManagerProvider.d.ts +1 -1
  12. package/dist/cjs/CompositionManagerProvider.js +3 -1
  13. package/dist/cjs/CompositionRegistryProvider.d.ts +1 -1
  14. package/dist/cjs/CompositionRegistryProvider.js +1 -1
  15. package/dist/cjs/EditorProps.d.ts +2 -2
  16. package/dist/cjs/EditorProps.js +1 -1
  17. package/dist/cjs/Folder.js +1 -1
  18. package/dist/cjs/HtmlInCanvas.d.ts +58 -67
  19. package/dist/cjs/HtmlInCanvas.js +84 -20
  20. package/dist/cjs/HtmlInCanvasFallback.d.ts +6 -0
  21. package/dist/cjs/HtmlInCanvasFallback.js +39 -0
  22. package/dist/cjs/IFrame.d.ts +2 -2
  23. package/dist/cjs/IFrame.js +1 -1
  24. package/dist/cjs/Img.d.ts +62 -62
  25. package/dist/cjs/Img.js +160 -132
  26. package/dist/cjs/Interactive.d.ts +147 -145
  27. package/dist/cjs/Interactive.js +2 -2
  28. package/dist/cjs/RemotionRoot.js +1 -1
  29. package/dist/cjs/RenderAssetManager.js +1 -1
  30. package/dist/cjs/Sequence.js +37 -27
  31. package/dist/cjs/SequenceActivityBoundary.js +1 -1
  32. package/dist/cjs/SequenceActivityBudget.js +1 -1
  33. package/dist/cjs/SequenceActivitySuspensionProvider.js +1 -1
  34. package/dist/cjs/SequenceManager.d.ts +6 -0
  35. package/dist/cjs/SequenceManager.js +71 -27
  36. package/dist/cjs/SequenceRegistryProvider.js +16 -3
  37. package/dist/cjs/TimelineContext.js +1 -1
  38. package/dist/cjs/Track.js +2 -2
  39. package/dist/cjs/animated-image/AnimatedImage.d.ts +69 -69
  40. package/dist/cjs/animated-image/AnimatedImage.js +17 -12
  41. package/dist/cjs/animated-image/canvas.d.ts +6 -5
  42. package/dist/cjs/animated-image/canvas.js +1 -1
  43. package/dist/cjs/animated-image/create-image-decoder.d.ts +1 -1
  44. package/dist/cjs/animated-image/decode-image.d.ts +1 -1
  45. package/dist/cjs/animated-image/get-duration-in-seconds.d.ts +1 -1
  46. package/dist/cjs/animated-image/index.js +1 -1
  47. package/dist/cjs/audio/AudioForPreview.js +5 -28
  48. package/dist/cjs/audio/AudioForRendering.d.ts +5 -20
  49. package/dist/cjs/audio/AudioForRendering.js +44 -5
  50. package/dist/cjs/audio/html5-audio.d.ts +36 -36
  51. package/dist/cjs/audio/html5-audio.js +8 -10
  52. package/dist/cjs/audio/index.js +1 -1
  53. package/dist/cjs/audio/shared-audio-tags.js +10 -16
  54. package/dist/cjs/audio/shared-element-source-node.d.ts +1 -1
  55. package/dist/cjs/audio/use-audio-context.d.ts +2 -1
  56. package/dist/cjs/audio/wait-until-actually-resumed.d.ts +2 -1
  57. package/dist/cjs/buffer-until-first-frame.d.ts +4 -3
  58. package/dist/cjs/buffering.js +1 -1
  59. package/dist/cjs/cancel-render.js +3 -0
  60. package/dist/cjs/canvas-image/CanvasImage.d.ts +71 -71
  61. package/dist/cjs/canvas-image/CanvasImage.js +27 -24
  62. package/dist/cjs/canvas-image/index.js +1 -1
  63. package/dist/cjs/codec.d.ts +1 -1
  64. package/dist/cjs/committed-metadata.d.ts +4 -2
  65. package/dist/cjs/composition-registry-fallback.d.ts +4 -2
  66. package/dist/cjs/composition-registry-fallback.js +12 -10
  67. package/dist/cjs/create-element-source-proxy.js +46 -6
  68. package/dist/cjs/default-css.d.ts +1 -1
  69. package/dist/cjs/delay-render.d.ts +2 -1
  70. package/dist/cjs/delay-render.js +4 -2
  71. package/dist/cjs/easing.js +3 -1
  72. package/dist/cjs/effects/Solid.d.ts +60 -60
  73. package/dist/cjs/effects/Solid.js +2 -2
  74. package/dist/cjs/effects/canvas-pool.js +6 -9
  75. package/dist/cjs/effects/index.js +1 -1
  76. package/dist/cjs/effects/use-memoized-effects.d.ts +2 -1
  77. package/dist/cjs/effects/use-memoized-effects.js +107 -54
  78. package/dist/cjs/freeze.js +2 -2
  79. package/dist/cjs/get-cross-origin-value.d.ts +1 -1
  80. package/dist/cjs/get-effective-visual-mode-value.d.ts +2 -2
  81. package/dist/cjs/index.d.ts +3 -1
  82. package/dist/cjs/index.js +32 -32
  83. package/dist/cjs/interactivity-schema.d.ts +286 -286
  84. package/dist/cjs/internals.d.ts +411 -595
  85. package/dist/cjs/internals.js +8 -0
  86. package/dist/cjs/interpolate-colors.d.ts +1 -1
  87. package/dist/cjs/interpolate-colors.js +17 -16
  88. package/dist/cjs/interpolate.d.ts +2 -9
  89. package/dist/cjs/is-player.js +1 -1
  90. package/dist/cjs/loading-indicator.js +2 -6
  91. package/dist/cjs/log-level-context.d.ts +1 -1
  92. package/dist/cjs/log.d.ts +12 -7
  93. package/dist/cjs/loop/index.js +1 -1
  94. package/dist/cjs/media-resource-manager.d.ts +1 -1
  95. package/dist/cjs/media-tag-current-time-timestamp.d.ts +1 -1
  96. package/dist/cjs/no-react.d.ts +85 -91
  97. package/dist/cjs/no-react.js +2 -2
  98. package/dist/cjs/play-and-handle-not-allowed-error.d.ts +5 -4
  99. package/dist/cjs/playback-logging.d.ts +2 -1
  100. package/dist/cjs/playback-pitch-context.d.ts +1 -0
  101. package/dist/cjs/playback-pitch-context.js +5 -0
  102. package/dist/cjs/prefetch-state.js +1 -1
  103. package/dist/cjs/prefetch.d.ts +7 -6
  104. package/dist/cjs/props-if-has-props.d.ts +2 -1
  105. package/dist/cjs/prores-profile.d.ts +1 -1
  106. package/dist/cjs/register-root.d.ts +2 -2
  107. package/dist/cjs/render-resource-manager.d.ts +1 -1
  108. package/dist/cjs/render-types.d.ts +2 -2
  109. package/dist/cjs/resolve-video-config.d.ts +8 -8
  110. package/dist/cjs/runtime-value-store.d.ts +1 -1
  111. package/dist/cjs/scale-value.d.ts +1 -1
  112. package/dist/cjs/seek.d.ts +3 -2
  113. package/dist/cjs/sequence-activity-context.js +1 -1
  114. package/dist/cjs/sequence-crop.js +1 -4
  115. package/dist/cjs/series/flatten-children.d.ts +3 -1
  116. package/dist/cjs/series/index.js +4 -5
  117. package/dist/cjs/series/is-inside-series.js +2 -2
  118. package/dist/cjs/spring/index.d.ts +1 -1
  119. package/dist/cjs/spring/index.js +1 -1
  120. package/dist/cjs/spring/measure-spring.d.ts +1 -1
  121. package/dist/cjs/spring/spring-utils.d.ts +1 -1
  122. package/dist/cjs/spring/spring-utils.js +11 -5
  123. package/dist/cjs/timeline-position-state.d.ts +2 -1
  124. package/dist/cjs/timeline-position-state.js +23 -3
  125. package/dist/cjs/use-amplification.d.ts +4 -7
  126. package/dist/cjs/use-current-frame.d.ts +1 -0
  127. package/dist/cjs/use-current-frame.js +14 -7
  128. package/dist/cjs/use-current-scale.d.ts +2 -2
  129. package/dist/cjs/use-delay-render.d.ts +2 -1
  130. package/dist/cjs/use-lazy-component.d.ts +1 -1
  131. package/dist/cjs/use-lazy-component.js +15 -5
  132. package/dist/cjs/use-media-buffering.d.ts +3 -2
  133. package/dist/cjs/use-media-duration.d.ts +4 -0
  134. package/dist/cjs/use-media-duration.js +36 -0
  135. package/dist/cjs/use-media-enabled.d.ts +1 -1
  136. package/dist/cjs/use-media-enabled.js +1 -1
  137. package/dist/cjs/use-media-in-timeline.d.ts +1 -1
  138. package/dist/cjs/use-media-playback.d.ts +3 -3
  139. package/dist/cjs/use-media-tag.d.ts +2 -2
  140. package/dist/cjs/use-pixel-density.d.ts +1 -1
  141. package/dist/cjs/use-premounting.d.ts +1 -1
  142. package/dist/cjs/use-premounting.js +6 -2
  143. package/dist/cjs/use-request-video-callback-time.d.ts +3 -3
  144. package/dist/cjs/use-schema.d.ts +4 -4
  145. package/dist/cjs/use-video.js +1 -1
  146. package/dist/cjs/validate-media-props.d.ts +1 -1
  147. package/dist/cjs/validation/validate-default-props.d.ts +1 -1
  148. package/dist/cjs/validation/validate-duration-in-frames.js +3 -3
  149. package/dist/cjs/version.d.ts +1 -1
  150. package/dist/cjs/version.js +1 -1
  151. package/dist/cjs/video/MediaPlaybackError.js +0 -1
  152. package/dist/cjs/video/OffthreadVideo.js +5 -5
  153. package/dist/cjs/video/OffthreadVideoForRendering.js +9 -7
  154. package/dist/cjs/video/VideoForPreview.js +6 -28
  155. package/dist/cjs/video/VideoForRendering.d.ts +5 -3
  156. package/dist/cjs/video/VideoForRendering.js +4 -2
  157. package/dist/cjs/video/duration-state.d.ts +1 -0
  158. package/dist/cjs/video/duration-state.js +8 -2
  159. package/dist/cjs/video/emit-video-frame.d.ts +1 -1
  160. package/dist/cjs/video/html5-video.d.ts +36 -36
  161. package/dist/cjs/video/html5-video.js +8 -10
  162. package/dist/cjs/video/index.js +2 -2
  163. package/dist/cjs/video/seek-until-right.d.ts +3 -2
  164. package/dist/cjs/warn-about-non-seekable-media.d.ts +1 -1
  165. package/dist/cjs/with-interactivity-schema.d.ts +1 -1
  166. package/dist/cjs/with-interactivity-schema.js +15 -18
  167. package/dist/cjs/wrap-remotion-context.d.ts +4 -4
  168. package/dist/cjs/wrap-remotion-context.js +2 -2
  169. package/dist/esm/index.mjs +1060 -728
  170. package/dist/esm/no-react.mjs +30 -25
  171. package/dist/esm/version.mjs +1 -1
  172. package/package.json +4 -4
@@ -27,6 +27,7 @@ __export(exports_timeline_position_state, {
27
27
  usePlaying: () => usePlaying,
28
28
  useTimelineContext: () => useTimelineContext,
29
29
  useTimelinePosition: () => useTimelinePosition,
30
+ useTimelinePositionWithOptionalSubscription: () => useTimelinePositionWithOptionalSubscription,
30
31
  useTimelineSeekFrame: () => useTimelineSeekFrame,
31
32
  useTimelineSetFrameWithoutSeek: () => useTimelineSetFrameWithoutSeek
32
33
  });
@@ -63,13 +64,7 @@ var Clipper = () => {
63
64
  };
64
65
 
65
66
  // src/Composition.tsx
66
- import {
67
- Suspense,
68
- useCallback as useCallback3,
69
- useContext as useContext10,
70
- useEffect as useEffect4,
71
- useMemo as useMemo8
72
- } from "react";
67
+ import { Suspense, useContext as useContext10, useEffect as useEffect4, useMemo as useMemo8 } from "react";
73
68
  import { createPortal } from "react-dom";
74
69
 
75
70
  // src/CanUseRemotionHooks.tsx
@@ -174,6 +169,15 @@ import {
174
169
  } from "react";
175
170
  var CompositionRegistryFallbackContext = createContext5(null);
176
171
  var useIsomorphicLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
172
+ var createEntryCleanup = (registry, identity) => {
173
+ if (registry === null) {
174
+ return;
175
+ }
176
+ return () => {
177
+ registry.entries.delete(identity);
178
+ registry.notifyCommit();
179
+ };
180
+ };
177
181
  var useCommittedCompositionEntry = (entry) => {
178
182
  const registry = useContext(CompositionRegistryFallbackContext);
179
183
  const key = useRef({});
@@ -188,16 +192,7 @@ var useCommittedCompositionEntry = (entry) => {
188
192
  }
189
193
  registry.notifyCommit();
190
194
  }, [entry, registry]);
191
- useIsomorphicLayoutEffect(() => {
192
- if (registry === null) {
193
- return;
194
- }
195
- const identity = key.current;
196
- return () => {
197
- registry.entries.delete(identity);
198
- registry.notifyCommit();
199
- };
200
- }, [registry]);
195
+ useIsomorphicLayoutEffect(createEntryCleanup.bind(null, registry, key.current), [registry]);
201
196
  };
202
197
 
203
198
  // src/composition-render-error-context.ts
@@ -284,13 +279,15 @@ class CompositionErrorBoundary extends React5.Component {
284
279
  // src/CompositionManagerContext.tsx
285
280
  import { createContext as createContext7 } from "react";
286
281
  var getAssetPreviewCompositionId = (asset) => `asset:${asset}`;
287
- var CompositionManager = createContext7({
282
+ var defaultCompositionManagerContext = {
288
283
  compositions: [],
289
284
  folders: [],
290
285
  currentCompositionMetadata: null,
291
286
  currentAssetMetadata: null,
292
287
  canvasContent: null
293
- });
288
+ };
289
+ var CompositionManager = createContext7(defaultCompositionManagerContext);
290
+ var CompositionManagerRefContext = createContext7({ current: defaultCompositionManagerContext });
294
291
  var CompositionSetters = createContext7({
295
292
  setCanvasContent: () => {
296
293
  return;
@@ -472,7 +469,7 @@ var useIsPlayer = () => {
472
469
  };
473
470
 
474
471
  // src/AbsoluteFillElement.tsx
475
- import { forwardRef, useMemo as useMemo2 } from "react";
472
+ import React6, { forwardRef, useMemo as useMemo2 } from "react";
476
473
  import { jsx as jsx5 } from "react/jsx-runtime";
477
474
  var hasTailwindClassName = ({
478
475
  className,
@@ -565,7 +562,7 @@ var AbsoluteFillElementRefForwarding = (props, ref) => {
565
562
  ...other
566
563
  });
567
564
  };
568
- var AbsoluteFillElement = forwardRef(AbsoluteFillElementRefForwarding);
565
+ var AbsoluteFillElement = React6.memo(forwardRef(AbsoluteFillElementRefForwarding));
569
566
 
570
567
  // src/use-current-scale.ts
571
568
  import React10, { createContext as createContext14 } from "react";
@@ -761,12 +758,12 @@ function validateDurationInFrames(durationInFrames, options) {
761
758
  if (durationInFrames <= 0) {
762
759
  throw new TypeError(`The "durationInFrames" prop ${component} must be positive, but got ${durationInFrames}.`);
763
760
  }
764
- if (!allowFloats && durationInFrames % 1 !== 0) {
765
- throw new TypeError(`The "durationInFrames" prop ${component} must be an integer, but got ${durationInFrames}.`);
766
- }
767
761
  if (!Number.isFinite(durationInFrames)) {
768
762
  throw new TypeError(`The "durationInFrames" prop ${component} must be finite, but got ${durationInFrames}.`);
769
763
  }
764
+ if (!allowFloats && durationInFrames % 1 !== 0) {
765
+ throw new TypeError(`The "durationInFrames" prop ${component} must be an integer, but got ${durationInFrames}.`);
766
+ }
770
767
  }
771
768
 
772
769
  // src/validation/validate-fps.ts
@@ -1166,6 +1163,7 @@ function cancelRenderInternal(scope, err) {
1166
1163
  error = Error("Rendering was cancelled");
1167
1164
  }
1168
1165
  if (scope) {
1166
+ scope.remotion_cancelledErrorObject = error;
1169
1167
  scope.remotion_cancelledError = getErrorStackWithMessage(error);
1170
1168
  }
1171
1169
  throw error;
@@ -1271,7 +1269,9 @@ var delayRenderInternal = ({
1271
1269
  called
1272
1270
  ].filter(truthy).join(" ");
1273
1271
  if (environment.isClientSideRendering) {
1274
- scope.remotion_cancelledError = getErrorStackWithMessage(Error(message));
1272
+ const error = Error(message);
1273
+ scope.remotion_cancelledErrorObject = error;
1274
+ scope.remotion_cancelledError = getErrorStackWithMessage(error);
1275
1275
  } else {
1276
1276
  cancelRenderInternal(scope, Error(message));
1277
1277
  }
@@ -1494,6 +1494,13 @@ var useSyncExternalStore2 = React12.useSyncExternalStore ?? shim;
1494
1494
 
1495
1495
  // src/use-lazy-component.ts
1496
1496
  var useIsomorphicLayoutEffect2 = typeof window === "undefined" ? useEffect3 : useLayoutEffect3;
1497
+ var createComponentWrapper = (componentStore) => {
1498
+ const Wrapper = (props) => {
1499
+ const Comp = useSyncExternalStore2(componentStore.subscribe, componentStore.getSnapshot, componentStore.getSnapshot);
1500
+ return React13.createElement(Comp, props);
1501
+ };
1502
+ return Wrapper;
1503
+ };
1497
1504
  var useLazyComponent = ({
1498
1505
  compProps,
1499
1506
  componentName,
@@ -1510,15 +1517,15 @@ var useLazyComponent = ({
1510
1517
  componentStore.setSnapshot(() => componentFromProps);
1511
1518
  }
1512
1519
  }, [componentFromProps, componentStore]);
1520
+ const createWrapper = createComponentWrapper;
1521
+ const Wrapper = useMemo7(createWrapper.bind(null, componentStore), [
1522
+ componentStore
1523
+ ]);
1513
1524
  const lazy = useMemo7(() => {
1514
1525
  if ("component" in compProps) {
1515
1526
  if (typeof document === "undefined" || noSuspense) {
1516
1527
  return compProps.component;
1517
1528
  }
1518
- const Wrapper = (props) => {
1519
- const Comp = useSyncExternalStore2(componentStore.subscribe, componentStore.getSnapshot, componentStore.getSnapshot);
1520
- return React13.createElement(Comp, props);
1521
- };
1522
1529
  return Wrapper;
1523
1530
  }
1524
1531
  if ("lazyComponent" in compProps && typeof compProps.lazyComponent !== "undefined") {
@@ -1528,7 +1535,7 @@ var useLazyComponent = ({
1528
1535
  return React13.lazy(compProps.lazyComponent);
1529
1536
  }
1530
1537
  throw new Error("You must pass either 'component' or 'lazyComponent'");
1531
- }, [lazyComponentFromProps, componentStore]);
1538
+ }, [lazyComponentFromProps, componentStore, Wrapper]);
1532
1539
  return lazy;
1533
1540
  };
1534
1541
 
@@ -1636,13 +1643,7 @@ var InnerComposition = ({
1636
1643
  const metadata = useMemo8(() => ({ type: "composition", id, value: registration }), [id, registration]);
1637
1644
  useCommittedCompositionEntry(metadata);
1638
1645
  const resolved = useResolvedVideoConfig(id);
1639
- const { setError, clearError } = useContext10(CompositionRenderErrorContext);
1640
- const onError = useCallback3((error) => {
1641
- setError(error);
1642
- }, [setError]);
1643
- const onClear = useCallback3(() => {
1644
- clearError();
1645
- }, [clearError]);
1646
+ const { setError: onError, clearError: onClear } = useContext10(CompositionRenderErrorContext);
1646
1647
  const wrapRegistration = (content) => /* @__PURE__ */ jsx9(CommittedMetadataProvider, {
1647
1648
  value: null,
1648
1649
  _remotionCommitMetadata: metadata,
@@ -1741,7 +1742,7 @@ var getStackForControls = (controls) => {
1741
1742
  };
1742
1743
 
1743
1744
  // src/version.ts
1744
- var VERSION = "4.0.536";
1745
+ var VERSION = "4.0.538";
1745
1746
 
1746
1747
  // src/multiple-versions-warning.ts
1747
1748
  var checkMultipleRemotionVersions = () => {
@@ -1779,12 +1780,11 @@ var Null = () => {
1779
1780
 
1780
1781
  // src/Sequence.tsx
1781
1782
  import React26, {
1782
- createContext as createContext27,
1783
+ createContext as createContext28,
1783
1784
  forwardRef as forwardRef3,
1784
- useCallback as useCallback7,
1785
1785
  useContext as useContext28,
1786
1786
  useLayoutEffect as useLayoutEffect8,
1787
- useMemo as useMemo19,
1787
+ useMemo as useMemo20,
1788
1788
  useRef as useRef8,
1789
1789
  useState as useState9
1790
1790
  } from "react";
@@ -1805,7 +1805,7 @@ var DEFAULT_PREMOUNT_IN_SECONDS = ENABLE_V5_BREAKING_CHANGES ? 2 : 0;
1805
1805
  var DefaultPremountContext = createContext17(DEFAULT_PREMOUNT_IN_SECONDS);
1806
1806
 
1807
1807
  // src/freeze.tsx
1808
- import { createContext as createContext20, useContext as useContext17, useMemo as useMemo11 } from "react";
1808
+ import { createContext as createContext21, useContext as useContext17, useMemo as useMemo11 } from "react";
1809
1809
 
1810
1810
  // src/sequence-activity-context.ts
1811
1811
  import { createContext as createContext18, useContext as useContext11 } from "react";
@@ -1825,12 +1825,12 @@ var SequenceContent = ({ children }) => {
1825
1825
  };
1826
1826
 
1827
1827
  // src/timeline-position-state.ts
1828
- import { useContext as useContext14 } from "react";
1828
+ import { createContext as createContext20, useContext as useContext14 } from "react";
1829
1829
 
1830
1830
  // src/TimelineContext.tsx
1831
1831
  import {
1832
1832
  createContext as createContext19,
1833
- useCallback as useCallback4,
1833
+ useCallback as useCallback3,
1834
1834
  useLayoutEffect as useLayoutEffect4,
1835
1835
  useMemo as useMemo10,
1836
1836
  useRef as useRef3,
@@ -1923,8 +1923,8 @@ var TimelineContextProvider = ({ children, frameState }) => {
1923
1923
  const frame = frameState ?? _frame;
1924
1924
  const frameRef = useRef3(frame);
1925
1925
  frameRef.current = frame;
1926
- const readIsPlaying = useCallback4(() => playingStore.store.getSnapshot().playing, [playingStore]);
1927
- const readIsBuffering = useCallback4(() => bufferingStore.store.getSnapshot().buffering, [bufferingStore]);
1926
+ const readIsPlaying = useCallback3(() => playingStore.store.getSnapshot().playing, [playingStore]);
1927
+ const readIsBuffering = useCallback3(() => bufferingStore.store.getSnapshot().buffering, [bufferingStore]);
1928
1928
  const { delayRender, continueRender } = useDelayRender();
1929
1929
  if (typeof window !== "undefined") {
1930
1930
  useLayoutEffect4(() => {
@@ -2020,6 +2020,7 @@ var useBuffering = () => {
2020
2020
  };
2021
2021
 
2022
2022
  // src/timeline-position-state.ts
2023
+ var UnsubscribedTimelineContext = createContext20(null);
2023
2024
  var makeKey = () => {
2024
2025
  return `remotion.time-all`;
2025
2026
  };
@@ -2049,6 +2050,9 @@ var useTimelinePositionFromContext = (state) => {
2049
2050
  const videoConfig = useVideo();
2050
2051
  const env = useRemotionEnvironment();
2051
2052
  const dormant = useContext14(SequenceActivityDormantContext);
2053
+ if (state === null) {
2054
+ return 0;
2055
+ }
2052
2056
  if (!videoConfig) {
2053
2057
  return typeof window === "undefined" ? 0 : window.remotion_initialFrame ?? 0;
2054
2058
  }
@@ -2074,6 +2078,15 @@ var useTimelinePosition = () => {
2074
2078
  const state = useTimelineContext();
2075
2079
  return useTimelinePositionFromContext(state);
2076
2080
  };
2081
+ var useTimelinePositionWithOptionalSubscription = (subscribe) => {
2082
+ const dormant = useContext14(SequenceActivityDormantContext);
2083
+ const state = useContext14(subscribe ? dormant ? SequenceActivityTimelineContext : TimelineContext : UnsubscribedTimelineContext);
2084
+ const frame = useTimelinePositionFromContext(state);
2085
+ if (subscribe && state === null) {
2086
+ throw new Error("TimelineContext is not available. This hook must be used inside a <Player> or the Remotion Studio.");
2087
+ }
2088
+ return frame;
2089
+ };
2077
2090
  var useIsInsideFreeze = () => {
2078
2091
  return useTimelineContext().isInsideFreeze;
2079
2092
  };
@@ -2096,7 +2109,7 @@ var useTimelineSeekFrame = () => {
2096
2109
 
2097
2110
  // src/use-current-frame.ts
2098
2111
  import { useContext as useContext15 } from "react";
2099
- var useCurrentFrame = () => {
2112
+ var useCurrentFrameWithOptionalSubscription = (subscribe) => {
2100
2113
  const canUseRemotionHooks = useContext15(CanUseRemotionHooks);
2101
2114
  const env = useRemotionEnvironment();
2102
2115
  if (!canUseRemotionHooks) {
@@ -2105,11 +2118,17 @@ var useCurrentFrame = () => {
2105
2118
  }
2106
2119
  throw new Error(`useCurrentFrame() can only be called inside a component that was registered as a composition. See https://www.remotion.dev/docs/the-fundamentals#defining-compositions`);
2107
2120
  }
2108
- const frame = useTimelinePosition();
2121
+ const frame = useTimelinePositionWithOptionalSubscription(subscribe);
2109
2122
  const context = useContext15(SequenceContext);
2123
+ if (!subscribe) {
2124
+ return 0;
2125
+ }
2110
2126
  const contextOffset = context ? context.cumulatedFrom + context.relativeFrom : 0;
2111
2127
  return (frame - contextOffset) * (context?.playbackRate ?? 1);
2112
2128
  };
2129
+ var useCurrentFrame = () => {
2130
+ return useCurrentFrameWithOptionalSubscription(true);
2131
+ };
2113
2132
 
2114
2133
  // src/use-video-config.ts
2115
2134
  import { useContext as useContext16 } from "react";
@@ -2135,7 +2154,7 @@ var useVideoConfig = () => {
2135
2154
 
2136
2155
  // src/freeze.tsx
2137
2156
  import { jsx as jsx11 } from "react/jsx-runtime";
2138
- var NonPremountFreezeContext = createContext20(false);
2157
+ var NonPremountFreezeContext = createContext21(false);
2139
2158
  var useIsInsideNonPremountFreeze = () => useContext17(NonPremountFreezeContext);
2140
2159
  var Freeze = ({
2141
2160
  frame: frameToFreeze,
@@ -2670,8 +2689,8 @@ var sequenceSchemaDefaultLayoutNone = {
2670
2689
  };
2671
2690
 
2672
2691
  // src/loop/loop-context.ts
2673
- import { createContext as createContext21 } from "react";
2674
- var LoopContext = createContext21(null);
2692
+ import { createContext as createContext22 } from "react";
2693
+ var LoopContext = createContext22(null);
2675
2694
 
2676
2695
  // src/resolve-sequence-duration.ts
2677
2696
  var resolveSequenceContentDuration = ({
@@ -2840,7 +2859,7 @@ var SequenceActivityBoundary = ({ children, dormant, frame }) => {
2840
2859
  };
2841
2860
 
2842
2861
  // src/SequenceActivityBudget.tsx
2843
- import React19, { createContext as createContext22, useContext as useContext19, useMemo as useMemo13, useState as useState4 } from "react";
2862
+ import React19, { createContext as createContext23, useContext as useContext19, useMemo as useMemo13, useState as useState4 } from "react";
2844
2863
  import { jsx as jsx13 } from "react/jsx-runtime";
2845
2864
  var useCommitEffect = React19.useInsertionEffect ?? React19.useLayoutEffect;
2846
2865
  var createActivityBudget = () => {
@@ -2919,10 +2938,10 @@ var createActivityBudget = () => {
2919
2938
  }
2920
2939
  };
2921
2940
  };
2922
- var ActivityBudgetContext = createContext22(null);
2923
- var InactiveTimelineContext = createContext22(null);
2941
+ var ActivityBudgetContext = createContext23(null);
2942
+ var InactiveTimelineContext = createContext23(null);
2924
2943
  var emptySelection = new Set;
2925
- var ActivitySelectionContext = createContext22(emptySelection);
2944
+ var ActivitySelectionContext = createContext23(emptySelection);
2926
2945
  var SequenceActivityBudgetProvider = ({ children }) => {
2927
2946
  const enabled = useContext19(SequenceActivityContext);
2928
2947
  const settings = useContext19(SequenceActivitySettingsContext);
@@ -2969,7 +2988,7 @@ var useSequenceActivityAdmission = (candidate) => {
2969
2988
  };
2970
2989
 
2971
2990
  // src/SequenceManager.tsx
2972
- import React23, { useCallback as useCallback6, useContext as useContext23, useMemo as useMemo15, useRef as useRef5, useState as useState7 } from "react";
2991
+ import React23, { useCallback as useCallback5, useContext as useContext23, useMemo as useMemo15, useRef as useRef5, useState as useState7 } from "react";
2973
2992
 
2974
2993
  // src/sequence-registry-context.tsx
2975
2994
  import React20, { useContext as useContext20 } from "react";
@@ -3048,12 +3067,13 @@ var SequenceActivitySuspensionProvider = ({ children }) => {
3048
3067
  };
3049
3068
 
3050
3069
  // src/SequenceRegistryProvider.tsx
3051
- import React22, { useCallback as useCallback5, useContext as useContext22, useMemo as useMemo14, useRef as useRef4, useState as useState6 } from "react";
3070
+ import React22, { useCallback as useCallback4, useContext as useContext22, useMemo as useMemo14, useRef as useRef4, useState as useState6 } from "react";
3052
3071
  import { jsx as jsx15 } from "react/jsx-runtime";
3053
3072
  var useIsomorphicLayoutEffect3 = typeof window === "undefined" ? React22.useEffect : React22.useLayoutEffect;
3054
3073
  var SequenceManagerRefProvider = withCommittedMetadata(SequenceManagerRefContext.Provider);
3055
3074
  var SequenceRegistryProvider = ({ children }) => {
3056
3075
  const { isStudio } = useRemotionEnvironment();
3076
+ const logLevel = useLogLevel();
3057
3077
  const sequenceRegistrationEnabled = useContext22(SequenceRegistrationContext);
3058
3078
  const shouldObserveCommits = isStudio || sequenceRegistrationEnabled;
3059
3079
  const [sequenceManagerId] = useState6(() => String(Math.random()));
@@ -3077,7 +3097,7 @@ var SequenceRegistryProvider = ({ children }) => {
3077
3097
  return registry.getSnapshot();
3078
3098
  }
3079
3099
  }), [registry]);
3080
- const onCommitSequences = useCallback5((scopeId, snapshot, sequenceIds) => {
3100
+ const onCommitSequences = useCallback4((scopeId, snapshot, sequenceIds) => {
3081
3101
  if (registrationObserverFailedRef.current || registrationUnmountedRef.current) {
3082
3102
  return;
3083
3103
  }
@@ -3117,6 +3137,13 @@ var SequenceRegistryProvider = ({ children }) => {
3117
3137
  committedOrderIdsRef.current = ids;
3118
3138
  committedOrderRef.current = order;
3119
3139
  committedRegistrationIdsRef.current = nextIds;
3140
+ if (isStudio && logLevel === "trace") {
3141
+ for (const sequence of sequences) {
3142
+ if (!previousIds.has(sequence.id)) {
3143
+ Log.trace({ logLevel, tag: null }, `[Sequence registration] Registered "${sequence.displayName}" (${sequence.id}) after commit`, sequence);
3144
+ }
3145
+ }
3146
+ }
3120
3147
  setSequences((current) => reconcileRegistryEntries({
3121
3148
  current,
3122
3149
  entries: sequences,
@@ -3128,8 +3155,8 @@ var SequenceRegistryProvider = ({ children }) => {
3128
3155
  orderProperty: "timelineOrder"
3129
3156
  }));
3130
3157
  });
3131
- }, [sequenceManagerId, setSequences]);
3132
- const onCommitRootSequences = useCallback5((sequences, sequenceIds) => {
3158
+ }, [isStudio, logLevel, sequenceManagerId, setSequences]);
3159
+ const onCommitRootSequences = useCallback4((sequences, sequenceIds) => {
3133
3160
  if (!rootObservationFailedRef.current) {
3134
3161
  observedCommitRef.current = true;
3135
3162
  onCommitSequences(sequenceManagerId, sequences, sequenceIds);
@@ -3224,7 +3251,10 @@ var SequenceRegistryProvider = ({ children }) => {
3224
3251
  commitRegistrationEnabled,
3225
3252
  onCommitSequences
3226
3253
  ]);
3227
- const registerSequence = useCallback5((seq) => {
3254
+ const registerSequence = useCallback4((seq) => {
3255
+ if (isStudio) {
3256
+ Log.trace({ logLevel, tag: null }, `[Sequence registration] Registered "${seq.displayName}" (${seq.id}) after commit`, seq);
3257
+ }
3228
3258
  setSequences((seqs) => {
3229
3259
  return [
3230
3260
  ...seqs,
@@ -3234,8 +3264,8 @@ var SequenceRegistryProvider = ({ children }) => {
3234
3264
  }
3235
3265
  ];
3236
3266
  });
3237
- }, [setSequences]);
3238
- const updateSequence = useCallback5((seq) => {
3267
+ }, [isStudio, logLevel, setSequences]);
3268
+ const updateSequence = useCallback4((seq) => {
3239
3269
  setSequences((seqs) => {
3240
3270
  const index = seqs.findIndex((item) => item.id === seq.id);
3241
3271
  if (index === -1) {
@@ -3253,7 +3283,7 @@ var SequenceRegistryProvider = ({ children }) => {
3253
3283
  return next;
3254
3284
  });
3255
3285
  }, [setSequences]);
3256
- const unregisterSequence = useCallback5((seq) => {
3286
+ const unregisterSequence = useCallback4((seq) => {
3257
3287
  setSequences((seqs) => seqs.filter((s) => s.id !== seq));
3258
3288
  }, [setSequences]);
3259
3289
  const actions = useMemo14(() => {
@@ -3332,6 +3362,12 @@ var VisualModePropStatusesContext = React23.createContext({
3332
3362
  var VisualModePropStatusesRefContext = React23.createContext({
3333
3363
  current: {}
3334
3364
  });
3365
+ var VisualModePropStatusesSubscriptionContext = React23.createContext({
3366
+ subscribe: () => () => {
3367
+ return;
3368
+ },
3369
+ getSnapshot: () => null
3370
+ });
3335
3371
  var defaultVisualModeDragOverrides = {
3336
3372
  getDragOverrides: () => {
3337
3373
  throw new Error("VisualModeDragOverridesContext not initialized");
@@ -3342,7 +3378,7 @@ var defaultVisualModeDragOverrides = {
3342
3378
  };
3343
3379
  var VisualModeDragOverridesContext = React23.createContext(defaultVisualModeDragOverrides);
3344
3380
  var VisualModeDragOverridesRefContext = React23.createContext({ current: defaultVisualModeDragOverrides });
3345
- var useDragOverrideSnapshot = (subscribe, getSnapshot) => {
3381
+ var useVisualModeSnapshot = (subscribe, getSnapshot) => {
3346
3382
  const dormant = useContext23(SequenceActivityDormantContext);
3347
3383
  const [, forceUpdate] = useState7(0);
3348
3384
  const snapshot = useSyncExternalStore2(subscribe, getSnapshot, getSnapshot);
@@ -3359,11 +3395,18 @@ var useDragOverridesForNodePath = (nodePath) => {
3359
3395
  const manager = useContext23(SequenceManagerActionsContext);
3360
3396
  const scopedSubscription = subscription?.manager === manager ? subscription : null;
3361
3397
  const key = nodePath === null ? null : makeSequencePropsSubscriptionKey(nodePath);
3362
- const subscribe = useCallback6((listener) => scopedSubscription?.subscribe(key, listener) ?? (() => {
3398
+ const subscribe = useCallback5((listener) => scopedSubscription?.subscribe(key, listener) ?? (() => {
3363
3399
  return;
3364
3400
  }), [key, scopedSubscription]);
3365
- const getSnapshot = useCallback6(() => scopedSubscription?.getSnapshot(key) ?? emptyDragOverrides, [key, scopedSubscription]);
3366
- return useDragOverrideSnapshot(subscribe, getSnapshot);
3401
+ const getSnapshot = useCallback5(() => scopedSubscription?.getSnapshot(key) ?? emptyDragOverrides, [key, scopedSubscription]);
3402
+ return useVisualModeSnapshot(subscribe, getSnapshot);
3403
+ };
3404
+ var usePropStatusForNodePath = (nodePath) => {
3405
+ const subscription = useContext23(VisualModePropStatusesSubscriptionContext);
3406
+ const key = nodePath === null ? null : makeSequencePropsSubscriptionKey(nodePath);
3407
+ const subscribe = useCallback5((listener) => subscription.subscribe(key, listener), [key, subscription]);
3408
+ const getSnapshot = useCallback5(() => subscription.getSnapshot(key), [key, subscription]);
3409
+ return useVisualModeSnapshot(subscribe, getSnapshot);
3367
3410
  };
3368
3411
  var useActiveFromDragOverrideKeys = () => {
3369
3412
  const snapshot = useContext23(ActiveFromDragOverrideKeysContext);
@@ -3375,11 +3418,11 @@ var useEffectDragOverridesForNodePath = (nodePath) => {
3375
3418
  const manager = useContext23(SequenceManagerActionsContext);
3376
3419
  const scopedSubscription = subscription?.manager === manager ? subscription : null;
3377
3420
  const key = nodePath === null ? null : makeSequencePropsSubscriptionKey(nodePath);
3378
- const subscribe = useCallback6((listener) => scopedSubscription?.subscribeEffects(key, listener) ?? (() => {
3421
+ const subscribe = useCallback5((listener) => scopedSubscription?.subscribeEffects(key, listener) ?? (() => {
3379
3422
  return;
3380
3423
  }), [key, scopedSubscription]);
3381
- const getSnapshot = useCallback6(() => scopedSubscription?.getEffectSnapshot(key) ?? emptyEffectDragOverrides, [key, scopedSubscription]);
3382
- return useDragOverrideSnapshot(subscribe, getSnapshot);
3424
+ const getSnapshot = useCallback5(() => scopedSubscription?.getEffectSnapshot(key) ?? emptyEffectDragOverrides, [key, scopedSubscription]);
3425
+ return useVisualModeSnapshot(subscribe, getSnapshot);
3383
3426
  };
3384
3427
  var VisualModeSettersContext = React23.createContext({
3385
3428
  setDragOverrides: () => {
@@ -3421,10 +3464,20 @@ var SequenceManagerProvider = ({ children }) => {
3421
3464
  });
3422
3465
  const [propStatuses, setPropStatusesMapState] = useState7({});
3423
3466
  const propStatusesRef = useRef5(propStatuses);
3467
+ const requestedPropStatusesRef = useRef5(propStatuses);
3468
+ const propStatusListeners = useRef5(new Map);
3424
3469
  useIsomorphicLayoutEffect4(() => {
3470
+ const previous = propStatusesRef.current;
3425
3471
  propStatusesRef.current = propStatuses;
3472
+ for (const [key, listeners] of propStatusListeners.current) {
3473
+ if (previous[key] !== propStatuses[key]) {
3474
+ for (const listener of listeners) {
3475
+ listener();
3476
+ }
3477
+ }
3478
+ }
3426
3479
  }, [propStatuses]);
3427
- const setDragOverridesBatch = useCallback6((overrides) => {
3480
+ const setDragOverridesBatch = useCallback5((overrides) => {
3428
3481
  setDragOverrideState((prevState) => {
3429
3482
  const prev = prevState.overrides;
3430
3483
  let next = null;
@@ -3450,8 +3503,8 @@ var SequenceManagerProvider = ({ children }) => {
3450
3503
  return next === null ? prevState : { overrides: next, fromKeys: nextFromKeys };
3451
3504
  });
3452
3505
  }, []);
3453
- const setDragOverrides = useCallback6((nodePath, key, value) => setDragOverridesBatch([{ nodePath, key, value }]), [setDragOverridesBatch]);
3454
- const subscribeDragOverrides = useCallback6((key, listener) => {
3506
+ const setDragOverrides = useCallback5((nodePath, key, value) => setDragOverridesBatch([{ nodePath, key, value }]), [setDragOverridesBatch]);
3507
+ const subscribeDragOverrides = useCallback5((key, listener) => {
3455
3508
  if (key === null) {
3456
3509
  return () => {
3457
3510
  return;
@@ -3470,7 +3523,7 @@ var SequenceManagerProvider = ({ children }) => {
3470
3523
  }
3471
3524
  };
3472
3525
  }, []);
3473
- const getDragOverridesSnapshot = useCallback6((key) => {
3526
+ const getDragOverridesSnapshot = useCallback5((key) => {
3474
3527
  return key === null ? emptyDragOverrides : dragOverridesStore.current.snapshot[key] ?? emptyDragOverrides;
3475
3528
  }, []);
3476
3529
  useIsomorphicLayoutEffect4(() => {
@@ -3487,7 +3540,7 @@ var SequenceManagerProvider = ({ children }) => {
3487
3540
  }
3488
3541
  }
3489
3542
  }, [dragOverrides]);
3490
- const subscribeEffectDragOverrides = useCallback6((key, listener) => {
3543
+ const subscribeEffectDragOverrides = useCallback5((key, listener) => {
3491
3544
  if (key === null) {
3492
3545
  return () => {
3493
3546
  return;
@@ -3506,7 +3559,7 @@ var SequenceManagerProvider = ({ children }) => {
3506
3559
  }
3507
3560
  };
3508
3561
  }, []);
3509
- const getEffectDragOverridesSnapshot = useCallback6((key) => {
3562
+ const getEffectDragOverridesSnapshot = useCallback5((key) => {
3510
3563
  return key === null ? emptyEffectDragOverrides : effectDragOverridesStore.current.byNode.get(key) ?? emptyEffectDragOverrides;
3511
3564
  }, []);
3512
3565
  useIsomorphicLayoutEffect4(() => {
@@ -3550,7 +3603,7 @@ var SequenceManagerProvider = ({ children }) => {
3550
3603
  }
3551
3604
  }
3552
3605
  }, [effectDragOverridesState]);
3553
- const clearDragOverrides = useCallback6((nodePath) => {
3606
+ const clearDragOverrides = useCallback5((nodePath) => {
3554
3607
  setDragOverrideState((prevState) => {
3555
3608
  const prev = prevState.overrides;
3556
3609
  const key = makeSequencePropsSubscriptionKey(nodePath);
@@ -3564,7 +3617,7 @@ var SequenceManagerProvider = ({ children }) => {
3564
3617
  return { overrides: next, fromKeys: nextFromKeys };
3565
3618
  });
3566
3619
  }, []);
3567
- const setEffectDragOverridesBatch = useCallback6((overrides) => {
3620
+ const setEffectDragOverridesBatch = useCallback5((overrides) => {
3568
3621
  setEffectDragOverridesState((prev) => {
3569
3622
  let next = null;
3570
3623
  for (const { nodePath, effectIndex, key, value } of overrides) {
@@ -3584,8 +3637,8 @@ var SequenceManagerProvider = ({ children }) => {
3584
3637
  return next ?? prev;
3585
3638
  });
3586
3639
  }, []);
3587
- const setEffectDragOverrides = useCallback6((nodePath, effectIndex, key, value) => setEffectDragOverridesBatch([{ nodePath, effectIndex, key, value }]), [setEffectDragOverridesBatch]);
3588
- const clearEffectDragOverrides = useCallback6((nodePath, effectIndex) => {
3640
+ const setEffectDragOverrides = useCallback5((nodePath, effectIndex, key, value) => setEffectDragOverridesBatch([{ nodePath, effectIndex, key, value }]), [setEffectDragOverridesBatch]);
3641
+ const clearEffectDragOverrides = useCallback5((nodePath, effectIndex) => {
3589
3642
  setEffectDragOverridesState((prev) => {
3590
3643
  const mapKey = effectDragOverridesKey(nodePath, effectIndex);
3591
3644
  if (!prev[mapKey]) {
@@ -3596,8 +3649,17 @@ var SequenceManagerProvider = ({ children }) => {
3596
3649
  return next;
3597
3650
  });
3598
3651
  }, []);
3599
- const setPropStatuses = useCallback6((nodePath, values) => {
3600
- setPropStatusesMapState((prev) => {
3652
+ const updatePropStatuses = useCallback5((update) => {
3653
+ const previous = requestedPropStatusesRef.current;
3654
+ const next = update(previous);
3655
+ if (next === previous) {
3656
+ return;
3657
+ }
3658
+ requestedPropStatusesRef.current = next;
3659
+ setPropStatusesMapState(next);
3660
+ }, []);
3661
+ const setPropStatuses = useCallback5((nodePath, values) => {
3662
+ updatePropStatuses((prev) => {
3601
3663
  const key = makeSequencePropsSubscriptionKey(nodePath);
3602
3664
  const prevKey = prev[key];
3603
3665
  const newKey = values(prevKey);
@@ -3606,9 +3668,9 @@ var SequenceManagerProvider = ({ children }) => {
3606
3668
  }
3607
3669
  return { ...prev, [key]: newKey };
3608
3670
  });
3609
- }, []);
3610
- const remapPropStatuses = useCallback6((remappings) => {
3611
- setPropStatusesMapState((prev) => {
3671
+ }, [updatePropStatuses]);
3672
+ const remapPropStatuses = useCallback5((remappings) => {
3673
+ updatePropStatuses((prev) => {
3612
3674
  const next = { ...prev };
3613
3675
  for (const remapping of remappings) {
3614
3676
  delete next[makeSequencePropsSubscriptionKey(remapping.previousNodePath)];
@@ -3620,7 +3682,7 @@ var SequenceManagerProvider = ({ children }) => {
3620
3682
  }
3621
3683
  return next;
3622
3684
  });
3623
- }, []);
3685
+ }, [updatePropStatuses]);
3624
3686
  const dragOverridesSubscription = useMemo15(() => ({
3625
3687
  subscribe: subscribeDragOverrides,
3626
3688
  getSnapshot: getDragOverridesSnapshot,
@@ -3632,10 +3694,10 @@ var SequenceManagerProvider = ({ children }) => {
3632
3694
  subscribeDragOverrides,
3633
3695
  subscribeEffectDragOverrides
3634
3696
  ]);
3635
- const getDragOverrides = useCallback6((nodePath) => {
3697
+ const getDragOverrides = useCallback5((nodePath) => {
3636
3698
  return dragOverrides[makeSequencePropsSubscriptionKey(nodePath)] ?? {};
3637
3699
  }, [dragOverrides]);
3638
- const getEffectDragOverrides = useCallback6((nodePath, effectIndex) => {
3700
+ const getEffectDragOverrides = useCallback5((nodePath, effectIndex) => {
3639
3701
  return effectDragOverridesState[effectDragOverridesKey(nodePath, effectIndex)] ?? {};
3640
3702
  }, [effectDragOverridesState]);
3641
3703
  const propStatusesContext = useMemo15(() => {
@@ -3643,6 +3705,28 @@ var SequenceManagerProvider = ({ children }) => {
3643
3705
  propStatuses
3644
3706
  };
3645
3707
  }, [propStatuses]);
3708
+ const propStatusesSubscription = useMemo15(() => ({
3709
+ subscribe: (key, listener) => {
3710
+ if (key === null) {
3711
+ return () => {
3712
+ return;
3713
+ };
3714
+ }
3715
+ let listeners = propStatusListeners.current.get(key);
3716
+ if (!listeners) {
3717
+ listeners = new Set;
3718
+ propStatusListeners.current.set(key, listeners);
3719
+ }
3720
+ listeners.add(listener);
3721
+ return () => {
3722
+ listeners.delete(listener);
3723
+ if (listeners.size === 0) {
3724
+ propStatusListeners.current.delete(key);
3725
+ }
3726
+ };
3727
+ },
3728
+ getSnapshot: (key) => key === null ? null : requestedPropStatusesRef.current[key] ?? null
3729
+ }), []);
3646
3730
  const dragOverridesContext = useMemo15(() => {
3647
3731
  return {
3648
3732
  getDragOverrides,
@@ -3674,20 +3758,23 @@ var SequenceManagerProvider = ({ children }) => {
3674
3758
  return /* @__PURE__ */ jsx16(SequenceRegistryProvider, {
3675
3759
  children: /* @__PURE__ */ jsx16(VisualModePropStatusesRefContext.Provider, {
3676
3760
  value: propStatusesRef,
3677
- children: /* @__PURE__ */ jsx16(VisualModePropStatusesContext.Provider, {
3678
- value: propStatusesContext,
3679
- children: /* @__PURE__ */ jsx16(SequenceManagerScopeProviders, {
3680
- dragOverridesSubscription,
3681
- fromKeys: dragOverrideState.fromKeys,
3682
- children: /* @__PURE__ */ jsx16(VisualModeDragOverridesContext.Provider, {
3683
- value: dragOverridesContext,
3684
- children: /* @__PURE__ */ jsx16(VisualModeDragOverridesRefContext.Provider, {
3685
- value: dragOverridesRef,
3686
- children: /* @__PURE__ */ jsx16(VisualModeSettersContext.Provider, {
3687
- value: settersContext,
3688
- children: /* @__PURE__ */ jsx16(VisualModeBatchSettersContext.Provider, {
3689
- value: batchSettersContext,
3690
- children
3761
+ children: /* @__PURE__ */ jsx16(VisualModePropStatusesSubscriptionContext.Provider, {
3762
+ value: propStatusesSubscription,
3763
+ children: /* @__PURE__ */ jsx16(VisualModePropStatusesContext.Provider, {
3764
+ value: propStatusesContext,
3765
+ children: /* @__PURE__ */ jsx16(SequenceManagerScopeProviders, {
3766
+ dragOverridesSubscription,
3767
+ fromKeys: dragOverrideState.fromKeys,
3768
+ children: /* @__PURE__ */ jsx16(VisualModeDragOverridesContext.Provider, {
3769
+ value: dragOverridesContext,
3770
+ children: /* @__PURE__ */ jsx16(VisualModeDragOverridesRefContext.Provider, {
3771
+ value: dragOverridesRef,
3772
+ children: /* @__PURE__ */ jsx16(VisualModeSettersContext.Provider, {
3773
+ value: settersContext,
3774
+ children: /* @__PURE__ */ jsx16(VisualModeBatchSettersContext.Provider, {
3775
+ value: batchSettersContext,
3776
+ children
3777
+ })
3691
3778
  })
3692
3779
  })
3693
3780
  })
@@ -3699,15 +3786,15 @@ var SequenceManagerProvider = ({ children }) => {
3699
3786
  };
3700
3787
 
3701
3788
  // src/timeline-track-context.ts
3702
- import { createContext as createContext23 } from "react";
3703
- var TimelineTrackContext = createContext23(null);
3789
+ import { createContext as createContext24 } from "react";
3790
+ var TimelineTrackContext = createContext24(null);
3704
3791
 
3705
3792
  // src/use-premounting.ts
3706
3793
  import { useContext as useContext24, useMemo as useMemo16 } from "react";
3707
3794
 
3708
3795
  // src/PremountContext.tsx
3709
- import { createContext as createContext24 } from "react";
3710
- var PremountContext = createContext24({
3796
+ import { createContext as createContext25 } from "react";
3797
+ var PremountContext = createContext25({
3711
3798
  premountFramesRemaining: 0
3712
3799
  });
3713
3800
 
@@ -3723,16 +3810,17 @@ var usePremounting = ({
3723
3810
  hideWhilePremounted
3724
3811
  }) => {
3725
3812
  const parentPremountContext = useContext24(PremountContext);
3726
- const frame = useCurrentFrame() - parentPremountContext.premountFramesRemaining;
3727
3813
  const environment = useRemotionEnvironment();
3728
3814
  const { fps } = useVideoConfig();
3729
3815
  const defaultPremountInSeconds = useContext24(DefaultPremountContext);
3730
3816
  const effectivePremountFor = premountFor ?? Math.round(defaultPremountInSeconds * fps);
3731
3817
  const effectivePostmountFor = postmountFor ?? 0;
3818
+ const needsFrame = !environment.isRendering && (effectivePremountFor !== 0 || effectivePostmountFor !== 0);
3819
+ const frame = useCurrentFrameWithOptionalSubscription(needsFrame) - parentPremountContext.premountFramesRemaining;
3732
3820
  const endExclusive = from + durationInFrames;
3733
3821
  const sequenceContext = useContext24(SequenceContext);
3734
3822
  const boundaryTolerance = getSequenceBoundaryTolerance({
3735
- absoluteFrame: useTimelinePosition(),
3823
+ absoluteFrame: useTimelinePositionWithOptionalSubscription(needsFrame),
3736
3824
  cumulatedFrom: sequenceContext ? sequenceContext.cumulatedFrom + sequenceContext.relativeFrom : 0,
3737
3825
  from,
3738
3826
  parentPlaybackRate: sequenceContext?.playbackRate ?? 1,
@@ -3822,11 +3910,11 @@ var useSequenceRegistration = ({
3822
3910
 
3823
3911
  // src/with-interactivity-schema.ts
3824
3912
  import React25, {
3825
- createContext as createContext26,
3913
+ createContext as createContext27,
3826
3914
  forwardRef as forwardRef2,
3827
3915
  useContext as useContext27,
3828
3916
  useLayoutEffect as useLayoutEffect7,
3829
- useMemo as useMemo18,
3917
+ useMemo as useMemo19,
3830
3918
  useState as useState8
3831
3919
  } from "react";
3832
3920
 
@@ -3864,7 +3952,7 @@ var deleteNestedKey = (obj, keysToRemove) => {
3864
3952
  };
3865
3953
 
3866
3954
  // src/effects/use-memoized-effects.ts
3867
- import React24, { useContext as useContext26, useLayoutEffect as useLayoutEffect6, useRef as useRef7 } from "react";
3955
+ import React24, { useContext as useContext26, useLayoutEffect as useLayoutEffect6, useMemo as useMemo18, useRef as useRef7 } from "react";
3868
3956
 
3869
3957
  // src/evaluate-source-expressions.ts
3870
3958
  var evaluateSourceNumericValue = (expression, config) => {
@@ -5011,27 +5099,30 @@ function springCalculation({
5011
5099
  stiffness: config.stiffness ?? defaultSpringConfig.stiffness,
5012
5100
  overshootClamping: config.overshootClamping ?? defaultSpringConfig.overshootClamping
5013
5101
  };
5014
- const cacheKey = [
5015
- frame,
5102
+ const configKey = [
5016
5103
  fps,
5017
5104
  resolvedConfig.damping,
5018
5105
  resolvedConfig.mass,
5019
5106
  resolvedConfig.overshootClamping,
5020
5107
  resolvedConfig.stiffness
5021
5108
  ].join("-");
5109
+ const cacheKey = `${frame}-${configKey}`;
5022
5110
  if (calculationCache[cacheKey]) {
5023
5111
  return calculationCache[cacheKey];
5024
5112
  }
5025
- let animation = {
5113
+ const frameClamped = Math.max(0, frame);
5114
+ const previousFrame = Math.ceil(frameClamped) - 1;
5115
+ const previousAnimation = previousFrame >= 0 ? calculationCache[`${previousFrame}-${configKey}`] : undefined;
5116
+ let animation = previousAnimation ?? {
5026
5117
  lastTimestamp: 0,
5027
5118
  current: from,
5028
5119
  toValue: to,
5029
5120
  velocity: 0,
5030
5121
  prevPosition: 0
5031
5122
  };
5032
- const frameClamped = Math.max(0, frame);
5033
5123
  const unevenRest = frameClamped % 1;
5034
- for (let f = 0;f <= Math.floor(frameClamped); f++) {
5124
+ const startFrame = previousAnimation ? previousFrame + 1 : 0;
5125
+ for (let f = startFrame;f <= Math.floor(frameClamped); f++) {
5035
5126
  const time = f / fps * 1000;
5036
5127
  animation = advance({
5037
5128
  animation,
@@ -5171,6 +5262,7 @@ function spring({
5171
5262
  // src/easing.ts
5172
5263
  var clampUnit = (t) => Math.min(1, Math.max(0, t));
5173
5264
  var springEasingDurationInFrames = 30;
5265
+ var easeBezier = null;
5174
5266
 
5175
5267
  class Easing {
5176
5268
  static step0(n) {
@@ -5183,7 +5275,8 @@ class Easing {
5183
5275
  return t;
5184
5276
  }
5185
5277
  static ease(t) {
5186
- return Easing.bezier(0.42, 0, 1, 1)(t);
5278
+ easeBezier ??= Easing.bezier(0.42, 0, 1, 1);
5279
+ return easeBezier(t);
5187
5280
  }
5188
5281
  static quad(t) {
5189
5282
  return t * t;
@@ -5291,23 +5384,23 @@ var MODERN_VALUE = "(?:none|[-+]?\\d*\\.?\\d+(?:%|deg|rad|grad|turn)?)";
5291
5384
  function modernColorCall(name) {
5292
5385
  return new RegExp(name + "\\(\\s*(" + MODERN_VALUE + ")\\s+(" + MODERN_VALUE + ")\\s+(" + MODERN_VALUE + ")(?:\\s*\\/\\s*(" + MODERN_VALUE + "))?\\s*\\)");
5293
5386
  }
5387
+ var cachedMatchers = {
5388
+ rgb: undefined,
5389
+ rgba: undefined,
5390
+ hsl: undefined,
5391
+ hsla: undefined,
5392
+ hex3: undefined,
5393
+ hex4: undefined,
5394
+ hex5: undefined,
5395
+ hex6: undefined,
5396
+ hex8: undefined,
5397
+ oklch: undefined,
5398
+ oklab: undefined,
5399
+ lab: undefined,
5400
+ lch: undefined,
5401
+ hwb: undefined
5402
+ };
5294
5403
  function getMatchers() {
5295
- const cachedMatchers = {
5296
- rgb: undefined,
5297
- rgba: undefined,
5298
- hsl: undefined,
5299
- hsla: undefined,
5300
- hex3: undefined,
5301
- hex4: undefined,
5302
- hex5: undefined,
5303
- hex6: undefined,
5304
- hex8: undefined,
5305
- oklch: undefined,
5306
- oklab: undefined,
5307
- lab: undefined,
5308
- lch: undefined,
5309
- hwb: undefined
5310
- };
5311
5404
  if (cachedMatchers.rgb === undefined) {
5312
5405
  cachedMatchers.rgb = new RegExp("rgb" + call(NUMBER, NUMBER, NUMBER));
5313
5406
  cachedMatchers.rgba = new RegExp("rgba" + call(NUMBER, NUMBER, NUMBER, NUMBER));
@@ -5970,11 +6063,11 @@ var getEffectiveVisualModeValue = ({
5970
6063
  };
5971
6064
 
5972
6065
  // src/sequence-node-path.tsx
5973
- import { createContext as createContext25 } from "react";
5974
- var OverrideIdsToNodePathsGettersContext = createContext25({
6066
+ import { createContext as createContext26 } from "react";
6067
+ var OverrideIdsToNodePathsGettersContext = createContext26({
5975
6068
  overrideIdToNodePathMappings: {}
5976
6069
  });
5977
- var OverrideIdsToNodePathsSettersContext = createContext25({
6070
+ var OverrideIdsToNodePathsSettersContext = createContext26({
5978
6071
  setOverrideIdToNodePath: () => {
5979
6072
  throw new Error("OverrideIdsToNodePathsSettersContext not initialized");
5980
6073
  }
@@ -5983,6 +6076,15 @@ var OverrideIdsToNodePathsSettersContext = createContext25({
5983
6076
  // src/effects/use-memoized-effects.ts
5984
6077
  var emptyDragOverrides2 = {};
5985
6078
  var useCacheCommitEffect = React24.useInsertionEffect ?? useLayoutEffect6;
6079
+ var areEffectParamsEqual = (previous, next) => {
6080
+ if (Object.is(previous, next)) {
6081
+ return true;
6082
+ }
6083
+ if (previous === null || next === null || typeof previous !== "object" || typeof next !== "object" || Object.getPrototypeOf(previous) !== Object.prototype || Object.getPrototypeOf(next) !== Object.prototype) {
6084
+ return false;
6085
+ }
6086
+ return areRegistryEntriesEqual(previous, next);
6087
+ };
5986
6088
  var mergeOverrides = ({
5987
6089
  descriptor,
5988
6090
  propStatusOverrides,
@@ -6047,11 +6149,10 @@ var resolvePropStatusOverrides = (propStatus, frame) => {
6047
6149
  var useMemoizedEffectDefinitions = (effects) => {
6048
6150
  const activityDormant = useContext26(SequenceActivityDormantContext);
6049
6151
  const previousRef = useRef7(null);
6050
- const definitions = effects.map((descriptor) => descriptor.definition);
6051
6152
  const previous = previousRef.current;
6052
- const isSame = previous !== null && previous.definitions.length === definitions.length && previous.definitions.every((definition, i) => definition === definitions[i]);
6153
+ const isSame = previous !== null && previous.definitions.length === effects.length && previous.definitions.every((definition, i) => definition === effects[i].definition);
6053
6154
  const controllers = isSame ? previous.controllers : effects.map((effect) => createRuntimeValueStore(effect.params));
6054
- const stableDefinitions = isSame ? previous.definitions : Object.assign(definitions, {
6155
+ const stableDefinitions = isSame ? previous.definitions : Object.assign(effects.map((descriptor) => descriptor.definition), {
6055
6156
  runtimeValues: controllers.map((controller) => controller.store)
6056
6157
  });
6057
6158
  useCacheCommitEffect(() => {
@@ -6059,6 +6160,9 @@ var useMemoizedEffectDefinitions = (effects) => {
6059
6160
  if (!activityDormant || controllers.length === 0) {
6060
6161
  return;
6061
6162
  }
6163
+ if (controllers.every((controller, index) => areEffectParamsEqual(controller.store.getSnapshot(), effects[index]?.params))) {
6164
+ return;
6165
+ }
6062
6166
  let cancelled = false;
6063
6167
  queueMicrotask(() => {
6064
6168
  if (cancelled) {
@@ -6067,15 +6171,9 @@ var useMemoizedEffectDefinitions = (effects) => {
6067
6171
  controllers.forEach((controller, index) => {
6068
6172
  const snapshot = effects[index]?.params;
6069
6173
  const currentSnapshot = controller.store.getSnapshot();
6070
- if (Object.is(snapshot, currentSnapshot)) {
6174
+ if (areEffectParamsEqual(snapshot, currentSnapshot)) {
6071
6175
  return;
6072
6176
  }
6073
- if (snapshot !== null && currentSnapshot !== null && typeof snapshot === "object" && typeof currentSnapshot === "object") {
6074
- const keys = Object.keys(snapshot);
6075
- if (keys.length === Object.keys(currentSnapshot).length && keys.every((key) => Object.prototype.hasOwnProperty.call(currentSnapshot, key) && Object.is(snapshot[key], currentSnapshot[key]))) {
6076
- return;
6077
- }
6078
- }
6079
6177
  controller.setSnapshot(snapshot);
6080
6178
  });
6081
6179
  });
@@ -6086,17 +6184,18 @@ var useMemoizedEffectDefinitions = (effects) => {
6086
6184
  useLayoutEffect6(() => {
6087
6185
  stableDefinitions.forEach((_definition, index) => {
6088
6186
  const snapshot = effects[index]?.params;
6089
- controllers[index].setSnapshot(snapshot);
6187
+ if (!areEffectParamsEqual(controllers[index].store.getSnapshot(), snapshot)) {
6188
+ controllers[index].setSnapshot(snapshot);
6189
+ }
6090
6190
  });
6091
6191
  }, [controllers, effects, stableDefinitions]);
6092
6192
  return stableDefinitions;
6093
6193
  };
6094
- var getEffectPropStatusesCtx = ({
6095
- propStatuses,
6096
- nodePath,
6097
- effectIndex
6194
+ var getEffectStatusForSequenceStatus = ({
6195
+ status,
6196
+ effectIndex,
6197
+ videoConfigValues
6098
6198
  }) => {
6099
- const status = propStatuses[makeSequencePropsSubscriptionKey(nodePath)];
6100
6199
  if (!status) {
6101
6200
  return { type: "cannot-update-sequence", reason: "not-found" };
6102
6201
  }
@@ -6112,18 +6211,31 @@ var getEffectPropStatusesCtx = ({
6112
6211
  }
6113
6212
  return {
6114
6213
  type: "can-update-effect",
6115
- props: evaluateSourcePropStatuses(effect.props, nodePath.videoConfigValues)
6214
+ props: evaluateSourcePropStatuses(effect.props, videoConfigValues)
6116
6215
  };
6117
6216
  };
6118
- var getPropStatusesCtx = (propStatuses, nodePath) => {
6119
- const status = propStatuses[makeSequencePropsSubscriptionKey(nodePath)];
6217
+ var getEffectPropStatusesCtx = ({
6218
+ propStatuses,
6219
+ nodePath,
6220
+ effectIndex
6221
+ }) => {
6222
+ return getEffectStatusForSequenceStatus({
6223
+ status: propStatuses[makeSequencePropsSubscriptionKey(nodePath)] ?? null,
6224
+ effectIndex,
6225
+ videoConfigValues: nodePath.videoConfigValues
6226
+ });
6227
+ };
6228
+ var getPropStatusesForSequenceStatus = (status, videoConfigValues) => {
6120
6229
  if (!status) {
6121
6230
  return;
6122
6231
  }
6123
6232
  if (!status.canUpdate) {
6124
6233
  return;
6125
6234
  }
6126
- return evaluateSourcePropStatuses(status.props, nodePath.videoConfigValues);
6235
+ return evaluateSourcePropStatuses(status.props, videoConfigValues);
6236
+ };
6237
+ var getPropStatusesCtx = (propStatuses, nodePath) => {
6238
+ return getPropStatusesForSequenceStatus(propStatuses[makeSequencePropsSubscriptionKey(nodePath)] ?? null, nodePath.videoConfigValues);
6127
6239
  };
6128
6240
  var useMemoizedEffects = ({
6129
6241
  effects,
@@ -6131,46 +6243,60 @@ var useMemoizedEffects = ({
6131
6243
  videoConfigValues
6132
6244
  }) => {
6133
6245
  const previousRef = useRef7(null);
6134
- const { propStatuses } = useContext26(VisualModePropStatusesContext);
6135
- const frame = useCurrentFrame();
6136
6246
  const { overrideIdToNodePathMappings } = useContext26(OverrideIdsToNodePathsGettersContext);
6137
6247
  const previous = previousRef.current;
6138
6248
  const nodePath = overrideId ? overrideIdToNodePathMappings[overrideId] ?? null : null;
6139
6249
  const effectDragOverrides = useEffectDragOverridesForNodePath(nodePath);
6140
- const resolved = effects.map((descriptor, index) => {
6250
+ const sequenceStatus = usePropStatusForNodePath(nodePath);
6251
+ const effectPropStatuses = useMemo18(() => Array.from({ length: effects.length }, (_, effectIndex) => {
6141
6252
  if (nodePath === null) {
6142
- return {
6143
- descriptor,
6144
- params: descriptor.params,
6145
- effectKey: descriptor.effectKey
6146
- };
6253
+ return null;
6147
6254
  }
6148
- const effectStatus = getEffectPropStatusesCtx({
6149
- propStatuses,
6150
- nodePath: { ...nodePath, videoConfigValues },
6151
- effectIndex: index
6255
+ const status = getEffectStatusForSequenceStatus({
6256
+ status: sequenceStatus,
6257
+ effectIndex,
6258
+ videoConfigValues
6152
6259
  });
6153
- const propStatusOverrides = effectStatus.type === "can-update-effect" ? resolvePropStatusOverrides(effectStatus.props, frame) : null;
6260
+ return status.type === "can-update-effect" ? status.props : null;
6261
+ }), [effects.length, nodePath, sequenceStatus, videoConfigValues]);
6262
+ const animatedEffects = useMemo18(() => effectPropStatuses.map((status, index) => Object.values(status ?? {}).some((prop) => prop.status === "keyframed") || Object.values(effectDragOverrides[index] ?? emptyDragOverrides2).some((override) => override.type === "keyframed")), [effectDragOverrides, effectPropStatuses]);
6263
+ const frame = useCurrentFrameWithOptionalSubscription(animatedEffects.some(Boolean));
6264
+ const prepared = effects.map((descriptor, index) => {
6265
+ const propStatus = effectPropStatuses[index];
6154
6266
  const dragOverridesMap = effectDragOverrides[index] ?? emptyDragOverrides2;
6155
6267
  const dragOverrides = Object.keys(dragOverridesMap).length === 0 ? null : dragOverridesMap;
6268
+ const effectFrame = animatedEffects[index] ? frame : null;
6269
+ const cached = previous?.prepared[index];
6270
+ if (cached && cached.definition === descriptor.definition && cached.sourceKey === descriptor.effectKey && areEffectParamsEqual(cached.params, descriptor.params) && cached.propStatus === propStatus && cached.dragOverrides === dragOverrides && cached.frame === effectFrame) {
6271
+ return cached;
6272
+ }
6273
+ const propStatusOverrides = resolvePropStatusOverrides(propStatus ?? undefined, frame);
6156
6274
  const { params, effectKey } = mergeOverrides({
6157
6275
  descriptor,
6158
6276
  propStatusOverrides,
6159
6277
  dragOverrides,
6160
6278
  frame
6161
6279
  });
6162
- return { descriptor, params, effectKey };
6280
+ return {
6281
+ definition: descriptor.definition,
6282
+ sourceKey: descriptor.effectKey,
6283
+ params: descriptor.params !== null && typeof descriptor.params === "object" && Object.getPrototypeOf(descriptor.params) === Object.prototype ? { ...descriptor.params } : descriptor.params,
6284
+ propStatus,
6285
+ dragOverrides,
6286
+ frame: effectFrame,
6287
+ value: cached?.value.definition === descriptor.definition && cached.value.effectKey === effectKey ? cached.value : {
6288
+ definition: descriptor.definition,
6289
+ effectKey,
6290
+ params,
6291
+ memoized: true
6292
+ }
6293
+ };
6163
6294
  });
6164
- const isSame = previous !== null && previous.length === resolved.length && previous.every((p, i) => p.definition === resolved[i].descriptor.definition && p.effectKey === resolved[i].effectKey);
6165
- const next = isSame ? previous : resolved.map(({ descriptor, params, effectKey }) => ({
6166
- definition: descriptor.definition,
6167
- effectKey,
6168
- params,
6169
- memoized: true
6170
- }));
6295
+ const isSame = previous !== null && previous.effects.length === prepared.length && previous.effects.every((effect, i) => effect === prepared[i].value);
6296
+ const next = isSame ? previous.effects : prepared.map((effect) => effect.value);
6171
6297
  useCacheCommitEffect(() => {
6172
- previousRef.current = next;
6173
- }, [next]);
6298
+ previousRef.current = { prepared, effects: next };
6299
+ }, [next, prepared]);
6174
6300
  return next;
6175
6301
  };
6176
6302
 
@@ -6571,11 +6697,11 @@ var mergeValues = ({
6571
6697
  deleteNestedKey(merged, propsToDeleteWithoutTextContent);
6572
6698
  return merged;
6573
6699
  };
6574
- var DisableInteractivityContext = createContext26(false);
6700
+ var DisableInteractivityContext = createContext27(false);
6575
6701
  var DisableInteractivityProvider = ({ children }) => {
6576
6702
  return React25.createElement(DisableInteractivityContext.Provider, { value: true }, children);
6577
6703
  };
6578
- var EnableInteractivityContext = createContext26(false);
6704
+ var EnableInteractivityContext = createContext27(false);
6579
6705
  var EnableInteractivityProvider = ({ children }) => {
6580
6706
  return React25.createElement(EnableInteractivityContext.Provider, { value: true }, children);
6581
6707
  };
@@ -6608,22 +6734,20 @@ var withInteractivitySchema = ({
6608
6734
  ref
6609
6735
  });
6610
6736
  }
6611
- const { propStatuses } = useContext27(VisualModePropStatusesContext);
6612
6737
  const nodePathMapping = useContext27(OverrideIdsToNodePathsGettersContext);
6613
- const frame = useCurrentFrame();
6614
6738
  const videoConfig = useUnsafeVideoConfig();
6615
6739
  const durationInFrames = videoConfig?.durationInFrames;
6616
6740
  const fps = videoConfig?.fps;
6617
6741
  const height = videoConfig?.height;
6618
6742
  const width = videoConfig?.width;
6619
- const videoConfigValues = useMemo18(() => durationInFrames === undefined || fps === undefined || height === undefined || width === undefined ? null : {
6743
+ const videoConfigValues = useMemo19(() => durationInFrames === undefined || fps === undefined || height === undefined || width === undefined ? null : {
6620
6744
  durationInFrames,
6621
6745
  fps,
6622
6746
  height,
6623
6747
  width
6624
6748
  }, [durationInFrames, fps, height, width]);
6625
6749
  const passedControls = cleanProps.controls;
6626
- const resolvedPassedControls = useMemo18(() => {
6750
+ const resolvedPassedControls = useMemo19(() => {
6627
6751
  if (!passedControls || getStackForControls(passedControls) !== null || internalStack === undefined) {
6628
6752
  return passedControls;
6629
6753
  }
@@ -6652,17 +6776,21 @@ var withInteractivitySchema = ({
6652
6776
  });
6653
6777
  const nodePath = env.isReadOnlyStudio ? null : nodePathMapping.overrideIdToNodePathMappings[overrideId] ?? null;
6654
6778
  const dragOverrides = useDragOverridesForNodePath(nodePath);
6779
+ const sequenceStatus = usePropStatusForNodePath(nodePath);
6780
+ const propStatus = useMemo19(() => getPropStatusesForSequenceStatus(sequenceStatus, videoConfigValues), [sequenceStatus, videoConfigValues]);
6781
+ const needsFrame = flatKeys.some((key) => propStatus?.[key]?.status === "keyframed" || dragOverrides[key]?.type === "keyframed");
6782
+ const frame = useCurrentFrameWithOptionalSubscription(needsFrame);
6655
6783
  const runtimeValues = flatKeys.map((key) => getRuntimeValueForSchemaKey({
6656
6784
  flatSchema,
6657
6785
  key,
6658
6786
  props: cleanProps
6659
6787
  }));
6660
- const currentRuntimeValueDotNotation = useMemo18(() => readValuesFromProps(cleanProps, flatKeys, flatSchema), runtimeValues);
6788
+ const currentRuntimeValueDotNotation = useMemo19(() => readValuesFromProps(cleanProps, flatKeys, flatSchema), runtimeValues);
6661
6789
  const [runtimeValueStore] = useState8(() => createRuntimeValueStore(currentRuntimeValueDotNotation));
6662
6790
  useLayoutEffect7(() => {
6663
6791
  runtimeValueStore.setSnapshot(currentRuntimeValueDotNotation);
6664
6792
  }, [currentRuntimeValueDotNotation, runtimeValueStore]);
6665
- const controls = useMemo18(() => {
6793
+ const controls = useMemo19(() => {
6666
6794
  const controlsForRender = {
6667
6795
  schema: schemaWithSequenceName,
6668
6796
  currentRuntimeValueDotNotation,
@@ -6685,25 +6813,15 @@ var withInteractivitySchema = ({
6685
6813
  useLayoutEffect7(() => {
6686
6814
  OptimisticSequenceDeletion.register(internalStack ?? null, nodePath);
6687
6815
  }, [internalStack, nodePath]);
6688
- const { merged: valuesDotNotation, propsToDelete } = useMemo18(() => {
6816
+ const { merged: valuesDotNotation, propsToDelete } = useMemo19(() => {
6689
6817
  return computeEffectiveSchemaValuesDotNotation({
6690
6818
  schema: schemaWithSequenceName,
6691
6819
  currentValue: currentRuntimeValueDotNotation,
6692
6820
  overrideValues: dragOverrides,
6693
- propStatus: nodePath === null ? undefined : getPropStatusesCtx(propStatuses, {
6694
- ...nodePath,
6695
- videoConfigValues
6696
- }),
6821
+ propStatus,
6697
6822
  frame
6698
6823
  });
6699
- }, [
6700
- currentRuntimeValueDotNotation,
6701
- dragOverrides,
6702
- nodePath,
6703
- propStatuses,
6704
- videoConfigValues,
6705
- frame
6706
- ]);
6824
+ }, [currentRuntimeValueDotNotation, dragOverrides, propStatus, frame]);
6707
6825
  const activeKeys = selectActiveKeys(schemaWithSequenceName, valuesDotNotation);
6708
6826
  const mergedProps = mergeValues({
6709
6827
  flatSchema,
@@ -6727,9 +6845,26 @@ var withInteractivitySchema = ({
6727
6845
 
6728
6846
  // src/Sequence.tsx
6729
6847
  import { jsx as jsx17 } from "react/jsx-runtime";
6730
- var SeriesContentVisibilityContext = createContext27(true);
6848
+ var SeriesContentVisibilityContext = createContext28(true);
6731
6849
  var SequenceContextProvider = withCommittedMetadata(SequenceContext.Provider);
6732
6850
  var EMPTY_EFFECTS = [];
6851
+ var getSequenceRegistration = (sequence) => {
6852
+ return sequence;
6853
+ };
6854
+ var getSequenceStack = (stack) => {
6855
+ return stack;
6856
+ };
6857
+ var getSequenceCurrentFrame = (ref) => {
6858
+ return ref.current;
6859
+ };
6860
+ var setSequenceWrapperRef = (ref, wrapperRef, node) => {
6861
+ wrapperRef.current = node;
6862
+ if (typeof ref === "function") {
6863
+ ref(node);
6864
+ } else if (ref) {
6865
+ ref.current = node;
6866
+ }
6867
+ };
6733
6868
  var RegularSequenceRefForwardingFunction = ({
6734
6869
  from = 0,
6735
6870
  trimBefore = 0,
@@ -6875,13 +7010,13 @@ var RegularSequenceRefForwardingFunction = ({
6875
7010
  const sequenceRegistrationEnabled = useContext28(SequenceRegistrationContext);
6876
7011
  const canvasOutlinesEnabled = useContext28(SequenceOutlineContext);
6877
7012
  const shouldDiscoverOutline = env.isStudio || canvasOutlinesEnabled;
6878
- const automaticOutlineRef = useMemo19(() => shouldDiscoverOutline && layout === "none" ? SequenceOutlineInternals.createRef() : null, [shouldDiscoverOutline, layout]);
7013
+ const automaticOutlineRef = useMemo20(() => shouldDiscoverOutline && layout === "none" ? SequenceOutlineInternals.createRef() : null, [shouldDiscoverOutline, layout]);
6879
7014
  const wrapperRefForOutline = useRef8(null);
6880
7015
  const refForOutline = layout === "none" ? automaticOutlineRef : wrapperRefForOutline;
6881
- const premounting = useMemo19(() => {
7016
+ const premounting = useMemo20(() => {
6882
7017
  return parentSequence?.premounting || Boolean(other._remotionInternalIsPremounting);
6883
7018
  }, [other._remotionInternalIsPremounting, parentSequence?.premounting]);
6884
- const postmounting = useMemo19(() => {
7019
+ const postmounting = useMemo20(() => {
6885
7020
  return parentSequence?.postmounting || Boolean(other._remotionInternalIsPostmounting);
6886
7021
  }, [other._remotionInternalIsPostmounting, parentSequence?.postmounting]);
6887
7022
  const currentSequenceStart = cumulatedFrom + relativeFrom;
@@ -6889,7 +7024,7 @@ var RegularSequenceRefForwardingFunction = ({
6889
7024
  const parentFirstFrame = parentSequence ? parentSequenceStart - parentSequence.cumulatedNegativeFrom / parentPlaybackRate : 0;
6890
7025
  const firstFrame = Math.max(0, parentFirstFrame, cumulatedFrom + clockFrom / parentPlaybackRate);
6891
7026
  const cumulatedNegativeFrom = (currentSequenceStart - firstFrame) * cumulativePlaybackRate;
6892
- const contextValue = useMemo19(() => {
7027
+ const contextValue = useMemo20(() => {
6893
7028
  return {
6894
7029
  playbackRate: cumulativePlaybackRate,
6895
7030
  absoluteFrom,
@@ -6922,7 +7057,7 @@ var RegularSequenceRefForwardingFunction = ({
6922
7057
  postmountDisplay,
6923
7058
  cumulatedNegativeFrom
6924
7059
  ]);
6925
- const loopContextValue = useMemo19(() => {
7060
+ const loopContextValue = useMemo20(() => {
6926
7061
  if (loopPeriod === null) {
6927
7062
  return null;
6928
7063
  }
@@ -6931,7 +7066,7 @@ var RegularSequenceRefForwardingFunction = ({
6931
7066
  durationInFrames: contentDurationInFrames
6932
7067
  };
6933
7068
  }, [contentDurationInFrames, loopIteration, loopPeriod]);
6934
- const resolvedLoopDisplay = useMemo19(() => {
7069
+ const resolvedLoopDisplay = useMemo20(() => {
6935
7070
  if (loopDisplay || loopPeriod === null) {
6936
7071
  return loopDisplay;
6937
7072
  }
@@ -6941,21 +7076,21 @@ var RegularSequenceRefForwardingFunction = ({
6941
7076
  durationInFrames: loopPeriod
6942
7077
  };
6943
7078
  }, [actualDurationInFrames, loopDisplay, loopPeriod]);
6944
- const timelineClipName = useMemo19(() => {
7079
+ const timelineClipName = useMemo20(() => {
6945
7080
  return name ?? "";
6946
7081
  }, [name]);
6947
7082
  const resolvedDocumentationLink = documentationLink ?? "https://www.remotion.dev/docs/sequence";
6948
7083
  const isInsideSeries = useContext28(IsInsideSeriesContext);
6949
- const singleChildComponent = useMemo19(() => childComponentOverride === undefined ? getSingleChildComponent(children) : childComponentOverride, [children, childComponentOverride]);
7084
+ const singleChildComponent = useMemo20(() => childComponentOverride === undefined ? getSingleChildComponent(children) : childComponentOverride, [children, childComponentOverride]);
6950
7085
  const registrationStack = controls ? getStackForControls(controls) ?? stack ?? null : stack ?? null;
6951
- const getStack = useCallback7(() => registrationStack, [registrationStack]);
7086
+ const getStack = useMemo20(() => getSequenceStack.bind(null, registrationStack), [registrationStack]);
6952
7087
  const registeredFrozenFrame = typeof freeze === "number" ? freeze : null;
6953
7088
  const currentFrame = registeredFrozenFrame ?? (absoluteFrame - currentSequenceStart) * cumulativePlaybackRate;
6954
7089
  const currentFrameRef = useRef8(currentFrame);
6955
7090
  useLayoutEffect8(() => {
6956
7091
  currentFrameRef.current = currentFrame;
6957
7092
  }, [currentFrame]);
6958
- const getCurrentFrame = useCallback7(() => currentFrameRef.current, []);
7093
+ const getCurrentFrame = useMemo20(() => getSequenceCurrentFrame.bind(null, currentFrameRef), [currentFrameRef]);
6959
7094
  const registeredTrimBefore = trimBefore === 0 ? null : trimBefore;
6960
7095
  const parentCumulatedNegativeFrom = parentSequence?.cumulatedNegativeFrom ?? 0;
6961
7096
  const startMediaFrom = isMedia && isMedia.type !== "image" ? isMedia.data.startMediaFrom + parentCumulatedNegativeFrom - cumulatedNegativeFrom : null;
@@ -6973,8 +7108,8 @@ var RegularSequenceRefForwardingFunction = ({
6973
7108
  const autoDuration = canInferDuration && durationInFrames === undefined;
6974
7109
  const isSeriesChild = controlsComponentIdentity === "dev.remotion.remotion.Series.Sequence" || controlsComponentIdentity === "dev.remotion.transitions.TransitionSeries.Sequence" || controlsComponentIdentity === "dev.remotion.transitions.TransitionSeries.Transition" || controlsComponentIdentity === "dev.remotion.transitions.TransitionSeries.Overlay";
6975
7110
  const seriesContentVisible = useContext28(SeriesContentVisibilityContext);
6976
- const effectRuntimeValues = useMemo19(() => _remotionInternalEffects?.runtimeValues ?? null, [_remotionInternalEffects]);
6977
- const registrationControls = useMemo19(() => {
7111
+ const effectRuntimeValues = useMemo20(() => _remotionInternalEffects?.runtimeValues ?? null, [_remotionInternalEffects]);
7112
+ const registrationControls = useMemo20(() => {
6978
7113
  if (controlsSchema === undefined || controlsRuntimeValues === undefined || controlsOverrideId === undefined || controlsSupportsEffects === undefined || controlsComponentIdentity === undefined || controlsComponentName === undefined || controlsVideoConfigValues === undefined) {
6979
7114
  return null;
6980
7115
  }
@@ -6996,7 +7131,7 @@ var RegularSequenceRefForwardingFunction = ({
6996
7131
  controlsSchema,
6997
7132
  controlsSupportsEffects
6998
7133
  ]);
6999
- const getSequenceForRegistration = useCallback7(() => {
7134
+ const sequenceForRegistration = useMemo20(() => {
7000
7135
  const trackRegistration = timelineTrack ? {
7001
7136
  timelineTrack: {
7002
7137
  ...timelineTrack,
@@ -7130,6 +7265,7 @@ var RegularSequenceRefForwardingFunction = ({
7130
7265
  frozenMediaFrame,
7131
7266
  singleChildComponent
7132
7267
  ]);
7268
+ const getSequenceForRegistration = useMemo20(() => getSequenceRegistration.bind(null, sequenceForRegistration), [sequenceForRegistration]);
7133
7269
  const registration = useSequenceRegistration({
7134
7270
  getSequence: env.isStudio || sequenceRegistrationEnabled ? getSequenceForRegistration : null,
7135
7271
  id
@@ -7173,15 +7309,8 @@ var RegularSequenceRefForwardingFunction = ({
7173
7309
  bottom: resolvedCropBottom,
7174
7310
  style: styleIfThere
7175
7311
  });
7176
- const sequenceRef = useCallback7((node) => {
7177
- wrapperRefForOutline.current = node;
7178
- if (typeof ref === "function") {
7179
- ref(node);
7180
- } else if (ref) {
7181
- ref.current = node;
7182
- }
7183
- }, [ref]);
7184
- const defaultStyle = useMemo19(() => {
7312
+ const sequenceRef = useMemo20(() => setSequenceWrapperRef.bind(null, ref, wrapperRefForOutline), [ref, wrapperRefForOutline]);
7313
+ const defaultStyle = useMemo20(() => {
7185
7314
  return {
7186
7315
  flexDirection: undefined,
7187
7316
  ...width ? { width } : {},
@@ -7195,7 +7324,7 @@ var RegularSequenceRefForwardingFunction = ({
7195
7324
  if (ref !== null && layout === "none") {
7196
7325
  throw new TypeError('It is not supported to pass both a `ref` and `layout="none"` to <Sequence />.');
7197
7326
  }
7198
- const metadata = useMemo19(() => shouldDiscoverOutline || registration !== null ? {
7327
+ const metadata = useMemo20(() => shouldDiscoverOutline || registration !== null ? {
7199
7328
  type: "sequence",
7200
7329
  id,
7201
7330
  value: registration,
@@ -7328,7 +7457,7 @@ var SequenceWithoutFrom = withInteractivitySchema({
7328
7457
  });
7329
7458
 
7330
7459
  // src/AbsoluteFill.tsx
7331
- import { useCallback as useCallback8 } from "react";
7460
+ import { useCallback as useCallback6 } from "react";
7332
7461
  import { jsx as jsx18 } from "react/jsx-runtime";
7333
7462
  var absoluteFillSchema = {
7334
7463
  ...baseSchema,
@@ -7441,7 +7570,7 @@ var AbsoluteFillInner = ({
7441
7570
  ...divProps
7442
7571
  }) => {
7443
7572
  const videoConfig = useUnsafeVideoConfig();
7444
- const callbackRef = useCallback8((element) => {
7573
+ const callbackRef = useCallback6((element) => {
7445
7574
  setRef(ref, element);
7446
7575
  }, [ref]);
7447
7576
  if (videoConfig === null) {
@@ -7483,7 +7612,6 @@ addSequenceStackTraces(AbsoluteFill);
7483
7612
  // src/animated-image/AnimatedImage.tsx
7484
7613
  import {
7485
7614
  forwardRef as forwardRef4,
7486
- useEffect as useEffect8,
7487
7615
  useImperativeHandle as useImperativeHandle2,
7488
7616
  useLayoutEffect as useLayoutEffect9,
7489
7617
  useRef as useRef11,
@@ -7491,7 +7619,7 @@ import {
7491
7619
  } from "react";
7492
7620
 
7493
7621
  // src/use-crop-style.ts
7494
- import { useMemo as useMemo20 } from "react";
7622
+ import { useMemo as useMemo21 } from "react";
7495
7623
  var useCropStyle = ({
7496
7624
  cropLeft,
7497
7625
  cropRight,
@@ -7501,7 +7629,7 @@ var useCropStyle = ({
7501
7629
  componentName
7502
7630
  }) => {
7503
7631
  validateSequenceCrop({ cropLeft, cropRight, cropTop, cropBottom }, componentName);
7504
- return useMemo20(() => {
7632
+ return useMemo21(() => {
7505
7633
  const cropClipPath = getSequenceCropClipPath({
7506
7634
  ...resolveSequenceCrop({ cropLeft, cropRight, cropTop, cropBottom }),
7507
7635
  style
@@ -7514,7 +7642,7 @@ var useCropStyle = ({
7514
7642
  };
7515
7643
 
7516
7644
  // src/animated-image/canvas.tsx
7517
- import React28, { useCallback as useCallback9, useImperativeHandle, useMemo as useMemo22, useRef as useRef10 } from "react";
7645
+ import React28, { useCallback as useCallback7, useImperativeHandle, useMemo as useMemo23, useRef as useRef10 } from "react";
7518
7646
 
7519
7647
  // src/calculate-image-fit.ts
7520
7648
  var calculateImageFit = (fit, imageSize, canvasSize) => {
@@ -7884,7 +8012,7 @@ var runEffectChain = async (options) => {
7884
8012
  };
7885
8013
 
7886
8014
  // src/effects/use-effect-chain-state.ts
7887
- import { useEffect as useEffect7, useMemo as useMemo21, useRef as useRef9 } from "react";
8015
+ import { useEffect as useEffect7, useMemo as useMemo22, useRef as useRef9 } from "react";
7888
8016
  var useEffectChainState = (effectsOutputSize = null) => {
7889
8017
  const effectWidth = effectsOutputSize?.width;
7890
8018
  const effectHeight = effectsOutputSize?.height;
@@ -7906,7 +8034,7 @@ var useEffectChainState = (effectsOutputSize = null) => {
7906
8034
  }
7907
8035
  };
7908
8036
  }, []);
7909
- return useMemo21(() => ({
8037
+ return useMemo22(() => ({
7910
8038
  get: (width, height) => {
7911
8039
  width = effectWidth ?? width;
7912
8040
  height = effectHeight ?? height;
@@ -7930,13 +8058,13 @@ import { jsx as jsx19 } from "react/jsx-runtime";
7930
8058
  var CanvasRefForwardingFunction = ({ width, height, fit, className, style, effects, effectsOutputSize, ...props }, ref) => {
7931
8059
  const canvasRef = useRef10(null);
7932
8060
  const chainState = useEffectChainState(effectsOutputSize);
7933
- const sourceCanvas = useMemo22(() => {
8061
+ const sourceCanvas = useMemo23(() => {
7934
8062
  if (typeof document === "undefined") {
7935
8063
  return null;
7936
8064
  }
7937
8065
  return document.createElement("canvas");
7938
8066
  }, []);
7939
- const draw = useCallback9((imageData) => {
8067
+ const draw = useCallback7((imageData) => {
7940
8068
  const canvas = canvasRef.current;
7941
8069
  const canvasWidth = width ?? imageData.displayWidth;
7942
8070
  const canvasHeight = height ?? imageData.displayHeight;
@@ -8273,6 +8401,7 @@ var AnimatedImageContent = forwardRef4(({
8273
8401
  const resolvedSrc = resolveAnimatedImageSource(src);
8274
8402
  const [decodedImage, setDecodedImage] = useState10(null);
8275
8403
  const imageDecoder = decodedImage?.decoder ?? null;
8404
+ const activeDecoderRef = useRef11(null);
8276
8405
  const { delayRender, continueRender, cancelRender } = useDelayRender();
8277
8406
  const frame = useCurrentFrame();
8278
8407
  const { fps } = useVideoConfig();
@@ -8301,6 +8430,7 @@ var AnimatedImageContent = forwardRef4(({
8301
8430
  const controller = new AbortController;
8302
8431
  let cancelled = false;
8303
8432
  let continued = false;
8433
+ let decoder = null;
8304
8434
  const continueRenderOnce = () => {
8305
8435
  if (continued) {
8306
8436
  return;
@@ -8319,6 +8449,8 @@ var AnimatedImageContent = forwardRef4(({
8319
8449
  d.close();
8320
8450
  return;
8321
8451
  }
8452
+ decoder = d;
8453
+ activeDecoderRef.current = d;
8322
8454
  setDecodedImage({ decoder: d, handle: decodeHandle });
8323
8455
  }).catch((err) => {
8324
8456
  if (cancelled) {
@@ -8337,6 +8469,8 @@ var AnimatedImageContent = forwardRef4(({
8337
8469
  });
8338
8470
  return () => {
8339
8471
  cancelled = true;
8472
+ activeDecoderRef.current = null;
8473
+ decoder?.close();
8340
8474
  controller.abort();
8341
8475
  continueRenderOnce();
8342
8476
  };
@@ -8349,13 +8483,8 @@ var AnimatedImageContent = forwardRef4(({
8349
8483
  delayRender,
8350
8484
  cancelRender
8351
8485
  ]);
8352
- useEffect8(() => {
8353
- return () => {
8354
- imageDecoder?.close();
8355
- };
8356
- }, [imageDecoder]);
8357
8486
  useLayoutEffect9(() => {
8358
- if (!imageDecoder || !decodedImage) {
8487
+ if (!imageDecoder || !decodedImage || activeDecoderRef.current !== imageDecoder) {
8359
8488
  return;
8360
8489
  }
8361
8490
  const delay = delayRender(`Rendering frame at ${currentTime} of <AnimatedImage src="${src}"/>`);
@@ -8641,11 +8770,11 @@ import { useContext as useContext29, useLayoutEffect as useLayoutEffect11, useSt
8641
8770
 
8642
8771
  // src/RenderAssetManager.tsx
8643
8772
  import {
8644
- createContext as createContext28,
8645
- useCallback as useCallback10,
8773
+ createContext as createContext29,
8774
+ useCallback as useCallback8,
8646
8775
  useImperativeHandle as useImperativeHandle3,
8647
8776
  useLayoutEffect as useLayoutEffect10,
8648
- useMemo as useMemo23,
8777
+ useMemo as useMemo24,
8649
8778
  useRef as useRef12,
8650
8779
  useState as useState11
8651
8780
  } from "react";
@@ -8683,7 +8812,7 @@ var validateRenderAsset = (artifact) => {
8683
8812
 
8684
8813
  // src/RenderAssetManager.tsx
8685
8814
  import { jsx as jsx21 } from "react/jsx-runtime";
8686
- var RenderAssetManager = createContext28({
8815
+ var RenderAssetManager = createContext29({
8687
8816
  registerRenderAsset: () => {
8688
8817
  return;
8689
8818
  },
@@ -8695,7 +8824,7 @@ var RenderAssetManager = createContext28({
8695
8824
  var RenderAssetManagerProvider = ({ children, collectAssets }) => {
8696
8825
  const [renderAssets, setRenderAssets] = useState11([]);
8697
8826
  const renderAssetsRef = useRef12([]);
8698
- const registerRenderAsset = useCallback10((renderAsset) => {
8827
+ const registerRenderAsset = useCallback8((renderAsset) => {
8699
8828
  validateRenderAsset(renderAsset);
8700
8829
  renderAssetsRef.current = [...renderAssetsRef.current, renderAsset];
8701
8830
  setRenderAssets(renderAssetsRef.current);
@@ -8712,7 +8841,7 @@ var RenderAssetManagerProvider = ({ children, collectAssets }) => {
8712
8841
  };
8713
8842
  }, []);
8714
8843
  }
8715
- const unregisterRenderAsset = useCallback10((id) => {
8844
+ const unregisterRenderAsset = useCallback8((id) => {
8716
8845
  renderAssetsRef.current = renderAssetsRef.current.filter((a) => a.id !== id);
8717
8846
  setRenderAssets(renderAssetsRef.current);
8718
8847
  }, []);
@@ -8726,7 +8855,7 @@ var RenderAssetManagerProvider = ({ children, collectAssets }) => {
8726
8855
  };
8727
8856
  }
8728
8857
  }, []);
8729
- const contextValue = useMemo23(() => {
8858
+ const contextValue = useMemo24(() => {
8730
8859
  return {
8731
8860
  registerRenderAsset,
8732
8861
  unregisterRenderAsset,
@@ -8799,7 +8928,7 @@ var Artifact = ({ filename, content, downloadBehavior }) => {
8799
8928
  };
8800
8929
  Artifact.Thumbnail = ArtifactThumbnail;
8801
8930
  // src/audio/html5-audio.tsx
8802
- import { forwardRef as forwardRef7, useCallback as useCallback17, useContext as useContext44 } from "react";
8931
+ import { forwardRef as forwardRef7, useCallback as useCallback15, useContext as useContext44, useMemo as useMemo37 } from "react";
8803
8932
 
8804
8933
  // src/absolute-src.ts
8805
8934
  var getAbsoluteSrc = (relativeSrc) => {
@@ -8841,9 +8970,9 @@ var getMediaTrimAfter = ({
8841
8970
  };
8842
8971
 
8843
8972
  // src/loop/index.tsx
8844
- import React29, { createContext as createContext29, useContext as useContext30, useMemo as useMemo24 } from "react";
8973
+ import React29, { createContext as createContext30, useContext as useContext30, useMemo as useMemo25 } from "react";
8845
8974
  import { jsx as jsx22 } from "react/jsx-runtime";
8846
- var LoopTimelineContext = createContext29(null);
8975
+ var LoopTimelineContext = createContext30(null);
8847
8976
  var useLoop = () => {
8848
8977
  return React29.useContext(LoopContext);
8849
8978
  };
@@ -8887,20 +9016,20 @@ var Loop = ({
8887
9016
  const iteration = Math.max(0, Math.min(actualTimes - 1, isAtBoundary ? nearestIteration : Math.floor(loopsElapsed)));
8888
9017
  const start = isAtBoundary ? currentFrame : iteration * iterationDurationInFrames;
8889
9018
  const from = Math.max(0, Math.min(start, maxFrame));
8890
- const loopDisplay = useMemo24(() => {
9019
+ const loopDisplay = useMemo25(() => {
8891
9020
  return {
8892
9021
  numberOfTimes: Math.min(compDuration / iterationDurationInFrames, times),
8893
9022
  startOffset: -from,
8894
9023
  durationInFrames: iterationDurationInFrames
8895
9024
  };
8896
9025
  }, [compDuration, from, iterationDurationInFrames, times]);
8897
- const loopContext = useMemo24(() => {
9026
+ const loopContext = useMemo25(() => {
8898
9027
  return {
8899
9028
  iteration,
8900
9029
  durationInFrames
8901
9030
  };
8902
9031
  }, [iteration, durationInFrames]);
8903
- const timelineContext = useMemo24(() => ({
9032
+ const timelineContext = useMemo25(() => ({
8904
9033
  startFrame: loopStartFrame,
8905
9034
  firstVisibleFrame,
8906
9035
  endFrame,
@@ -8944,9 +9073,9 @@ var playbackLogging = ({
8944
9073
  };
8945
9074
 
8946
9075
  // src/prefetch-state.tsx
8947
- import { createContext as createContext30, useEffect as useEffect9, useState as useState13 } from "react";
9076
+ import { createContext as createContext31, useEffect as useEffect8, useState as useState13 } from "react";
8948
9077
  import { jsx as jsx23 } from "react/jsx-runtime";
8949
- var PreloadContext = createContext30({});
9078
+ var PreloadContext = createContext31({});
8950
9079
  var preloads = {};
8951
9080
  var updaters = [];
8952
9081
  var setPreloads = (updater) => {
@@ -8955,7 +9084,7 @@ var setPreloads = (updater) => {
8955
9084
  };
8956
9085
  var PrefetchProvider = ({ children }) => {
8957
9086
  const [_preloads, _setPreloads] = useState13(() => preloads);
8958
- useEffect9(() => {
9087
+ useEffect8(() => {
8959
9088
  const updaterFunction = () => {
8960
9089
  _setPreloads(preloads);
8961
9090
  };
@@ -9271,7 +9400,7 @@ var resolveTrimProps = ({
9271
9400
  };
9272
9401
 
9273
9402
  // src/video/duration-state.tsx
9274
- import { createContext as createContext31, useMemo as useMemo25, useReducer } from "react";
9403
+ import { createContext as createContext32, useMemo as useMemo26, useReducer } from "react";
9275
9404
  import { jsx as jsx24 } from "react/jsx-runtime";
9276
9405
  var durationReducer = (state, action) => {
9277
9406
  switch (action.type) {
@@ -9289,7 +9418,10 @@ var durationReducer = (state, action) => {
9289
9418
  return state;
9290
9419
  }
9291
9420
  };
9292
- var DurationsContext = createContext31({
9421
+ var onMediaDuration = (setDurations, src, durationInSeconds) => {
9422
+ setDurations({ type: "got-duration", durationInSeconds, src });
9423
+ };
9424
+ var DurationsContext = createContext32({
9293
9425
  durations: {},
9294
9426
  setDurations: () => {
9295
9427
  throw new Error("context missing");
@@ -9297,7 +9429,7 @@ var DurationsContext = createContext31({
9297
9429
  });
9298
9430
  var DurationsContextProvider = ({ children }) => {
9299
9431
  const [durations, setDurations] = useReducer(durationReducer, {});
9300
- const value = useMemo25(() => {
9432
+ const value = useMemo26(() => {
9301
9433
  return {
9302
9434
  durations,
9303
9435
  setDurations
@@ -9310,14 +9442,12 @@ var DurationsContextProvider = ({ children }) => {
9310
9442
  };
9311
9443
 
9312
9444
  // src/audio/AudioForPreview.tsx
9313
- import { useCallback as useCallback16 } from "react";
9445
+ import { useCallback as useCallback14 } from "react";
9314
9446
  import React35, {
9315
9447
  forwardRef as forwardRef5,
9316
9448
  useContext as useContext41,
9317
- useEffect as useEffect16,
9318
9449
  useImperativeHandle as useImperativeHandle4,
9319
- useMemo as useMemo33,
9320
- useRef as useRef21,
9450
+ useMemo as useMemo34,
9321
9451
  useState as useState17
9322
9452
  } from "react";
9323
9453
 
@@ -9378,12 +9508,12 @@ import { useContext as useContext33, useLayoutEffect as useLayoutEffect12, useRe
9378
9508
 
9379
9509
  // src/audio/shared-audio-tags.tsx
9380
9510
  import React32, {
9381
- createContext as createContext32,
9511
+ createContext as createContext33,
9382
9512
  createRef as createRef2,
9383
- useCallback as useCallback11,
9513
+ useCallback as useCallback9,
9384
9514
  useContext as useContext32,
9385
- useEffect as useEffect10,
9386
- useMemo as useMemo27,
9515
+ useEffect as useEffect9,
9516
+ useMemo as useMemo28,
9387
9517
  useRef as useRef14,
9388
9518
  useState as useState14
9389
9519
  } from "react";
@@ -9488,7 +9618,7 @@ var makeSharedElementSourceNode = ({
9488
9618
  };
9489
9619
 
9490
9620
  // src/audio/use-audio-context.ts
9491
- import { useMemo as useMemo26, useRef as useRef13 } from "react";
9621
+ import { useMemo as useMemo27, useRef as useRef13 } from "react";
9492
9622
  var warned = false;
9493
9623
  var warnOnce = (logLevel) => {
9494
9624
  if (warned) {
@@ -9510,7 +9640,7 @@ var useSingletonAudioContext = ({
9510
9640
  if (sampleRate !== initialSampleRate.current) {
9511
9641
  throw new Error(`Changing the AudioContext sample rate dynamically is not supported. The sample rate was initialized with ${initialSampleRate.current} Hz, but ${sampleRate} Hz was passed later.`);
9512
9642
  }
9513
- const context = useMemo26(() => {
9643
+ const context = useMemo27(() => {
9514
9644
  if (env.isRendering) {
9515
9645
  return null;
9516
9646
  }
@@ -9674,8 +9804,8 @@ var didPropChange = (key, newProp, prevProp) => {
9674
9804
  }
9675
9805
  return true;
9676
9806
  };
9677
- var SharedAudioContext = createContext32(null);
9678
- var SharedAudioTagsContext = createContext32(null);
9807
+ var SharedAudioContext = createContext33(null);
9808
+ var SharedAudioTagsContext = createContext33(null);
9679
9809
  var shouldSaveForLater = (state) => {
9680
9810
  if (state === "suspended" || state === "running-to-suspended" || state === "interrupted") {
9681
9811
  return true;
@@ -9708,9 +9838,9 @@ var SharedAudioContextProvider = ({
9708
9838
  const isResuming = useRef14(null);
9709
9839
  const nextResumeAttemptId = useRef14(0);
9710
9840
  const nextResumeIsAutoPlayAttempt = useRef14(false);
9711
- const audioSyncAnchor = useMemo27(() => ({ value: 0 }), []);
9841
+ const audioSyncAnchor = useMemo28(() => ({ value: 0 }), []);
9712
9842
  const audioSyncAnchorListeners = useRef14([]);
9713
- const audioSyncAnchorEmitter = useMemo27(() => {
9843
+ const audioSyncAnchorEmitter = useMemo28(() => {
9714
9844
  return {
9715
9845
  dispatch: (event) => {
9716
9846
  audioSyncAnchorListeners.current.forEach((l) => l(event));
@@ -9727,10 +9857,10 @@ var SharedAudioContextProvider = ({
9727
9857
  }, []);
9728
9858
  const prevEndTimes = useRef14({ scheduledEndTime: null, mediaEndTime: null });
9729
9859
  const nodesToResume = useRef14(new Map);
9730
- const unscheduleAudioNode = useCallback11((node) => {
9860
+ const unscheduleAudioNode = useCallback9((node) => {
9731
9861
  return nodesToResume.current.delete(node);
9732
9862
  }, []);
9733
- const scheduleAudioNode = useMemo27(() => {
9863
+ const scheduleAudioNode = useMemo28(() => {
9734
9864
  return ({
9735
9865
  node,
9736
9866
  mediaTimestamp,
@@ -9782,7 +9912,7 @@ var SharedAudioContextProvider = ({
9782
9912
  };
9783
9913
  };
9784
9914
  }, [ctxAndGain, _experimentalKeepAudioContextAlive, logLevel]);
9785
- const resume = useCallback11(() => {
9915
+ const resume = useCallback9(() => {
9786
9916
  const isAutoPlayAttempt = nextResumeIsAutoPlayAttempt.current;
9787
9917
  nextResumeIsAutoPlayAttempt.current = false;
9788
9918
  if (!ctxAndGain) {
@@ -9824,14 +9954,14 @@ var SharedAudioContextProvider = ({
9824
9954
  };
9825
9955
  return resumePromise.catch(() => {});
9826
9956
  }, [ctxAndGain, _experimentalKeepAudioContextAlive, logLevel]);
9827
- const resumeAsAutoPlay = useCallback11(() => {
9957
+ const resumeAsAutoPlay = useCallback9(() => {
9828
9958
  nextResumeIsAutoPlayAttempt.current = true;
9829
9959
  return resume();
9830
9960
  }, [resume]);
9831
- const getIsResumingAudioContext = useCallback11(() => {
9961
+ const getIsResumingAudioContext = useCallback9(() => {
9832
9962
  return isResuming.current?.promise ?? null;
9833
9963
  }, []);
9834
- const suspend = useCallback11(() => {
9964
+ const suspend = useCallback9(() => {
9835
9965
  isResuming.current?.abortController.abort();
9836
9966
  if (!ctxAndGain) {
9837
9967
  return Promise.resolve();
@@ -9847,7 +9977,7 @@ var SharedAudioContextProvider = ({
9847
9977
  }
9848
9978
  return ctxAndGain.suspend();
9849
9979
  }, [ctxAndGain, _experimentalKeepAudioContextAlive]);
9850
- useEffect10(() => {
9980
+ useEffect9(() => {
9851
9981
  if (!_experimentalKeepAudioContextAlive) {
9852
9982
  return;
9853
9983
  }
@@ -9875,7 +10005,7 @@ var SharedAudioContextProvider = ({
9875
10005
  ctxAndGain.suspend().catch(() => {});
9876
10006
  };
9877
10007
  }, [ctxAndGain, _experimentalKeepAudioContextAlive]);
9878
- const audioContextValue = useMemo27(() => {
10008
+ const audioContextValue = useMemo28(() => {
9879
10009
  return {
9880
10010
  sampleRate,
9881
10011
  audioContext: ctxAndGain?.audioContext ?? null,
@@ -9948,7 +10078,7 @@ var SharedAudioTagsContextProvider = ({ children, numberOfAudioTags }) => {
9948
10078
  };
9949
10079
  }, [refs]);
9950
10080
  const takenAudios = useRef14(new Array(numberOfAudioTags).fill(false));
9951
- const rerenderAudios = useCallback11(() => {
10081
+ const rerenderAudios = useCallback9(() => {
9952
10082
  refs.forEach(({ ref, id }) => {
9953
10083
  const data = audios.current?.find((a) => a.id === id);
9954
10084
  const { current } = ref;
@@ -9971,7 +10101,7 @@ var SharedAudioTagsContextProvider = ({ children, numberOfAudioTags }) => {
9971
10101
  });
9972
10102
  });
9973
10103
  }, [refs]);
9974
- const registerAudio = useCallback11((options) => {
10104
+ const registerAudio = useCallback9((options) => {
9975
10105
  const { aud, audioId, premounting, postmounting } = options;
9976
10106
  const found = audios.current?.find((a) => a.audioId === audioId);
9977
10107
  if (found) {
@@ -10000,7 +10130,7 @@ var SharedAudioTagsContextProvider = ({ children, numberOfAudioTags }) => {
10000
10130
  rerenderAudios();
10001
10131
  return newElem;
10002
10132
  }, [numberOfAudioTags, refs, rerenderAudios]);
10003
- const unregisterAudio = useCallback11((id) => {
10133
+ const unregisterAudio = useCallback9((id) => {
10004
10134
  const cloned = [...takenAudios.current];
10005
10135
  const index = refs.findIndex((r) => r.id === id);
10006
10136
  if (index === -1) {
@@ -10011,7 +10141,7 @@ var SharedAudioTagsContextProvider = ({ children, numberOfAudioTags }) => {
10011
10141
  audios.current = audios.current?.filter((a) => a.id !== id);
10012
10142
  rerenderAudios();
10013
10143
  }, [refs, rerenderAudios]);
10014
- const updateAudio = useCallback11(({
10144
+ const updateAudio = useCallback9(({
10015
10145
  aud,
10016
10146
  audioId,
10017
10147
  id,
@@ -10045,7 +10175,7 @@ var SharedAudioTagsContextProvider = ({ children, numberOfAudioTags }) => {
10045
10175
  rerenderAudios();
10046
10176
  }
10047
10177
  }, [rerenderAudios]);
10048
- const playAllAudios = useCallback11(() => {
10178
+ const playAllAudios = useCallback9(() => {
10049
10179
  refs.forEach((ref) => {
10050
10180
  const audio = audios.current.find((a) => a.el === ref.ref);
10051
10181
  if (audio?.premounting) {
@@ -10063,7 +10193,7 @@ var SharedAudioTagsContextProvider = ({ children, numberOfAudioTags }) => {
10063
10193
  });
10064
10194
  resume?.();
10065
10195
  }, [logLevel, mountTime, refs, env.isPlayer, resume]);
10066
- const audioTagsValue = useMemo27(() => {
10196
+ const audioTagsValue = useMemo28(() => {
10067
10197
  return {
10068
10198
  registerAudio,
10069
10199
  unregisterAudio,
@@ -10078,7 +10208,7 @@ var SharedAudioTagsContextProvider = ({ children, numberOfAudioTags }) => {
10078
10208
  unregisterAudio,
10079
10209
  updateAudio
10080
10210
  ]);
10081
- const sharedAudioTagElements = useMemo27(() => {
10211
+ const sharedAudioTagElements = useMemo28(() => {
10082
10212
  return refs.map(({ id, ref }) => {
10083
10213
  return /* @__PURE__ */ jsx25("audio", {
10084
10214
  ref,
@@ -10095,6 +10225,11 @@ var SharedAudioTagsContextProvider = ({ children, numberOfAudioTags }) => {
10095
10225
  ]
10096
10226
  });
10097
10227
  };
10228
+ var unregisterSharedAudio = (tagsContext, id) => {
10229
+ if (tagsContext && tagsContext.numberOfAudioTags > 0) {
10230
+ tagsContext.unregisterAudio(id);
10231
+ }
10232
+ };
10098
10233
  var useSharedAudio = ({
10099
10234
  aud,
10100
10235
  audioId,
@@ -10141,11 +10276,7 @@ var useSharedAudio = ({
10141
10276
  }
10142
10277
  }, [aud, tagsCtx, elem.id, audioId, premounting, postmounting]);
10143
10278
  effectToUse(() => {
10144
- return () => {
10145
- if (tagsCtx && tagsCtx.numberOfAudioTags > 0) {
10146
- tagsCtx.unregisterAudio(elem.id);
10147
- }
10148
- };
10279
+ return unregisterSharedAudio.bind(null, tagsCtx, elem.id);
10149
10280
  }, [tagsCtx, elem.id]);
10150
10281
  }
10151
10282
  return elem;
@@ -10356,12 +10487,40 @@ var useVolume = ({
10356
10487
  return audioStuffRef;
10357
10488
  };
10358
10489
 
10490
+ // src/use-media-duration.ts
10491
+ import { useEffect as useEffect10, useRef as useRef17 } from "react";
10492
+ var subscribeToMediaDuration = (mediaRef, onDurationRef, src) => {
10493
+ const { current } = mediaRef;
10494
+ if (!current) {
10495
+ return;
10496
+ }
10497
+ if (current.duration) {
10498
+ onDurationRef.current?.(src ?? current.src, current.duration);
10499
+ return;
10500
+ }
10501
+ const onLoadedMetadata = () => {
10502
+ onDurationRef.current?.(src ?? current.src, current.duration);
10503
+ };
10504
+ current.addEventListener("loadedmetadata", onLoadedMetadata);
10505
+ return () => {
10506
+ current.removeEventListener("loadedmetadata", onLoadedMetadata);
10507
+ };
10508
+ };
10509
+ var useMediaDuration = (mediaRef, onDuration, src, useCurrentSrc) => {
10510
+ const onDurationRef = useRef17(onDuration);
10511
+ onDurationRef.current = onDuration;
10512
+ useEffect10(subscribeToMediaDuration.bind(null, mediaRef, onDurationRef, useCurrentSrc ? null : src), [mediaRef, src, useCurrentSrc]);
10513
+ };
10514
+ var scheduleMediaSourceCleanup = (cleanup) => {
10515
+ requestAnimationFrame(() => cleanup?.());
10516
+ };
10517
+
10359
10518
  // src/use-media-in-timeline.ts
10360
- import { useCallback as useCallback12, useContext as useContext35, useMemo as useMemo28 } from "react";
10519
+ import { useCallback as useCallback10, useContext as useContext35, useMemo as useMemo29 } from "react";
10361
10520
 
10362
10521
  // src/audio/use-audio-frame.ts
10363
- import { createContext as createContext33, useContext as useContext34 } from "react";
10364
- var Html5MediaTrimContext = createContext33(0);
10522
+ import { createContext as createContext34, useContext as useContext34 } from "react";
10523
+ var Html5MediaTrimContext = createContext34(0);
10365
10524
  var useMediaStartsAt = () => {
10366
10525
  const parentSequence = useContext34(SequenceContext);
10367
10526
  return parentSequence?.cumulatedNegativeFrom ?? 0;
@@ -10447,7 +10606,7 @@ var useBasicMediaInTimeline = ({
10447
10606
  loop
10448
10607
  });
10449
10608
  const startMediaFrom = 0 - mediaStartsAt + (trimBefore ?? 0);
10450
- const memoizedResult = useMemo28(() => {
10609
+ const memoizedResult = useMemo29(() => {
10451
10610
  return {
10452
10611
  duration,
10453
10612
  finalDisplayName: displayName ?? getAssetDisplayName(src),
@@ -10482,8 +10641,8 @@ var useMediaInTimelineRegistration = ({
10482
10641
  const canvasOutlinesEnabled = useContext35(SequenceOutlineContext);
10483
10642
  const { isStudio } = useRemotionEnvironment();
10484
10643
  const stack = getStack();
10485
- const getStackForRegistration = useCallback12(() => stack, [stack]);
10486
- const automaticOutlineRef = useMemo28(() => mediaType === "video" && (isStudio || canvasOutlinesEnabled) ? SequenceOutlineInternals.createRef() : null, [canvasOutlinesEnabled, isStudio, mediaType]);
10644
+ const getStackForRegistration = useCallback10(() => stack, [stack]);
10645
+ const automaticOutlineRef = useMemo29(() => mediaType === "video" && (isStudio || canvasOutlinesEnabled) ? SequenceOutlineInternals.createRef() : null, [canvasOutlinesEnabled, isStudio, mediaType]);
10487
10646
  const { duration, finalDisplayName } = useBasicMediaInTimeline({
10488
10647
  src,
10489
10648
  displayName,
@@ -10495,7 +10654,7 @@ var useMediaInTimelineRegistration = ({
10495
10654
  loop: false,
10496
10655
  muted
10497
10656
  });
10498
- const getSequenceForRegistration = useCallback12(() => {
10657
+ const getSequenceForRegistration = useCallback10(() => {
10499
10658
  if (!src) {
10500
10659
  throw new Error("No src passed");
10501
10660
  }
@@ -10563,26 +10722,26 @@ var useMediaInTimelineRegistration = ({
10563
10722
 
10564
10723
  // src/use-media-playback.ts
10565
10724
  import {
10566
- useCallback as useCallback15,
10725
+ useCallback as useCallback13,
10567
10726
  useContext as useContext38,
10568
10727
  useEffect as useEffect14,
10569
10728
  useLayoutEffect as useLayoutEffect14,
10570
- useRef as useRef19
10729
+ useRef as useRef20
10571
10730
  } from "react";
10572
10731
 
10573
10732
  // src/buffer-until-first-frame.ts
10574
- import { useCallback as useCallback14, useMemo as useMemo31, useRef as useRef17 } from "react";
10733
+ import { useCallback as useCallback12, useMemo as useMemo32, useRef as useRef18 } from "react";
10575
10734
 
10576
10735
  // src/use-buffer-state.ts
10577
- import { useContext as useContext37, useMemo as useMemo30 } from "react";
10736
+ import { useContext as useContext37, useMemo as useMemo31 } from "react";
10578
10737
 
10579
10738
  // src/buffering.tsx
10580
10739
  import React33, {
10581
- useCallback as useCallback13,
10740
+ useCallback as useCallback11,
10582
10741
  useContext as useContext36,
10583
10742
  useEffect as useEffect11,
10584
10743
  useLayoutEffect as useLayoutEffect13,
10585
- useMemo as useMemo29,
10744
+ useMemo as useMemo30,
10586
10745
  useState as useState15
10587
10746
  } from "react";
10588
10747
  import { jsx as jsx26 } from "react/jsx-runtime";
@@ -10590,7 +10749,7 @@ var useBufferManager = (logLevel, mountTime, setBuffering, isBuffering) => {
10590
10749
  const [blockCount, setBlockCount] = useState15(0);
10591
10750
  const env = useRemotionEnvironment();
10592
10751
  const rendering = env.isRendering;
10593
- const addBlock = useCallback13(() => {
10752
+ const addBlock = useCallback11(() => {
10594
10753
  if (rendering) {
10595
10754
  return {
10596
10755
  unblock: () => {
@@ -10640,7 +10799,7 @@ var useBufferManager = (logLevel, mountTime, setBuffering, isBuffering) => {
10640
10799
  }
10641
10800
  }, [blockCount]);
10642
10801
  }
10643
- return useMemo29(() => ({ addBlock }), [addBlock]);
10802
+ return useMemo30(() => ({ addBlock }), [addBlock]);
10644
10803
  };
10645
10804
  var BufferingContextReact = React33.createContext(null);
10646
10805
  var BufferingProvider = ({ children }) => {
@@ -10658,7 +10817,7 @@ var useBufferState = () => {
10658
10817
  const buffer = useContext37(BufferingContextReact);
10659
10818
  const logLevel = useLogLevel();
10660
10819
  const addBlock = buffer ? buffer.addBlock : null;
10661
- return useMemo30(() => ({
10820
+ return useMemo31(() => ({
10662
10821
  delayPlayback: () => {
10663
10822
  if (!addBlock) {
10664
10823
  throw new Error("Tried to enable the buffering state, but a Remotion context was not found. This API can only be called in a component that was passed to the Remotion Player or a <Composition>. Or you might have experienced a version mismatch - run `npx remotion versions` and ensure all packages have the same version. This error is thrown by the buffer state https://remotion.dev/docs/player/buffer-state");
@@ -10693,9 +10852,9 @@ var useBufferUntilFirstFrame = ({
10693
10852
  logLevel,
10694
10853
  mountTime
10695
10854
  }) => {
10696
- const bufferingRef = useRef17(false);
10855
+ const bufferingRef = useRef18(false);
10697
10856
  const { delayPlayback } = useBufferState();
10698
- const bufferUntilFirstFrame = useCallback14((requestedTime) => {
10857
+ const bufferUntilFirstFrame = useCallback12((requestedTime) => {
10699
10858
  if (mediaType !== "video") {
10700
10859
  return;
10701
10860
  }
@@ -10766,7 +10925,7 @@ var useBufferUntilFirstFrame = ({
10766
10925
  onVariableFpsVideoDetected,
10767
10926
  pauseWhenBuffering
10768
10927
  ]);
10769
- return useMemo31(() => {
10928
+ return useMemo32(() => {
10770
10929
  return {
10771
10930
  isBuffering: () => bufferingRef.current,
10772
10931
  bufferUntilFirstFrame
@@ -11019,14 +11178,14 @@ var useMediaBuffering = ({
11019
11178
  };
11020
11179
 
11021
11180
  // src/use-request-video-callback-time.ts
11022
- import { useEffect as useEffect13, useRef as useRef18 } from "react";
11181
+ import { useEffect as useEffect13, useRef as useRef19 } from "react";
11023
11182
  var useRequestVideoCallbackTime = ({
11024
11183
  mediaRef,
11025
11184
  mediaType,
11026
11185
  lastSeek,
11027
11186
  onVariableFpsVideoDetected
11028
11187
  }) => {
11029
- const currentTime = useRef18(null);
11188
+ const currentTime = useRef19(null);
11030
11189
  useEffect13(() => {
11031
11190
  const { current } = mediaRef;
11032
11191
  if (current) {
@@ -11179,12 +11338,12 @@ var useMediaPlayback = ({
11179
11338
  const playerBuffering = useBuffering();
11180
11339
  const { fps } = useVideoConfig();
11181
11340
  const mediaTrimBefore = useContext38(Html5MediaTrimContext);
11182
- const lastSeekDueToShift = useRef19(null);
11183
- const lastSeek = useRef19(null);
11341
+ const lastSeekDueToShift = useRef20(null);
11342
+ const lastSeek = useRef20(null);
11184
11343
  const logLevel = useLogLevel();
11185
11344
  const mountTime = useMountTime();
11186
- const isVariableFpsVideoMap = useRef19({});
11187
- const onVariableFpsVideoDetected = useCallback15(() => {
11345
+ const isVariableFpsVideoMap = useRef20({});
11346
+ const onVariableFpsVideoDetected = useCallback13(() => {
11188
11347
  if (!src) {
11189
11348
  return;
11190
11349
  }
@@ -11388,7 +11547,7 @@ var useMediaPlayback = ({
11388
11547
  };
11389
11548
 
11390
11549
  // src/use-media-tag.ts
11391
- import { useContext as useContext39, useEffect as useEffect15, useRef as useRef20 } from "react";
11550
+ import { useContext as useContext39, useEffect as useEffect15, useRef as useRef21 } from "react";
11392
11551
  var useMediaTag = ({
11393
11552
  mediaRef,
11394
11553
  id,
@@ -11399,7 +11558,7 @@ var useMediaTag = ({
11399
11558
  }) => {
11400
11559
  const { audioAndVideoTags, isPlaying } = useTimelineContext();
11401
11560
  const { subscribePlaying } = useContext39(SetTimelineContext);
11402
- const isPlayingRef = useRef20(isPlaying);
11561
+ const isPlayingRef = useRef21(isPlaying);
11403
11562
  isPlayingRef.current = isPlaying;
11404
11563
  const logLevel = useLogLevel();
11405
11564
  const mountTime = useMountTime();
@@ -11462,12 +11621,12 @@ var useMediaTag = ({
11462
11621
  };
11463
11622
 
11464
11623
  // src/volume-position-state.ts
11465
- import { createContext as createContext34, useContext as useContext40, useMemo as useMemo32 } from "react";
11466
- var MediaVolumeContext = createContext34({
11624
+ import { createContext as createContext35, useContext as useContext40, useMemo as useMemo33 } from "react";
11625
+ var MediaVolumeContext = createContext35({
11467
11626
  playerMuted: false,
11468
11627
  mediaVolume: 1
11469
11628
  });
11470
- var SetMediaVolumeContext = createContext34({
11629
+ var SetMediaVolumeContext = createContext35({
11471
11630
  setPlayerMuted: () => {
11472
11631
  throw new Error("default");
11473
11632
  },
@@ -11478,14 +11637,14 @@ var SetMediaVolumeContext = createContext34({
11478
11637
  var useMediaVolumeState = () => {
11479
11638
  const { mediaVolume } = useContext40(MediaVolumeContext);
11480
11639
  const { setMediaVolume } = useContext40(SetMediaVolumeContext);
11481
- return useMemo32(() => {
11640
+ return useMemo33(() => {
11482
11641
  return [mediaVolume, setMediaVolume];
11483
11642
  }, [mediaVolume, setMediaVolume]);
11484
11643
  };
11485
11644
  var usePlayerMutedState = () => {
11486
11645
  const { playerMuted } = useContext40(MediaVolumeContext);
11487
11646
  const { setPlayerMuted } = useContext40(SetMediaVolumeContext);
11488
- return useMemo32(() => {
11647
+ return useMemo33(() => {
11489
11648
  return [playerMuted, setPlayerMuted];
11490
11649
  }, [playerMuted, setPlayerMuted]);
11491
11650
  };
@@ -11607,7 +11766,7 @@ var AudioForDevelopmentForwardRefFunction = (props, ref) => {
11607
11766
  requestsVideoFrame: false,
11608
11767
  isClientSideRendering: false
11609
11768
  });
11610
- const propsToPass = useMemo33(() => {
11769
+ const propsToPass = useMemo34(() => {
11611
11770
  return {
11612
11771
  muted: isMutedForPlayback,
11613
11772
  src: preloadedSrc,
@@ -11622,7 +11781,7 @@ var AudioForDevelopmentForwardRefFunction = (props, ref) => {
11622
11781
  preloadedSrc,
11623
11782
  crossOriginValue
11624
11783
  ]);
11625
- const id = useMemo33(() => `audio-${random(src ?? "")}-${sequenceContext?.relativeFrom}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.durationInFrames}-muted:${props.muted}-loop:${props.loop}`, [
11784
+ const id = useMemo34(() => `audio-${random(src ?? "")}-${sequenceContext?.relativeFrom}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.durationInFrames}-muted:${props.muted}-loop:${props.loop}`, [
11626
11785
  src,
11627
11786
  sequenceContext?.relativeFrom,
11628
11787
  sequenceContext?.cumulatedFrom,
@@ -11670,34 +11829,12 @@ var AudioForDevelopmentForwardRefFunction = (props, ref) => {
11670
11829
  });
11671
11830
  const effectToUse = React35.useInsertionEffect ?? React35.useLayoutEffect;
11672
11831
  effectToUse(() => {
11673
- return () => {
11674
- requestAnimationFrame(() => {
11675
- cleanupOnMediaTagUnmount();
11676
- });
11677
- };
11832
+ return scheduleMediaSourceCleanup.bind(null, cleanupOnMediaTagUnmount);
11678
11833
  }, [cleanupOnMediaTagUnmount]);
11679
11834
  useImperativeHandle4(ref, () => {
11680
11835
  return audioRef.current;
11681
11836
  }, [audioRef]);
11682
- const currentOnDurationCallback = useRef21(onDuration);
11683
- currentOnDurationCallback.current = onDuration;
11684
- useEffect16(() => {
11685
- const { current } = audioRef;
11686
- if (!current) {
11687
- return;
11688
- }
11689
- if (current.duration) {
11690
- currentOnDurationCallback.current?.(current.src, current.duration);
11691
- return;
11692
- }
11693
- const onLoadedMetadata = () => {
11694
- currentOnDurationCallback.current?.(current.src, current.duration);
11695
- };
11696
- current.addEventListener("loadedmetadata", onLoadedMetadata);
11697
- return () => {
11698
- current.removeEventListener("loadedmetadata", onLoadedMetadata);
11699
- };
11700
- }, [audioRef, src]);
11837
+ useMediaDuration(audioRef, onDuration, src, true);
11701
11838
  if (initialShouldPreMountAudioElements) {
11702
11839
  return null;
11703
11840
  }
@@ -11736,7 +11873,7 @@ var AudioForPreviewRefForwardingFunction = (props, ref) => {
11736
11873
  volume: userPreferredVolume,
11737
11874
  audioEnabled: true
11738
11875
  });
11739
- const getStack = useCallback16(() => {
11876
+ const getStack = useCallback14(() => {
11740
11877
  return _remotionInternalStack ?? null;
11741
11878
  }, [_remotionInternalStack]);
11742
11879
  const { registration } = useMediaInTimelineRegistration({
@@ -11753,7 +11890,7 @@ var AudioForPreviewRefForwardingFunction = (props, ref) => {
11753
11890
  documentationLink: "https://www.remotion.dev/docs/html5-audio",
11754
11891
  muted: isMutedForTimeline
11755
11892
  });
11756
- const metadata = useMemo33(() => isStudio || registration !== null ? {
11893
+ const metadata = useMemo34(() => isStudio || registration !== null ? {
11757
11894
  type: "sequence",
11758
11895
  id: timelineId,
11759
11896
  value: registration,
@@ -11776,20 +11913,20 @@ var AudioForPreviewRefForwardingFunction = (props, ref) => {
11776
11913
  var AudioForPreview = forwardRef5(AudioForPreviewRefForwardingFunction);
11777
11914
 
11778
11915
  // src/audio/AudioForRendering.tsx
11779
- import {
11916
+ import React36, {
11780
11917
  forwardRef as forwardRef6,
11781
11918
  useContext as useContext43,
11782
- useEffect as useEffect17,
11919
+ useEffect as useEffect16,
11783
11920
  useImperativeHandle as useImperativeHandle5,
11784
11921
  useLayoutEffect as useLayoutEffect15,
11785
- useMemo as useMemo35,
11922
+ useMemo as useMemo36,
11786
11923
  useRef as useRef22
11787
11924
  } from "react";
11788
11925
 
11789
11926
  // src/use-media-enabled.tsx
11790
- import { createContext as createContext35, useContext as useContext42, useMemo as useMemo34 } from "react";
11927
+ import { createContext as createContext36, useContext as useContext42, useMemo as useMemo35 } from "react";
11791
11928
  import { jsx as jsx28 } from "react/jsx-runtime";
11792
- var MediaEnabledContext = createContext35(null);
11929
+ var MediaEnabledContext = createContext36(null);
11793
11930
  var useVideoEnabled = () => {
11794
11931
  const context = useContext42(MediaEnabledContext);
11795
11932
  if (!context) {
@@ -11815,7 +11952,7 @@ var MediaEnabledProvider = ({
11815
11952
  videoEnabled,
11816
11953
  audioEnabled
11817
11954
  }) => {
11818
- const value = useMemo34(() => ({ videoEnabled, audioEnabled }), [videoEnabled, audioEnabled]);
11955
+ const value = useMemo35(() => ({ videoEnabled, audioEnabled }), [videoEnabled, audioEnabled]);
11819
11956
  return /* @__PURE__ */ jsx28(MediaEnabledContext.Provider, {
11820
11957
  value,
11821
11958
  children
@@ -11827,6 +11964,8 @@ import { jsx as jsx29 } from "react/jsx-runtime";
11827
11964
  var AudioForRenderingRefForwardingFunction = (props, ref) => {
11828
11965
  const audioRef = useRef22(null);
11829
11966
  const {
11967
+ registerRenderAsset,
11968
+ unregisterRenderAsset,
11830
11969
  volume: volumeProp,
11831
11970
  playbackRate,
11832
11971
  allowAmplificationDuringRender,
@@ -11842,7 +11981,7 @@ var AudioForRenderingRefForwardingFunction = (props, ref) => {
11842
11981
  loopVolumeCurveBehavior,
11843
11982
  pauseWhenBuffering,
11844
11983
  audioStreamIndex,
11845
- preservePitch: _preservePitch,
11984
+ preservePitch,
11846
11985
  ...nativeProps
11847
11986
  } = props;
11848
11987
  const absoluteFrame = useTimelinePosition();
@@ -11851,9 +11990,8 @@ var AudioForRenderingRefForwardingFunction = (props, ref) => {
11851
11990
  const sequenceContext = useContext43(SequenceContext);
11852
11991
  const sequencePlaybackRate = sequenceContext?.playbackRate ?? 1;
11853
11992
  const audioStartFrame = useContext43(Html5MediaTrimContext);
11854
- const { registerRenderAsset, unregisterRenderAsset } = useContext43(RenderAssetManager);
11855
11993
  const { delayRender, continueRender } = useDelayRender();
11856
- const id = useMemo35(() => `audio-${random(props.src ?? "")}-${sequenceContext?.relativeFrom}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.durationInFrames}`, [
11994
+ const id = useMemo36(() => `audio-${random(props.src ?? "")}-${sequenceContext?.relativeFrom}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.durationInFrames}`, [
11857
11995
  props.src,
11858
11996
  sequenceContext?.relativeFrom,
11859
11997
  sequenceContext?.cumulatedFrom,
@@ -11874,7 +12012,7 @@ var AudioForRenderingRefForwardingFunction = (props, ref) => {
11874
12012
  useImperativeHandle5(ref, () => {
11875
12013
  return audioRef.current;
11876
12014
  }, []);
11877
- useEffect17(() => {
12015
+ useEffect16(() => {
11878
12016
  if (!props.src) {
11879
12017
  throw new Error("No src passed");
11880
12018
  }
@@ -11891,7 +12029,8 @@ var AudioForRenderingRefForwardingFunction = (props, ref) => {
11891
12029
  playbackRate: (props.playbackRate ?? 1) * sequencePlaybackRate,
11892
12030
  toneFrequency: toneFrequency ?? 1,
11893
12031
  audioStartFrame,
11894
- audioStreamIndex: audioStreamIndex ?? 0
12032
+ audioStreamIndex: audioStreamIndex ?? 0,
12033
+ preservePitch: preservePitch ?? true
11895
12034
  });
11896
12035
  return () => unregisterRenderAsset(id);
11897
12036
  }, [
@@ -11909,7 +12048,8 @@ var AudioForRenderingRefForwardingFunction = (props, ref) => {
11909
12048
  toneFrequency,
11910
12049
  audioStartFrame,
11911
12050
  sequencePlaybackRate,
11912
- audioStreamIndex
12051
+ audioStreamIndex,
12052
+ preservePitch
11913
12053
  ]);
11914
12054
  const { src } = props;
11915
12055
  const needsToRenderAudioTag = ref || _remotionInternalNeedsDurationCalculation;
@@ -11959,7 +12099,16 @@ var AudioForRenderingRefForwardingFunction = (props, ref) => {
11959
12099
  onError: onNativeError
11960
12100
  });
11961
12101
  };
11962
- var AudioForRendering = forwardRef6(AudioForRenderingRefForwardingFunction);
12102
+ var MemoAudioForRendering = React36.memo(forwardRef6(AudioForRenderingRefForwardingFunction));
12103
+ var AudioForRendering = forwardRef6((props, ref) => {
12104
+ const { registerRenderAsset, unregisterRenderAsset } = useContext43(RenderAssetManager);
12105
+ return /* @__PURE__ */ jsx29(MemoAudioForRendering, {
12106
+ ...props,
12107
+ ref,
12108
+ registerRenderAsset,
12109
+ unregisterRenderAsset
12110
+ });
12111
+ });
11963
12112
 
11964
12113
  // src/audio/html5-audio.tsx
11965
12114
  import { jsx as jsx30 } from "react/jsx-runtime";
@@ -11995,7 +12144,7 @@ var AudioRefForwardingFunction = (props, ref) => {
11995
12144
  throw new TypeError(`The \`<Html5Audio>\` tag requires a string for \`src\`, but got ${JSON.stringify(props.src)} instead.`);
11996
12145
  }
11997
12146
  const preloadedSrc = usePreload(props.src);
11998
- const onError = useCallback17((e) => {
12147
+ const onError = useCallback15((e) => {
11999
12148
  console.log(e.currentTarget.error);
12000
12149
  const errMessage = `Could not play audio with src ${preloadedSrc}: ${e.currentTarget.error}. See https://remotion.dev/docs/media-playback-error for help.`;
12001
12150
  if (loop) {
@@ -12009,9 +12158,7 @@ var AudioRefForwardingFunction = (props, ref) => {
12009
12158
  console.warn(errMessage);
12010
12159
  }
12011
12160
  }, [loop, onRemotionError, preloadedSrc]);
12012
- const onDuration = useCallback17((src, durationInSeconds) => {
12013
- setDurations({ type: "got-duration", durationInSeconds, src });
12014
- }, [setDurations]);
12161
+ const onDuration = useMemo37(() => onMediaDuration.bind(null, setDurations), [setDurations]);
12015
12162
  const durationFetched = durations[getAbsoluteSrc(preloadedSrc)] ?? durations[getAbsoluteSrc(props.src)];
12016
12163
  validateMediaTrimProps({ startFrom, endAt, trimBefore, trimAfter });
12017
12164
  if (durationInFrames !== undefined) {
@@ -12106,10 +12253,10 @@ var Audio = Html5Audio;
12106
12253
  // src/effects/Solid.tsx
12107
12254
  import {
12108
12255
  forwardRef as forwardRef8,
12109
- useCallback as useCallback18,
12110
- useEffect as useEffect18,
12256
+ useCallback as useCallback16,
12257
+ useEffect as useEffect17,
12111
12258
  useImperativeHandle as useImperativeHandle6,
12112
- useMemo as useMemo36,
12259
+ useMemo as useMemo38,
12113
12260
  useRef as useRef23,
12114
12261
  useState as useState18
12115
12262
  } from "react";
@@ -12185,7 +12332,7 @@ var SolidInner = ({
12185
12332
  overrideId: overrideId ?? null,
12186
12333
  videoConfigValues
12187
12334
  });
12188
- const sourceCanvas = useMemo36(() => {
12335
+ const sourceCanvas = useMemo38(() => {
12189
12336
  if (typeof document === "undefined") {
12190
12337
  return null;
12191
12338
  }
@@ -12195,7 +12342,7 @@ var SolidInner = ({
12195
12342
  return canvas;
12196
12343
  }, []);
12197
12344
  const chainState = useEffectChainState(effectsOutputSize);
12198
- const canvasRef = useCallback18((canvas) => {
12345
+ const canvasRef = useCallback16((canvas) => {
12199
12346
  setOutputCanvas(canvas);
12200
12347
  if (typeof reference === "function") {
12201
12348
  reference(canvas);
@@ -12203,7 +12350,7 @@ var SolidInner = ({
12203
12350
  reference.current = canvas;
12204
12351
  }
12205
12352
  }, [reference]);
12206
- useEffect18(() => {
12353
+ useEffect17(() => {
12207
12354
  if (!outputCanvas || !sourceCanvas) {
12208
12355
  return;
12209
12356
  }
@@ -12253,7 +12400,7 @@ var SolidInner = ({
12253
12400
  cancelRender,
12254
12401
  memoizedEffects
12255
12402
  ]);
12256
- const canvasStyle = useMemo36(() => {
12403
+ const canvasStyle = useMemo38(() => {
12257
12404
  return {
12258
12405
  width,
12259
12406
  height,
@@ -12384,15 +12531,71 @@ Solid.displayName = "Solid";
12384
12531
  addSequenceStackTraces(Solid);
12385
12532
  // src/HtmlInCanvas.tsx
12386
12533
  import {
12387
- createContext as createContext36,
12534
+ createContext as createContext37,
12388
12535
  forwardRef as forwardRef9,
12389
- useCallback as useCallback19,
12536
+ useCallback as useCallback17,
12390
12537
  useContext as useContext45,
12391
12538
  useLayoutEffect as useLayoutEffect16,
12392
- useMemo as useMemo37,
12539
+ useMemo as useMemo39,
12393
12540
  useRef as useRef24
12394
12541
  } from "react";
12542
+
12543
+ // src/HtmlInCanvasFallback.tsx
12395
12544
  import { jsx as jsx32, jsxs as jsxs3 } from "react/jsx-runtime";
12545
+ var HtmlInCanvasFallback = ({ children, style, label }) => {
12546
+ const currentScale = useCurrentScale({ dontThrowIfOutsideOfRemotion: true });
12547
+ const scale = currentScale > 0 ? currentScale : 1;
12548
+ return /* @__PURE__ */ jsxs3("div", {
12549
+ style: { position: "relative", ...style },
12550
+ children: [
12551
+ children,
12552
+ /* @__PURE__ */ jsxs3("div", {
12553
+ className: "css-reset",
12554
+ style: {
12555
+ position: "absolute",
12556
+ top: 8 / scale,
12557
+ right: 8 / scale,
12558
+ zIndex: 1000,
12559
+ transform: `scale(${1 / scale})`,
12560
+ transformOrigin: "top right",
12561
+ maxWidth: `calc(${scale * 100}% - 16px)`,
12562
+ padding: "8px 10px",
12563
+ borderRadius: 6,
12564
+ border: "1px solid #7f3540",
12565
+ backgroundColor: "#2b171c",
12566
+ boxShadow: "0 2px 8px #0003",
12567
+ pointerEvents: "none",
12568
+ textAlign: "left"
12569
+ },
12570
+ children: [
12571
+ /* @__PURE__ */ jsx32("div", {
12572
+ style: {
12573
+ fontFamily: "Arial, Helvetica, sans-serif",
12574
+ fontSize: 12,
12575
+ fontWeight: 600,
12576
+ lineHeight: 1.5,
12577
+ color: "#ffabb5"
12578
+ },
12579
+ children: "HTML-in-canvas is not available"
12580
+ }),
12581
+ /* @__PURE__ */ jsx32("div", {
12582
+ style: {
12583
+ fontFamily: "Arial, Helvetica, sans-serif",
12584
+ fontSize: 11,
12585
+ fontWeight: 400,
12586
+ lineHeight: 1.5,
12587
+ color: "#e8bdc3"
12588
+ },
12589
+ children: label
12590
+ })
12591
+ ]
12592
+ })
12593
+ ]
12594
+ });
12595
+ };
12596
+
12597
+ // src/HtmlInCanvas.tsx
12598
+ import { jsx as jsx33, jsxs as jsxs4 } from "react/jsx-runtime";
12396
12599
  var transferredOffscreenCanvases = new WeakMap;
12397
12600
  var getTransferredOffscreenCanvas = (canvas) => {
12398
12601
  const existing = transferredOffscreenCanvases.get(canvas);
@@ -12499,7 +12702,17 @@ var defaultOnPaint = ({
12499
12702
  ctx.reset();
12500
12703
  ctx.drawElementImage(elementImage, 0, 0);
12501
12704
  };
12502
- var HtmlInCanvasAncestorContext = createContext36(null);
12705
+ var HtmlInCanvasAncestorContext = createContext37(null);
12706
+ var useHtmlInCanvasUnsupportedMessage = () => {
12707
+ const ancestorPaintState = useContext45(HtmlInCanvasAncestorContext);
12708
+ if (!isHtmlInCanvasSupported()) {
12709
+ return getHtmlInCanvasUnsupportedMessage();
12710
+ }
12711
+ if (ancestorPaintState && !isHtmlInCanvasNestingSupported()) {
12712
+ return `Nested <HtmlInCanvas> components require Chrome ${MINIMUM_CHROME_VERSION_FOR_NESTED_HTML_IN_CANVAS} or newer with HTML-in-canvas enabled.`;
12713
+ }
12714
+ return null;
12715
+ };
12503
12716
  var HtmlInCanvasContent = forwardRef9(({
12504
12717
  width,
12505
12718
  height,
@@ -12526,7 +12739,7 @@ var HtmlInCanvasContent = forwardRef9(({
12526
12739
  const { isClientSideRendering, isRendering } = useRemotionEnvironment();
12527
12740
  const canRetryMissingPaintRecord = !isRendering || isClientSideRendering;
12528
12741
  const usesDirectLayoutCanvas = onPaint === undefined && onInit === undefined;
12529
- const paintTargetMode = usesDirectLayoutCanvas ? "direct" : isRendering ? "copied" : "transferred";
12742
+ const paintTargetMode = ancestorPaintState ? "copied" : usesDirectLayoutCanvas ? "direct" : isRendering ? "copied" : "transferred";
12530
12743
  if (!isHtmlInCanvasSupported()) {
12531
12744
  cancelRender(new Error(getHtmlInCanvasUnsupportedMessage()));
12532
12745
  }
@@ -12535,7 +12748,7 @@ var HtmlInCanvasContent = forwardRef9(({
12535
12748
  const paintTargetRef = useRef24(null);
12536
12749
  const divRef = useRef24(null);
12537
12750
  const canvasSizeKey = `${width}x${height}@${resolvedPixelDensity}-${paintTargetMode}`;
12538
- const paintState = useMemo37(() => {
12751
+ const paintState = useMemo39(() => {
12539
12752
  const state = {
12540
12753
  pendingChildren: 0,
12541
12754
  generation: 0,
@@ -12566,7 +12779,7 @@ var HtmlInCanvasContent = forwardRef9(({
12566
12779
  };
12567
12780
  return state;
12568
12781
  }, [continueRender, delayRender, ancestorPaintState]);
12569
- const setVisibleCanvasRef = useCallback19((node) => {
12782
+ const setVisibleCanvasRef = useCallback17((node) => {
12570
12783
  if (paintTargetMode === "copied") {
12571
12784
  outputCanvasRef.current = node;
12572
12785
  } else {
@@ -12593,8 +12806,9 @@ var HtmlInCanvasContent = forwardRef9(({
12593
12806
  const initializedRef = useRef24(false);
12594
12807
  const onInitCleanupRef = useRef24(null);
12595
12808
  const unmountedRef = useRef24(false);
12809
+ const effectScratchCanvasesRef = useRef24(null);
12596
12810
  const paintingTargets = useRef24(new WeakMap);
12597
- const onPaintCb = useCallback19(async () => {
12811
+ const onPaintCb = useCallback17(async () => {
12598
12812
  if (isRendering && paintState.pendingChildren > 0) {
12599
12813
  return;
12600
12814
  }
@@ -12688,6 +12902,7 @@ var HtmlInCanvasContent = forwardRef9(({
12688
12902
  }
12689
12903
  throw error;
12690
12904
  }
12905
+ let effectSourceCanvas = null;
12691
12906
  try {
12692
12907
  const currentOnPaint = onPaintRef.current;
12693
12908
  if (currentOnPaint) {
@@ -12703,6 +12918,41 @@ var HtmlInCanvasContent = forwardRef9(({
12703
12918
  if (paintResult) {
12704
12919
  await paintResult;
12705
12920
  }
12921
+ } else if (paintTarget instanceof HTMLCanvasElement && effectsRef.current.some((effect) => !effect.params.disabled)) {
12922
+ effectScratchCanvasesRef.current ??= {
12923
+ source: document.createElement("canvas"),
12924
+ previousOutput: document.createElement("canvas")
12925
+ };
12926
+ const { source: effectSource, previousOutput } = effectScratchCanvasesRef.current;
12927
+ resizePaintTarget({
12928
+ target: effectSource,
12929
+ width: canvasWidth,
12930
+ height: canvasHeight
12931
+ });
12932
+ resizePaintTarget({
12933
+ target: previousOutput,
12934
+ width: canvasWidth,
12935
+ height: canvasHeight
12936
+ });
12937
+ const effectSourceCtx = effectSource.getContext("2d");
12938
+ const previousOutputCtx = previousOutput.getContext("2d");
12939
+ const paintTargetCtx = paintTarget.getContext("2d");
12940
+ if (!effectSourceCtx || !previousOutputCtx || !paintTargetCtx) {
12941
+ throw new Error("Failed to acquire 2D context for <HtmlInCanvas> canvas");
12942
+ }
12943
+ previousOutputCtx.reset();
12944
+ previousOutputCtx.drawImage(paintTarget, 0, 0);
12945
+ defaultOnPaint({
12946
+ canvas: paintTarget,
12947
+ element,
12948
+ elementImage: elImage,
12949
+ pixelDensity: resolvedPixelDensity
12950
+ });
12951
+ effectSourceCtx.reset();
12952
+ effectSourceCtx.drawImage(paintTarget, 0, 0);
12953
+ paintTargetCtx.reset();
12954
+ paintTargetCtx.drawImage(previousOutput, 0, 0);
12955
+ effectSourceCanvas = effectSource;
12706
12956
  } else {
12707
12957
  defaultOnPaint({
12708
12958
  canvas: paintTarget,
@@ -12715,7 +12965,7 @@ var HtmlInCanvasContent = forwardRef9(({
12715
12965
  if (state) {
12716
12966
  await runEffectChain({
12717
12967
  state,
12718
- source: paintTarget,
12968
+ source: effectSourceCanvas ?? paintTarget,
12719
12969
  effects: effectsRef.current,
12720
12970
  output: paintTarget,
12721
12971
  width: canvasWidth,
@@ -12835,23 +13085,23 @@ var HtmlInCanvasContent = forwardRef9(({
12835
13085
  isRendering,
12836
13086
  ancestorPaintState
12837
13087
  ]);
12838
- const innerStyle = useMemo37(() => {
13088
+ const innerStyle = useMemo39(() => {
12839
13089
  return {
12840
13090
  width,
12841
13091
  height
12842
13092
  };
12843
13093
  }, [width, height]);
12844
- const canvasStyle = useMemo37(() => {
13094
+ const canvasStyle = useMemo39(() => {
12845
13095
  return {
12846
13096
  width,
12847
13097
  height,
12848
13098
  ...style ?? {}
12849
13099
  };
12850
13100
  }, [height, style, width]);
12851
- return /* @__PURE__ */ jsxs3(HtmlInCanvasAncestorContext.Provider, {
13101
+ return /* @__PURE__ */ jsxs4(HtmlInCanvasAncestorContext.Provider, {
12852
13102
  value: paintState,
12853
13103
  children: [
12854
- /* @__PURE__ */ jsxs3("canvas", {
13104
+ /* @__PURE__ */ jsx33("canvas", {
12855
13105
  ref: paintTargetMode === "copied" ? canvas2dRef : setVisibleCanvasRef,
12856
13106
  width: canvasWidth,
12857
13107
  height: canvasHeight,
@@ -12861,16 +13111,19 @@ var HtmlInCanvasContent = forwardRef9(({
12861
13111
  visibility: "hidden",
12862
13112
  pointerEvents: "none"
12863
13113
  } : canvasStyle,
12864
- children: [
12865
- /* @__PURE__ */ jsx32("div", {
12866
- ref: divRef,
12867
- style: paintTargetMode === "copied" ? { ...innerStyle, visibility: "visible" } : innerStyle,
12868
- children
12869
- }),
12870
- canvasSiblings
12871
- ]
13114
+ children: /* @__PURE__ */ jsxs4(DefaultPremountContext.Provider, {
13115
+ value: 0,
13116
+ children: [
13117
+ /* @__PURE__ */ jsx33("div", {
13118
+ ref: divRef,
13119
+ style: paintTargetMode === "copied" ? { ...innerStyle, visibility: "visible" } : innerStyle,
13120
+ children
13121
+ }),
13122
+ canvasSiblings
13123
+ ]
13124
+ })
12872
13125
  }, canvasSizeKey),
12873
- paintTargetMode === "copied" ? /* @__PURE__ */ jsx32("canvas", {
13126
+ paintTargetMode === "copied" ? /* @__PURE__ */ jsx33("canvas", {
12874
13127
  ref: setVisibleCanvasRef,
12875
13128
  width: canvasWidth,
12876
13129
  height: canvasHeight,
@@ -12882,7 +13135,7 @@ var HtmlInCanvasContent = forwardRef9(({
12882
13135
  HtmlInCanvasContent.displayName = "HtmlInCanvasContent";
12883
13136
  var HtmlInCanvasContentForRendering = forwardRef9((props, ref) => {
12884
13137
  const frame = useCurrentFrame();
12885
- return /* @__PURE__ */ jsx32(HtmlInCanvasContent, {
13138
+ return /* @__PURE__ */ jsx33(HtmlInCanvasContent, {
12886
13139
  ...props,
12887
13140
  ref,
12888
13141
  renderFrame: frame
@@ -12899,6 +13152,7 @@ var HtmlInCanvasInner = forwardRef9(({
12899
13152
  onInit,
12900
13153
  pixelDensity,
12901
13154
  _remotionInternalCanvasSiblings,
13155
+ _remotionInternalFallbackLabel = "Effects are not visible",
12902
13156
  controls,
12903
13157
  style,
12904
13158
  cropLeft,
@@ -12914,10 +13168,13 @@ var HtmlInCanvasInner = forwardRef9(({
12914
13168
  ...sequenceProps
12915
13169
  }, ref) => {
12916
13170
  const { isRendering } = useRemotionEnvironment();
13171
+ const unsupportedMessage = useHtmlInCanvasUnsupportedMessage();
13172
+ assertHtmlInCanvasDimensions(width, height);
13173
+ resolveHtmlInCanvasPixelDensity(pixelDensity);
12917
13174
  const Content = isRendering ? HtmlInCanvasContentForRendering : HtmlInCanvasContent;
12918
13175
  const memoizedEffectDefinitions = useMemoizedEffectDefinitions(effects);
12919
13176
  const actualRef = useRef24(null);
12920
- const setCanvasRef = useCallback19((node) => {
13177
+ const setCanvasRef = useCallback17((node) => {
12921
13178
  actualRef.current = node;
12922
13179
  if (typeof ref === "function") {
12923
13180
  ref(node);
@@ -12955,11 +13212,11 @@ var HtmlInCanvasInner = forwardRef9(({
12955
13212
  style: premountingStyle,
12956
13213
  componentName: "<HtmlInCanvas />"
12957
13214
  });
12958
- return /* @__PURE__ */ jsx32(Freeze, {
13215
+ return /* @__PURE__ */ jsx33(Freeze, {
12959
13216
  frame: freezeFrame,
12960
13217
  active: isPremountingOrPostmounting,
12961
13218
  _remotionInternalIsPremounting: premountingActive,
12962
- children: /* @__PURE__ */ jsx32(Sequence, {
13219
+ children: /* @__PURE__ */ jsx33(Sequence, {
12963
13220
  layout: "none",
12964
13221
  durationInFrames,
12965
13222
  name: name ?? "<HtmlInCanvas>",
@@ -12971,7 +13228,17 @@ var HtmlInCanvasInner = forwardRef9(({
12971
13228
  _remotionInternalPostmountDisplay: effectivePostmountFor || null,
12972
13229
  _remotionInternalIsPremounting: premountingActive,
12973
13230
  _remotionInternalIsPostmounting: postmountingActive,
12974
- children: /* @__PURE__ */ jsx32(Content, {
13231
+ children: !isRendering && unsupportedMessage !== null ? /* @__PURE__ */ jsx33(HtmlInCanvasFallback, {
13232
+ style: { width, height, ...croppedStyle },
13233
+ label: _remotionInternalFallbackLabel,
13234
+ children: /* @__PURE__ */ jsx33(DefaultPremountContext.Provider, {
13235
+ value: 0,
13236
+ children: /* @__PURE__ */ jsx33("div", {
13237
+ style: { width, height },
13238
+ children
13239
+ })
13240
+ })
13241
+ }) : /* @__PURE__ */ jsx33(Content, {
12975
13242
  ref: setCanvasRef,
12976
13243
  renderFrame: null,
12977
13244
  width,
@@ -13024,11 +13291,10 @@ addSequenceStackTraces(HtmlInCanvas);
13024
13291
  // src/canvas-image/CanvasImage.tsx
13025
13292
  import {
13026
13293
  forwardRef as forwardRef10,
13027
- useCallback as useCallback20,
13028
13294
  useContext as useContext46,
13029
13295
  useImperativeHandle as useImperativeHandle7,
13030
13296
  useLayoutEffect as useLayoutEffect17,
13031
- useMemo as useMemo38,
13297
+ useMemo as useMemo40,
13032
13298
  useRef as useRef25,
13033
13299
  useState as useState19
13034
13300
  } from "react";
@@ -13045,7 +13311,7 @@ function truncateSrcForLabel(src) {
13045
13311
  }
13046
13312
 
13047
13313
  // src/canvas-image/CanvasImage.tsx
13048
- import { jsx as jsx33 } from "react/jsx-runtime";
13314
+ import { jsx as jsx34 } from "react/jsx-runtime";
13049
13315
  var canvasImageSchema = {
13050
13316
  src: {
13051
13317
  type: "asset",
@@ -13072,6 +13338,26 @@ var canvasImageSchema = {
13072
13338
  ...borderSchema,
13073
13339
  ...borderRadiusSchema
13074
13340
  };
13341
+ var continueImageLoadDelay = (pendingLoadDelayRef, setIsLoadPending, continueRender, { markAsReady }) => {
13342
+ const pending = pendingLoadDelayRef.current;
13343
+ if (!pending || pending.continued) {
13344
+ return;
13345
+ }
13346
+ pending.continued = true;
13347
+ if (markAsReady) {
13348
+ setIsLoadPending(false);
13349
+ }
13350
+ continueRender(pending.handle);
13351
+ pendingLoadDelayRef.current = null;
13352
+ };
13353
+ var setCanvasRef = (setOutputCanvas, ref, canvas) => {
13354
+ setOutputCanvas(canvas);
13355
+ if (typeof ref === "function") {
13356
+ ref(canvas);
13357
+ } else if (ref) {
13358
+ ref.current = canvas;
13359
+ }
13360
+ };
13075
13361
  var makeAbortError = () => {
13076
13362
  if (typeof DOMException !== "undefined") {
13077
13363
  return new DOMException("Image loading was aborted", "AbortError");
@@ -13124,7 +13410,7 @@ var loadImage = ({
13124
13410
  onAbort();
13125
13411
  return;
13126
13412
  }
13127
- image.crossOrigin = crossOrigin ?? "anonymous";
13413
+ image.crossOrigin = crossOrigin || "anonymous";
13128
13414
  image.src = src;
13129
13415
  });
13130
13416
  };
@@ -13178,32 +13464,14 @@ var CanvasImageContent = forwardRef10(({
13178
13464
  const [isLoadPending, setIsLoadPending] = useState19(false);
13179
13465
  const isPremounting = Boolean(sequenceContext?.premounting);
13180
13466
  const isPostmounting = Boolean(sequenceContext?.postmounting);
13181
- const continuePendingLoadDelay = useCallback20(({ markAsReady }) => {
13182
- const pending = pendingLoadDelayRef.current;
13183
- if (!pending || pending.continued) {
13184
- return;
13185
- }
13186
- pending.continued = true;
13187
- if (markAsReady) {
13188
- setIsLoadPending(false);
13189
- }
13190
- continueRender(pending.handle);
13191
- pendingLoadDelayRef.current = null;
13192
- }, [continueRender]);
13193
- const sourceCanvas = useMemo38(() => {
13467
+ const continuePendingLoadDelay = useMemo40(() => continueImageLoadDelay.bind(null, pendingLoadDelayRef, setIsLoadPending, continueRender), [continueRender]);
13468
+ const sourceCanvas = useMemo40(() => {
13194
13469
  if (typeof document === "undefined") {
13195
13470
  return null;
13196
13471
  }
13197
13472
  return document.createElement("canvas");
13198
13473
  }, []);
13199
- const canvasRef = useCallback20((canvas) => {
13200
- setOutputCanvas(canvas);
13201
- if (typeof ref === "function") {
13202
- ref(canvas);
13203
- } else if (ref) {
13204
- ref.current = canvas;
13205
- }
13206
- }, [ref]);
13474
+ const canvasRef = useMemo40(() => setCanvasRef.bind(null, setOutputCanvas, ref), [ref]);
13207
13475
  useLayoutEffect17(() => {
13208
13476
  if (!pauseWhenLoading || !isLoadPending || isPremounting || isPostmounting) {
13209
13477
  return;
@@ -13366,7 +13634,7 @@ var CanvasImageContent = forwardRef10(({
13366
13634
  sourceCanvas,
13367
13635
  width
13368
13636
  ]);
13369
- return /* @__PURE__ */ jsx33("canvas", {
13637
+ return /* @__PURE__ */ jsx34("canvas", {
13370
13638
  ...canvasProps,
13371
13639
  ref: canvasRef,
13372
13640
  width,
@@ -13417,7 +13685,7 @@ var CanvasImageInner = forwardRef10(({
13417
13685
  if (!src) {
13418
13686
  throw new Error('No "src" prop was passed to <CanvasImage>.');
13419
13687
  }
13420
- const isMedia = useMemo38(() => ({
13688
+ const isMedia = useMemo40(() => ({
13421
13689
  type: "image",
13422
13690
  src
13423
13691
  }), [src]);
@@ -13456,11 +13724,11 @@ var CanvasImageInner = forwardRef10(({
13456
13724
  style: premountingStyle,
13457
13725
  componentName: _remotionInternalCropComponentName ?? "<CanvasImage />"
13458
13726
  });
13459
- return /* @__PURE__ */ jsx33(Freeze, {
13727
+ return /* @__PURE__ */ jsx34(Freeze, {
13460
13728
  frame: freezeFrame,
13461
13729
  active: isPremountingOrPostmounting,
13462
13730
  _remotionInternalIsPremounting: premountingActive,
13463
- children: /* @__PURE__ */ jsx33(Sequence, {
13731
+ children: /* @__PURE__ */ jsx34(Sequence, {
13464
13732
  layout: "none",
13465
13733
  from: from ?? 0,
13466
13734
  trimBefore,
@@ -13478,8 +13746,8 @@ var CanvasImageInner = forwardRef10(({
13478
13746
  _remotionInternalPostmountDisplay: effectivePostmountFor || null,
13479
13747
  _remotionInternalIsPremounting: premountingActive,
13480
13748
  _remotionInternalIsPostmounting: postmountingActive,
13481
- children: /* @__PURE__ */ jsx33(SequenceContent, {
13482
- children: /* @__PURE__ */ jsx33(CanvasImageContent, {
13749
+ children: /* @__PURE__ */ jsx34(SequenceContent, {
13750
+ children: /* @__PURE__ */ jsx34(CanvasImageContent, {
13483
13751
  ref: actualRef,
13484
13752
  src,
13485
13753
  crossOrigin,
@@ -13544,8 +13812,8 @@ var getStaticFiles = () => {
13544
13812
  return window.remotion_staticFiles;
13545
13813
  };
13546
13814
  // src/IFrame.tsx
13547
- import { forwardRef as forwardRef11, useCallback as useCallback21, useLayoutEffect as useLayoutEffect18, useRef as useRef26 } from "react";
13548
- import { jsx as jsx34 } from "react/jsx-runtime";
13815
+ import { forwardRef as forwardRef11, useCallback as useCallback18, useLayoutEffect as useLayoutEffect18, useRef as useRef26 } from "react";
13816
+ import { jsx as jsx35 } from "react/jsx-runtime";
13549
13817
  var IFrameRefForwarding = ({
13550
13818
  onLoad,
13551
13819
  onError,
@@ -13579,7 +13847,7 @@ var IFrameRefForwarding = ({
13579
13847
  src,
13580
13848
  srcDoc
13581
13849
  ]);
13582
- const didLoad = useCallback21((e) => {
13850
+ const didLoad = useCallback18((e) => {
13583
13851
  loadedSource.current = { src, srcDoc };
13584
13852
  if (handle.current !== null) {
13585
13853
  continueRender(handle.current);
@@ -13587,7 +13855,7 @@ var IFrameRefForwarding = ({
13587
13855
  }
13588
13856
  onLoad?.(e);
13589
13857
  }, [onLoad, continueRender, src, srcDoc]);
13590
- const didGetError = useCallback21((e) => {
13858
+ const didGetError = useCallback18((e) => {
13591
13859
  loadedSource.current = { src, srcDoc };
13592
13860
  if (handle.current !== null) {
13593
13861
  continueRender(handle.current);
@@ -13599,7 +13867,7 @@ var IFrameRefForwarding = ({
13599
13867
  console.error("Error loading iframe:", e, "Handle the event using the onError() prop to make this message disappear.");
13600
13868
  }
13601
13869
  }, [onError, continueRender, src, srcDoc]);
13602
- return /* @__PURE__ */ jsx34("iframe", {
13870
+ return /* @__PURE__ */ jsx35("iframe", {
13603
13871
  referrerPolicy: "strict-origin-when-cross-origin",
13604
13872
  ...props,
13605
13873
  ref,
@@ -13610,17 +13878,130 @@ var IFrameRefForwarding = ({
13610
13878
  var IFrame = forwardRef11(IFrameRefForwarding);
13611
13879
  // src/Img.tsx
13612
13880
  import {
13613
- useCallback as useCallback22,
13614
13881
  useContext as useContext47,
13615
13882
  useLayoutEffect as useLayoutEffect19,
13616
- useMemo as useMemo39,
13883
+ useMemo as useMemo41,
13617
13884
  useRef as useRef27,
13618
13885
  useState as useState20
13619
13886
  } from "react";
13620
- import { jsx as jsx35 } from "react/jsx-runtime";
13887
+ import { jsx as jsx36 } from "react/jsx-runtime";
13621
13888
  function exponentialBackoff2(errorCount) {
13622
13889
  return 1000 * 2 ** (errorCount - 1);
13623
13890
  }
13891
+ var setImageRef = (imageRef, ref, img) => {
13892
+ imageRef.current = img;
13893
+ if (typeof ref === "function") {
13894
+ ref(img);
13895
+ } else if (ref) {
13896
+ ref.current = img;
13897
+ }
13898
+ };
13899
+ var retryImage = (imageRef, timeout) => {
13900
+ if (!imageRef.current) {
13901
+ return;
13902
+ }
13903
+ const currentSrc = imageRef.current.src;
13904
+ setTimeout(() => {
13905
+ if (!imageRef.current) {
13906
+ return;
13907
+ }
13908
+ const newSrc = imageRef.current?.src;
13909
+ if (newSrc !== currentSrc) {
13910
+ return;
13911
+ }
13912
+ imageRef.current.removeAttribute("src");
13913
+ imageRef.current.setAttribute("src", newSrc);
13914
+ }, timeout);
13915
+ };
13916
+ var handleImageError = ({
13917
+ errors,
13918
+ imageRef,
13919
+ onError,
13920
+ onImageError,
13921
+ maxRetries,
13922
+ cancelRender,
13923
+ retryIn
13924
+ }, e) => {
13925
+ if (!errors.current) {
13926
+ return;
13927
+ }
13928
+ errors.current[imageRef.current?.src] = (errors.current[imageRef.current?.src] ?? 0) + 1;
13929
+ if ((onError || onImageError) && (errors.current[imageRef.current?.src] ?? 0) > maxRetries) {
13930
+ onError?.(e);
13931
+ onImageError?.(new Error("Error loading image with src: " + truncateSrcForLabel(imageRef.current?.src)));
13932
+ return;
13933
+ }
13934
+ if ((errors.current[imageRef.current?.src] ?? 0) <= maxRetries) {
13935
+ const backoff = exponentialBackoff2(errors.current[imageRef.current?.src] ?? 0);
13936
+ console.warn(`Could not load image with source ${truncateSrcForLabel(imageRef.current?.src)}, retrying again in ${backoff}ms`);
13937
+ retryIn(backoff);
13938
+ return;
13939
+ }
13940
+ try {
13941
+ cancelRender("Error loading image with src: " + truncateSrcForLabel(imageRef.current?.src));
13942
+ } catch {}
13943
+ };
13944
+ var loadImage2 = ({
13945
+ imageRef,
13946
+ errors,
13947
+ actualSrc,
13948
+ delayRenderRetries,
13949
+ delayRenderTimeoutInMilliseconds,
13950
+ onImageFrame,
13951
+ delayRender,
13952
+ continueRender,
13953
+ setIsLoading
13954
+ }) => {
13955
+ if (window.process?.env?.NODE_ENV === "test") {
13956
+ if (imageRef.current) {
13957
+ imageRef.current.src = actualSrc;
13958
+ }
13959
+ return;
13960
+ }
13961
+ const { current } = imageRef;
13962
+ if (!current) {
13963
+ return;
13964
+ }
13965
+ setIsLoading(true);
13966
+ const newHandle = delayRender("Loading <Img> with src=" + truncateSrcForLabel(actualSrc), {
13967
+ retries: delayRenderRetries ?? undefined,
13968
+ timeoutInMilliseconds: delayRenderTimeoutInMilliseconds ?? undefined
13969
+ });
13970
+ let unmounted = false;
13971
+ const onComplete = () => {
13972
+ if (unmounted) {
13973
+ continueRender(newHandle);
13974
+ return;
13975
+ }
13976
+ if ((errors.current[imageRef.current?.src] ?? 0) > 0) {
13977
+ delete errors.current[imageRef.current?.src];
13978
+ console.info(`Retry successful - ${truncateSrcForLabel(imageRef.current?.src)} is now loaded`);
13979
+ }
13980
+ if (current) {
13981
+ onImageFrame?.(current);
13982
+ }
13983
+ setIsLoading(false);
13984
+ continueRender(newHandle);
13985
+ };
13986
+ if (!imageRef.current) {
13987
+ onComplete();
13988
+ return;
13989
+ }
13990
+ current.src = actualSrc;
13991
+ current.decode().then(onComplete).catch((err) => {
13992
+ console.warn(err);
13993
+ if (current.complete && current.naturalWidth > 0 && current.naturalHeight > 0) {
13994
+ onComplete();
13995
+ } else {
13996
+ current.addEventListener("load", onComplete);
13997
+ }
13998
+ });
13999
+ return () => {
14000
+ unmounted = true;
14001
+ current.removeEventListener("load", onComplete);
14002
+ continueRender(newHandle);
14003
+ };
14004
+ };
13624
14005
  var ImgContent = ({
13625
14006
  onError,
13626
14007
  onImageError,
@@ -13644,55 +14025,21 @@ var ImgContent = ({
13644
14025
  if (!_propsValid) {
13645
14026
  throw new Error("typecheck error");
13646
14027
  }
13647
- const imageCallbackRef = useCallback22((img) => {
13648
- imageRef.current = img;
13649
- if (typeof ref === "function") {
13650
- ref(img);
13651
- } else if (ref) {
13652
- ref.current = img;
13653
- }
13654
- }, [ref]);
14028
+ const imageCallbackRef = useMemo41(() => setImageRef.bind(null, imageRef, ref ?? null), [ref]);
13655
14029
  const actualSrc = usePreload(src);
13656
- const retryIn = useCallback22((timeout) => {
13657
- if (!imageRef.current) {
13658
- return;
13659
- }
13660
- const currentSrc = imageRef.current.src;
13661
- setTimeout(() => {
13662
- if (!imageRef.current) {
13663
- return;
13664
- }
13665
- const newSrc = imageRef.current?.src;
13666
- if (newSrc !== currentSrc) {
13667
- return;
13668
- }
13669
- imageRef.current.removeAttribute("src");
13670
- imageRef.current.setAttribute("src", newSrc);
13671
- }, timeout);
13672
- }, []);
14030
+ const retryIn = useMemo41(() => retryImage.bind(null, imageRef), []);
13673
14031
  const { delayRender, continueRender, cancelRender } = useDelayRender();
13674
14032
  const isPremounting = Boolean(sequenceContext?.premounting);
13675
14033
  const isPostmounting = Boolean(sequenceContext?.postmounting);
13676
- const didGetError = useCallback22((e) => {
13677
- if (!errors.current) {
13678
- return;
13679
- }
13680
- errors.current[imageRef.current?.src] = (errors.current[imageRef.current?.src] ?? 0) + 1;
13681
- if ((onError || onImageError) && (errors.current[imageRef.current?.src] ?? 0) > maxRetries) {
13682
- onError?.(e);
13683
- onImageError?.(new Error("Error loading image with src: " + truncateSrcForLabel(imageRef.current?.src)));
13684
- return;
13685
- }
13686
- if ((errors.current[imageRef.current?.src] ?? 0) <= maxRetries) {
13687
- const backoff = exponentialBackoff2(errors.current[imageRef.current?.src] ?? 0);
13688
- console.warn(`Could not load image with source ${truncateSrcForLabel(imageRef.current?.src)}, retrying again in ${backoff}ms`);
13689
- retryIn(backoff);
13690
- return;
13691
- }
13692
- try {
13693
- cancelRender("Error loading image with src: " + truncateSrcForLabel(imageRef.current?.src));
13694
- } catch {}
13695
- }, [cancelRender, maxRetries, onError, onImageError, retryIn]);
14034
+ const didGetError = useMemo41(() => handleImageError.bind(null, {
14035
+ errors,
14036
+ imageRef,
14037
+ onError: onError ?? null,
14038
+ onImageError: onImageError ?? null,
14039
+ maxRetries,
14040
+ cancelRender,
14041
+ retryIn
14042
+ }), [cancelRender, maxRetries, onError, onImageError, retryIn]);
13696
14043
  if (typeof window !== "undefined") {
13697
14044
  useLayoutEffect19(() => {
13698
14045
  if (!pauseWhenLoading || !isLoading || isPremounting || isPostmounting) {
@@ -13706,57 +14053,17 @@ var ImgContent = ({
13706
14053
  isPremounting,
13707
14054
  pauseWhenLoading
13708
14055
  ]);
13709
- useLayoutEffect19(() => {
13710
- if (window.process?.env?.NODE_ENV === "test") {
13711
- if (imageRef.current) {
13712
- imageRef.current.src = actualSrc;
13713
- }
13714
- return;
13715
- }
13716
- const { current } = imageRef;
13717
- if (!current) {
13718
- return;
13719
- }
13720
- setIsLoading(true);
13721
- const newHandle = delayRender("Loading <Img> with src=" + truncateSrcForLabel(actualSrc), {
13722
- retries: delayRenderRetries ?? undefined,
13723
- timeoutInMilliseconds: delayRenderTimeoutInMilliseconds ?? undefined
13724
- });
13725
- let unmounted = false;
13726
- const onComplete = () => {
13727
- if (unmounted) {
13728
- continueRender(newHandle);
13729
- return;
13730
- }
13731
- if ((errors.current[imageRef.current?.src] ?? 0) > 0) {
13732
- delete errors.current[imageRef.current?.src];
13733
- console.info(`Retry successful - ${truncateSrcForLabel(imageRef.current?.src)} is now loaded`);
13734
- }
13735
- if (current) {
13736
- onImageFrame?.(current);
13737
- }
13738
- setIsLoading(false);
13739
- continueRender(newHandle);
13740
- };
13741
- if (!imageRef.current) {
13742
- onComplete();
13743
- return;
13744
- }
13745
- current.src = actualSrc;
13746
- current.decode().then(onComplete).catch((err) => {
13747
- console.warn(err);
13748
- if (current.complete && current.naturalWidth > 0 && current.naturalHeight > 0) {
13749
- onComplete();
13750
- } else {
13751
- current.addEventListener("load", onComplete);
13752
- }
13753
- });
13754
- return () => {
13755
- unmounted = true;
13756
- current.removeEventListener("load", onComplete);
13757
- continueRender(newHandle);
13758
- };
13759
- }, [
14056
+ useLayoutEffect19(loadImage2.bind(null, {
14057
+ imageRef,
14058
+ errors,
14059
+ actualSrc,
14060
+ delayRenderRetries: delayRenderRetries ?? null,
14061
+ delayRenderTimeoutInMilliseconds: delayRenderTimeoutInMilliseconds ?? null,
14062
+ onImageFrame: onImageFrame ?? null,
14063
+ delayRender,
14064
+ continueRender,
14065
+ setIsLoading
14066
+ }), [
13760
14067
  actualSrc,
13761
14068
  delayRenderRetries,
13762
14069
  delayRenderTimeoutInMilliseconds,
@@ -13771,7 +14078,7 @@ var ImgContent = ({
13771
14078
  requestsVideoFrame: false,
13772
14079
  isClientSideRendering
13773
14080
  });
13774
- return /* @__PURE__ */ jsx35("img", {
14081
+ return /* @__PURE__ */ jsx36("img", {
13775
14082
  ...props,
13776
14083
  ref: imageCallbackRef,
13777
14084
  crossOrigin: crossOriginValue,
@@ -13804,7 +14111,7 @@ var NativeImgInner = ({
13804
14111
  if (!src) {
13805
14112
  throw new Error('No "src" prop was passed to <Img>.');
13806
14113
  }
13807
- const isMedia = useMemo39(() => ({
14114
+ const isMedia = useMemo41(() => ({
13808
14115
  type: "image",
13809
14116
  src
13810
14117
  }), [src]);
@@ -13838,11 +14145,11 @@ var NativeImgInner = ({
13838
14145
  style: premountingStyle,
13839
14146
  componentName: "<Img />"
13840
14147
  });
13841
- return /* @__PURE__ */ jsx35(Freeze, {
14148
+ return /* @__PURE__ */ jsx36(Freeze, {
13842
14149
  frame: freezeFrame,
13843
14150
  active: isPremountingOrPostmounting,
13844
14151
  _remotionInternalIsPremounting: premountingActive,
13845
- children: /* @__PURE__ */ jsx35(Sequence, {
14152
+ children: /* @__PURE__ */ jsx36(Sequence, {
13846
14153
  layout: "none",
13847
14154
  from: from ?? 0,
13848
14155
  trimBefore,
@@ -13859,8 +14166,8 @@ var NativeImgInner = ({
13859
14166
  controls,
13860
14167
  showInTimeline: showInTimeline ?? true,
13861
14168
  hidden,
13862
- children: /* @__PURE__ */ jsx35(SequenceContent, {
13863
- children: /* @__PURE__ */ jsx35(ImgContent, {
14169
+ children: /* @__PURE__ */ jsx36(SequenceContent, {
14170
+ children: /* @__PURE__ */ jsx36(ImgContent, {
13864
14171
  src,
13865
14172
  style: croppedStyle ?? undefined,
13866
14173
  ...props
@@ -13962,7 +14269,7 @@ var ImgInner = ({
13962
14269
  }) => {
13963
14270
  const shouldPauseWhenLoading = resolveV5Default(pauseWhenLoading);
13964
14271
  if (effects.length === 0) {
13965
- return /* @__PURE__ */ jsx35(NativeImgInner, {
14272
+ return /* @__PURE__ */ jsx36(NativeImgInner, {
13966
14273
  ...props,
13967
14274
  ref,
13968
14275
  hidden,
@@ -14007,7 +14314,7 @@ var ImgInner = ({
14007
14314
  const canvasHeight = typeof height === "number" ? height : undefined;
14008
14315
  const canvasProps = props;
14009
14316
  const canvasFit = getFitFromObjectFit(style) ?? "fill";
14010
- return /* @__PURE__ */ jsx35(CanvasImageWithPrivateProps, {
14317
+ return /* @__PURE__ */ jsx36(CanvasImageWithPrivateProps, {
14011
14318
  src,
14012
14319
  width: canvasWidth,
14013
14320
  height: canvasHeight,
@@ -14052,8 +14359,8 @@ var Img = withInteractivitySchema({
14052
14359
  });
14053
14360
  addSequenceStackTraces(Img);
14054
14361
  // src/Interactive.tsx
14055
- import React42, { forwardRef as forwardRef12, useCallback as useCallback23, useContext as useContext48 } from "react";
14056
- import { jsx as jsx36 } from "react/jsx-runtime";
14362
+ import React42, { forwardRef as forwardRef12, useCallback as useCallback19, useContext as useContext48 } from "react";
14363
+ import { jsx as jsx37 } from "react/jsx-runtime";
14057
14364
  var sourcePathToIdentityPrefix = (packageName) => {
14058
14365
  if (packageName === "remotion") {
14059
14366
  return "dev.remotion.remotion";
@@ -14199,10 +14506,10 @@ var withSchema = (untypedOptions) => {
14199
14506
  style: premountingStyle,
14200
14507
  componentName
14201
14508
  });
14202
- return /* @__PURE__ */ jsx36(Freeze, {
14509
+ return /* @__PURE__ */ jsx37(Freeze, {
14203
14510
  frame: freezeFrame,
14204
14511
  active: isPremountingOrPostmounting,
14205
- children: /* @__PURE__ */ jsx36(SequenceWithoutSchema, {
14512
+ children: /* @__PURE__ */ jsx37(SequenceWithoutSchema, {
14206
14513
  _remotionInternalSingleChildComponent: isCurrentComposition ? null : componentIdentity,
14207
14514
  layout,
14208
14515
  ...layout === "absolute-fill" ? {
@@ -14312,14 +14619,14 @@ var makeInteractiveElement = (tag, displayName, schema) => {
14312
14619
  style: premountingStyle,
14313
14620
  componentName: displayName
14314
14621
  });
14315
- const callbackRef = useCallback23((element) => {
14622
+ const callbackRef = useCallback19((element) => {
14316
14623
  setRef2(ref, element);
14317
14624
  }, [ref]);
14318
- return /* @__PURE__ */ jsx36(Freeze, {
14625
+ return /* @__PURE__ */ jsx37(Freeze, {
14319
14626
  frame: freezeFrame,
14320
14627
  active: isPremountingOrPostmounting,
14321
14628
  _remotionInternalIsPremounting: premountingActive,
14322
- children: /* @__PURE__ */ jsx36(Sequence, {
14629
+ children: /* @__PURE__ */ jsx37(Sequence, {
14323
14630
  layout: "none",
14324
14631
  from: from ?? 0,
14325
14632
  trimBefore,
@@ -14437,9 +14744,9 @@ var compositionsRef = React43.createRef();
14437
14744
 
14438
14745
  // src/CompositionManagerProvider.tsx
14439
14746
  import {
14440
- useCallback as useCallback25,
14747
+ useCallback as useCallback21,
14441
14748
  useImperativeHandle as useImperativeHandle9,
14442
- useMemo as useMemo41,
14749
+ useMemo as useMemo43,
14443
14750
  useRef as useRef29,
14444
14751
  useState as useState22
14445
14752
  } from "react";
@@ -14447,16 +14754,16 @@ import {
14447
14754
  // src/CompositionRegistryProvider.tsx
14448
14755
  import {
14449
14756
  forwardRef as forwardRef13,
14450
- useCallback as useCallback24,
14451
- useEffect as useEffect19,
14757
+ useCallback as useCallback20,
14758
+ useEffect as useEffect18,
14452
14759
  useImperativeHandle as useImperativeHandle8,
14453
14760
  useLayoutEffect as useLayoutEffect20,
14454
- useMemo as useMemo40,
14761
+ useMemo as useMemo42,
14455
14762
  useRef as useRef28,
14456
14763
  useState as useState21
14457
14764
  } from "react";
14458
- import { jsx as jsx37 } from "react/jsx-runtime";
14459
- var useIsomorphicLayoutEffect6 = typeof window === "undefined" ? useEffect19 : useLayoutEffect20;
14765
+ import { jsx as jsx38 } from "react/jsx-runtime";
14766
+ var useIsomorphicLayoutEffect6 = typeof window === "undefined" ? useEffect18 : useLayoutEffect20;
14460
14767
  var CompositionRegistryFallbackProvider = withCommittedMetadata(CompositionRegistryFallbackContext.Provider);
14461
14768
  var CompositionRegistryProvider = forwardRef13(({ children, onSnapshot }, flushSnapshotRef) => {
14462
14769
  const { isStudio } = useRemotionEnvironment();
@@ -14468,7 +14775,7 @@ var CompositionRegistryProvider = forwardRef13(({ children, onSnapshot }, flushS
14468
14775
  const onSnapshotRef = useRef28(onSnapshot);
14469
14776
  const lastSnapshotRef = useRef28(null);
14470
14777
  const pendingSnapshotRef = useRef28(null);
14471
- const flushSnapshot = useCallback24(() => {
14778
+ const flushSnapshot = useCallback20(() => {
14472
14779
  const pending = pendingSnapshotRef.current;
14473
14780
  pendingSnapshotRef.current = null;
14474
14781
  if (pending === null || unmountedRef.current) {
@@ -14483,7 +14790,7 @@ var CompositionRegistryProvider = forwardRef13(({ children, onSnapshot }, flushS
14483
14790
  onSnapshotRef.current(committed);
14484
14791
  }, []);
14485
14792
  useImperativeHandle8(flushSnapshotRef, () => flushSnapshot, [flushSnapshot]);
14486
- const queueSnapshot = useCallback24((snapshot) => {
14793
+ const queueSnapshot = useCallback20((snapshot) => {
14487
14794
  const alreadyPending = pendingSnapshotRef.current !== null;
14488
14795
  pendingSnapshotRef.current = snapshot;
14489
14796
  if (alreadyPending) {
@@ -14491,14 +14798,14 @@ var CompositionRegistryProvider = forwardRef13(({ children, onSnapshot }, flushS
14491
14798
  }
14492
14799
  queueMicrotask(flushSnapshot);
14493
14800
  }, [flushSnapshot]);
14494
- const onObservedSnapshot = useCallback24((snapshot) => {
14801
+ const onObservedSnapshot = useCallback20((snapshot) => {
14495
14802
  if (observerFailedRef.current) {
14496
14803
  return;
14497
14804
  }
14498
14805
  observedCommitRef.current = true;
14499
14806
  queueSnapshot(snapshot);
14500
14807
  }, [queueSnapshot]);
14501
- const fallbackRegistry = useMemo40(() => {
14808
+ const fallbackRegistry = useMemo42(() => {
14502
14809
  const entries = new Map;
14503
14810
  const getSnapshot = () => {
14504
14811
  const compositions = [];
@@ -14569,12 +14876,12 @@ var CompositionRegistryProvider = forwardRef13(({ children, onSnapshot }, flushS
14569
14876
  }
14570
14877
  };
14571
14878
  }, [isStudio, useCommitObserver]);
14572
- const metadata = useMemo40(() => isStudio ? {
14879
+ const metadata = useMemo42(() => isStudio ? {
14573
14880
  type: "composition-manager",
14574
14881
  id: managerId,
14575
14882
  onCommit: useCommitObserver ? onObservedSnapshot : null
14576
14883
  } : null, [isStudio, managerId, onObservedSnapshot, useCommitObserver]);
14577
- return /* @__PURE__ */ jsx37(CompositionRegistryFallbackProvider, {
14884
+ return /* @__PURE__ */ jsx38(CompositionRegistryFallbackProvider, {
14578
14885
  value: useCommitObserver ? null : fallbackRegistry,
14579
14886
  _remotionCommitMetadata: metadata,
14580
14887
  children
@@ -14582,7 +14889,7 @@ var CompositionRegistryProvider = forwardRef13(({ children, onSnapshot }, flushS
14582
14889
  });
14583
14890
 
14584
14891
  // src/CompositionManagerProvider.tsx
14585
- import { jsx as jsx38 } from "react/jsx-runtime";
14892
+ import { jsx as jsx39 } from "react/jsx-runtime";
14586
14893
  var CompositionManagerProvider = ({
14587
14894
  children,
14588
14895
  onlyRenderComposition,
@@ -14604,7 +14911,7 @@ var CompositionManagerProvider = ({
14604
14911
  const { compositions, folders } = useSyncExternalStore2(registry.subscribe, registry.getSnapshot, registry.getSnapshot);
14605
14912
  const [canvasContent, setCanvasContent] = useState22(initialCanvasContent);
14606
14913
  const [currentAssetMetadata, setCurrentAssetMetadata] = useState22(null);
14607
- const onCommitRegistrations = useCallback25((pending) => {
14914
+ const onCommitRegistrations = useCallback21((pending) => {
14608
14915
  const previousKeys = committedKeysRef.current;
14609
14916
  const previousDescriptors = committedDescriptorsRef.current;
14610
14917
  const existingIds = new Set(registry.getSnapshot().compositions.map((composition) => composition.id));
@@ -14656,12 +14963,12 @@ var CompositionManagerProvider = ({
14656
14963
  }
14657
14964
  };
14658
14965
  }, [registry]);
14659
- const compositionManagerSetters = useMemo41(() => ({
14966
+ const compositionManagerSetters = useMemo43(() => ({
14660
14967
  setCanvasContent,
14661
14968
  setCurrentAssetMetadata,
14662
14969
  onlyRenderComposition
14663
14970
  }), [onlyRenderComposition]);
14664
- const compositionManagerContextValue = useMemo41(() => {
14971
+ const compositionManagerContextValue = useMemo43(() => {
14665
14972
  return {
14666
14973
  compositions,
14667
14974
  folders,
@@ -14676,17 +14983,22 @@ var CompositionManagerProvider = ({
14676
14983
  currentAssetMetadata,
14677
14984
  canvasContent
14678
14985
  ]);
14986
+ const compositionManagerRef = useRef29(compositionManagerContextValue);
14987
+ compositionManagerRef.current = compositionManagerContextValue;
14679
14988
  if (registrationError !== null) {
14680
14989
  throw registrationError;
14681
14990
  }
14682
- return /* @__PURE__ */ jsx38(CompositionRegistryProvider, {
14991
+ return /* @__PURE__ */ jsx39(CompositionRegistryProvider, {
14683
14992
  ref: flushSnapshotRef,
14684
14993
  onSnapshot: onCommitRegistrations,
14685
- children: /* @__PURE__ */ jsx38(CompositionManager.Provider, {
14994
+ children: /* @__PURE__ */ jsx39(CompositionManager.Provider, {
14686
14995
  value: compositionManagerContextValue,
14687
- children: /* @__PURE__ */ jsx38(CompositionSetters.Provider, {
14688
- value: compositionManagerSetters,
14689
- children
14996
+ children: /* @__PURE__ */ jsx39(CompositionManagerRefContext.Provider, {
14997
+ value: compositionManagerRef,
14998
+ children: /* @__PURE__ */ jsx39(CompositionSetters.Provider, {
14999
+ value: compositionManagerSetters,
15000
+ children
15001
+ })
14690
15002
  })
14691
15003
  })
14692
15004
  });
@@ -14704,11 +15016,41 @@ var createElementSourceProxy = (api, sourceArgumentIndex, getSourceFileName) =>
14704
15016
  const source = sourceArgumentIndex === null ? null : argArray[sourceArgumentIndex];
14705
15017
  const existingStack = props?.[internalStackProp];
14706
15018
  const controlsStack = !existingStack && component === getSequenceComponent() && props?.controls ? getStackForControls(props.controls) : null;
14707
- const stack = existingStack || (controlsStack ?? (source && typeof source.fileName === "string" && typeof source.lineNumber === "number" && typeof source.columnNumber === "number" ? makeOriginalSourceStack({
14708
- fileName: getSourceFileName(source.fileName),
14709
- lineNumber: source.lineNumber,
14710
- columnNumber: source.columnNumber - 1
14711
- }) : new Error().stack));
15019
+ let stack = existingStack || controlsStack;
15020
+ if (!stack) {
15021
+ if (source && typeof source.fileName === "string" && typeof source.lineNumber === "number" && typeof source.columnNumber === "number") {
15022
+ stack = makeOriginalSourceStack({
15023
+ fileName: getSourceFileName(source.fileName),
15024
+ lineNumber: source.lineNumber,
15025
+ columnNumber: source.columnNumber - 1
15026
+ });
15027
+ } else {
15028
+ const { stackTraceLimit } = Error;
15029
+ const canLimitStack = typeof stackTraceLimit === "number" && stackTraceLimit > 2 && Object.getOwnPropertyDescriptor(Error, "stackTraceLimit")?.writable;
15030
+ let capturedError;
15031
+ try {
15032
+ if (canLimitStack) {
15033
+ Error.stackTraceLimit = 2;
15034
+ }
15035
+ capturedError = new Error;
15036
+ } finally {
15037
+ if (canLimitStack) {
15038
+ Error.stackTraceLimit = stackTraceLimit;
15039
+ }
15040
+ }
15041
+ const capturedStack = capturedError.stack;
15042
+ if (capturedStack) {
15043
+ const firstFrameEnd = capturedStack.indexOf(`
15044
+ `, capturedStack.startsWith(`Error
15045
+ `) ? 6 : 0);
15046
+ const callerEnd = firstFrameEnd === -1 ? -1 : capturedStack.indexOf(`
15047
+ `, firstFrameEnd + 1);
15048
+ stack = callerEnd === -1 ? capturedStack : capturedStack.slice(0, callerEnd);
15049
+ } else {
15050
+ stack = capturedStack;
15051
+ }
15052
+ }
15053
+ }
14712
15054
  const newProps = existingStack ? { ...props } : {
14713
15055
  ...props ?? {},
14714
15056
  [internalStackProp]: stack
@@ -14899,6 +15241,10 @@ var getMediabunnyInputResourceKey = ({
14899
15241
  var MEDIABUNNY_DURATION_VALUE_KEY = "mediabunny-duration";
14900
15242
  var globalMediaResourceManager = makeMediaResourceManager();
14901
15243
 
15244
+ // src/playback-pitch-context.ts
15245
+ import { createContext as createContext38 } from "react";
15246
+ var PlaybackPitchContext = createContext38(false);
15247
+
14902
15248
  // src/react-refresh-event.ts
14903
15249
  var REACT_REFRESH_STARTED_EVENT = "remotion-react-refresh-started";
14904
15250
  var REACT_REFRESH_FINISHED_EVENT = "remotion-react-refresh-finished";
@@ -14935,8 +15281,8 @@ var waitForRoot = (fn) => {
14935
15281
  };
14936
15282
 
14937
15283
  // src/RemotionRoot.tsx
14938
- import { useMemo as useMemo42 } from "react";
14939
- import { jsx as jsx39 } from "react/jsx-runtime";
15284
+ import { useMemo as useMemo44 } from "react";
15285
+ import { jsx as jsx40 } from "react/jsx-runtime";
14940
15286
  var RemotionRootContexts = ({
14941
15287
  children,
14942
15288
  numberOfAudioTags,
@@ -14948,29 +15294,29 @@ var RemotionRootContexts = ({
14948
15294
  frameState,
14949
15295
  _experimentalKeepAudioContextAlive
14950
15296
  }) => {
14951
- const logging = useMemo42(() => {
15297
+ const logging = useMemo44(() => {
14952
15298
  return { logLevel, mountTime: Date.now() };
14953
15299
  }, [logLevel]);
14954
- return /* @__PURE__ */ jsx39(LogLevelContext.Provider, {
15300
+ return /* @__PURE__ */ jsx40(LogLevelContext.Provider, {
14955
15301
  value: logging,
14956
- children: /* @__PURE__ */ jsx39(TimelineContextProvider, {
15302
+ children: /* @__PURE__ */ jsx40(TimelineContextProvider, {
14957
15303
  frameState,
14958
- children: /* @__PURE__ */ jsx39(MediaEnabledProvider, {
15304
+ children: /* @__PURE__ */ jsx40(MediaEnabledProvider, {
14959
15305
  videoEnabled,
14960
15306
  audioEnabled,
14961
- children: /* @__PURE__ */ jsx39(EditorPropsProvider, {
14962
- children: /* @__PURE__ */ jsx39(PrefetchProvider, {
14963
- children: /* @__PURE__ */ jsx39(SequenceManagerProvider, {
14964
- children: /* @__PURE__ */ jsx39(DurationsContextProvider, {
14965
- children: /* @__PURE__ */ jsx39(BufferingProvider, {
14966
- children: /* @__PURE__ */ jsx39(SharedAudioContextProvider, {
15307
+ children: /* @__PURE__ */ jsx40(EditorPropsProvider, {
15308
+ children: /* @__PURE__ */ jsx40(PrefetchProvider, {
15309
+ children: /* @__PURE__ */ jsx40(SequenceManagerProvider, {
15310
+ children: /* @__PURE__ */ jsx40(DurationsContextProvider, {
15311
+ children: /* @__PURE__ */ jsx40(BufferingProvider, {
15312
+ children: /* @__PURE__ */ jsx40(SharedAudioContextProvider, {
14967
15313
  audioLatencyHint,
14968
15314
  audioEnabled,
14969
15315
  previewSampleRate,
14970
15316
  _experimentalKeepAudioContextAlive,
14971
- children: /* @__PURE__ */ jsx39(SharedAudioTagsContextProvider, {
15317
+ children: /* @__PURE__ */ jsx40(SharedAudioTagsContextProvider, {
14972
15318
  numberOfAudioTags,
14973
- children: /* @__PURE__ */ jsx39(VideoProvider, {
15319
+ children: /* @__PURE__ */ jsx40(VideoProvider, {
14974
15320
  children
14975
15321
  })
14976
15322
  })
@@ -15249,8 +15595,8 @@ var setupEnvVariables = () => {
15249
15595
  };
15250
15596
 
15251
15597
  // src/Track.tsx
15252
- import { useMemo as useMemo43, useState as useState23 } from "react";
15253
- import { jsx as jsx40 } from "react/jsx-runtime";
15598
+ import { useMemo as useMemo45, useState as useState23 } from "react";
15599
+ import { jsx as jsx41 } from "react/jsx-runtime";
15254
15600
  var {
15255
15601
  freeze: _freeze,
15256
15602
  layout: _layout,
@@ -15267,10 +15613,10 @@ var TrackWithoutSchema = ({
15267
15613
  ...props
15268
15614
  }) => {
15269
15615
  const [id] = useState23(() => String(Math.random()));
15270
- const value = useMemo43(() => ({ id, name }), [id, name]);
15271
- return /* @__PURE__ */ jsx40(TimelineTrackContext.Provider, {
15616
+ const value = useMemo45(() => ({ id, name }), [id, name]);
15617
+ return /* @__PURE__ */ jsx41(TimelineTrackContext.Provider, {
15272
15618
  value,
15273
- children: /* @__PURE__ */ jsx40(SequenceWithoutSchema, {
15619
+ children: /* @__PURE__ */ jsx41(SequenceWithoutSchema, {
15274
15620
  _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/track",
15275
15621
  ...props,
15276
15622
  name,
@@ -15281,7 +15627,7 @@ var TrackWithoutSchema = ({
15281
15627
  });
15282
15628
  };
15283
15629
  var Track = withInteractivitySchema({
15284
- Component: (props) => /* @__PURE__ */ jsx40(TrackWithoutSchema, {
15630
+ Component: (props) => /* @__PURE__ */ jsx41(TrackWithoutSchema, {
15285
15631
  ...props,
15286
15632
  layout: "none"
15287
15633
  }),
@@ -15320,15 +15666,15 @@ var usePixelDensity = (options) => {
15320
15666
  };
15321
15667
 
15322
15668
  // src/video/OffthreadVideo.tsx
15323
- import { useCallback as useCallback28 } from "react";
15669
+ import { useCallback as useCallback24 } from "react";
15324
15670
 
15325
15671
  // src/video/OffthreadVideoForRendering.tsx
15326
15672
  import {
15327
- useCallback as useCallback26,
15673
+ useCallback as useCallback22,
15328
15674
  useContext as useContext50,
15329
- useEffect as useEffect20,
15675
+ useEffect as useEffect19,
15330
15676
  useLayoutEffect as useLayoutEffect21,
15331
- useMemo as useMemo44,
15677
+ useMemo as useMemo46,
15332
15678
  useState as useState24
15333
15679
  } from "react";
15334
15680
 
@@ -15343,7 +15689,7 @@ var getOffthreadVideoSource = ({
15343
15689
  };
15344
15690
 
15345
15691
  // src/video/OffthreadVideoForRendering.tsx
15346
- import { jsx as jsx41 } from "react/jsx-runtime";
15692
+ import { jsx as jsx42 } from "react/jsx-runtime";
15347
15693
  var OffthreadVideoForRendering = ({
15348
15694
  onError,
15349
15695
  volume: volumeProp,
@@ -15361,7 +15707,7 @@ var OffthreadVideoForRendering = ({
15361
15707
  onVideoFrame,
15362
15708
  crossOrigin,
15363
15709
  audioStreamIndex,
15364
- preservePitch: _preservePitch,
15710
+ preservePitch,
15365
15711
  ...props
15366
15712
  }) => {
15367
15713
  const absoluteFrame = useTimelinePosition();
@@ -15375,7 +15721,7 @@ var OffthreadVideoForRendering = ({
15375
15721
  if (!src) {
15376
15722
  throw new TypeError("No `src` was passed to <OffthreadVideo>.");
15377
15723
  }
15378
- const id = useMemo44(() => `offthreadvideo-${random(src)}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.relativeFrom}-${sequenceContext?.durationInFrames}`, [
15724
+ const id = useMemo46(() => `offthreadvideo-${random(src)}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.relativeFrom}-${sequenceContext?.durationInFrames}`, [
15379
15725
  src,
15380
15726
  sequenceContext?.cumulatedFrom,
15381
15727
  sequenceContext?.relativeFrom,
@@ -15396,7 +15742,7 @@ var OffthreadVideoForRendering = ({
15396
15742
  if (!videoConfig) {
15397
15743
  throw new Error("No video config found");
15398
15744
  }
15399
- useEffect20(() => {
15745
+ useEffect19(() => {
15400
15746
  if (!src) {
15401
15747
  throw new Error("No src passed");
15402
15748
  }
@@ -15413,7 +15759,8 @@ var OffthreadVideoForRendering = ({
15413
15759
  playbackRate: playbackRate * sequencePlaybackRate,
15414
15760
  toneFrequency,
15415
15761
  audioStartFrame,
15416
- audioStreamIndex
15762
+ audioStreamIndex,
15763
+ preservePitch: preservePitch ?? true
15417
15764
  });
15418
15765
  return () => unregisterRenderAsset(id);
15419
15766
  }, [
@@ -15429,16 +15776,17 @@ var OffthreadVideoForRendering = ({
15429
15776
  toneFrequency,
15430
15777
  audioStartFrame,
15431
15778
  sequencePlaybackRate,
15432
- audioStreamIndex
15779
+ audioStreamIndex,
15780
+ preservePitch
15433
15781
  ]);
15434
- const currentTime = useMemo44(() => {
15782
+ const currentTime = useMemo46(() => {
15435
15783
  return getExpectedMediaFrameUncorrected({
15436
15784
  frame,
15437
15785
  playbackRate: playbackRate || 1,
15438
15786
  startFrom: audioStartFrame
15439
15787
  }) / videoConfig.fps;
15440
15788
  }, [frame, audioStartFrame, playbackRate, videoConfig.fps]);
15441
- const actualSrc = useMemo44(() => {
15789
+ const actualSrc = useMemo46(() => {
15442
15790
  return getOffthreadVideoSource({
15443
15791
  src,
15444
15792
  currentTime,
@@ -15447,7 +15795,7 @@ var OffthreadVideoForRendering = ({
15447
15795
  });
15448
15796
  }, [toneMapped, currentTime, src, transparent]);
15449
15797
  const [imageSrc, setImageSrc] = useState24(null);
15450
- const { delayRender, continueRender } = useDelayRender();
15798
+ const { delayRender, continueRender, cancelRender } = useDelayRender();
15451
15799
  useLayoutEffect21(() => {
15452
15800
  if (!window.remotion_videoEnabled) {
15453
15801
  return;
@@ -15517,19 +15865,20 @@ var OffthreadVideoForRendering = ({
15517
15865
  delayRenderTimeoutInMilliseconds,
15518
15866
  onError,
15519
15867
  continueRender,
15868
+ cancelRender,
15520
15869
  delayRender
15521
15870
  ]);
15522
- const onErr = useCallback26(() => {
15871
+ const onErr = useCallback22(() => {
15523
15872
  if (onError) {
15524
15873
  onError?.(new Error("Failed to load image with src " + imageSrc));
15525
15874
  } else {
15526
15875
  cancelRender("Failed to load image with src " + imageSrc);
15527
15876
  }
15528
- }, [imageSrc, onError]);
15529
- const className = useMemo44(() => {
15877
+ }, [imageSrc, onError, cancelRender]);
15878
+ const className = useMemo46(() => {
15530
15879
  return [OBJECTFIT_CONTAIN_CLASS_NAME, props.className].filter(truthy).join(" ");
15531
15880
  }, [props.className]);
15532
- const onImageFrame = useCallback26((img) => {
15881
+ const onImageFrame = useCallback22((img) => {
15533
15882
  if (onVideoFrame) {
15534
15883
  onVideoFrame(img);
15535
15884
  }
@@ -15538,7 +15887,7 @@ var OffthreadVideoForRendering = ({
15538
15887
  return null;
15539
15888
  }
15540
15889
  continueRender(imageSrc.handle);
15541
- return /* @__PURE__ */ jsx41(Img, {
15890
+ return /* @__PURE__ */ jsx42(Img, {
15542
15891
  src: imageSrc.src,
15543
15892
  delayRenderRetries,
15544
15893
  delayRenderTimeoutInMilliseconds,
@@ -15552,22 +15901,22 @@ var OffthreadVideoForRendering = ({
15552
15901
  // src/video/VideoForPreview.tsx
15553
15902
  import React51, {
15554
15903
  forwardRef as forwardRef14,
15555
- useCallback as useCallback27,
15904
+ useCallback as useCallback23,
15556
15905
  useContext as useContext51,
15557
- useEffect as useEffect22,
15906
+ useEffect as useEffect21,
15558
15907
  useImperativeHandle as useImperativeHandle10,
15559
- useMemo as useMemo45,
15908
+ useMemo as useMemo47,
15560
15909
  useRef as useRef30,
15561
15910
  useState as useState25
15562
15911
  } from "react";
15563
15912
 
15564
15913
  // src/video/emit-video-frame.ts
15565
- import { useEffect as useEffect21 } from "react";
15914
+ import { useEffect as useEffect20 } from "react";
15566
15915
  var useEmitVideoFrame = ({
15567
15916
  ref,
15568
15917
  onVideoFrame
15569
15918
  }) => {
15570
- useEffect21(() => {
15919
+ useEffect20(() => {
15571
15920
  const { current } = ref;
15572
15921
  if (!current) {
15573
15922
  return;
@@ -15607,14 +15956,14 @@ class MediaPlaybackError extends Error {
15607
15956
  }
15608
15957
 
15609
15958
  // src/video/VideoForPreview.tsx
15610
- import { jsx as jsx42 } from "react/jsx-runtime";
15959
+ import { jsx as jsx43 } from "react/jsx-runtime";
15611
15960
  var VideoForDevelopmentRefForwardingFunction = (props, ref) => {
15612
15961
  const context = useContext51(SharedAudioContext);
15613
15962
  if (!context) {
15614
15963
  throw new Error("SharedAudioContext not found");
15615
15964
  }
15616
15965
  const videoRef = useRef30(null);
15617
- const sharedSource = useMemo45(() => {
15966
+ const sharedSource = useMemo47(() => {
15618
15967
  if (!context.audioContext) {
15619
15968
  return null;
15620
15969
  }
@@ -15625,11 +15974,7 @@ var VideoForDevelopmentRefForwardingFunction = (props, ref) => {
15625
15974
  }, [context.audioContext]);
15626
15975
  const effectToUse = React51.useInsertionEffect ?? React51.useLayoutEffect;
15627
15976
  effectToUse(() => {
15628
- return () => {
15629
- requestAnimationFrame(() => {
15630
- sharedSource?.cleanup();
15631
- });
15632
- };
15977
+ return scheduleMediaSourceCleanup.bind(null, sharedSource?.cleanup ?? null);
15633
15978
  }, [sharedSource]);
15634
15979
  const {
15635
15980
  timelineId,
@@ -15721,7 +16066,7 @@ var VideoForDevelopmentRefForwardingFunction = (props, ref) => {
15721
16066
  tag: "video",
15722
16067
  mountTime
15723
16068
  }));
15724
- useEffect22(() => {
16069
+ useEffect21(() => {
15725
16070
  const { current } = videoRef;
15726
16071
  if (!current) {
15727
16072
  return;
@@ -15761,27 +16106,9 @@ var VideoForDevelopmentRefForwardingFunction = (props, ref) => {
15761
16106
  current.removeEventListener("error", errorHandler);
15762
16107
  };
15763
16108
  }, [onError, src]);
15764
- const currentOnDurationCallback = useRef30(onDuration);
15765
- currentOnDurationCallback.current = onDuration;
15766
16109
  useEmitVideoFrame({ ref: videoRef, onVideoFrame });
15767
- useEffect22(() => {
15768
- const { current } = videoRef;
15769
- if (!current) {
15770
- return;
15771
- }
15772
- if (current.duration) {
15773
- currentOnDurationCallback.current?.(src, current.duration);
15774
- return;
15775
- }
15776
- const onLoadedMetadata = () => {
15777
- currentOnDurationCallback.current?.(src, current.duration);
15778
- };
15779
- current.addEventListener("loadedmetadata", onLoadedMetadata);
15780
- return () => {
15781
- current.removeEventListener("loadedmetadata", onLoadedMetadata);
15782
- };
15783
- }, [src]);
15784
- useEffect22(() => {
16110
+ useMediaDuration(videoRef, onDuration, src, false);
16111
+ useEffect21(() => {
15785
16112
  const { current } = videoRef;
15786
16113
  if (!current) {
15787
16114
  return;
@@ -15792,7 +16119,7 @@ var VideoForDevelopmentRefForwardingFunction = (props, ref) => {
15792
16119
  current.preload = "auto";
15793
16120
  }
15794
16121
  }, []);
15795
- const actualStyle = useMemo45(() => {
16122
+ const actualStyle = useMemo47(() => {
15796
16123
  return {
15797
16124
  ...style
15798
16125
  };
@@ -15802,7 +16129,7 @@ var VideoForDevelopmentRefForwardingFunction = (props, ref) => {
15802
16129
  requestsVideoFrame: Boolean(onVideoFrame),
15803
16130
  isClientSideRendering: false
15804
16131
  });
15805
- const video = /* @__PURE__ */ jsx42("video", {
16132
+ const video = /* @__PURE__ */ jsx43("video", {
15806
16133
  ...nativeProps,
15807
16134
  ref: videoRef,
15808
16135
  muted: isMutedForPlayback,
@@ -15844,7 +16171,7 @@ var VideoForPreviewRefForwardingFunction = (props, ref) => {
15844
16171
  volume: userPreferredVolume,
15845
16172
  audioEnabled: true
15846
16173
  });
15847
- const getStack = useCallback27(() => {
16174
+ const getStack = useCallback23(() => {
15848
16175
  return _remotionInternalStack ?? null;
15849
16176
  }, [_remotionInternalStack]);
15850
16177
  const { automaticOutlineRef, registration } = useMediaInTimelineRegistration({
@@ -15861,17 +16188,17 @@ var VideoForPreviewRefForwardingFunction = (props, ref) => {
15861
16188
  documentationLink: onlyWarnForMediaSeekingError ? "https://www.remotion.dev/docs/offthreadvideo" : "https://www.remotion.dev/docs/html5-video",
15862
16189
  muted: isMutedForTimeline
15863
16190
  });
15864
- const metadata = useMemo45(() => isStudio || automaticOutlineRef || registration !== null ? {
16191
+ const metadata = useMemo47(() => isStudio || automaticOutlineRef || registration !== null ? {
15865
16192
  type: "sequence",
15866
16193
  id: timelineId,
15867
16194
  value: registration,
15868
16195
  outlineChildrenRef: automaticOutlineRef
15869
16196
  } : null, [automaticOutlineRef, isStudio, registration, timelineId]);
15870
- return /* @__PURE__ */ jsx42(CommittedMetadataProvider, {
16197
+ return /* @__PURE__ */ jsx43(CommittedMetadataProvider, {
15871
16198
  value: null,
15872
16199
  _remotionCommitMetadata: metadata,
15873
- children: /* @__PURE__ */ jsx42(SequenceContent, {
15874
- children: /* @__PURE__ */ jsx42(VideoForPreviewContent, {
16200
+ children: /* @__PURE__ */ jsx43(SequenceContent, {
16201
+ children: /* @__PURE__ */ jsx43(VideoForPreviewContent, {
15875
16202
  ...props,
15876
16203
  ref,
15877
16204
  timelineId,
@@ -15884,7 +16211,7 @@ var VideoForPreviewRefForwardingFunction = (props, ref) => {
15884
16211
  var VideoForPreview = forwardRef14(VideoForPreviewRefForwardingFunction);
15885
16212
 
15886
16213
  // src/video/OffthreadVideo.tsx
15887
- import { jsx as jsx43 } from "react/jsx-runtime";
16214
+ import { jsx as jsx44 } from "react/jsx-runtime";
15888
16215
  var InnerOffthreadVideo = (props) => {
15889
16216
  const {
15890
16217
  startFrom,
@@ -15903,7 +16230,7 @@ var InnerOffthreadVideo = (props) => {
15903
16230
  if (environment.isClientSideRendering) {
15904
16231
  throw new Error("<OffthreadVideo> is not supported in @remotion/web-renderer. Use <Video> from @remotion/media instead. See https://remotion.dev/docs/client-side-rendering/limitations");
15905
16232
  }
15906
- const onDuration = useCallback28(() => {
16233
+ const onDuration = useCallback24(() => {
15907
16234
  return;
15908
16235
  }, []);
15909
16236
  if (typeof props.src !== "string") {
@@ -15928,15 +16255,15 @@ var InnerOffthreadVideo = (props) => {
15928
16255
  trimBefore: trimBeforeValue
15929
16256
  });
15930
16257
  if (typeof trimBeforeValue !== "undefined" || typeof effectiveTrimAfter !== "undefined") {
15931
- return /* @__PURE__ */ jsx43(Html5MediaTrimContext.Provider, {
16258
+ return /* @__PURE__ */ jsx44(Html5MediaTrimContext.Provider, {
15932
16259
  value: trimBeforeValue ?? 0,
15933
- children: /* @__PURE__ */ jsx43(Sequence, {
16260
+ children: /* @__PURE__ */ jsx44(Sequence, {
15934
16261
  layout: "none",
15935
16262
  from: 0 - (trimBeforeValue ?? 0),
15936
16263
  showInTimeline: false,
15937
16264
  durationInFrames: effectiveTrimAfter === undefined ? undefined : (trimBeforeValue ?? 0) + (effectiveTrimAfter - (trimBeforeValue ?? 0)) / (props.playbackRate ?? 1),
15938
16265
  name,
15939
- children: /* @__PURE__ */ jsx43(InnerOffthreadVideo, {
16266
+ children: /* @__PURE__ */ jsx44(InnerOffthreadVideo, {
15940
16267
  pauseWhenBuffering: shouldPauseWhenBuffering,
15941
16268
  ...otherProps,
15942
16269
  trimAfter: undefined,
@@ -15953,7 +16280,7 @@ var InnerOffthreadVideo = (props) => {
15953
16280
  }
15954
16281
  validateMediaProps(props, "Video");
15955
16282
  if (environment.isRendering) {
15956
- return /* @__PURE__ */ jsx43(OffthreadVideoForRendering, {
16283
+ return /* @__PURE__ */ jsx44(OffthreadVideoForRendering, {
15957
16284
  pauseWhenBuffering: shouldPauseWhenBuffering,
15958
16285
  ...otherProps,
15959
16286
  trimAfter: undefined,
@@ -15976,7 +16303,7 @@ var InnerOffthreadVideo = (props) => {
15976
16303
  delayRenderTimeoutInMilliseconds,
15977
16304
  ...propsForPreview
15978
16305
  } = otherProps;
15979
- return /* @__PURE__ */ jsx43(VideoForPreview, {
16306
+ return /* @__PURE__ */ jsx44(VideoForPreview, {
15980
16307
  _remotionInternalStack: _remotionInternalStack ?? null,
15981
16308
  onDuration,
15982
16309
  onlyWarnForMediaSeekingError: true,
@@ -16026,7 +16353,7 @@ var OffthreadVideo = ({
16026
16353
  if (imageFormat) {
16027
16354
  throw new TypeError(`The \`<OffthreadVideo>\` tag does no longer accept \`imageFormat\`. Use the \`transparent\` prop if you want to render a transparent video.`);
16028
16355
  }
16029
- return /* @__PURE__ */ jsx43(InnerOffthreadVideo, {
16356
+ return /* @__PURE__ */ jsx44(InnerOffthreadVideo, {
16030
16357
  acceptableTimeShiftInSeconds,
16031
16358
  allowAmplificationDuringRender: allowAmplificationDuringRender ?? true,
16032
16359
  audioStreamIndex: audioStreamIndex ?? 0,
@@ -16100,8 +16427,8 @@ var watchStaticFile = (fileName, callback) => {
16100
16427
  };
16101
16428
 
16102
16429
  // src/wrap-remotion-context.tsx
16103
- import React53, { useCallback as useCallback29, useMemo as useMemo46, useRef as useRef31, useState as useState26 } from "react";
16104
- import { jsx as jsx44 } from "react/jsx-runtime";
16430
+ import React53, { useCallback as useCallback25, useMemo as useMemo48, useRef as useRef31, useState as useState26 } from "react";
16431
+ import { jsx as jsx45 } from "react/jsx-runtime";
16105
16432
  function useRemotionContexts() {
16106
16433
  const compositionManagerCtx = React53.useContext(CompositionManager);
16107
16434
  const videoContext = React53.useContext(VideoContext);
@@ -16124,7 +16451,7 @@ function useRemotionContexts() {
16124
16451
  const visualModePropStatusesRefContext = React53.useContext(VisualModePropStatusesRefContext);
16125
16452
  const bufferManagerContext = React53.useContext(BufferingContextReact);
16126
16453
  const logLevelContext = React53.useContext(LogLevelContext);
16127
- return useMemo46(() => ({
16454
+ return useMemo48(() => ({
16128
16455
  compositionManagerCtx,
16129
16456
  videoContext,
16130
16457
  timelineContext,
@@ -16185,7 +16512,7 @@ var ForwardedSequenceRegistry = ({
16185
16512
  const scope = contexts.sequenceRegistryScopeContext;
16186
16513
  const activeRegistryRef = useRef31(registry);
16187
16514
  const commitRegistrationEnabled = scope?.commitRegistrationRequested === true && registry !== null && observerAvailable;
16188
- const onCommitSequences = useCallback29((sequences, sequenceIds) => {
16515
+ const onCommitSequences = useCallback25((sequences, sequenceIds) => {
16189
16516
  if (observerFailedRef.current && sequenceIds.length > 0) {
16190
16517
  return;
16191
16518
  }
@@ -16231,19 +16558,19 @@ var ForwardedSequenceRegistry = ({
16231
16558
  });
16232
16559
  };
16233
16560
  }, [scope, scopeId, registry, commitRegistrationEnabled]);
16234
- const metadata = useMemo46(() => ({
16561
+ const metadata = useMemo48(() => ({
16235
16562
  type: "sequence-manager",
16236
16563
  id: scopeId,
16237
16564
  onCommit: commitRegistrationEnabled ? onCommitSequences : null
16238
16565
  }), [commitRegistrationEnabled, onCommitSequences, scopeId]);
16239
- return /* @__PURE__ */ jsx44(SequenceRegistryScopeProvider, {
16566
+ return /* @__PURE__ */ jsx45(SequenceRegistryScopeProvider, {
16240
16567
  value: scope,
16241
16568
  _remotionCommitMetadata: metadata,
16242
- children: /* @__PURE__ */ jsx44(SequenceManagerActionsContext.Provider, {
16569
+ children: /* @__PURE__ */ jsx45(SequenceManagerActionsContext.Provider, {
16243
16570
  value: contexts.sequenceManagerActionsContext,
16244
- children: /* @__PURE__ */ jsx44(SequenceRegistryContext.Provider, {
16571
+ children: /* @__PURE__ */ jsx45(SequenceRegistryContext.Provider, {
16245
16572
  value: registry,
16246
- children: /* @__PURE__ */ jsx44(SequenceCommitRegistrationContext.Provider, {
16573
+ children: /* @__PURE__ */ jsx45(SequenceCommitRegistrationContext.Provider, {
16247
16574
  value: commitRegistrationEnabled,
16248
16575
  children
16249
16576
  })
@@ -16253,43 +16580,43 @@ var ForwardedSequenceRegistry = ({
16253
16580
  };
16254
16581
  var RemotionContextProvider = (props) => {
16255
16582
  const { children, contexts } = props;
16256
- return /* @__PURE__ */ jsx44(LogLevelContext.Provider, {
16583
+ return /* @__PURE__ */ jsx45(LogLevelContext.Provider, {
16257
16584
  value: contexts.logLevelContext,
16258
- children: /* @__PURE__ */ jsx44(CanUseRemotionHooks.Provider, {
16585
+ children: /* @__PURE__ */ jsx45(CanUseRemotionHooks.Provider, {
16259
16586
  value: contexts.canUseRemotionHooksContext,
16260
- children: /* @__PURE__ */ jsx44(PreloadContext.Provider, {
16587
+ children: /* @__PURE__ */ jsx45(PreloadContext.Provider, {
16261
16588
  value: contexts.preloadContext,
16262
- children: /* @__PURE__ */ jsx44(CompositionManager.Provider, {
16589
+ children: /* @__PURE__ */ jsx45(CompositionManager.Provider, {
16263
16590
  value: contexts.compositionManagerCtx,
16264
- children: /* @__PURE__ */ jsx44(SequenceManagerRefContext.Provider, {
16591
+ children: /* @__PURE__ */ jsx45(SequenceManagerRefContext.Provider, {
16265
16592
  value: contexts.sequenceManagerRefContext,
16266
- children: /* @__PURE__ */ jsx44(RemotionEnvironmentContext.Provider, {
16593
+ children: /* @__PURE__ */ jsx45(RemotionEnvironmentContext.Provider, {
16267
16594
  value: contexts.remotionEnvironmentContext,
16268
- children: /* @__PURE__ */ jsx44(SequenceRegistrationContext.Provider, {
16595
+ children: /* @__PURE__ */ jsx45(SequenceRegistrationContext.Provider, {
16269
16596
  value: contexts.sequenceRegistrationContext,
16270
- children: /* @__PURE__ */ jsx44(DisableSequenceRegistrationContext.Provider, {
16597
+ children: /* @__PURE__ */ jsx45(DisableSequenceRegistrationContext.Provider, {
16271
16598
  value: contexts.disableSequenceRegistrationContext,
16272
- children: /* @__PURE__ */ jsx44(ForwardedSequenceRegistry, {
16599
+ children: /* @__PURE__ */ jsx45(ForwardedSequenceRegistry, {
16273
16600
  contexts,
16274
- children: /* @__PURE__ */ jsx44(VisualModePropStatusesRefContext.Provider, {
16601
+ children: /* @__PURE__ */ jsx45(VisualModePropStatusesRefContext.Provider, {
16275
16602
  value: contexts.visualModePropStatusesRefContext,
16276
- children: /* @__PURE__ */ jsx44(RenderAssetManager.Provider, {
16603
+ children: /* @__PURE__ */ jsx45(RenderAssetManager.Provider, {
16277
16604
  value: contexts.renderAssetManagerContext,
16278
- children: /* @__PURE__ */ jsx44(ResolveCompositionContext.Provider, {
16605
+ children: /* @__PURE__ */ jsx45(ResolveCompositionContext.Provider, {
16279
16606
  value: contexts.resolveCompositionContext,
16280
- children: /* @__PURE__ */ jsx44(TimelineContext.Provider, {
16607
+ children: /* @__PURE__ */ jsx45(TimelineContext.Provider, {
16281
16608
  value: contexts.timelineContext,
16282
- children: /* @__PURE__ */ jsx44(SetTimelineContext.Provider, {
16609
+ children: /* @__PURE__ */ jsx45(SetTimelineContext.Provider, {
16283
16610
  value: contexts.setTimelineContext,
16284
- children: /* @__PURE__ */ jsx44(SequenceContext.Provider, {
16611
+ children: /* @__PURE__ */ jsx45(SequenceContext.Provider, {
16285
16612
  value: contexts.sequenceContext,
16286
- children: /* @__PURE__ */ jsx44(BufferingContextReact.Provider, {
16613
+ children: /* @__PURE__ */ jsx45(BufferingContextReact.Provider, {
16287
16614
  value: contexts.bufferManagerContext,
16288
- children: /* @__PURE__ */ jsx44(TimelineTrackContext.Provider, {
16615
+ children: /* @__PURE__ */ jsx45(TimelineTrackContext.Provider, {
16289
16616
  value: contexts.timelineTrackContext,
16290
- children: /* @__PURE__ */ jsx44(DefaultPremountContext.Provider, {
16617
+ children: /* @__PURE__ */ jsx45(DefaultPremountContext.Provider, {
16291
16618
  value: contexts.defaultPremountInSeconds,
16292
- children: /* @__PURE__ */ jsx44(VideoContext.Provider, {
16619
+ children: /* @__PURE__ */ jsx45(VideoContext.Provider, {
16293
16620
  value: contexts.videoContext,
16294
16621
  children
16295
16622
  })
@@ -16316,6 +16643,8 @@ var RemotionContextProvider = (props) => {
16316
16643
  // src/internals.ts
16317
16644
  var compositionSelectorRef = createRef3();
16318
16645
  var Internals = {
16646
+ HtmlInCanvasFallback,
16647
+ useHtmlInCanvasUnsupportedMessage,
16319
16648
  OptimisticSequenceDeletion,
16320
16649
  usePendingSequenceDeletions,
16321
16650
  createElementSourceProxy,
@@ -16350,9 +16679,11 @@ var Internals = {
16350
16679
  resolveTrimProps,
16351
16680
  VideoForPreview,
16352
16681
  CompositionManager,
16682
+ CompositionManagerRefContext,
16353
16683
  CompositionSetters,
16354
16684
  VisualModePropStatusesContext,
16355
16685
  VisualModePropStatusesRefContext,
16686
+ VisualModePropStatusesSubscriptionContext,
16356
16687
  VisualModeBatchSettersContext,
16357
16688
  VisualModeDragOverridesContext,
16358
16689
  VisualModeDragOverridesRefContext,
@@ -16490,6 +16821,7 @@ var Internals = {
16490
16821
  DelayRenderContextType,
16491
16822
  TimelineContext,
16492
16823
  usePlaying,
16824
+ PlaybackPitchContext,
16493
16825
  PlaybackRateContext,
16494
16826
  AbsoluteTimeContext,
16495
16827
  RenderAssetManagerProvider,
@@ -16532,7 +16864,7 @@ var fontDataByUrl = new Map;
16532
16864
  // src/series/index.tsx
16533
16865
  import React55, {
16534
16866
  forwardRef as forwardRef15,
16535
- useMemo as useMemo47
16867
+ useMemo as useMemo49
16536
16868
  } from "react";
16537
16869
 
16538
16870
  // src/series/flatten-children.tsx
@@ -16549,7 +16881,7 @@ var flattenChildren = (children) => {
16549
16881
  };
16550
16882
 
16551
16883
  // src/series/index.tsx
16552
- import { jsx as jsx45, jsxs as jsxs4, Fragment } from "react/jsx-runtime";
16884
+ import { jsx as jsx46, jsxs as jsxs5, Fragment } from "react/jsx-runtime";
16553
16885
  var seriesSequenceSchema = {
16554
16886
  durationInFrames: Interactive.baseSchema.durationInFrames,
16555
16887
  name: Interactive.sequenceSchema.name,
@@ -16565,7 +16897,7 @@ var SeriesSequenceInner = forwardRef15(({ offset = 0, className = "", _remotionI
16565
16897
  if (_remotionInternalRender) {
16566
16898
  return _remotionInternalRender({ ...props, offset, className: className || undefined }, ref);
16567
16899
  }
16568
- return /* @__PURE__ */ jsx45(IsNotInsideSeriesProvider, {
16900
+ return /* @__PURE__ */ jsx46(IsNotInsideSeriesProvider, {
16569
16901
  children: props.children
16570
16902
  });
16571
16903
  });
@@ -16604,7 +16936,7 @@ var validateSeriesSequenceProps = ({
16604
16936
  };
16605
16937
  var SeriesInner = (props) => {
16606
16938
  const pendingDeletions = usePendingSequenceDeletions();
16607
- const childrenValue = useMemo47(() => {
16939
+ const childrenValue = useMemo49(() => {
16608
16940
  const flattenedChildren = flattenChildren(props.children).filter((child) => !OptimisticSequenceDeletion.isElementDeleted(child, pendingDeletions));
16609
16941
  const renderChildren = (i, startFrame) => {
16610
16942
  if (i === flattenedChildren.length) {
@@ -16652,9 +16984,9 @@ var SeriesInner = (props) => {
16652
16984
  });
16653
16985
  const currentStartFrame = startFrame + offset;
16654
16986
  const nextStartFrame = startFrame + timelineDurationInFrames + offset;
16655
- return /* @__PURE__ */ jsxs4(Fragment, {
16987
+ return /* @__PURE__ */ jsxs5(Fragment, {
16656
16988
  children: [
16657
- /* @__PURE__ */ jsx45(SequenceWithoutSchemaWithRef, {
16989
+ /* @__PURE__ */ jsx46(SequenceWithoutSchemaWithRef, {
16658
16990
  ref,
16659
16991
  name: name || "<Series.Sequence>",
16660
16992
  _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/series",
@@ -16666,7 +16998,7 @@ var SeriesInner = (props) => {
16666
16998
  role: "clip",
16667
16999
  seriesOffset: offset
16668
17000
  },
16669
- children: /* @__PURE__ */ jsx45(IsNotInsideSeriesProvider, {
17001
+ children: /* @__PURE__ */ jsx46(IsNotInsideSeriesProvider, {
16670
17002
  children: sequenceChildren
16671
17003
  })
16672
17004
  }),
@@ -16678,12 +17010,12 @@ var SeriesInner = (props) => {
16678
17010
  };
16679
17011
  return renderChildren(0, 0);
16680
17012
  }, [props.children, pendingDeletions]);
16681
- return /* @__PURE__ */ jsx45(TrackWithoutSchema, {
17013
+ return /* @__PURE__ */ jsx46(TrackWithoutSchema, {
16682
17014
  layout: "none",
16683
17015
  _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/series",
16684
17016
  ...props,
16685
17017
  name: props.name ?? "<Series>",
16686
- children: /* @__PURE__ */ jsx45(IsInsideSeriesContainer, {
17018
+ children: /* @__PURE__ */ jsx46(IsInsideSeriesContainer, {
16687
17019
  children: childrenValue
16688
17020
  })
16689
17021
  });
@@ -16808,16 +17140,16 @@ var Still = (props) => {
16808
17140
  };
16809
17141
  addSequenceStackTraces(Still);
16810
17142
  // src/video/html5-video.tsx
16811
- import { forwardRef as forwardRef17, useCallback as useCallback30, useContext as useContext53 } from "react";
17143
+ import { forwardRef as forwardRef17, useContext as useContext53, useMemo as useMemo51 } from "react";
16812
17144
 
16813
17145
  // src/video/VideoForRendering.tsx
16814
17146
  import {
16815
17147
  forwardRef as forwardRef16,
16816
17148
  useContext as useContext52,
16817
- useEffect as useEffect23,
17149
+ useEffect as useEffect22,
16818
17150
  useImperativeHandle as useImperativeHandle11,
16819
17151
  useLayoutEffect as useLayoutEffect22,
16820
- useMemo as useMemo48,
17152
+ useMemo as useMemo50,
16821
17153
  useRef as useRef32
16822
17154
  } from "react";
16823
17155
 
@@ -16946,7 +17278,7 @@ var seekToTimeMultipleUntilRight = ({
16946
17278
  };
16947
17279
 
16948
17280
  // src/video/VideoForRendering.tsx
16949
- import { jsx as jsx46 } from "react/jsx-runtime";
17281
+ import { jsx as jsx47 } from "react/jsx-runtime";
16950
17282
  var VideoForRenderingForwardFunction = ({
16951
17283
  onError,
16952
17284
  volume: volumeProp,
@@ -16961,7 +17293,7 @@ var VideoForRenderingForwardFunction = ({
16961
17293
  loopVolumeCurveBehavior,
16962
17294
  audioStreamIndex,
16963
17295
  onVideoFrame,
16964
- preservePitch: _preservePitch,
17296
+ preservePitch,
16965
17297
  ...props
16966
17298
  }, ref) => {
16967
17299
  const absoluteFrame = useTimelinePosition();
@@ -16977,7 +17309,7 @@ var VideoForRenderingForwardFunction = ({
16977
17309
  const mountTime = useMountTime();
16978
17310
  const { delayRender, continueRender } = useDelayRender();
16979
17311
  const { registerRenderAsset, unregisterRenderAsset } = useContext52(RenderAssetManager);
16980
- const id = useMemo48(() => `video-${random(props.src ?? "")}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.relativeFrom}-${sequenceContext?.durationInFrames}`, [
17312
+ const id = useMemo50(() => `video-${random(props.src ?? "")}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.relativeFrom}-${sequenceContext?.durationInFrames}`, [
16981
17313
  props.src,
16982
17314
  sequenceContext?.cumulatedFrom,
16983
17315
  sequenceContext?.relativeFrom,
@@ -16998,7 +17330,7 @@ var VideoForRenderingForwardFunction = ({
16998
17330
  if (!videoConfig) {
16999
17331
  throw new Error("No video config found");
17000
17332
  }
17001
- useEffect23(() => {
17333
+ useEffect22(() => {
17002
17334
  if (!props.src) {
17003
17335
  throw new Error("No src passed");
17004
17336
  }
@@ -17015,7 +17347,8 @@ var VideoForRenderingForwardFunction = ({
17015
17347
  playbackRate: (playbackRate ?? 1) * sequencePlaybackRate,
17016
17348
  toneFrequency: toneFrequency ?? 1,
17017
17349
  audioStartFrame,
17018
- audioStreamIndex: audioStreamIndex ?? 0
17350
+ audioStreamIndex: audioStreamIndex ?? 0,
17351
+ preservePitch: preservePitch ?? true
17019
17352
  });
17020
17353
  return () => unregisterRenderAsset(id);
17021
17354
  }, [
@@ -17031,13 +17364,14 @@ var VideoForRenderingForwardFunction = ({
17031
17364
  toneFrequency,
17032
17365
  audioStartFrame,
17033
17366
  sequencePlaybackRate,
17034
- audioStreamIndex
17367
+ audioStreamIndex,
17368
+ preservePitch
17035
17369
  ]);
17036
17370
  useImperativeHandle11(ref, () => {
17037
17371
  return videoRef.current;
17038
17372
  }, []);
17039
17373
  useEmitVideoFrame({ ref: videoRef, onVideoFrame });
17040
- useEffect23(() => {
17374
+ useEffect22(() => {
17041
17375
  if (!window.remotion_videoEnabled) {
17042
17376
  return;
17043
17377
  }
@@ -17161,7 +17495,7 @@ var VideoForRenderingForwardFunction = ({
17161
17495
  delayRender
17162
17496
  ]);
17163
17497
  }
17164
- return /* @__PURE__ */ jsx46("video", {
17498
+ return /* @__PURE__ */ jsx47("video", {
17165
17499
  ref: videoRef,
17166
17500
  disableRemotePlayback: true,
17167
17501
  ...props
@@ -17170,7 +17504,7 @@ var VideoForRenderingForwardFunction = ({
17170
17504
  var VideoForRendering = forwardRef16(VideoForRenderingForwardFunction);
17171
17505
 
17172
17506
  // src/video/html5-video.tsx
17173
- import { jsx as jsx47 } from "react/jsx-runtime";
17507
+ import { jsx as jsx48 } from "react/jsx-runtime";
17174
17508
  var VideoForwardingFunction = (props, ref) => {
17175
17509
  const {
17176
17510
  startFrom,
@@ -17202,9 +17536,7 @@ var VideoForwardingFunction = (props, ref) => {
17202
17536
  throw new TypeError(`The \`<Html5Video>\` tag requires a string for \`src\`, but got ${JSON.stringify(props.src)} instead.`);
17203
17537
  }
17204
17538
  const preloadedSrc = usePreload(props.src);
17205
- const onDuration = useCallback30((src, durationInSeconds) => {
17206
- setDurations({ type: "got-duration", durationInSeconds, src });
17207
- }, [setDurations]);
17539
+ const onDuration = useMemo51(() => onMediaDuration.bind(null, setDurations), [setDurations]);
17208
17540
  const durationFetched = durations[getAbsoluteSrc(preloadedSrc)] ?? durations[getAbsoluteSrc(props.src)];
17209
17541
  validateMediaTrimProps({ startFrom, endAt, trimBefore, trimAfter });
17210
17542
  if (durationInFrames !== undefined) {
@@ -17227,14 +17559,14 @@ var VideoForwardingFunction = (props, ref) => {
17227
17559
  const loopDuration = effectiveTrimAfter ?? (durationFetched === undefined ? undefined : durationFetched * fps);
17228
17560
  if (loop && loopDuration !== undefined) {
17229
17561
  if (!Number.isFinite(loopDuration)) {
17230
- return /* @__PURE__ */ jsx47(Html5Video, {
17562
+ return /* @__PURE__ */ jsx48(Html5Video, {
17231
17563
  ...propsOtherThanLoop,
17232
17564
  ref,
17233
17565
  _remotionInternalStack,
17234
17566
  _remotionInternalNativeLoopPassed: true
17235
17567
  });
17236
17568
  }
17237
- return /* @__PURE__ */ jsx47(Loop, {
17569
+ return /* @__PURE__ */ jsx48(Loop, {
17238
17570
  durationInFrames: calculateMediaDuration({
17239
17571
  trimAfter: effectiveTrimAfter,
17240
17572
  mediaDurationInFrames: loopDuration,
@@ -17244,7 +17576,7 @@ var VideoForwardingFunction = (props, ref) => {
17244
17576
  layout: "none",
17245
17577
  name,
17246
17578
  showInTimeline: false,
17247
- children: /* @__PURE__ */ jsx47(Html5Video, {
17579
+ children: /* @__PURE__ */ jsx48(Html5Video, {
17248
17580
  ...propsOtherThanLoop,
17249
17581
  ref,
17250
17582
  _remotionInternalStack,
@@ -17253,15 +17585,15 @@ var VideoForwardingFunction = (props, ref) => {
17253
17585
  });
17254
17586
  }
17255
17587
  if (typeof trimBeforeValue !== "undefined" || typeof effectiveTrimAfter !== "undefined") {
17256
- return /* @__PURE__ */ jsx47(Html5MediaTrimContext.Provider, {
17588
+ return /* @__PURE__ */ jsx48(Html5MediaTrimContext.Provider, {
17257
17589
  value: trimBeforeValue ?? 0,
17258
- children: /* @__PURE__ */ jsx47(Sequence, {
17590
+ children: /* @__PURE__ */ jsx48(Sequence, {
17259
17591
  layout: "none",
17260
17592
  from: 0 - (trimBeforeValue ?? 0),
17261
17593
  showInTimeline: false,
17262
17594
  durationInFrames: effectiveTrimAfter === undefined ? undefined : (trimBeforeValue ?? 0) + (effectiveTrimAfter - (trimBeforeValue ?? 0)) / (props.playbackRate ?? 1),
17263
17595
  name,
17264
- children: /* @__PURE__ */ jsx47(Html5Video, {
17596
+ children: /* @__PURE__ */ jsx48(Html5Video, {
17265
17597
  pauseWhenBuffering: shouldPauseWhenBuffering,
17266
17598
  onVideoFrame,
17267
17599
  ...otherProps,
@@ -17278,14 +17610,14 @@ var VideoForwardingFunction = (props, ref) => {
17278
17610
  volume: props.volume
17279
17611
  }, "Html5Video");
17280
17612
  if (environment.isRendering) {
17281
- return /* @__PURE__ */ jsx47(VideoForRendering, {
17613
+ return /* @__PURE__ */ jsx48(VideoForRendering, {
17282
17614
  onDuration,
17283
17615
  onVideoFrame: onVideoFrame ?? null,
17284
17616
  ...otherProps,
17285
17617
  ref
17286
17618
  });
17287
17619
  }
17288
- return /* @__PURE__ */ jsx47(VideoForPreview, {
17620
+ return /* @__PURE__ */ jsx48(VideoForPreview, {
17289
17621
  onlyWarnForMediaSeekingError: false,
17290
17622
  ...otherProps,
17291
17623
  ref,