remotion 4.0.537 → 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 (167) 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/CompositionManagerProvider.d.ts +1 -1
  10. package/dist/cjs/CompositionManagerProvider.js +1 -1
  11. package/dist/cjs/CompositionRegistryProvider.d.ts +1 -1
  12. package/dist/cjs/CompositionRegistryProvider.js +1 -1
  13. package/dist/cjs/EditorProps.d.ts +2 -2
  14. package/dist/cjs/EditorProps.js +1 -1
  15. package/dist/cjs/Folder.js +1 -1
  16. package/dist/cjs/HtmlInCanvas.d.ts +58 -67
  17. package/dist/cjs/HtmlInCanvas.js +22 -9
  18. package/dist/cjs/HtmlInCanvasFallback.d.ts +6 -0
  19. package/dist/cjs/HtmlInCanvasFallback.js +39 -0
  20. package/dist/cjs/IFrame.d.ts +2 -2
  21. package/dist/cjs/IFrame.js +1 -1
  22. package/dist/cjs/Img.d.ts +62 -62
  23. package/dist/cjs/Img.js +160 -132
  24. package/dist/cjs/Interactive.d.ts +147 -145
  25. package/dist/cjs/Interactive.js +2 -2
  26. package/dist/cjs/RemotionRoot.js +1 -1
  27. package/dist/cjs/RenderAssetManager.js +1 -1
  28. package/dist/cjs/Sequence.js +37 -27
  29. package/dist/cjs/SequenceActivityBoundary.js +1 -1
  30. package/dist/cjs/SequenceActivityBudget.js +1 -1
  31. package/dist/cjs/SequenceActivitySuspensionProvider.js +1 -1
  32. package/dist/cjs/SequenceManager.d.ts +6 -0
  33. package/dist/cjs/SequenceManager.js +71 -27
  34. package/dist/cjs/SequenceRegistryProvider.js +16 -3
  35. package/dist/cjs/TimelineContext.js +1 -1
  36. package/dist/cjs/Track.js +2 -2
  37. package/dist/cjs/animated-image/AnimatedImage.d.ts +69 -69
  38. package/dist/cjs/animated-image/AnimatedImage.js +6 -6
  39. package/dist/cjs/animated-image/canvas.d.ts +6 -5
  40. package/dist/cjs/animated-image/canvas.js +1 -1
  41. package/dist/cjs/animated-image/create-image-decoder.d.ts +1 -1
  42. package/dist/cjs/animated-image/decode-image.d.ts +1 -1
  43. package/dist/cjs/animated-image/get-duration-in-seconds.d.ts +1 -1
  44. package/dist/cjs/animated-image/index.js +1 -1
  45. package/dist/cjs/audio/AudioForPreview.js +5 -28
  46. package/dist/cjs/audio/AudioForRendering.d.ts +5 -20
  47. package/dist/cjs/audio/AudioForRendering.js +44 -5
  48. package/dist/cjs/audio/html5-audio.d.ts +36 -36
  49. package/dist/cjs/audio/html5-audio.js +8 -10
  50. package/dist/cjs/audio/index.js +1 -1
  51. package/dist/cjs/audio/shared-audio-tags.js +10 -16
  52. package/dist/cjs/audio/shared-element-source-node.d.ts +1 -1
  53. package/dist/cjs/audio/use-audio-context.d.ts +2 -1
  54. package/dist/cjs/audio/wait-until-actually-resumed.d.ts +2 -1
  55. package/dist/cjs/buffer-until-first-frame.d.ts +4 -3
  56. package/dist/cjs/buffering.js +1 -1
  57. package/dist/cjs/cancel-render.js +3 -0
  58. package/dist/cjs/canvas-image/CanvasImage.d.ts +71 -71
  59. package/dist/cjs/canvas-image/CanvasImage.js +27 -24
  60. package/dist/cjs/canvas-image/index.js +1 -1
  61. package/dist/cjs/codec.d.ts +1 -1
  62. package/dist/cjs/committed-metadata.d.ts +4 -2
  63. package/dist/cjs/composition-registry-fallback.d.ts +4 -2
  64. package/dist/cjs/composition-registry-fallback.js +12 -10
  65. package/dist/cjs/create-element-source-proxy.js +46 -6
  66. package/dist/cjs/default-css.d.ts +1 -1
  67. package/dist/cjs/delay-render.d.ts +2 -1
  68. package/dist/cjs/delay-render.js +4 -2
  69. package/dist/cjs/easing.js +3 -1
  70. package/dist/cjs/effects/Solid.d.ts +60 -60
  71. package/dist/cjs/effects/Solid.js +2 -2
  72. package/dist/cjs/effects/canvas-pool.js +6 -9
  73. package/dist/cjs/effects/index.js +1 -1
  74. package/dist/cjs/effects/use-memoized-effects.d.ts +2 -1
  75. package/dist/cjs/effects/use-memoized-effects.js +23 -12
  76. package/dist/cjs/freeze.js +2 -2
  77. package/dist/cjs/get-cross-origin-value.d.ts +1 -1
  78. package/dist/cjs/get-effective-visual-mode-value.d.ts +2 -2
  79. package/dist/cjs/index.d.ts +3 -1
  80. package/dist/cjs/index.js +32 -32
  81. package/dist/cjs/interactivity-schema.d.ts +286 -286
  82. package/dist/cjs/internals.d.ts +408 -595
  83. package/dist/cjs/internals.js +7 -0
  84. package/dist/cjs/interpolate-colors.d.ts +1 -1
  85. package/dist/cjs/interpolate-colors.js +17 -16
  86. package/dist/cjs/interpolate.d.ts +2 -9
  87. package/dist/cjs/is-player.js +1 -1
  88. package/dist/cjs/loading-indicator.js +2 -6
  89. package/dist/cjs/log-level-context.d.ts +1 -1
  90. package/dist/cjs/log.d.ts +12 -7
  91. package/dist/cjs/loop/index.js +1 -1
  92. package/dist/cjs/media-resource-manager.d.ts +1 -1
  93. package/dist/cjs/media-tag-current-time-timestamp.d.ts +1 -1
  94. package/dist/cjs/no-react.d.ts +85 -91
  95. package/dist/cjs/no-react.js +2 -2
  96. package/dist/cjs/play-and-handle-not-allowed-error.d.ts +5 -4
  97. package/dist/cjs/playback-logging.d.ts +2 -1
  98. package/dist/cjs/playback-pitch-context.d.ts +1 -0
  99. package/dist/cjs/playback-pitch-context.js +5 -0
  100. package/dist/cjs/prefetch-state.js +1 -1
  101. package/dist/cjs/prefetch.d.ts +7 -6
  102. package/dist/cjs/props-if-has-props.d.ts +2 -1
  103. package/dist/cjs/prores-profile.d.ts +1 -1
  104. package/dist/cjs/register-root.d.ts +2 -2
  105. package/dist/cjs/render-resource-manager.d.ts +1 -1
  106. package/dist/cjs/render-types.d.ts +2 -2
  107. package/dist/cjs/resolve-video-config.d.ts +8 -8
  108. package/dist/cjs/runtime-value-store.d.ts +1 -1
  109. package/dist/cjs/scale-value.d.ts +1 -1
  110. package/dist/cjs/seek.d.ts +3 -2
  111. package/dist/cjs/sequence-activity-context.js +1 -1
  112. package/dist/cjs/sequence-crop.js +1 -4
  113. package/dist/cjs/series/flatten-children.d.ts +3 -1
  114. package/dist/cjs/series/index.js +4 -5
  115. package/dist/cjs/series/is-inside-series.js +2 -2
  116. package/dist/cjs/spring/index.d.ts +1 -1
  117. package/dist/cjs/spring/index.js +1 -1
  118. package/dist/cjs/spring/measure-spring.d.ts +1 -1
  119. package/dist/cjs/spring/spring-utils.d.ts +1 -1
  120. package/dist/cjs/spring/spring-utils.js +11 -5
  121. package/dist/cjs/timeline-position-state.d.ts +1 -1
  122. package/dist/cjs/timeline-position-state.js +2 -2
  123. package/dist/cjs/use-amplification.d.ts +4 -7
  124. package/dist/cjs/use-current-scale.d.ts +2 -2
  125. package/dist/cjs/use-delay-render.d.ts +2 -1
  126. package/dist/cjs/use-lazy-component.d.ts +1 -1
  127. package/dist/cjs/use-lazy-component.js +15 -5
  128. package/dist/cjs/use-media-buffering.d.ts +3 -2
  129. package/dist/cjs/use-media-duration.d.ts +4 -0
  130. package/dist/cjs/use-media-duration.js +36 -0
  131. package/dist/cjs/use-media-enabled.d.ts +1 -1
  132. package/dist/cjs/use-media-enabled.js +1 -1
  133. package/dist/cjs/use-media-in-timeline.d.ts +1 -1
  134. package/dist/cjs/use-media-playback.d.ts +3 -3
  135. package/dist/cjs/use-media-tag.d.ts +2 -2
  136. package/dist/cjs/use-pixel-density.d.ts +1 -1
  137. package/dist/cjs/use-premounting.d.ts +1 -1
  138. package/dist/cjs/use-premounting.js +6 -2
  139. package/dist/cjs/use-request-video-callback-time.d.ts +3 -3
  140. package/dist/cjs/use-schema.d.ts +4 -4
  141. package/dist/cjs/use-video.js +1 -1
  142. package/dist/cjs/validate-media-props.d.ts +1 -1
  143. package/dist/cjs/validation/validate-default-props.d.ts +1 -1
  144. package/dist/cjs/version.d.ts +1 -1
  145. package/dist/cjs/version.js +1 -1
  146. package/dist/cjs/video/MediaPlaybackError.js +0 -1
  147. package/dist/cjs/video/OffthreadVideo.js +5 -5
  148. package/dist/cjs/video/OffthreadVideoForRendering.js +9 -7
  149. package/dist/cjs/video/VideoForPreview.js +6 -28
  150. package/dist/cjs/video/VideoForRendering.d.ts +5 -3
  151. package/dist/cjs/video/VideoForRendering.js +4 -2
  152. package/dist/cjs/video/duration-state.d.ts +1 -0
  153. package/dist/cjs/video/duration-state.js +8 -2
  154. package/dist/cjs/video/emit-video-frame.d.ts +1 -1
  155. package/dist/cjs/video/html5-video.d.ts +36 -36
  156. package/dist/cjs/video/html5-video.js +8 -10
  157. package/dist/cjs/video/index.js +2 -2
  158. package/dist/cjs/video/seek-until-right.d.ts +3 -2
  159. package/dist/cjs/warn-about-non-seekable-media.d.ts +1 -1
  160. package/dist/cjs/with-interactivity-schema.d.ts +1 -1
  161. package/dist/cjs/with-interactivity-schema.js +3 -8
  162. package/dist/cjs/wrap-remotion-context.d.ts +4 -4
  163. package/dist/cjs/wrap-remotion-context.js +2 -2
  164. package/dist/esm/index.mjs +808 -560
  165. package/dist/esm/no-react.mjs +27 -22
  166. package/dist/esm/version.mjs +1 -1
  167. package/package.json +4 -4
package/dist/cjs/Img.d.ts CHANGED
@@ -17,52 +17,52 @@ export type ImgProps = NativeImgProps & {
17
17
  } & Omit<InteractiveBaseProps, 'playbackRate'> & InteractiveCropProps & InteractivePremountProps;
18
18
  export declare const imgSchema: {
19
19
  readonly 'style.transformOrigin': {
20
- readonly type: "transform-origin";
20
+ readonly type: 'transform-origin';
21
21
  readonly step: 1;
22
- readonly default: "50% 50%";
23
- readonly description: "Transform origin";
22
+ readonly default: '50% 50%';
23
+ readonly description: 'Transform origin';
24
24
  };
25
25
  readonly 'style.translate': {
26
- readonly type: "translate";
26
+ readonly type: 'translate';
27
27
  readonly step: 1;
28
- readonly default: "0px 0px";
29
- readonly description: "Offset";
28
+ readonly default: '0px 0px';
29
+ readonly description: 'Offset';
30
30
  };
31
31
  readonly 'style.scale': {
32
- readonly type: "scale";
32
+ readonly type: 'scale';
33
33
  readonly max: 100;
34
34
  readonly step: 0.01;
35
35
  readonly default: 1;
36
- readonly description: "Scale";
37
- readonly defaultKeyframeOutput: "perceptual-scale";
36
+ readonly description: 'Scale';
37
+ readonly defaultKeyframeOutput: 'perceptual-scale';
38
38
  };
39
39
  readonly 'style.rotate': {
40
- readonly type: "rotation-css";
40
+ readonly type: 'rotation-css';
41
41
  readonly step: 1;
42
- readonly default: "0deg";
43
- readonly description: "Rotation";
42
+ readonly default: '0deg';
43
+ readonly description: 'Rotation';
44
44
  };
45
45
  readonly 'style.opacity': {
46
- readonly type: "number";
46
+ readonly type: 'number';
47
47
  readonly min: 0;
48
48
  readonly max: 1;
49
49
  readonly step: 0.01;
50
50
  readonly default: 1;
51
- readonly description: "Opacity";
51
+ readonly description: 'Opacity';
52
52
  readonly hiddenFromList: false;
53
53
  };
54
54
  readonly 'style.borderWidth': {
55
- readonly type: "number";
55
+ readonly type: 'number';
56
56
  readonly default: undefined;
57
57
  readonly min: 0;
58
58
  readonly step: 1;
59
- readonly description: "Border width";
59
+ readonly description: 'Border width';
60
60
  readonly hiddenFromList: false;
61
61
  };
62
62
  readonly 'style.borderStyle': {
63
- readonly type: "enum";
64
- readonly default: "none";
65
- readonly description: "Border style";
63
+ readonly type: 'enum';
64
+ readonly default: 'none';
65
+ readonly description: 'Border style';
66
66
  readonly variants: {
67
67
  readonly none: {};
68
68
  readonly hidden: {};
@@ -77,67 +77,67 @@ export declare const imgSchema: {
77
77
  };
78
78
  };
79
79
  readonly 'style.borderColor': {
80
- readonly type: "color";
80
+ readonly type: 'color';
81
81
  readonly default: undefined;
82
- readonly description: "Border color";
82
+ readonly description: 'Border color';
83
83
  };
84
84
  readonly 'style.borderRadius': {
85
- readonly type: "number";
85
+ readonly type: 'number';
86
86
  readonly default: 0;
87
87
  readonly min: 0;
88
88
  readonly step: 1;
89
- readonly description: "Border radius";
89
+ readonly description: 'Border radius';
90
90
  readonly hiddenFromList: false;
91
91
  readonly keyframable: true;
92
92
  };
93
93
  readonly 'style.borderTopLeftRadius': {
94
- readonly type: "number";
94
+ readonly type: 'number';
95
95
  readonly default: 0;
96
96
  readonly min: 0;
97
97
  readonly step: 1;
98
- readonly description: "Top left radius";
98
+ readonly description: 'Top left radius';
99
99
  readonly hiddenFromList: false;
100
100
  };
101
101
  readonly 'style.borderTopRightRadius': {
102
- readonly type: "number";
102
+ readonly type: 'number';
103
103
  readonly default: 0;
104
104
  readonly min: 0;
105
105
  readonly step: 1;
106
- readonly description: "Top right radius";
106
+ readonly description: 'Top right radius';
107
107
  readonly hiddenFromList: false;
108
108
  };
109
109
  readonly 'style.borderBottomRightRadius': {
110
- readonly type: "number";
110
+ readonly type: 'number';
111
111
  readonly default: 0;
112
112
  readonly min: 0;
113
113
  readonly step: 1;
114
- readonly description: "Bottom right radius";
114
+ readonly description: 'Bottom right radius';
115
115
  readonly hiddenFromList: false;
116
116
  };
117
117
  readonly 'style.borderBottomLeftRadius': {
118
- readonly type: "number";
118
+ readonly type: 'number';
119
119
  readonly default: 0;
120
120
  readonly min: 0;
121
121
  readonly step: 1;
122
- readonly description: "Bottom left radius";
122
+ readonly description: 'Bottom left radius';
123
123
  readonly hiddenFromList: false;
124
124
  };
125
125
  readonly 'style.backgroundColor': {
126
- readonly type: "color";
127
- readonly default: "transparent";
128
- readonly description: "Color";
126
+ readonly type: 'color';
127
+ readonly default: 'transparent';
128
+ readonly description: 'Color';
129
129
  };
130
130
  readonly premountFor: {
131
- readonly type: "number";
131
+ readonly type: 'number';
132
132
  readonly default: undefined;
133
- readonly description: "Premount For";
133
+ readonly description: 'Premount For';
134
134
  readonly min: 0;
135
135
  readonly step: 1;
136
136
  readonly hiddenFromList: false;
137
137
  readonly keyframable: false;
138
138
  };
139
139
  readonly postmountFor: {
140
- readonly type: "number";
140
+ readonly type: 'number';
141
141
  readonly default: 0;
142
142
  readonly min: 0;
143
143
  readonly step: 1;
@@ -145,9 +145,9 @@ export declare const imgSchema: {
145
145
  readonly keyframable: false;
146
146
  };
147
147
  readonly cropLeft: {
148
- readonly type: "number";
148
+ readonly type: 'number';
149
149
  readonly default: 0;
150
- readonly description: "Crop left";
150
+ readonly description: 'Crop left';
151
151
  readonly min: 0;
152
152
  readonly max: 1;
153
153
  readonly step: 0.01;
@@ -155,9 +155,9 @@ export declare const imgSchema: {
155
155
  readonly keyframable: true;
156
156
  };
157
157
  readonly cropRight: {
158
- readonly type: "number";
158
+ readonly type: 'number';
159
159
  readonly default: 0;
160
- readonly description: "Crop right";
160
+ readonly description: 'Crop right';
161
161
  readonly min: 0;
162
162
  readonly max: 1;
163
163
  readonly step: 0.01;
@@ -165,9 +165,9 @@ export declare const imgSchema: {
165
165
  readonly keyframable: true;
166
166
  };
167
167
  readonly cropTop: {
168
- readonly type: "number";
168
+ readonly type: 'number';
169
169
  readonly default: 0;
170
- readonly description: "Crop top";
170
+ readonly description: 'Crop top';
171
171
  readonly min: 0;
172
172
  readonly max: 1;
173
173
  readonly step: 0.01;
@@ -175,9 +175,9 @@ export declare const imgSchema: {
175
175
  readonly keyframable: true;
176
176
  };
177
177
  readonly cropBottom: {
178
- readonly type: "number";
178
+ readonly type: 'number';
179
179
  readonly default: 0;
180
- readonly description: "Crop bottom";
180
+ readonly description: 'Crop bottom';
181
181
  readonly min: 0;
182
182
  readonly max: 1;
183
183
  readonly step: 0.01;
@@ -185,27 +185,27 @@ export declare const imgSchema: {
185
185
  readonly keyframable: true;
186
186
  };
187
187
  readonly durationInFrames: {
188
- readonly type: "number";
188
+ readonly type: 'number';
189
189
  readonly default: undefined;
190
190
  readonly min: 1;
191
191
  readonly step: 1;
192
192
  readonly hiddenFromList: true;
193
193
  };
194
194
  readonly from: {
195
- readonly type: "number";
195
+ readonly type: 'number';
196
196
  readonly default: 0;
197
197
  readonly step: 1;
198
198
  readonly hiddenFromList: true;
199
199
  };
200
200
  readonly trimBefore: {
201
- readonly type: "number";
201
+ readonly type: 'number';
202
202
  readonly default: 0;
203
203
  readonly min: 0;
204
204
  readonly step: 1;
205
205
  readonly hiddenFromList: true;
206
206
  };
207
207
  readonly freeze: {
208
- readonly type: "number";
208
+ readonly type: 'number';
209
209
  readonly default: null;
210
210
  readonly step: 1;
211
211
  readonly hiddenFromList: true;
@@ -214,24 +214,24 @@ export declare const imgSchema: {
214
214
  readonly name: import("./interactivity-schema.js").HiddenFieldSchema;
215
215
  readonly showInTimeline: import("./interactivity-schema.js").HiddenFieldSchema;
216
216
  readonly src: {
217
- readonly type: "asset";
218
- readonly assetType: "image";
217
+ readonly type: 'asset';
218
+ readonly assetType: 'image';
219
219
  readonly default: undefined;
220
- readonly description: "Source";
220
+ readonly description: 'Source';
221
221
  readonly keyframable: false;
222
222
  };
223
223
  };
224
224
  export declare const Img: React.ComponentType<NativeImgProps & {
225
- readonly maxRetries?: number | undefined;
226
- readonly pauseWhenLoading?: boolean | undefined;
227
- readonly delayRenderRetries?: number | undefined;
228
- readonly delayRenderTimeoutInMilliseconds?: number | undefined;
229
- readonly onImageFrame?: ((imageElement: HTMLImageElement) => void) | undefined;
230
- readonly onImageError?: ((error: Error) => void) | undefined;
225
+ readonly maxRetries?: number;
226
+ readonly pauseWhenLoading?: boolean;
227
+ readonly delayRenderRetries?: number;
228
+ readonly delayRenderTimeoutInMilliseconds?: number;
229
+ readonly onImageFrame?: (imageElement: HTMLImageElement) => void;
230
+ readonly onImageError?: (error: Error) => void;
231
231
  readonly src: string;
232
- readonly effects?: EffectsProp | undefined;
233
- readonly effectsOutputSize?: EffectsOutputSize | undefined;
234
- readonly showInTimeline?: boolean | undefined;
235
- readonly name?: string | undefined;
232
+ readonly effects?: EffectsProp;
233
+ readonly effectsOutputSize?: EffectsOutputSize;
234
+ readonly showInTimeline?: boolean;
235
+ readonly name?: string;
236
236
  } & Omit<InteractiveBaseProps, "playbackRate"> & InteractiveCropProps & InteractivePremountProps>;
237
237
  export {};
package/dist/cjs/Img.js CHANGED
@@ -24,6 +24,137 @@ const with_interactivity_schema_js_1 = require("./with-interactivity-schema.js")
24
24
  function exponentialBackoff(errorCount) {
25
25
  return 1000 * 2 ** (errorCount - 1);
26
26
  }
27
+ // Bind only the inputs each persistent callback needs. A render-scope closure
28
+ // can otherwise keep replaced handlers alive, even when it never calls them.
29
+ const setImageRef = (imageRef, ref, img) => {
30
+ imageRef.current = img;
31
+ if (typeof ref === 'function') {
32
+ ref(img);
33
+ }
34
+ else if (ref) {
35
+ ref.current = img;
36
+ }
37
+ };
38
+ const retryImage = (imageRef, timeout) => {
39
+ if (!imageRef.current) {
40
+ return;
41
+ }
42
+ const currentSrc = imageRef.current.src;
43
+ setTimeout(() => {
44
+ var _a;
45
+ if (!imageRef.current) {
46
+ // Component has been unmounted, do not retry
47
+ return;
48
+ }
49
+ const newSrc = (_a = imageRef.current) === null || _a === void 0 ? void 0 : _a.src;
50
+ if (newSrc !== currentSrc) {
51
+ // src has changed, do not retry
52
+ return;
53
+ }
54
+ imageRef.current.removeAttribute('src');
55
+ imageRef.current.setAttribute('src', newSrc);
56
+ }, timeout);
57
+ };
58
+ const handleImageError = ({ errors, imageRef, onError, onImageError, maxRetries, cancelRender, retryIn, }, e) => {
59
+ var _a, _b, _c, _d, _e, _f, _g, _h;
60
+ var _j, _k, _l, _m;
61
+ if (!errors.current) {
62
+ return;
63
+ }
64
+ errors.current[(_a = imageRef.current) === null || _a === void 0 ? void 0 : _a.src] =
65
+ ((_j = errors.current[(_b = imageRef.current) === null || _b === void 0 ? void 0 : _b.src]) !== null && _j !== void 0 ? _j : 0) + 1;
66
+ if ((onError || onImageError) &&
67
+ ((_k = errors.current[(_c = imageRef.current) === null || _c === void 0 ? void 0 : _c.src]) !== null && _k !== void 0 ? _k : 0) > maxRetries) {
68
+ onError === null || onError === void 0 ? void 0 : onError(e);
69
+ onImageError === null || onImageError === void 0 ? void 0 : onImageError(new Error('Error loading image with src: ' +
70
+ (0, truncate_src_for_label_js_1.truncateSrcForLabel)((_d = imageRef.current) === null || _d === void 0 ? void 0 : _d.src)));
71
+ return;
72
+ }
73
+ if (((_l = errors.current[(_e = imageRef.current) === null || _e === void 0 ? void 0 : _e.src]) !== null && _l !== void 0 ? _l : 0) <= maxRetries) {
74
+ const backoff = exponentialBackoff((_m = errors.current[(_f = imageRef.current) === null || _f === void 0 ? void 0 : _f.src]) !== null && _m !== void 0 ? _m : 0);
75
+ // eslint-disable-next-line no-console
76
+ console.warn(`Could not load image with source ${(0, truncate_src_for_label_js_1.truncateSrcForLabel)((_g = imageRef.current) === null || _g === void 0 ? void 0 : _g.src)}, retrying again in ${backoff}ms`);
77
+ retryIn(backoff);
78
+ return;
79
+ }
80
+ try {
81
+ cancelRender('Error loading image with src: ' +
82
+ (0, truncate_src_for_label_js_1.truncateSrcForLabel)((_h = imageRef.current) === null || _h === void 0 ? void 0 : _h.src));
83
+ }
84
+ catch (_o) {
85
+ // cancelRender() intentionally throws after storing the error in scope.
86
+ // In async image callbacks, we rely on the stored error for renderer propagation.
87
+ }
88
+ };
89
+ // Keep the loading cleanup outside the render scope too: it can outlive many
90
+ // handler replacements while the source and onImageFrame stay unchanged.
91
+ const loadImage = ({ imageRef, errors, actualSrc, delayRenderRetries, delayRenderTimeoutInMilliseconds, onImageFrame, delayRender, continueRender, setIsLoading, }) => {
92
+ var _a, _b;
93
+ if (((_b = (_a = window.process) === null || _a === void 0 ? void 0 : _a.env) === null || _b === void 0 ? void 0 : _b.NODE_ENV) === 'test') {
94
+ if (imageRef.current) {
95
+ imageRef.current.src = actualSrc;
96
+ }
97
+ return;
98
+ }
99
+ const { current } = imageRef;
100
+ if (!current) {
101
+ return;
102
+ }
103
+ setIsLoading(true);
104
+ const newHandle = delayRender('Loading <Img> with src=' + (0, truncate_src_for_label_js_1.truncateSrcForLabel)(actualSrc), {
105
+ retries: delayRenderRetries !== null && delayRenderRetries !== void 0 ? delayRenderRetries : undefined,
106
+ timeoutInMilliseconds: delayRenderTimeoutInMilliseconds !== null && delayRenderTimeoutInMilliseconds !== void 0 ? delayRenderTimeoutInMilliseconds : undefined,
107
+ });
108
+ let unmounted = false;
109
+ const onComplete = () => {
110
+ var _a, _b, _c;
111
+ var _d;
112
+ // the decode() promise isn't cancelable -- it may still resolve after unmounting
113
+ if (unmounted) {
114
+ continueRender(newHandle);
115
+ return;
116
+ }
117
+ if (((_d = errors.current[(_a = imageRef.current) === null || _a === void 0 ? void 0 : _a.src]) !== null && _d !== void 0 ? _d : 0) > 0) {
118
+ delete errors.current[(_b = imageRef.current) === null || _b === void 0 ? void 0 : _b.src];
119
+ // eslint-disable-next-line no-console
120
+ console.info(`Retry successful - ${(0, truncate_src_for_label_js_1.truncateSrcForLabel)((_c = imageRef.current) === null || _c === void 0 ? void 0 : _c.src)} is now loaded`);
121
+ }
122
+ if (current) {
123
+ onImageFrame === null || onImageFrame === void 0 ? void 0 : onImageFrame(current);
124
+ }
125
+ setIsLoading(false);
126
+ continueRender(newHandle);
127
+ };
128
+ if (!imageRef.current) {
129
+ onComplete();
130
+ return;
131
+ }
132
+ current.src = actualSrc;
133
+ current
134
+ .decode()
135
+ .then(onComplete)
136
+ .catch((err) => {
137
+ // fall back to onload event if decode() fails
138
+ // eslint-disable-next-line no-console
139
+ console.warn(err);
140
+ // HTMLImageElement.complete is also true for broken images (e.g. 404),
141
+ // so only treat it as loaded if intrinsic dimensions are available.
142
+ if (current.complete &&
143
+ current.naturalWidth > 0 &&
144
+ current.naturalHeight > 0) {
145
+ onComplete();
146
+ }
147
+ else {
148
+ current.addEventListener('load', onComplete);
149
+ }
150
+ });
151
+ // If tag gets unmounted, clear pending handles because image is not going to load
152
+ return () => {
153
+ unmounted = true;
154
+ current.removeEventListener('load', onComplete);
155
+ continueRender(newHandle);
156
+ };
157
+ };
27
158
  const ImgContent = ({ onError, onImageError, maxRetries = 2, src, pauseWhenLoading, delayRenderRetries, delayRenderTimeoutInMilliseconds, onImageFrame, crossOrigin, decoding, ref, ...props }) => {
28
159
  const imageRef = (0, react_1.useRef)(null);
29
160
  const errors = (0, react_1.useRef)({});
@@ -34,70 +165,21 @@ const ImgContent = ({ onError, onImageError, maxRetries = 2, src, pauseWhenLoadi
34
165
  if (!_propsValid) {
35
166
  throw new Error('typecheck error');
36
167
  }
37
- const imageCallbackRef = (0, react_1.useCallback)((img) => {
38
- imageRef.current = img;
39
- if (typeof ref === 'function') {
40
- ref(img);
41
- }
42
- else if (ref) {
43
- ref.current = img;
44
- }
45
- }, [ref]);
168
+ const imageCallbackRef = (0, react_1.useMemo)(() => setImageRef.bind(null, imageRef, ref !== null && ref !== void 0 ? ref : null), [ref]);
46
169
  const actualSrc = (0, prefetch_js_1.usePreload)(src);
47
- const retryIn = (0, react_1.useCallback)((timeout) => {
48
- if (!imageRef.current) {
49
- return;
50
- }
51
- const currentSrc = imageRef.current.src;
52
- setTimeout(() => {
53
- var _a;
54
- if (!imageRef.current) {
55
- // Component has been unmounted, do not retry
56
- return;
57
- }
58
- const newSrc = (_a = imageRef.current) === null || _a === void 0 ? void 0 : _a.src;
59
- if (newSrc !== currentSrc) {
60
- // src has changed, do not retry
61
- return;
62
- }
63
- imageRef.current.removeAttribute('src');
64
- imageRef.current.setAttribute('src', newSrc);
65
- }, timeout);
66
- }, []);
170
+ const retryIn = (0, react_1.useMemo)(() => retryImage.bind(null, imageRef), []);
67
171
  const { delayRender, continueRender, cancelRender } = (0, use_delay_render_js_1.useDelayRender)();
68
172
  const isPremounting = Boolean(sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.premounting);
69
173
  const isPostmounting = Boolean(sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.postmounting);
70
- const didGetError = (0, react_1.useCallback)((e) => {
71
- var _a, _b, _c, _d, _e, _f, _g, _h;
72
- var _j, _k, _l, _m;
73
- if (!errors.current) {
74
- return;
75
- }
76
- errors.current[(_a = imageRef.current) === null || _a === void 0 ? void 0 : _a.src] =
77
- ((_j = errors.current[(_b = imageRef.current) === null || _b === void 0 ? void 0 : _b.src]) !== null && _j !== void 0 ? _j : 0) + 1;
78
- if ((onError || onImageError) &&
79
- ((_k = errors.current[(_c = imageRef.current) === null || _c === void 0 ? void 0 : _c.src]) !== null && _k !== void 0 ? _k : 0) > maxRetries) {
80
- onError === null || onError === void 0 ? void 0 : onError(e);
81
- onImageError === null || onImageError === void 0 ? void 0 : onImageError(new Error('Error loading image with src: ' +
82
- (0, truncate_src_for_label_js_1.truncateSrcForLabel)((_d = imageRef.current) === null || _d === void 0 ? void 0 : _d.src)));
83
- return;
84
- }
85
- if (((_l = errors.current[(_e = imageRef.current) === null || _e === void 0 ? void 0 : _e.src]) !== null && _l !== void 0 ? _l : 0) <= maxRetries) {
86
- const backoff = exponentialBackoff((_m = errors.current[(_f = imageRef.current) === null || _f === void 0 ? void 0 : _f.src]) !== null && _m !== void 0 ? _m : 0);
87
- // eslint-disable-next-line no-console
88
- console.warn(`Could not load image with source ${(0, truncate_src_for_label_js_1.truncateSrcForLabel)((_g = imageRef.current) === null || _g === void 0 ? void 0 : _g.src)}, retrying again in ${backoff}ms`);
89
- retryIn(backoff);
90
- return;
91
- }
92
- try {
93
- cancelRender('Error loading image with src: ' +
94
- (0, truncate_src_for_label_js_1.truncateSrcForLabel)((_h = imageRef.current) === null || _h === void 0 ? void 0 : _h.src));
95
- }
96
- catch (_o) {
97
- // cancelRender() intentionally throws after storing the error in scope.
98
- // In async image callbacks, we rely on the stored error for renderer propagation.
99
- }
100
- }, [cancelRender, maxRetries, onError, onImageError, retryIn]);
174
+ const didGetError = (0, react_1.useMemo)(() => handleImageError.bind(null, {
175
+ errors,
176
+ imageRef,
177
+ onError: onError !== null && onError !== void 0 ? onError : null,
178
+ onImageError: onImageError !== null && onImageError !== void 0 ? onImageError : null,
179
+ maxRetries,
180
+ cancelRender,
181
+ retryIn,
182
+ }), [cancelRender, maxRetries, onError, onImageError, retryIn]);
101
183
  if (typeof window !== 'undefined') {
102
184
  // eslint-disable-next-line react-hooks/rules-of-hooks
103
185
  (0, react_1.useLayoutEffect)(() => {
@@ -112,74 +194,20 @@ const ImgContent = ({ onError, onImageError, maxRetries = 2, src, pauseWhenLoadi
112
194
  isPremounting,
113
195
  pauseWhenLoading,
114
196
  ]);
115
- // eslint-disable-next-line react-hooks/rules-of-hooks
116
- (0, react_1.useLayoutEffect)(() => {
117
- var _a, _b;
118
- if (((_b = (_a = window.process) === null || _a === void 0 ? void 0 : _a.env) === null || _b === void 0 ? void 0 : _b.NODE_ENV) === 'test') {
119
- if (imageRef.current) {
120
- imageRef.current.src = actualSrc;
121
- }
122
- return;
123
- }
124
- const { current } = imageRef;
125
- if (!current) {
126
- return;
127
- }
128
- setIsLoading(true);
129
- const newHandle = delayRender('Loading <Img> with src=' + (0, truncate_src_for_label_js_1.truncateSrcForLabel)(actualSrc), {
130
- retries: delayRenderRetries !== null && delayRenderRetries !== void 0 ? delayRenderRetries : undefined,
131
- timeoutInMilliseconds: delayRenderTimeoutInMilliseconds !== null && delayRenderTimeoutInMilliseconds !== void 0 ? delayRenderTimeoutInMilliseconds : undefined,
132
- });
133
- let unmounted = false;
134
- const onComplete = () => {
135
- var _a, _b, _c;
136
- var _d;
137
- // the decode() promise isn't cancelable -- it may still resolve after unmounting
138
- if (unmounted) {
139
- continueRender(newHandle);
140
- return;
141
- }
142
- if (((_d = errors.current[(_a = imageRef.current) === null || _a === void 0 ? void 0 : _a.src]) !== null && _d !== void 0 ? _d : 0) > 0) {
143
- delete errors.current[(_b = imageRef.current) === null || _b === void 0 ? void 0 : _b.src];
144
- // eslint-disable-next-line no-console
145
- console.info(`Retry successful - ${(0, truncate_src_for_label_js_1.truncateSrcForLabel)((_c = imageRef.current) === null || _c === void 0 ? void 0 : _c.src)} is now loaded`);
146
- }
147
- if (current) {
148
- onImageFrame === null || onImageFrame === void 0 ? void 0 : onImageFrame(current);
149
- }
150
- setIsLoading(false);
151
- continueRender(newHandle);
152
- };
153
- if (!imageRef.current) {
154
- onComplete();
155
- return;
156
- }
157
- current.src = actualSrc;
158
- current
159
- .decode()
160
- .then(onComplete)
161
- .catch((err) => {
162
- // fall back to onload event if decode() fails
163
- // eslint-disable-next-line no-console
164
- console.warn(err);
165
- // HTMLImageElement.complete is also true for broken images (e.g. 404),
166
- // so only treat it as loaded if intrinsic dimensions are available.
167
- if (current.complete &&
168
- current.naturalWidth > 0 &&
169
- current.naturalHeight > 0) {
170
- onComplete();
171
- }
172
- else {
173
- current.addEventListener('load', onComplete);
174
- }
175
- });
176
- // If tag gets unmounted, clear pending handles because image is not going to load
177
- return () => {
178
- unmounted = true;
179
- current.removeEventListener('load', onComplete);
180
- continueRender(newHandle);
181
- };
182
- }, [
197
+ // Binding prevents production minification from inlining this scope
198
+ // back into the component and retaining unrelated handlers.
199
+ // eslint-disable-next-line react-hooks/rules-of-hooks, react-hooks/exhaustive-deps
200
+ (0, react_1.useLayoutEffect)(loadImage.bind(null, {
201
+ imageRef,
202
+ errors,
203
+ actualSrc,
204
+ delayRenderRetries: delayRenderRetries !== null && delayRenderRetries !== void 0 ? delayRenderRetries : null,
205
+ delayRenderTimeoutInMilliseconds: delayRenderTimeoutInMilliseconds !== null && delayRenderTimeoutInMilliseconds !== void 0 ? delayRenderTimeoutInMilliseconds : null,
206
+ onImageFrame: onImageFrame !== null && onImageFrame !== void 0 ? onImageFrame : null,
207
+ delayRender,
208
+ continueRender,
209
+ setIsLoading,
210
+ }), [
183
211
  actualSrc,
184
212
  delayRenderRetries,
185
213
  delayRenderTimeoutInMilliseconds,
@@ -197,7 +225,7 @@ const ImgContent = ({ onError, onImageError, maxRetries = 2, src, pauseWhenLoadi
197
225
  // `src` is assigned imperatively to this element in the layout effect above.
198
226
  // The element may paint while `decode()` is pending; `delayRender()` only
199
227
  // blocks frame rendering.
200
- return (jsx_runtime_1.jsx("img", { ...props, ref: imageCallbackRef, crossOrigin: crossOriginValue, onError: didGetError, decoding: isRendering ? 'sync' : decoding }));
228
+ return ((0, jsx_runtime_1.jsx)("img", { ...props, ref: imageCallbackRef, crossOrigin: crossOriginValue, onError: didGetError, decoding: isRendering ? 'sync' : decoding }));
201
229
  };
202
230
  const NativeImgInner = ({ hidden, name, showInTimeline, src, from, trimBefore, loop, durationInFrames, freeze, premountFor, postmountFor, style, styleWhilePremounted, styleWhilePostmounted, cropLeft, cropRight, cropTop, cropBottom, controls, ...props }) => {
203
231
  if (!src) {
@@ -229,7 +257,7 @@ const NativeImgInner = ({ hidden, name, showInTimeline, src, from, trimBefore, l
229
257
  style: premountingStyle,
230
258
  componentName: '<Img />',
231
259
  });
232
- return (jsx_runtime_1.jsx(freeze_js_1.Freeze, { frame: freezeFrame, active: isPremountingOrPostmounting, _remotionInternalIsPremounting: premountingActive, children: jsx_runtime_1.jsx(Sequence_js_1.Sequence, { layout: "none", from: from !== null && from !== void 0 ? from : 0, trimBefore: trimBefore, loop: loop, durationInFrames: durationInFrames, freeze: freeze, _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/img", _remotionInternalIsMedia: isMedia, _remotionInternalPremountDisplay: effectivePremountFor || null, _remotionInternalPostmountDisplay: effectivePostmountFor || null, _remotionInternalIsPremounting: premountingActive, _remotionInternalIsPostmounting: postmountingActive, name: name !== null && name !== void 0 ? name : '<Img>', controls: controls, showInTimeline: showInTimeline !== null && showInTimeline !== void 0 ? showInTimeline : true, hidden: hidden, children: jsx_runtime_1.jsx(sequence_activity_context_js_1.SequenceContent, { children: jsx_runtime_1.jsx(ImgContent, { src: src, style: croppedStyle !== null && croppedStyle !== void 0 ? croppedStyle : undefined, ...props }) }) }) }));
260
+ return ((0, jsx_runtime_1.jsx)(freeze_js_1.Freeze, { frame: freezeFrame, active: isPremountingOrPostmounting, _remotionInternalIsPremounting: premountingActive, children: (0, jsx_runtime_1.jsx)(Sequence_js_1.Sequence, { layout: "none", from: from !== null && from !== void 0 ? from : 0, trimBefore: trimBefore, loop: loop, durationInFrames: durationInFrames, freeze: freeze, _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/img", _remotionInternalIsMedia: isMedia, _remotionInternalPremountDisplay: effectivePremountFor || null, _remotionInternalPostmountDisplay: effectivePostmountFor || null, _remotionInternalIsPremounting: premountingActive, _remotionInternalIsPostmounting: postmountingActive, name: name !== null && name !== void 0 ? name : '<Img>', controls: controls, showInTimeline: showInTimeline !== null && showInTimeline !== void 0 ? showInTimeline : true, hidden: hidden, children: (0, jsx_runtime_1.jsx)(sequence_activity_context_js_1.SequenceContent, { children: (0, jsx_runtime_1.jsx)(ImgContent, { src: src, style: croppedStyle !== null && croppedStyle !== void 0 ? croppedStyle : undefined, ...props }) }) }) }));
233
261
  };
234
262
  const CanvasImageWithPrivateProps = index_js_1.CanvasImage;
235
263
  exports.imgSchema = {
@@ -290,7 +318,7 @@ const ImgInner = ({ effects = [], effectsOutputSize, ref, hidden, name, showInTi
290
318
  var _a;
291
319
  const shouldPauseWhenLoading = (0, v5_flag_js_1.resolveV5Default)(pauseWhenLoading);
292
320
  if (effects.length === 0) {
293
- return (jsx_runtime_1.jsx(NativeImgInner, { ...props, ref: ref, hidden: hidden, name: name, showInTimeline: showInTimeline, src: src, from: from, trimBefore: trimBefore, durationInFrames: durationInFrames, freeze: freeze, premountFor: premountFor, postmountFor: postmountFor, styleWhilePremounted: styleWhilePremounted, styleWhilePostmounted: styleWhilePostmounted, controls: controls, width: width, height: height, className: className, style: style, cropLeft: cropLeft, cropRight: cropRight, cropTop: cropTop, cropBottom: cropBottom, id: id, pauseWhenLoading: shouldPauseWhenLoading, maxRetries: maxRetries, delayRenderRetries: delayRenderRetries, delayRenderTimeoutInMilliseconds: delayRenderTimeoutInMilliseconds, onImageError: onImageError }));
321
+ return ((0, jsx_runtime_1.jsx)(NativeImgInner, { ...props, ref: ref, hidden: hidden, name: name, showInTimeline: showInTimeline, src: src, from: from, trimBefore: trimBefore, durationInFrames: durationInFrames, freeze: freeze, premountFor: premountFor, postmountFor: postmountFor, styleWhilePremounted: styleWhilePremounted, styleWhilePostmounted: styleWhilePostmounted, controls: controls, width: width, height: height, className: className, style: style, cropLeft: cropLeft, cropRight: cropRight, cropTop: cropTop, cropBottom: cropBottom, id: id, pauseWhenLoading: shouldPauseWhenLoading, maxRetries: maxRetries, delayRenderRetries: delayRenderRetries, delayRenderTimeoutInMilliseconds: delayRenderTimeoutInMilliseconds, onImageError: onImageError }));
294
322
  }
295
323
  if (!src) {
296
324
  throw new Error('No "src" prop was passed to <Img>.');
@@ -305,7 +333,7 @@ const ImgInner = ({ effects = [], effectsOutputSize, ref, hidden, name, showInTi
305
333
  const canvasHeight = typeof height === 'number' ? height : undefined;
306
334
  const canvasProps = props;
307
335
  const canvasFit = (_a = getFitFromObjectFit(style)) !== null && _a !== void 0 ? _a : 'fill';
308
- return (jsx_runtime_1.jsx(CanvasImageWithPrivateProps, { src: src, width: canvasWidth, height: canvasHeight, fit: canvasFit, effects: effects, effectsOutputSize: effectsOutputSize, className: className, style: style, cropLeft: cropLeft, cropRight: cropRight, cropTop: cropTop, cropBottom: cropBottom, id: id, onError: onImageError, pauseWhenLoading: shouldPauseWhenLoading, maxRetries: maxRetries, delayRenderRetries: delayRenderRetries, delayRenderTimeoutInMilliseconds: delayRenderTimeoutInMilliseconds, from: from, trimBefore: trimBefore, durationInFrames: durationInFrames, freeze: freeze, premountFor: premountFor, postmountFor: postmountFor, styleWhilePremounted: styleWhilePremounted, styleWhilePostmounted: styleWhilePostmounted, hidden: hidden, name: name !== null && name !== void 0 ? name : '<Img>', showInTimeline: showInTimeline, _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/img", _remotionInternalCropComponentName: "<Img />", controls: controls, ...canvasProps }));
336
+ return ((0, jsx_runtime_1.jsx)(CanvasImageWithPrivateProps, { src: src, width: canvasWidth, height: canvasHeight, fit: canvasFit, effects: effects, effectsOutputSize: effectsOutputSize, className: className, style: style, cropLeft: cropLeft, cropRight: cropRight, cropTop: cropTop, cropBottom: cropBottom, id: id, onError: onImageError, pauseWhenLoading: shouldPauseWhenLoading, maxRetries: maxRetries, delayRenderRetries: delayRenderRetries, delayRenderTimeoutInMilliseconds: delayRenderTimeoutInMilliseconds, from: from, trimBefore: trimBefore, durationInFrames: durationInFrames, freeze: freeze, premountFor: premountFor, postmountFor: postmountFor, styleWhilePremounted: styleWhilePremounted, styleWhilePostmounted: styleWhilePostmounted, hidden: hidden, name: name !== null && name !== void 0 ? name : '<Img>', showInTimeline: showInTimeline, _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/img", _remotionInternalCropComponentName: "<Img />", controls: controls, ...canvasProps }));
309
337
  };
310
338
  /*
311
339
  * @description Works just like a regular HTML img tag. When you use the <Img> tag, Remotion will ensure that the image is loaded before rendering the frame.