remotion 4.0.441 → 4.0.443

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.
@@ -32,27 +32,86 @@ var Clipper = () => {
32
32
  throw new Error("<Clipper> has been removed as of Remotion v4.0.228. The native clipping APIs were experimental and subject to removal at any time. We removed them because they were sparingly used and made rendering often slower rather than faster.");
33
33
  };
34
34
 
35
- // src/enable-sequence-stack-traces.ts
36
- var componentsToAddStacksTo = [];
37
- var getComponentsToAddStacksTo = () => componentsToAddStacksTo;
38
- var addSequenceStackTraces = (component) => {
39
- componentsToAddStacksTo.push(component);
40
- };
35
+ // src/Composition.tsx
36
+ import { Suspense, useContext as useContext9, useEffect as useEffect2 } from "react";
37
+ import { createPortal } from "react-dom";
41
38
 
42
- // src/is-player.tsx
43
- import { createContext as createContext2, useContext } from "react";
39
+ // src/CanUseRemotionHooks.tsx
40
+ import { createContext as createContext2 } from "react";
44
41
  import { jsx } from "react/jsx-runtime";
45
- var IsPlayerContext = createContext2(false);
46
- var IsPlayerContextProvider = ({
47
- children
48
- }) => {
49
- return /* @__PURE__ */ jsx(IsPlayerContext.Provider, {
42
+ var CanUseRemotionHooks = createContext2(false);
43
+ var CanUseRemotionHooksProvider = ({ children }) => {
44
+ return /* @__PURE__ */ jsx(CanUseRemotionHooks.Provider, {
50
45
  value: true,
51
46
  children
52
47
  });
53
48
  };
54
- var useIsPlayer = () => {
55
- return useContext(IsPlayerContext);
49
+
50
+ // src/CompositionManagerContext.tsx
51
+ import { createContext as createContext3 } from "react";
52
+ var CompositionManager = createContext3({
53
+ compositions: [],
54
+ folders: [],
55
+ currentCompositionMetadata: null,
56
+ canvasContent: null
57
+ });
58
+ var CompositionSetters = createContext3({
59
+ registerComposition: () => {
60
+ return;
61
+ },
62
+ unregisterComposition: () => {
63
+ return;
64
+ },
65
+ registerFolder: () => {
66
+ return;
67
+ },
68
+ unregisterFolder: () => {
69
+ return;
70
+ },
71
+ setCanvasContent: () => {
72
+ return;
73
+ },
74
+ onlyRenderComposition: null
75
+ });
76
+
77
+ // src/Folder.tsx
78
+ import { createContext as createContext5, useContext as useContext2, useEffect, useMemo as useMemo2 } from "react";
79
+
80
+ // src/nonce.ts
81
+ import { createContext as createContext4, useCallback, useContext, useMemo, useRef } from "react";
82
+ var NonceContext = createContext4({
83
+ getNonce: () => 0
84
+ });
85
+ var fastRefreshNonce = 0;
86
+ try {
87
+ if (typeof __webpack_module__ !== "undefined") {
88
+ if (__webpack_module__.hot) {
89
+ __webpack_module__.hot.addStatusHandler((status) => {
90
+ if (status === "idle") {
91
+ fastRefreshNonce++;
92
+ }
93
+ });
94
+ }
95
+ }
96
+ } catch {}
97
+ var useNonce = () => {
98
+ const context = useContext(NonceContext);
99
+ const nonce = context.getNonce();
100
+ const nonceRef = useRef(nonce);
101
+ nonceRef.current = nonce;
102
+ const history = useRef([[fastRefreshNonce, nonce]]);
103
+ const get = useCallback(() => {
104
+ if (fastRefreshNonce !== history.current[history.current.length - 1][0]) {
105
+ history.current = [
106
+ ...history.current,
107
+ [fastRefreshNonce, nonceRef.current]
108
+ ];
109
+ }
110
+ return history.current;
111
+ }, [history]);
112
+ return useMemo(() => {
113
+ return { get };
114
+ }, [get]);
56
115
  };
57
116
 
58
117
  // src/truthy.ts
@@ -60,55 +119,163 @@ function truthy(value) {
60
119
  return Boolean(value);
61
120
  }
62
121
 
63
- // src/version.ts
64
- var VERSION = "4.0.441";
65
-
66
- // src/multiple-versions-warning.ts
67
- var checkMultipleRemotionVersions = () => {
68
- if (typeof globalThis === "undefined") {
69
- return;
122
+ // src/validation/validate-folder-name.ts
123
+ var getRegex = () => /^([a-zA-Z0-9-\u4E00-\u9FFF])+$/g;
124
+ var isFolderNameValid = (name) => name.match(getRegex());
125
+ var validateFolderName = (name) => {
126
+ if (name === undefined || name === null) {
127
+ throw new TypeError("You must pass a name to a <Folder />.");
70
128
  }
71
- const set = () => {
72
- globalThis.remotion_imported = VERSION;
73
- if (typeof window !== "undefined") {
74
- window.remotion_imported = VERSION;
75
- }
129
+ if (typeof name !== "string") {
130
+ throw new TypeError(`The "name" you pass into <Folder /> must be a string. Got: ${typeof name}`);
131
+ }
132
+ if (!isFolderNameValid(name)) {
133
+ throw new Error(`Folder name can only contain a-z, A-Z, 0-9 and -. You passed ${name}`);
134
+ }
135
+ };
136
+ var invalidFolderNameErrorMessage = `Folder name must match ${String(getRegex())}`;
137
+
138
+ // src/Folder.tsx
139
+ import { jsx as jsx2 } from "react/jsx-runtime";
140
+ var FolderContext = createContext5({
141
+ folderName: null,
142
+ parentName: null
143
+ });
144
+ var Folder = ({ name, children }) => {
145
+ const parent = useContext2(FolderContext);
146
+ const { registerFolder, unregisterFolder } = useContext2(CompositionSetters);
147
+ const nonce = useNonce();
148
+ validateFolderName(name);
149
+ const parentNameArr = [parent.parentName, parent.folderName].filter(truthy);
150
+ const parentName = parentNameArr.length === 0 ? null : parentNameArr.join("/");
151
+ const value = useMemo2(() => {
152
+ return {
153
+ folderName: name,
154
+ parentName
155
+ };
156
+ }, [name, parentName]);
157
+ useEffect(() => {
158
+ registerFolder(name, parentName, nonce.get());
159
+ return () => {
160
+ unregisterFolder(name, parentName);
161
+ };
162
+ }, [
163
+ name,
164
+ parent.folderName,
165
+ parentName,
166
+ registerFolder,
167
+ unregisterFolder,
168
+ nonce
169
+ ]);
170
+ return /* @__PURE__ */ jsx2(FolderContext.Provider, {
171
+ value,
172
+ children
173
+ });
174
+ };
175
+
176
+ // src/get-remotion-environment.ts
177
+ function getNodeEnvString() {
178
+ return ["NOD", "E_EN", "V"].join("");
179
+ }
180
+ var getEnvString = () => {
181
+ return ["e", "nv"].join("");
182
+ };
183
+ var getRemotionEnvironment = () => {
184
+ const isPlayer = typeof window !== "undefined" && window.remotion_isPlayer;
185
+ const isRendering = typeof window !== "undefined" && typeof window.process !== "undefined" && typeof window.process.env !== "undefined" && (window.process[getEnvString()][getNodeEnvString()] === "test" || window.process[getEnvString()][getNodeEnvString()] === "production" && typeof window !== "undefined" && typeof window.remotion_puppeteerTimeout !== "undefined");
186
+ const isStudio = typeof window !== "undefined" && window.remotion_isStudio;
187
+ const isReadOnlyStudio = typeof window !== "undefined" && window.remotion_isReadOnlyStudio;
188
+ return {
189
+ isStudio,
190
+ isRendering,
191
+ isPlayer,
192
+ isReadOnlyStudio,
193
+ isClientSideRendering: false
76
194
  };
77
- const alreadyImported = globalThis.remotion_imported || typeof window !== "undefined" && window.remotion_imported;
78
- if (alreadyImported) {
79
- if (alreadyImported === VERSION) {
80
- return;
195
+ };
196
+
197
+ // src/input-props-serialization.ts
198
+ var DATE_TOKEN = "remotion-date:";
199
+ var FILE_TOKEN = "remotion-file:";
200
+ var serializeJSONWithSpecialTypes = ({
201
+ data,
202
+ indent,
203
+ staticBase
204
+ }) => {
205
+ let customDateUsed = false;
206
+ let customFileUsed = false;
207
+ let mapUsed = false;
208
+ let setUsed = false;
209
+ try {
210
+ const serializedString = JSON.stringify(data, function(key, value) {
211
+ const item = this[key];
212
+ if (item instanceof Date) {
213
+ customDateUsed = true;
214
+ return `${DATE_TOKEN}${item.toISOString()}`;
215
+ }
216
+ if (item instanceof Map) {
217
+ mapUsed = true;
218
+ return value;
219
+ }
220
+ if (item instanceof Set) {
221
+ setUsed = true;
222
+ return value;
223
+ }
224
+ if (typeof item === "string" && staticBase !== null && item.startsWith(staticBase)) {
225
+ customFileUsed = true;
226
+ return `${FILE_TOKEN}${item.replace(staticBase + "/", "")}`;
227
+ }
228
+ return value;
229
+ }, indent);
230
+ return { serializedString, customDateUsed, customFileUsed, mapUsed, setUsed };
231
+ } catch (err) {
232
+ throw new Error("Could not serialize the passed input props to JSON: " + err.message);
233
+ }
234
+ };
235
+ var deserializeJSONWithSpecialTypes = (data) => {
236
+ return JSON.parse(data, (_, value) => {
237
+ if (typeof value === "string" && value.startsWith(DATE_TOKEN)) {
238
+ return new Date(value.replace(DATE_TOKEN, ""));
81
239
  }
82
- if (typeof alreadyImported === "string" && alreadyImported.includes("webcodecs")) {
83
- set();
84
- return;
240
+ if (typeof value === "string" && value.startsWith(FILE_TOKEN)) {
241
+ return `${window.remotion_staticBase}/${value.replace(FILE_TOKEN, "")}`;
85
242
  }
86
- throw new TypeError(`\uD83D\uDEA8 Multiple versions of Remotion detected: ${[
87
- VERSION,
88
- typeof alreadyImported === "string" ? alreadyImported : "an older version"
89
- ].filter(truthy).join(" and ")}. This will cause things to break in an unexpected way.
90
- Check that all your Remotion packages are on the same version. If your dependencies depend on Remotion, make them peer dependencies. You can also run \`npx remotion versions\` from your terminal to see which versions are mismatching.`);
243
+ return value;
244
+ });
245
+ };
246
+ var serializeThenDeserialize = (props) => {
247
+ return deserializeJSONWithSpecialTypes(serializeJSONWithSpecialTypes({
248
+ data: props,
249
+ indent: 2,
250
+ staticBase: window.remotion_staticBase
251
+ }).serializedString);
252
+ };
253
+ var serializeThenDeserializeInStudio = (props) => {
254
+ if (getRemotionEnvironment().isStudio) {
255
+ return serializeThenDeserialize(props);
91
256
  }
92
- set();
257
+ return props;
93
258
  };
94
259
 
95
- // src/Null.tsx
96
- var Null = () => {
97
- throw new Error("<Null> has been removed as of Remotion v4.0.228. The native clipping APIs were experimental and subject to removal at any time. We removed them because they were sparingly used and made rendering often slower rather than faster.");
260
+ // src/is-player.tsx
261
+ import { createContext as createContext6, useContext as useContext3 } from "react";
262
+ import { jsx as jsx3 } from "react/jsx-runtime";
263
+ var IsPlayerContext = createContext6(false);
264
+ var IsPlayerContextProvider = ({
265
+ children
266
+ }) => {
267
+ return /* @__PURE__ */ jsx3(IsPlayerContext.Provider, {
268
+ value: true,
269
+ children
270
+ });
271
+ };
272
+ var useIsPlayer = () => {
273
+ return useContext3(IsPlayerContext);
98
274
  };
99
-
100
- // src/Sequence.tsx
101
- import {
102
- forwardRef as forwardRef2,
103
- useContext as useContext13,
104
- useEffect,
105
- useMemo as useMemo11,
106
- useState as useState4
107
- } from "react";
108
275
 
109
276
  // src/AbsoluteFill.tsx
110
- import { forwardRef, useMemo } from "react";
111
- import { jsx as jsx2 } from "react/jsx-runtime";
277
+ import { forwardRef, useMemo as useMemo3 } from "react";
278
+ import { jsx as jsx4 } from "react/jsx-runtime";
112
279
  var hasTailwindClassName = ({
113
280
  className,
114
281
  classPrefix,
@@ -131,7 +298,7 @@ var hasTailwindClassName = ({
131
298
  };
132
299
  var AbsoluteFillRefForwarding = (props, ref) => {
133
300
  const { style, ...other } = props;
134
- const actualStyle = useMemo(() => {
301
+ const actualStyle = useMemo3(() => {
135
302
  return {
136
303
  position: "absolute",
137
304
  top: hasTailwindClassName({
@@ -194,7 +361,7 @@ var AbsoluteFillRefForwarding = (props, ref) => {
194
361
  ...style
195
362
  };
196
363
  }, [other.className, style]);
197
- return /* @__PURE__ */ jsx2("div", {
364
+ return /* @__PURE__ */ jsx4("div", {
198
365
  ref,
199
366
  style: actualStyle,
200
367
  ...other
@@ -202,114 +369,379 @@ var AbsoluteFillRefForwarding = (props, ref) => {
202
369
  };
203
370
  var AbsoluteFill = forwardRef(AbsoluteFillRefForwarding);
204
371
 
205
- // src/freeze.tsx
206
- import { useContext as useContext11, useMemo as useMemo8 } from "react";
207
-
208
- // src/SequenceContext.tsx
209
- import { createContext as createContext3 } from "react";
210
- var SequenceContext = createContext3(null);
211
-
212
- // src/timeline-position-state.ts
213
- var exports_timeline_position_state = {};
214
- __export(exports_timeline_position_state, {
215
- useTimelineSetFrame: () => useTimelineSetFrame,
216
- useTimelinePosition: () => useTimelinePosition,
217
- useTimelineContext: () => useTimelineContext,
218
- usePlayingState: () => usePlayingState,
219
- useAbsoluteTimelinePosition: () => useAbsoluteTimelinePosition,
220
- persistCurrentFrame: () => persistCurrentFrame,
221
- getInitialFrameState: () => getInitialFrameState,
222
- getFrameForComposition: () => getFrameForComposition
223
- });
224
- import { useContext as useContext7, useMemo as useMemo6 } from "react";
372
+ // src/loading-indicator.tsx
373
+ import { jsx as jsx5, jsxs } from "react/jsx-runtime";
374
+ var rotate = {
375
+ transform: `rotate(90deg)`
376
+ };
377
+ var ICON_SIZE = 40;
378
+ var label = {
379
+ color: "white",
380
+ fontSize: 14,
381
+ fontFamily: "sans-serif"
382
+ };
383
+ var container = {
384
+ justifyContent: "center",
385
+ alignItems: "center"
386
+ };
387
+ var Loading = () => {
388
+ return /* @__PURE__ */ jsxs(AbsoluteFill, {
389
+ style: container,
390
+ id: "remotion-comp-loading",
391
+ children: [
392
+ /* @__PURE__ */ jsx5("style", {
393
+ type: "text/css",
394
+ children: `
395
+ @keyframes anim {
396
+ from {
397
+ opacity: 0
398
+ }
399
+ to {
400
+ opacity: 1
401
+ }
402
+ }
403
+ #remotion-comp-loading {
404
+ animation: anim 2s;
405
+ animation-fill-mode: forwards;
406
+ }
407
+ `
408
+ }),
409
+ /* @__PURE__ */ jsx5("svg", {
410
+ width: ICON_SIZE,
411
+ height: ICON_SIZE,
412
+ viewBox: "-100 -100 400 400",
413
+ style: rotate,
414
+ children: /* @__PURE__ */ jsx5("path", {
415
+ fill: "#555",
416
+ stroke: "#555",
417
+ strokeWidth: "100",
418
+ strokeLinejoin: "round",
419
+ d: "M 2 172 a 196 100 0 0 0 195 5 A 196 240 0 0 0 100 2.259 A 196 240 0 0 0 2 172 z"
420
+ })
421
+ }),
422
+ /* @__PURE__ */ jsxs("p", {
423
+ style: label,
424
+ children: [
425
+ "Resolving ",
426
+ "<Suspense>",
427
+ "..."
428
+ ]
429
+ })
430
+ ]
431
+ });
432
+ };
225
433
 
226
- // src/TimelineContext.tsx
227
- import {
228
- createContext as createContext6,
229
- useLayoutEffect,
230
- useMemo as useMemo2,
231
- useRef,
232
- useState as useState2
233
- } from "react";
434
+ // src/portal-node.ts
435
+ var _portalNode = null;
436
+ var portalNode = () => {
437
+ if (!_portalNode) {
438
+ if (typeof document === "undefined") {
439
+ throw new Error("Tried to call an API that only works in the browser from outside the browser");
440
+ }
441
+ _portalNode = document.createElement("div");
442
+ _portalNode.style.position = "absolute";
443
+ _portalNode.style.top = "0px";
444
+ _portalNode.style.left = "0px";
445
+ _portalNode.style.right = "0px";
446
+ _portalNode.style.bottom = "0px";
447
+ _portalNode.style.width = "100%";
448
+ _portalNode.style.height = "100%";
449
+ _portalNode.style.display = "flex";
450
+ _portalNode.style.flexDirection = "column";
451
+ const containerNode = document.createElement("div");
452
+ containerNode.style.position = "fixed";
453
+ containerNode.style.top = -999999 + "px";
454
+ containerNode.appendChild(_portalNode);
455
+ document.body.appendChild(containerNode);
456
+ }
457
+ return _portalNode;
458
+ };
234
459
 
235
- // src/random.ts
236
- function mulberry32(a) {
237
- let t = a + 1831565813;
238
- t = Math.imul(t ^ t >>> 15, t | 1);
239
- t ^= t + Math.imul(t ^ t >>> 7, t | 61);
240
- return ((t ^ t >>> 14) >>> 0) / 4294967296;
241
- }
242
- function hashCode(str) {
243
- let i = 0;
244
- let chr = 0;
245
- let hash = 0;
246
- for (i = 0;i < str.length; i++) {
247
- chr = str.charCodeAt(i);
248
- hash = (hash << 5) - hash + chr;
249
- hash |= 0;
460
+ // src/ResolveCompositionConfig.tsx
461
+ import { createContext as createContext8, createRef, useContext as useContext5, useMemo as useMemo5 } from "react";
462
+
463
+ // src/input-props-override.ts
464
+ var getKey = () => {
465
+ return `remotion_inputPropsOverride` + window.location.origin;
466
+ };
467
+ var getInputPropsOverride = () => {
468
+ if (typeof localStorage === "undefined")
469
+ return null;
470
+ const override = localStorage.getItem(getKey());
471
+ if (!override)
472
+ return null;
473
+ return JSON.parse(override);
474
+ };
475
+ var setInputPropsOverride = (override) => {
476
+ if (typeof localStorage === "undefined")
477
+ return;
478
+ if (override === null) {
479
+ localStorage.removeItem(getKey());
480
+ return;
250
481
  }
251
- return hash;
252
- }
253
- var random = (seed, dummy) => {
254
- if (dummy !== undefined) {
255
- throw new TypeError("random() takes only one argument");
482
+ localStorage.setItem(getKey(), JSON.stringify(override));
483
+ };
484
+
485
+ // src/config/input-props.ts
486
+ var didWarnSSRImport = false;
487
+ var warnOnceSSRImport = () => {
488
+ if (didWarnSSRImport) {
489
+ return;
256
490
  }
257
- if (seed === null) {
258
- return Math.random();
491
+ didWarnSSRImport = true;
492
+ console.warn("Called `getInputProps()` on the server. This function is not available server-side and has returned an empty object.");
493
+ console.warn("To hide this warning, don't call this function on the server:");
494
+ console.warn(" typeof window === 'undefined' ? {} : getInputProps()");
495
+ };
496
+ var getInputProps = () => {
497
+ if (typeof window === "undefined") {
498
+ warnOnceSSRImport();
499
+ return {};
259
500
  }
260
- if (typeof seed === "string") {
261
- return mulberry32(hashCode(seed));
501
+ if (getRemotionEnvironment().isPlayer) {
502
+ throw new Error("You cannot call `getInputProps()` from a <Player>. Instead, the props are available as React props from component that you passed as `component` prop.");
262
503
  }
263
- if (typeof seed === "number") {
264
- return mulberry32(seed * 10000000000);
504
+ const override = getInputPropsOverride();
505
+ if (override) {
506
+ return override;
265
507
  }
266
- throw new Error("random() argument must be a number or a string");
508
+ if (typeof window === "undefined" || typeof window.remotion_inputProps === "undefined") {
509
+ throw new Error("Cannot call `getInputProps()` - window.remotion_inputProps is not set. This API is only available if you are in the Studio, or while you are rendering server-side.");
510
+ }
511
+ const param = window.remotion_inputProps;
512
+ if (!param) {
513
+ return {};
514
+ }
515
+ const parsed = deserializeJSONWithSpecialTypes(param);
516
+ return parsed;
267
517
  };
268
518
 
269
- // src/use-delay-render.tsx
270
- import { createContext as createContext5, useCallback, useContext as useContext4 } from "react";
519
+ // src/EditorProps.tsx
520
+ import React3, { createContext as createContext7, useCallback as useCallback2, useMemo as useMemo4 } from "react";
521
+ import { jsx as jsx6 } from "react/jsx-runtime";
522
+ var EditorPropsContext = createContext7({
523
+ props: {},
524
+ updateProps: () => {
525
+ throw new Error("Not implemented");
526
+ }
527
+ });
528
+ var timeValueRef = React3.createRef();
529
+ var EditorPropsProvider = ({ children }) => {
530
+ const [props, setProps] = React3.useState({});
531
+ const updateProps = useCallback2(({
532
+ defaultProps,
533
+ id,
534
+ newProps
535
+ }) => {
536
+ setProps((prev) => {
537
+ return {
538
+ ...prev,
539
+ [id]: typeof newProps === "function" ? newProps(prev[id] ?? defaultProps) : newProps
540
+ };
541
+ });
542
+ }, []);
543
+ const ctx = useMemo4(() => {
544
+ return { props, updateProps };
545
+ }, [props, updateProps]);
546
+ return /* @__PURE__ */ jsx6(EditorPropsContext.Provider, {
547
+ value: ctx,
548
+ children
549
+ });
550
+ };
271
551
 
272
- // src/cancel-render.ts
273
- var getErrorStackWithMessage = (error) => {
274
- const stack = error.stack ?? "";
275
- return stack.startsWith("Error:") ? stack : `${error.message}
276
- ${stack}`;
552
+ // src/use-remotion-environment.ts
553
+ import { useContext as useContext4, useState } from "react";
554
+
555
+ // src/remotion-environment-context.ts
556
+ import React4 from "react";
557
+ var RemotionEnvironmentContext = React4.createContext(null);
558
+
559
+ // src/use-remotion-environment.ts
560
+ var useRemotionEnvironment = () => {
561
+ const context = useContext4(RemotionEnvironmentContext);
562
+ const [env] = useState(() => getRemotionEnvironment());
563
+ return context ?? env;
277
564
  };
278
- var isErrorLike = (err) => {
279
- if (err instanceof Error) {
280
- return true;
565
+
566
+ // src/validation/validate-dimensions.ts
567
+ function validateDimension(amount, nameOfProp, location) {
568
+ if (typeof amount !== "number") {
569
+ throw new Error(`The "${nameOfProp}" prop ${location} must be a number, but you passed a value of type ${typeof amount}`);
281
570
  }
282
- if (err === null) {
283
- return false;
571
+ if (isNaN(amount)) {
572
+ throw new TypeError(`The "${nameOfProp}" prop ${location} must not be NaN, but is NaN.`);
284
573
  }
285
- if (typeof err !== "object") {
286
- return false;
574
+ if (!Number.isFinite(amount)) {
575
+ throw new TypeError(`The "${nameOfProp}" prop ${location} must be finite, but is ${amount}.`);
287
576
  }
288
- if (!("stack" in err)) {
289
- return false;
577
+ if (amount % 1 !== 0) {
578
+ throw new TypeError(`The "${nameOfProp}" prop ${location} must be an integer, but is ${amount}.`);
290
579
  }
291
- if (typeof err.stack !== "string") {
292
- return false;
580
+ if (amount <= 0) {
581
+ throw new TypeError(`The "${nameOfProp}" prop ${location} must be positive, but got ${amount}.`);
293
582
  }
294
- if (!("message" in err)) {
295
- return false;
583
+ }
584
+
585
+ // src/validation/validate-duration-in-frames.ts
586
+ function validateDurationInFrames(durationInFrames, options) {
587
+ const { allowFloats, component } = options;
588
+ if (typeof durationInFrames === "undefined") {
589
+ throw new Error(`The "durationInFrames" prop ${component} is missing.`);
296
590
  }
297
- if (typeof err.message !== "string") {
298
- return false;
591
+ if (typeof durationInFrames !== "number") {
592
+ throw new Error(`The "durationInFrames" prop ${component} must be a number, but you passed a value of type ${typeof durationInFrames}`);
299
593
  }
300
- return true;
301
- };
302
- function cancelRenderInternal(scope, err) {
303
- let error;
304
- if (isErrorLike(err)) {
305
- error = err;
306
- if (!error.stack) {
307
- error.stack = new Error(error.message).stack;
308
- }
309
- } else if (typeof err === "string") {
310
- error = Error(err);
311
- } else {
312
- error = Error("Rendering was cancelled");
594
+ if (durationInFrames <= 0) {
595
+ throw new TypeError(`The "durationInFrames" prop ${component} must be positive, but got ${durationInFrames}.`);
596
+ }
597
+ if (!allowFloats && durationInFrames % 1 !== 0) {
598
+ throw new TypeError(`The "durationInFrames" prop ${component} must be an integer, but got ${durationInFrames}.`);
599
+ }
600
+ if (!Number.isFinite(durationInFrames)) {
601
+ throw new TypeError(`The "durationInFrames" prop ${component} must be finite, but got ${durationInFrames}.`);
602
+ }
603
+ }
604
+
605
+ // src/validation/validate-fps.ts
606
+ function validateFps(fps, location, isGif) {
607
+ if (typeof fps !== "number") {
608
+ throw new Error(`"fps" must be a number, but you passed a value of type ${typeof fps} ${location}`);
609
+ }
610
+ if (!Number.isFinite(fps)) {
611
+ throw new Error(`"fps" must be a finite, but you passed ${fps} ${location}`);
612
+ }
613
+ if (isNaN(fps)) {
614
+ throw new Error(`"fps" must not be NaN, but got ${fps} ${location}`);
615
+ }
616
+ if (fps <= 0) {
617
+ throw new TypeError(`"fps" must be positive, but got ${fps} ${location}`);
618
+ }
619
+ if (isGif && fps > 50) {
620
+ throw new TypeError(`The FPS for a GIF cannot be higher than 50. Use the --every-nth-frame option to lower the FPS: https://remotion.dev/docs/render-as-gif`);
621
+ }
622
+ }
623
+
624
+ // src/ResolveCompositionConfig.tsx
625
+ var ResolveCompositionContext = createContext8(null);
626
+ var resolveCompositionsRef = createRef();
627
+ var needsResolution = (composition) => {
628
+ return Boolean(composition.calculateMetadata);
629
+ };
630
+ var useResolvedVideoConfig = (preferredCompositionId) => {
631
+ const context = useContext5(ResolveCompositionContext);
632
+ const { props: allEditorProps } = useContext5(EditorPropsContext);
633
+ const { compositions, canvasContent, currentCompositionMetadata } = useContext5(CompositionManager);
634
+ const currentComposition = canvasContent?.type === "composition" ? canvasContent.compositionId : null;
635
+ const compositionId = preferredCompositionId ?? currentComposition;
636
+ const composition = compositions.find((c) => c.id === compositionId);
637
+ const selectedEditorProps = useMemo5(() => {
638
+ return composition ? allEditorProps[composition.id] ?? {} : {};
639
+ }, [allEditorProps, composition]);
640
+ const env = useRemotionEnvironment();
641
+ return useMemo5(() => {
642
+ if (!composition) {
643
+ return null;
644
+ }
645
+ if (currentCompositionMetadata) {
646
+ return {
647
+ type: "success",
648
+ result: {
649
+ ...currentCompositionMetadata,
650
+ id: composition.id,
651
+ defaultProps: composition.defaultProps ?? {}
652
+ }
653
+ };
654
+ }
655
+ if (!needsResolution(composition)) {
656
+ validateDurationInFrames(composition.durationInFrames, {
657
+ allowFloats: false,
658
+ component: `in <Composition id="${composition.id}">`
659
+ });
660
+ validateFps(composition.fps, `in <Composition id="${composition.id}">`, false);
661
+ validateDimension(composition.width, "width", `in <Composition id="${composition.id}">`);
662
+ validateDimension(composition.height, "height", `in <Composition id="${composition.id}">`);
663
+ return {
664
+ type: "success",
665
+ result: {
666
+ width: composition.width,
667
+ height: composition.height,
668
+ fps: composition.fps,
669
+ id: composition.id,
670
+ durationInFrames: composition.durationInFrames,
671
+ defaultProps: composition.defaultProps ?? {},
672
+ props: {
673
+ ...composition.defaultProps ?? {},
674
+ ...selectedEditorProps ?? {},
675
+ ...typeof window === "undefined" || env.isPlayer || !window.remotion_inputProps ? {} : getInputProps() ?? {}
676
+ },
677
+ defaultCodec: null,
678
+ defaultOutName: null,
679
+ defaultVideoImageFormat: null,
680
+ defaultPixelFormat: null,
681
+ defaultProResProfile: null
682
+ }
683
+ };
684
+ }
685
+ if (!context) {
686
+ return null;
687
+ }
688
+ if (!context[composition.id]) {
689
+ return null;
690
+ }
691
+ return context[composition.id];
692
+ }, [
693
+ composition,
694
+ context,
695
+ currentCompositionMetadata,
696
+ selectedEditorProps,
697
+ env.isPlayer
698
+ ]);
699
+ };
700
+
701
+ // src/use-delay-render.tsx
702
+ import { createContext as createContext10, useCallback as useCallback3, useContext as useContext7 } from "react";
703
+
704
+ // src/cancel-render.ts
705
+ var getErrorStackWithMessage = (error) => {
706
+ const stack = error.stack ?? "";
707
+ return stack.startsWith("Error:") ? stack : `${error.message}
708
+ ${stack}`;
709
+ };
710
+ var isErrorLike = (err) => {
711
+ if (err instanceof Error) {
712
+ return true;
713
+ }
714
+ if (err === null) {
715
+ return false;
716
+ }
717
+ if (typeof err !== "object") {
718
+ return false;
719
+ }
720
+ if (!("stack" in err)) {
721
+ return false;
722
+ }
723
+ if (typeof err.stack !== "string") {
724
+ return false;
725
+ }
726
+ if (!("message" in err)) {
727
+ return false;
728
+ }
729
+ if (typeof err.message !== "string") {
730
+ return false;
731
+ }
732
+ return true;
733
+ };
734
+ function cancelRenderInternal(scope, err) {
735
+ let error;
736
+ if (isErrorLike(err)) {
737
+ error = err;
738
+ if (!error.stack) {
739
+ error.stack = new Error(error.message).stack;
740
+ }
741
+ } else if (typeof err === "string") {
742
+ error = Error(err);
743
+ } else {
744
+ error = Error("Rendering was cancelled");
313
745
  }
314
746
  if (scope) {
315
747
  scope.remotion_cancelledError = getErrorStackWithMessage(error);
@@ -320,27 +752,6 @@ function cancelRender(err) {
320
752
  return cancelRenderInternal(typeof window !== "undefined" ? window : undefined, err);
321
753
  }
322
754
 
323
- // src/get-remotion-environment.ts
324
- function getNodeEnvString() {
325
- return ["NOD", "E_EN", "V"].join("");
326
- }
327
- var getEnvString = () => {
328
- return ["e", "nv"].join("");
329
- };
330
- var getRemotionEnvironment = () => {
331
- const isPlayer = typeof window !== "undefined" && window.remotion_isPlayer;
332
- const isRendering = typeof window !== "undefined" && typeof window.process !== "undefined" && typeof window.process.env !== "undefined" && (window.process[getEnvString()][getNodeEnvString()] === "test" || window.process[getEnvString()][getNodeEnvString()] === "production" && typeof window !== "undefined" && typeof window.remotion_puppeteerTimeout !== "undefined");
333
- const isStudio = typeof window !== "undefined" && window.remotion_isStudio;
334
- const isReadOnlyStudio = typeof window !== "undefined" && window.remotion_isReadOnlyStudio;
335
- return {
336
- isStudio,
337
- isRendering,
338
- isPlayer,
339
- isReadOnlyStudio,
340
- isClientSideRendering: false
341
- };
342
- };
343
-
344
755
  // src/log.ts
345
756
  var logLevels = ["trace", "verbose", "info", "warn", "error"];
346
757
  var getNumberForLogLevel = (level) => {
@@ -410,11 +821,11 @@ var defaultTimeout = 30000;
410
821
  var delayRenderInternal = ({
411
822
  scope,
412
823
  environment,
413
- label,
824
+ label: label2,
414
825
  options
415
826
  }) => {
416
- if (typeof label !== "string" && label !== null) {
417
- throw new Error("The label parameter of delayRender() must be a string or undefined, got: " + JSON.stringify(label));
827
+ if (typeof label2 !== "string" && label2 !== null) {
828
+ throw new Error("The label parameter of delayRender() must be a string or undefined, got: " + JSON.stringify(label2));
418
829
  }
419
830
  const handle = Math.random();
420
831
  scope.remotion_delayRenderHandles.push(handle);
@@ -423,12 +834,12 @@ var delayRenderInternal = ({
423
834
  const timeoutToUse = (options?.timeoutInMilliseconds ?? scope.remotion_puppeteerTimeout ?? defaultTimeout) - 2000;
424
835
  const retriesLeft = (options?.retries ?? 0) - (scope.remotion_attempt - 1);
425
836
  scope.remotion_delayRenderTimeouts[handle] = {
426
- label: label ?? null,
837
+ label: label2 ?? null,
427
838
  startTime: Date.now(),
428
839
  timeout: setTimeout(() => {
429
840
  const message = [
430
841
  `A delayRender()`,
431
- label ? `"${label}"` : null,
842
+ label2 ? `"${label2}"` : null,
432
843
  `was called but not cleared after ${timeoutToUse}ms. See https://remotion.dev/docs/timeout for help.`,
433
844
  retriesLeft > 0 ? DELAY_RENDER_RETRIES_LEFT + retriesLeft : null,
434
845
  retriesLeft > 0 ? DELAY_RENDER_RETRY_TOKEN : null,
@@ -446,14 +857,14 @@ var delayRenderInternal = ({
446
857
  scope.remotion_renderReady = false;
447
858
  return handle;
448
859
  };
449
- var delayRender = (label, options) => {
860
+ var delayRender = (label2, options) => {
450
861
  if (typeof window === "undefined") {
451
862
  return Math.random();
452
863
  }
453
864
  return delayRenderInternal({
454
865
  scope: window,
455
866
  environment: getRemotionEnvironment(),
456
- label: label ?? null,
867
+ label: label2 ?? null,
457
868
  options: options ?? {}
458
869
  });
459
870
  };
@@ -475,10 +886,10 @@ var continueRenderInternal = ({
475
886
  if (!scope.remotion_delayRenderTimeouts[handle]) {
476
887
  return false;
477
888
  }
478
- const { label, startTime, timeout } = scope.remotion_delayRenderTimeouts[handle];
889
+ const { label: label2, startTime, timeout } = scope.remotion_delayRenderTimeouts[handle];
479
890
  clearTimeout(timeout);
480
891
  const message = [
481
- label ? `"${label}"` : "A handle",
892
+ label2 ? `"${label2}"` : "A handle",
482
893
  DELAY_RENDER_CLEAR_TOKEN,
483
894
  `${Date.now() - startTime}ms`
484
895
  ].filter(truthy).join(" ");
@@ -506,59 +917,45 @@ var continueRender = (handle) => {
506
917
  };
507
918
 
508
919
  // src/log-level-context.tsx
509
- import { createContext as createContext4 } from "react";
510
- import * as React2 from "react";
511
- var LogLevelContext = createContext4({
920
+ import { createContext as createContext9 } from "react";
921
+ import * as React5 from "react";
922
+ var LogLevelContext = createContext9({
512
923
  logLevel: "info",
513
924
  mountTime: 0
514
925
  });
515
926
  var useLogLevel = () => {
516
- const { logLevel } = React2.useContext(LogLevelContext);
927
+ const { logLevel } = React5.useContext(LogLevelContext);
517
928
  if (logLevel === null) {
518
929
  throw new Error("useLogLevel must be used within a LogLevelProvider");
519
930
  }
520
931
  return logLevel;
521
932
  };
522
933
  var useMountTime = () => {
523
- const { mountTime } = React2.useContext(LogLevelContext);
934
+ const { mountTime } = React5.useContext(LogLevelContext);
524
935
  if (mountTime === null) {
525
936
  throw new Error("useMountTime must be used within a LogLevelProvider");
526
937
  }
527
938
  return mountTime;
528
939
  };
529
940
 
530
- // src/use-remotion-environment.ts
531
- import { useContext as useContext3, useState } from "react";
532
-
533
- // src/remotion-environment-context.ts
534
- import React3 from "react";
535
- var RemotionEnvironmentContext = React3.createContext(null);
536
-
537
- // src/use-remotion-environment.ts
538
- var useRemotionEnvironment = () => {
539
- const context = useContext3(RemotionEnvironmentContext);
540
- const [env] = useState(() => getRemotionEnvironment());
541
- return context ?? env;
542
- };
543
-
544
941
  // src/use-delay-render.tsx
545
- var DelayRenderContextType = createContext5(null);
942
+ var DelayRenderContextType = createContext10(null);
546
943
  var useDelayRender = () => {
547
944
  const environment = useRemotionEnvironment();
548
- const scope = useContext4(DelayRenderContextType) ?? (typeof window !== "undefined" ? window : undefined);
945
+ const scope = useContext7(DelayRenderContextType) ?? (typeof window !== "undefined" ? window : undefined);
549
946
  const logLevel = useLogLevel();
550
- const delayRender2 = useCallback((label, options) => {
947
+ const delayRender2 = useCallback3((label2, options) => {
551
948
  if (!scope) {
552
949
  return Math.random();
553
950
  }
554
951
  return delayRenderInternal({
555
952
  scope,
556
953
  environment,
557
- label: label ?? null,
954
+ label: label2 ?? null,
558
955
  options: options ?? {}
559
956
  });
560
957
  }, [environment, scope]);
561
- const continueRender2 = useCallback((handle) => {
958
+ const continueRender2 = useCallback3((handle) => {
562
959
  if (!scope) {
563
960
  return;
564
961
  }
@@ -569,515 +966,484 @@ var useDelayRender = () => {
569
966
  logLevel
570
967
  });
571
968
  }, [environment, logLevel, scope]);
572
- const cancelRender2 = useCallback((err) => {
969
+ const cancelRender2 = useCallback3((err) => {
573
970
  return cancelRenderInternal(scope ?? (typeof window !== "undefined" ? window : undefined), err);
574
971
  }, [scope]);
575
972
  return { delayRender: delayRender2, continueRender: continueRender2, cancelRender: cancelRender2 };
576
973
  };
577
974
 
578
- // src/TimelineContext.tsx
579
- import { jsx as jsx3 } from "react/jsx-runtime";
580
- var SetTimelineContext = createContext6({
581
- setFrame: () => {
582
- throw new Error("default");
583
- },
584
- setPlaying: () => {
585
- throw new Error("default");
975
+ // src/use-lazy-component.ts
976
+ import React6, { useMemo as useMemo6, useRef as useRef2 } from "react";
977
+ var useLazyComponent = ({
978
+ compProps,
979
+ componentName,
980
+ noSuspense
981
+ }) => {
982
+ const componentRef = useRef2(null);
983
+ if ("component" in compProps) {
984
+ componentRef.current = compProps.component;
586
985
  }
587
- });
588
- var TimelineContext = createContext6(null);
589
- var AbsoluteTimeContext = createContext6(null);
590
- var TimelineContextProvider = ({ children, frameState }) => {
591
- const [playing, setPlaying] = useState2(false);
592
- const imperativePlaying = useRef(false);
593
- const [playbackRate, setPlaybackRate] = useState2(1);
594
- const audioAndVideoTags = useRef([]);
595
- const [remotionRootId] = useState2(() => String(random(null)));
596
- const [_frame, setFrame] = useState2(() => getInitialFrameState());
597
- const frame = frameState ?? _frame;
598
- const { delayRender: delayRender2, continueRender: continueRender2 } = useDelayRender();
599
- if (typeof window !== "undefined") {
600
- useLayoutEffect(() => {
601
- window.remotion_setFrame = (f, composition, attempt) => {
602
- window.remotion_attempt = attempt;
603
- const id = delayRender2(`Setting the current frame to ${f}`);
604
- let asyncUpdate = true;
605
- setFrame((s) => {
606
- const currentFrame = s[composition] ?? window.remotion_initialFrame;
607
- if (currentFrame === f) {
608
- asyncUpdate = false;
609
- return s;
610
- }
611
- return {
612
- ...s,
613
- [composition]: f
614
- };
615
- });
616
- if (asyncUpdate) {
617
- requestAnimationFrame(() => continueRender2(id));
618
- } else {
619
- continueRender2(id);
620
- }
986
+ const lazy = useMemo6(() => {
987
+ if ("component" in compProps) {
988
+ if (typeof document === "undefined" || noSuspense) {
989
+ return compProps.component;
990
+ }
991
+ if (typeof compProps.component === "undefined") {
992
+ throw new Error(`A value of \`undefined\` was passed to the \`component\` prop. Check the value you are passing to the <${componentName}/> component.`);
993
+ }
994
+ const Wrapper = (props) => {
995
+ const Comp = componentRef.current;
996
+ return React6.createElement(Comp, props);
621
997
  };
622
- window.remotion_isPlayer = false;
623
- }, [continueRender2, delayRender2]);
624
- }
625
- const timelineContextValue = useMemo2(() => {
626
- return {
627
- frame,
628
- playing,
629
- imperativePlaying,
630
- rootId: remotionRootId,
631
- playbackRate,
632
- setPlaybackRate,
633
- audioAndVideoTags
634
- };
635
- }, [frame, playbackRate, playing, remotionRootId]);
636
- const setTimelineContextValue = useMemo2(() => {
637
- return {
638
- setFrame,
639
- setPlaying
640
- };
641
- }, []);
642
- return /* @__PURE__ */ jsx3(AbsoluteTimeContext.Provider, {
643
- value: timelineContextValue,
644
- children: /* @__PURE__ */ jsx3(TimelineContext.Provider, {
645
- value: timelineContextValue,
646
- children: /* @__PURE__ */ jsx3(SetTimelineContext.Provider, {
647
- value: setTimelineContextValue,
648
- children
649
- })
650
- })
651
- });
998
+ return Wrapper;
999
+ }
1000
+ if ("lazyComponent" in compProps && typeof compProps.lazyComponent !== "undefined") {
1001
+ if (typeof compProps.lazyComponent === "undefined") {
1002
+ throw new Error(`A value of \`undefined\` was passed to the \`lazyComponent\` prop. Check the value you are passing to the <${componentName}/> component.`);
1003
+ }
1004
+ return React6.lazy(compProps.lazyComponent);
1005
+ }
1006
+ throw new Error("You must pass either 'component' or 'lazyComponent'");
1007
+ }, [compProps.lazyComponent]);
1008
+ return lazy;
652
1009
  };
653
1010
 
654
1011
  // src/use-video.ts
655
- import { useContext as useContext6, useMemo as useMemo5 } from "react";
656
-
657
- // src/CompositionManagerContext.tsx
658
- import { createContext as createContext7 } from "react";
659
- var CompositionManager = createContext7({
660
- compositions: [],
661
- folders: [],
662
- currentCompositionMetadata: null,
663
- canvasContent: null
664
- });
665
- var CompositionSetters = createContext7({
666
- registerComposition: () => {
667
- return;
668
- },
669
- unregisterComposition: () => {
670
- return;
671
- },
672
- registerFolder: () => {
673
- return;
674
- },
675
- unregisterFolder: () => {
676
- return;
677
- },
678
- setCanvasContent: () => {
679
- return;
680
- },
681
- onlyRenderComposition: null
682
- });
683
-
684
- // src/ResolveCompositionConfig.tsx
685
- import { createContext as createContext9, createRef, useContext as useContext5, useMemo as useMemo4 } from "react";
686
-
687
- // src/input-props-override.ts
688
- var getKey = () => {
689
- return `remotion_inputPropsOverride` + window.location.origin;
690
- };
691
- var getInputPropsOverride = () => {
692
- if (typeof localStorage === "undefined")
693
- return null;
694
- const override = localStorage.getItem(getKey());
695
- if (!override)
696
- return null;
697
- return JSON.parse(override);
698
- };
699
- var setInputPropsOverride = (override) => {
700
- if (typeof localStorage === "undefined")
701
- return;
702
- if (override === null) {
703
- localStorage.removeItem(getKey());
704
- return;
705
- }
706
- localStorage.setItem(getKey(), JSON.stringify(override));
707
- };
708
-
709
- // src/input-props-serialization.ts
710
- var DATE_TOKEN = "remotion-date:";
711
- var FILE_TOKEN = "remotion-file:";
712
- var serializeJSONWithSpecialTypes = ({
713
- data,
714
- indent,
715
- staticBase
716
- }) => {
717
- let customDateUsed = false;
718
- let customFileUsed = false;
719
- let mapUsed = false;
720
- let setUsed = false;
721
- try {
722
- const serializedString = JSON.stringify(data, function(key, value) {
723
- const item = this[key];
724
- if (item instanceof Date) {
725
- customDateUsed = true;
726
- return `${DATE_TOKEN}${item.toISOString()}`;
727
- }
728
- if (item instanceof Map) {
729
- mapUsed = true;
730
- return value;
731
- }
732
- if (item instanceof Set) {
733
- setUsed = true;
734
- return value;
735
- }
736
- if (typeof item === "string" && staticBase !== null && item.startsWith(staticBase)) {
737
- customFileUsed = true;
738
- return `${FILE_TOKEN}${item.replace(staticBase + "/", "")}`;
739
- }
740
- return value;
741
- }, indent);
742
- return { serializedString, customDateUsed, customFileUsed, mapUsed, setUsed };
743
- } catch (err) {
744
- throw new Error("Could not serialize the passed input props to JSON: " + err.message);
745
- }
746
- };
747
- var deserializeJSONWithSpecialTypes = (data) => {
748
- return JSON.parse(data, (_, value) => {
749
- if (typeof value === "string" && value.startsWith(DATE_TOKEN)) {
750
- return new Date(value.replace(DATE_TOKEN, ""));
1012
+ import { useContext as useContext8, useMemo as useMemo7 } from "react";
1013
+ var useVideo = () => {
1014
+ const { canvasContent, compositions, currentCompositionMetadata } = useContext8(CompositionManager);
1015
+ const selected = compositions.find((c) => {
1016
+ return canvasContent?.type === "composition" && c.id === canvasContent.compositionId;
1017
+ });
1018
+ const resolved = useResolvedVideoConfig(selected?.id ?? null);
1019
+ return useMemo7(() => {
1020
+ if (!resolved) {
1021
+ return null;
751
1022
  }
752
- if (typeof value === "string" && value.startsWith(FILE_TOKEN)) {
753
- return `${window.remotion_staticBase}/${value.replace(FILE_TOKEN, "")}`;
1023
+ if (resolved.type === "error") {
1024
+ return null;
754
1025
  }
755
- return value;
756
- });
757
- };
758
- var serializeThenDeserialize = (props) => {
759
- return deserializeJSONWithSpecialTypes(serializeJSONWithSpecialTypes({
760
- data: props,
761
- indent: 2,
762
- staticBase: window.remotion_staticBase
763
- }).serializedString);
1026
+ if (resolved.type === "loading") {
1027
+ return null;
1028
+ }
1029
+ if (!selected) {
1030
+ return null;
1031
+ }
1032
+ return {
1033
+ ...resolved.result,
1034
+ defaultProps: selected.defaultProps ?? {},
1035
+ id: selected.id,
1036
+ ...currentCompositionMetadata ?? {},
1037
+ component: selected.component
1038
+ };
1039
+ }, [currentCompositionMetadata, resolved, selected]);
764
1040
  };
765
- var serializeThenDeserializeInStudio = (props) => {
766
- if (getRemotionEnvironment().isStudio) {
767
- return serializeThenDeserialize(props);
1041
+
1042
+ // src/validation/validate-composition-id.ts
1043
+ var getRegex2 = () => /^([a-zA-Z0-9-\u4E00-\u9FFF])+$/g;
1044
+ var isCompositionIdValid = (id) => id.match(getRegex2());
1045
+ var validateCompositionId = (id) => {
1046
+ if (!isCompositionIdValid(id)) {
1047
+ throw new Error(`Composition id can only contain a-z, A-Z, 0-9, CJK characters and -. You passed ${id}`);
768
1048
  }
769
- return props;
770
1049
  };
1050
+ var invalidCompositionErrorMessage = `Composition ID must match ${String(getRegex2())}`;
771
1051
 
772
- // src/config/input-props.ts
773
- var didWarnSSRImport = false;
774
- var warnOnceSSRImport = () => {
775
- if (didWarnSSRImport) {
1052
+ // src/validation/validate-default-props.ts
1053
+ var validateDefaultAndInputProps = (defaultProps, name, compositionId) => {
1054
+ if (!defaultProps) {
776
1055
  return;
777
1056
  }
778
- didWarnSSRImport = true;
779
- console.warn("Called `getInputProps()` on the server. This function is not available server-side and has returned an empty object.");
780
- console.warn("To hide this warning, don't call this function on the server:");
781
- console.warn(" typeof window === 'undefined' ? {} : getInputProps()");
782
- };
783
- var getInputProps = () => {
784
- if (typeof window === "undefined") {
785
- warnOnceSSRImport();
786
- return {};
787
- }
788
- if (getRemotionEnvironment().isPlayer) {
789
- throw new Error("You cannot call `getInputProps()` from a <Player>. Instead, the props are available as React props from component that you passed as `component` prop.");
790
- }
791
- const override = getInputPropsOverride();
792
- if (override) {
793
- return override;
794
- }
795
- if (typeof window === "undefined" || typeof window.remotion_inputProps === "undefined") {
796
- throw new Error("Cannot call `getInputProps()` - window.remotion_inputProps is not set. This API is only available if you are in the Studio, or while you are rendering server-side.");
1057
+ if (typeof defaultProps !== "object") {
1058
+ throw new Error(`"${name}" must be an object, but you passed a value of type ${typeof defaultProps}`);
797
1059
  }
798
- const param = window.remotion_inputProps;
799
- if (!param) {
800
- return {};
1060
+ if (Array.isArray(defaultProps)) {
1061
+ throw new Error(`"${name}" must be an object, an array was passed ${compositionId ? `for composition "${compositionId}"` : ""}`);
801
1062
  }
802
- const parsed = deserializeJSONWithSpecialTypes(param);
803
- return parsed;
804
1063
  };
805
1064
 
806
- // src/EditorProps.tsx
807
- import React5, { createContext as createContext8, useCallback as useCallback2, useMemo as useMemo3 } from "react";
808
- import { jsx as jsx4 } from "react/jsx-runtime";
809
- var EditorPropsContext = createContext8({
810
- props: {},
811
- updateProps: () => {
812
- throw new Error("Not implemented");
813
- }
814
- });
815
- var timeValueRef = React5.createRef();
816
- var EditorPropsProvider = ({ children }) => {
817
- const [props, setProps] = React5.useState({});
818
- const updateProps = useCallback2(({
819
- defaultProps,
820
- id,
821
- newProps
822
- }) => {
823
- setProps((prev) => {
824
- return {
825
- ...prev,
826
- [id]: typeof newProps === "function" ? newProps(prev[id] ?? defaultProps) : newProps
827
- };
828
- });
829
- }, []);
830
- const ctx = useMemo3(() => {
831
- return { props, updateProps };
832
- }, [props, updateProps]);
833
- return /* @__PURE__ */ jsx4(EditorPropsContext.Provider, {
834
- value: ctx,
835
- children
836
- });
1065
+ // src/Composition.tsx
1066
+ import { jsx as jsx7 } from "react/jsx-runtime";
1067
+ var Fallback = () => {
1068
+ const { continueRender: continueRender2, delayRender: delayRender2 } = useDelayRender();
1069
+ useEffect2(() => {
1070
+ const fallback = delayRender2("Waiting for Root component to unsuspend");
1071
+ return () => continueRender2(fallback);
1072
+ }, [continueRender2, delayRender2]);
1073
+ return null;
837
1074
  };
838
-
839
- // src/validation/validate-dimensions.ts
840
- function validateDimension(amount, nameOfProp, location) {
841
- if (typeof amount !== "number") {
842
- throw new Error(`The "${nameOfProp}" prop ${location} must be a number, but you passed a value of type ${typeof amount}`);
843
- }
844
- if (isNaN(amount)) {
845
- throw new TypeError(`The "${nameOfProp}" prop ${location} must not be NaN, but is NaN.`);
1075
+ var InnerComposition = ({
1076
+ width,
1077
+ height,
1078
+ fps,
1079
+ durationInFrames,
1080
+ id,
1081
+ defaultProps,
1082
+ schema,
1083
+ ...compProps
1084
+ }) => {
1085
+ const compManager = useContext9(CompositionSetters);
1086
+ const { registerComposition, unregisterComposition } = compManager;
1087
+ const video = useVideo();
1088
+ const lazy = useLazyComponent({
1089
+ compProps,
1090
+ componentName: "Composition",
1091
+ noSuspense: false
1092
+ });
1093
+ const nonce = useNonce();
1094
+ const isPlayer = useIsPlayer();
1095
+ const environment = useRemotionEnvironment();
1096
+ const canUseComposition = useContext9(CanUseRemotionHooks);
1097
+ if (typeof window !== "undefined") {
1098
+ window.remotion_seenCompositionIds = Array.from(new Set([...window.remotion_seenCompositionIds ?? [], id]));
846
1099
  }
847
- if (!Number.isFinite(amount)) {
848
- throw new TypeError(`The "${nameOfProp}" prop ${location} must be finite, but is ${amount}.`);
1100
+ if (canUseComposition) {
1101
+ if (isPlayer) {
1102
+ throw new Error("<Composition> was mounted inside the `component` that was passed to the <Player>. See https://remotion.dev/docs/wrong-composition-mount for help.");
1103
+ }
1104
+ throw new Error("<Composition> mounted inside another composition. See https://remotion.dev/docs/wrong-composition-mount for help.");
849
1105
  }
850
- if (amount % 1 !== 0) {
851
- throw new TypeError(`The "${nameOfProp}" prop ${location} must be an integer, but is ${amount}.`);
852
- }
853
- if (amount <= 0) {
854
- throw new TypeError(`The "${nameOfProp}" prop ${location} must be positive, but got ${amount}.`);
855
- }
856
- }
857
-
858
- // src/validation/validate-duration-in-frames.ts
859
- function validateDurationInFrames(durationInFrames, options) {
860
- const { allowFloats, component } = options;
861
- if (typeof durationInFrames === "undefined") {
862
- throw new Error(`The "durationInFrames" prop ${component} is missing.`);
863
- }
864
- if (typeof durationInFrames !== "number") {
865
- throw new Error(`The "durationInFrames" prop ${component} must be a number, but you passed a value of type ${typeof durationInFrames}`);
866
- }
867
- if (durationInFrames <= 0) {
868
- throw new TypeError(`The "durationInFrames" prop ${component} must be positive, but got ${durationInFrames}.`);
869
- }
870
- if (!allowFloats && durationInFrames % 1 !== 0) {
871
- throw new TypeError(`The "durationInFrames" prop ${component} must be an integer, but got ${durationInFrames}.`);
872
- }
873
- if (!Number.isFinite(durationInFrames)) {
874
- throw new TypeError(`The "durationInFrames" prop ${component} must be finite, but got ${durationInFrames}.`);
875
- }
876
- }
877
-
878
- // src/validation/validate-fps.ts
879
- function validateFps(fps, location, isGif) {
880
- if (typeof fps !== "number") {
881
- throw new Error(`"fps" must be a number, but you passed a value of type ${typeof fps} ${location}`);
882
- }
883
- if (!Number.isFinite(fps)) {
884
- throw new Error(`"fps" must be a finite, but you passed ${fps} ${location}`);
885
- }
886
- if (isNaN(fps)) {
887
- throw new Error(`"fps" must not be NaN, but got ${fps} ${location}`);
888
- }
889
- if (fps <= 0) {
890
- throw new TypeError(`"fps" must be positive, but got ${fps} ${location}`);
891
- }
892
- if (isGif && fps > 50) {
893
- throw new TypeError(`The FPS for a GIF cannot be higher than 50. Use the --every-nth-frame option to lower the FPS: https://remotion.dev/docs/render-as-gif`);
894
- }
895
- }
896
-
897
- // src/ResolveCompositionConfig.tsx
898
- var ResolveCompositionContext = createContext9(null);
899
- var resolveCompositionsRef = createRef();
900
- var needsResolution = (composition) => {
901
- return Boolean(composition.calculateMetadata);
902
- };
903
- var useResolvedVideoConfig = (preferredCompositionId) => {
904
- const context = useContext5(ResolveCompositionContext);
905
- const { props: allEditorProps } = useContext5(EditorPropsContext);
906
- const { compositions, canvasContent, currentCompositionMetadata } = useContext5(CompositionManager);
907
- const currentComposition = canvasContent?.type === "composition" ? canvasContent.compositionId : null;
908
- const compositionId = preferredCompositionId ?? currentComposition;
909
- const composition = compositions.find((c) => c.id === compositionId);
910
- const selectedEditorProps = useMemo4(() => {
911
- return composition ? allEditorProps[composition.id] ?? {} : {};
912
- }, [allEditorProps, composition]);
913
- const env = useRemotionEnvironment();
914
- return useMemo4(() => {
915
- if (!composition) {
916
- return null;
917
- }
918
- if (currentCompositionMetadata) {
919
- return {
920
- type: "success",
921
- result: {
922
- ...currentCompositionMetadata,
923
- id: composition.id,
924
- defaultProps: composition.defaultProps ?? {}
925
- }
926
- };
927
- }
928
- if (!needsResolution(composition)) {
929
- validateDurationInFrames(composition.durationInFrames, {
930
- allowFloats: false,
931
- component: `in <Composition id="${composition.id}">`
932
- });
933
- validateFps(composition.fps, `in <Composition id="${composition.id}">`, false);
934
- validateDimension(composition.width, "width", `in <Composition id="${composition.id}">`);
935
- validateDimension(composition.height, "height", `in <Composition id="${composition.id}">`);
936
- return {
937
- type: "success",
938
- result: {
939
- width: composition.width,
940
- height: composition.height,
941
- fps: composition.fps,
942
- id: composition.id,
943
- durationInFrames: composition.durationInFrames,
944
- defaultProps: composition.defaultProps ?? {},
945
- props: {
946
- ...composition.defaultProps ?? {},
947
- ...selectedEditorProps ?? {},
948
- ...typeof window === "undefined" || env.isPlayer || !window.remotion_inputProps ? {} : getInputProps() ?? {}
949
- },
950
- defaultCodec: null,
951
- defaultOutName: null,
952
- defaultVideoImageFormat: null,
953
- defaultPixelFormat: null,
954
- defaultProResProfile: null
955
- }
956
- };
957
- }
958
- if (!context) {
959
- return null;
960
- }
961
- if (!context[composition.id]) {
962
- return null;
1106
+ const { folderName, parentName } = useContext9(FolderContext);
1107
+ const stack = compProps.stack ?? null;
1108
+ useEffect2(() => {
1109
+ if (!id) {
1110
+ throw new Error("No id for composition passed.");
963
1111
  }
964
- return context[composition.id];
1112
+ validateCompositionId(id);
1113
+ validateDefaultAndInputProps(defaultProps, "defaultProps", id);
1114
+ registerComposition({
1115
+ durationInFrames: durationInFrames ?? undefined,
1116
+ fps: fps ?? undefined,
1117
+ height: height ?? undefined,
1118
+ width: width ?? undefined,
1119
+ id,
1120
+ folderName,
1121
+ component: lazy,
1122
+ defaultProps: serializeThenDeserializeInStudio(defaultProps ?? {}),
1123
+ nonce: nonce.get(),
1124
+ parentFolderName: parentName,
1125
+ schema: schema ?? null,
1126
+ calculateMetadata: compProps.calculateMetadata ?? null,
1127
+ stack
1128
+ });
1129
+ return () => {
1130
+ unregisterComposition(id);
1131
+ };
965
1132
  }, [
966
- composition,
967
- context,
968
- currentCompositionMetadata,
969
- selectedEditorProps,
970
- env.isPlayer
1133
+ durationInFrames,
1134
+ fps,
1135
+ height,
1136
+ lazy,
1137
+ id,
1138
+ folderName,
1139
+ defaultProps,
1140
+ width,
1141
+ nonce,
1142
+ parentName,
1143
+ schema,
1144
+ compProps.calculateMetadata,
1145
+ stack,
1146
+ registerComposition,
1147
+ unregisterComposition
971
1148
  ]);
972
- };
973
-
974
- // src/use-video.ts
975
- var useVideo = () => {
976
- const { canvasContent, compositions, currentCompositionMetadata } = useContext6(CompositionManager);
977
- const selected = compositions.find((c) => {
978
- return canvasContent?.type === "composition" && c.id === canvasContent.compositionId;
979
- });
980
- const resolved = useResolvedVideoConfig(selected?.id ?? null);
981
- return useMemo5(() => {
982
- if (!resolved) {
983
- return null;
984
- }
985
- if (resolved.type === "error") {
986
- return null;
987
- }
988
- if (resolved.type === "loading") {
1149
+ const resolved = useResolvedVideoConfig(id);
1150
+ if (environment.isStudio && video && video.component === lazy && video.id === id) {
1151
+ const Comp = lazy;
1152
+ if (resolved === null || resolved.type !== "success" && resolved.type !== "success-and-refreshing") {
989
1153
  return null;
990
1154
  }
991
- if (!selected) {
1155
+ return createPortal(/* @__PURE__ */ jsx7(CanUseRemotionHooksProvider, {
1156
+ children: /* @__PURE__ */ jsx7(Suspense, {
1157
+ fallback: /* @__PURE__ */ jsx7(Loading, {}),
1158
+ children: /* @__PURE__ */ jsx7(Comp, {
1159
+ ...resolved.result.props ?? {}
1160
+ })
1161
+ })
1162
+ }), portalNode());
1163
+ }
1164
+ if (environment.isRendering && video && video.component === lazy && video.id === id) {
1165
+ const Comp = lazy;
1166
+ if (resolved === null || resolved.type !== "success" && resolved.type !== "success-and-refreshing") {
992
1167
  return null;
993
1168
  }
994
- return {
995
- ...resolved.result,
996
- defaultProps: selected.defaultProps ?? {},
997
- id: selected.id,
998
- ...currentCompositionMetadata ?? {},
999
- component: selected.component
1000
- };
1001
- }, [currentCompositionMetadata, resolved, selected]);
1002
- };
1003
-
1004
- // src/timeline-position-state.ts
1005
- var makeKey = () => {
1006
- return `remotion.time-all`;
1007
- };
1008
- var persistCurrentFrame = (time) => {
1009
- localStorage.setItem(makeKey(), JSON.stringify(time));
1010
- };
1011
- var getInitialFrameState = () => {
1012
- const item = localStorage.getItem(makeKey()) ?? "{}";
1013
- const obj = JSON.parse(item);
1014
- return obj;
1015
- };
1016
- var getFrameForComposition = (composition) => {
1017
- const item = localStorage.getItem(makeKey()) ?? "{}";
1018
- const obj = JSON.parse(item);
1019
- if (obj[composition] !== undefined) {
1020
- return Number(obj[composition]);
1021
- }
1022
- if (typeof window === "undefined") {
1023
- return 0;
1024
- }
1025
- return window.remotion_initialFrame ?? 0;
1026
- };
1027
- var useTimelinePositionFromContext = (state) => {
1028
- const videoConfig = useVideo();
1029
- const env = useRemotionEnvironment();
1030
- if (!videoConfig) {
1031
- return typeof window === "undefined" ? 0 : window.remotion_initialFrame ?? 0;
1032
- }
1033
- const unclamped = state.frame[videoConfig.id] ?? (env.isPlayer ? 0 : getFrameForComposition(videoConfig.id));
1034
- return Math.min(videoConfig.durationInFrames - 1, unclamped);
1035
- };
1036
- var useTimelineContext = () => {
1037
- const state = useContext7(TimelineContext);
1038
- if (state === null) {
1039
- throw new Error("TimelineContext is not available. This hook must be used inside a <Player> or the Remotion Studio.");
1169
+ return createPortal(/* @__PURE__ */ jsx7(CanUseRemotionHooksProvider, {
1170
+ children: /* @__PURE__ */ jsx7(Suspense, {
1171
+ fallback: /* @__PURE__ */ jsx7(Fallback, {}),
1172
+ children: /* @__PURE__ */ jsx7(Comp, {
1173
+ ...resolved.result.props ?? {}
1174
+ })
1175
+ })
1176
+ }), portalNode());
1040
1177
  }
1041
- return state;
1042
- };
1043
- var useTimelinePosition = () => {
1044
- const state = useTimelineContext();
1045
- return useTimelinePositionFromContext(state);
1178
+ return null;
1046
1179
  };
1047
- var useAbsoluteTimelinePosition = () => {
1048
- const state = useContext7(AbsoluteTimeContext);
1049
- if (state === null) {
1050
- throw new Error("AbsoluteTimeContext is not available. This hook must be used inside a <Player> or the Remotion Studio.");
1180
+ var Composition = (props) => {
1181
+ const { onlyRenderComposition } = useContext9(CompositionSetters);
1182
+ if (onlyRenderComposition && onlyRenderComposition !== props.id) {
1183
+ return null;
1051
1184
  }
1052
- return useTimelinePositionFromContext(state);
1053
- };
1054
- var useTimelineSetFrame = () => {
1055
- const { setFrame } = useContext7(SetTimelineContext);
1056
- return setFrame;
1185
+ return /* @__PURE__ */ jsx7(InnerComposition, {
1186
+ ...props
1187
+ });
1057
1188
  };
1058
- var usePlayingState = () => {
1059
- const { playing, imperativePlaying } = useTimelineContext();
1060
- const { setPlaying } = useContext7(SetTimelineContext);
1061
- return useMemo6(() => [playing, setPlaying, imperativePlaying], [imperativePlaying, playing, setPlaying]);
1189
+
1190
+ // src/enable-sequence-stack-traces.ts
1191
+ var componentsToAddStacksTo = [];
1192
+ var getComponentsToAddStacksTo = () => componentsToAddStacksTo;
1193
+ var addSequenceStackTraces = (component) => {
1194
+ componentsToAddStacksTo.push(component);
1062
1195
  };
1063
1196
 
1064
- // src/use-current-frame.ts
1065
- import { useContext as useContext8 } from "react";
1197
+ // src/version.ts
1198
+ var VERSION = "4.0.443";
1066
1199
 
1067
- // src/CanUseRemotionHooks.tsx
1068
- import { createContext as createContext10 } from "react";
1069
- import { jsx as jsx5 } from "react/jsx-runtime";
1070
- var CanUseRemotionHooks = createContext10(false);
1071
- var CanUseRemotionHooksProvider = ({ children }) => {
1072
- return /* @__PURE__ */ jsx5(CanUseRemotionHooks.Provider, {
1073
- value: true,
1074
- children
1200
+ // src/multiple-versions-warning.ts
1201
+ var checkMultipleRemotionVersions = () => {
1202
+ if (typeof globalThis === "undefined") {
1203
+ return;
1204
+ }
1205
+ const set = () => {
1206
+ globalThis.remotion_imported = VERSION;
1207
+ if (typeof window !== "undefined") {
1208
+ window.remotion_imported = VERSION;
1209
+ }
1210
+ };
1211
+ const alreadyImported = globalThis.remotion_imported || typeof window !== "undefined" && window.remotion_imported;
1212
+ if (alreadyImported) {
1213
+ if (alreadyImported === VERSION) {
1214
+ return;
1215
+ }
1216
+ if (typeof alreadyImported === "string" && alreadyImported.includes("webcodecs")) {
1217
+ set();
1218
+ return;
1219
+ }
1220
+ throw new TypeError(`\uD83D\uDEA8 Multiple versions of Remotion detected: ${[
1221
+ VERSION,
1222
+ typeof alreadyImported === "string" ? alreadyImported : "an older version"
1223
+ ].filter(truthy).join(" and ")}. This will cause things to break in an unexpected way.
1224
+ Check that all your Remotion packages are on the same version. If your dependencies depend on Remotion, make them peer dependencies. You can also run \`npx remotion versions\` from your terminal to see which versions are mismatching.`);
1225
+ }
1226
+ set();
1227
+ };
1228
+
1229
+ // src/Null.tsx
1230
+ var Null = () => {
1231
+ throw new Error("<Null> has been removed as of Remotion v4.0.228. The native clipping APIs were experimental and subject to removal at any time. We removed them because they were sparingly used and made rendering often slower rather than faster.");
1232
+ };
1233
+
1234
+ // src/Sequence.tsx
1235
+ import {
1236
+ forwardRef as forwardRef2,
1237
+ useContext as useContext15,
1238
+ useEffect as useEffect3,
1239
+ useMemo as useMemo13,
1240
+ useState as useState4
1241
+ } from "react";
1242
+
1243
+ // src/freeze.tsx
1244
+ import { useContext as useContext14, useMemo as useMemo11 } from "react";
1245
+
1246
+ // src/SequenceContext.tsx
1247
+ import { createContext as createContext11 } from "react";
1248
+ var SequenceContext = createContext11(null);
1249
+
1250
+ // src/timeline-position-state.ts
1251
+ var exports_timeline_position_state = {};
1252
+ __export(exports_timeline_position_state, {
1253
+ useTimelineSetFrame: () => useTimelineSetFrame,
1254
+ useTimelinePosition: () => useTimelinePosition,
1255
+ useTimelineContext: () => useTimelineContext,
1256
+ usePlayingState: () => usePlayingState,
1257
+ useAbsoluteTimelinePosition: () => useAbsoluteTimelinePosition,
1258
+ persistCurrentFrame: () => persistCurrentFrame,
1259
+ getInitialFrameState: () => getInitialFrameState,
1260
+ getFrameForComposition: () => getFrameForComposition
1261
+ });
1262
+ import { useContext as useContext10, useMemo as useMemo9 } from "react";
1263
+
1264
+ // src/TimelineContext.tsx
1265
+ import {
1266
+ createContext as createContext12,
1267
+ useLayoutEffect,
1268
+ useMemo as useMemo8,
1269
+ useRef as useRef3,
1270
+ useState as useState2
1271
+ } from "react";
1272
+
1273
+ // src/random.ts
1274
+ function mulberry32(a) {
1275
+ let t = a + 1831565813;
1276
+ t = Math.imul(t ^ t >>> 15, t | 1);
1277
+ t ^= t + Math.imul(t ^ t >>> 7, t | 61);
1278
+ return ((t ^ t >>> 14) >>> 0) / 4294967296;
1279
+ }
1280
+ function hashCode(str) {
1281
+ let i = 0;
1282
+ let chr = 0;
1283
+ let hash = 0;
1284
+ for (i = 0;i < str.length; i++) {
1285
+ chr = str.charCodeAt(i);
1286
+ hash = (hash << 5) - hash + chr;
1287
+ hash |= 0;
1288
+ }
1289
+ return hash;
1290
+ }
1291
+ var random = (seed, dummy) => {
1292
+ if (dummy !== undefined) {
1293
+ throw new TypeError("random() takes only one argument");
1294
+ }
1295
+ if (seed === null) {
1296
+ return Math.random();
1297
+ }
1298
+ if (typeof seed === "string") {
1299
+ return mulberry32(hashCode(seed));
1300
+ }
1301
+ if (typeof seed === "number") {
1302
+ return mulberry32(seed * 10000000000);
1303
+ }
1304
+ throw new Error("random() argument must be a number or a string");
1305
+ };
1306
+
1307
+ // src/TimelineContext.tsx
1308
+ import { jsx as jsx8 } from "react/jsx-runtime";
1309
+ var SetTimelineContext = createContext12({
1310
+ setFrame: () => {
1311
+ throw new Error("default");
1312
+ },
1313
+ setPlaying: () => {
1314
+ throw new Error("default");
1315
+ }
1316
+ });
1317
+ var TimelineContext = createContext12(null);
1318
+ var AbsoluteTimeContext = createContext12(null);
1319
+ var TimelineContextProvider = ({ children, frameState }) => {
1320
+ const [playing, setPlaying] = useState2(false);
1321
+ const imperativePlaying = useRef3(false);
1322
+ const [playbackRate, setPlaybackRate] = useState2(1);
1323
+ const audioAndVideoTags = useRef3([]);
1324
+ const [remotionRootId] = useState2(() => String(random(null)));
1325
+ const [_frame, setFrame] = useState2(() => getInitialFrameState());
1326
+ const frame = frameState ?? _frame;
1327
+ const { delayRender: delayRender2, continueRender: continueRender2 } = useDelayRender();
1328
+ if (typeof window !== "undefined") {
1329
+ useLayoutEffect(() => {
1330
+ window.remotion_setFrame = (f, composition, attempt) => {
1331
+ window.remotion_attempt = attempt;
1332
+ const id = delayRender2(`Setting the current frame to ${f}`);
1333
+ let asyncUpdate = true;
1334
+ setFrame((s) => {
1335
+ const currentFrame = s[composition] ?? window.remotion_initialFrame;
1336
+ if (currentFrame === f) {
1337
+ asyncUpdate = false;
1338
+ return s;
1339
+ }
1340
+ return {
1341
+ ...s,
1342
+ [composition]: f
1343
+ };
1344
+ });
1345
+ if (asyncUpdate) {
1346
+ requestAnimationFrame(() => continueRender2(id));
1347
+ } else {
1348
+ continueRender2(id);
1349
+ }
1350
+ };
1351
+ window.remotion_isPlayer = false;
1352
+ }, [continueRender2, delayRender2]);
1353
+ }
1354
+ const timelineContextValue = useMemo8(() => {
1355
+ return {
1356
+ frame,
1357
+ playing,
1358
+ imperativePlaying,
1359
+ rootId: remotionRootId,
1360
+ playbackRate,
1361
+ setPlaybackRate,
1362
+ audioAndVideoTags
1363
+ };
1364
+ }, [frame, playbackRate, playing, remotionRootId]);
1365
+ const setTimelineContextValue = useMemo8(() => {
1366
+ return {
1367
+ setFrame,
1368
+ setPlaying
1369
+ };
1370
+ }, []);
1371
+ return /* @__PURE__ */ jsx8(AbsoluteTimeContext.Provider, {
1372
+ value: timelineContextValue,
1373
+ children: /* @__PURE__ */ jsx8(TimelineContext.Provider, {
1374
+ value: timelineContextValue,
1375
+ children: /* @__PURE__ */ jsx8(SetTimelineContext.Provider, {
1376
+ value: setTimelineContextValue,
1377
+ children
1378
+ })
1379
+ })
1075
1380
  });
1076
1381
  };
1077
1382
 
1383
+ // src/timeline-position-state.ts
1384
+ var makeKey = () => {
1385
+ return `remotion.time-all`;
1386
+ };
1387
+ var persistCurrentFrame = (time) => {
1388
+ localStorage.setItem(makeKey(), JSON.stringify(time));
1389
+ };
1390
+ var getInitialFrameState = () => {
1391
+ const item = localStorage.getItem(makeKey()) ?? "{}";
1392
+ const obj = JSON.parse(item);
1393
+ return obj;
1394
+ };
1395
+ var getFrameForComposition = (composition) => {
1396
+ const item = localStorage.getItem(makeKey()) ?? "{}";
1397
+ const obj = JSON.parse(item);
1398
+ if (obj[composition] !== undefined) {
1399
+ return Number(obj[composition]);
1400
+ }
1401
+ if (typeof window === "undefined") {
1402
+ return 0;
1403
+ }
1404
+ return window.remotion_initialFrame ?? 0;
1405
+ };
1406
+ var useTimelinePositionFromContext = (state) => {
1407
+ const videoConfig = useVideo();
1408
+ const env = useRemotionEnvironment();
1409
+ if (!videoConfig) {
1410
+ return typeof window === "undefined" ? 0 : window.remotion_initialFrame ?? 0;
1411
+ }
1412
+ const unclamped = state.frame[videoConfig.id] ?? (env.isPlayer ? 0 : getFrameForComposition(videoConfig.id));
1413
+ return Math.min(videoConfig.durationInFrames - 1, unclamped);
1414
+ };
1415
+ var useTimelineContext = () => {
1416
+ const state = useContext10(TimelineContext);
1417
+ if (state === null) {
1418
+ throw new Error("TimelineContext is not available. This hook must be used inside a <Player> or the Remotion Studio.");
1419
+ }
1420
+ return state;
1421
+ };
1422
+ var useTimelinePosition = () => {
1423
+ const state = useTimelineContext();
1424
+ return useTimelinePositionFromContext(state);
1425
+ };
1426
+ var useAbsoluteTimelinePosition = () => {
1427
+ const state = useContext10(AbsoluteTimeContext);
1428
+ if (state === null) {
1429
+ throw new Error("AbsoluteTimeContext is not available. This hook must be used inside a <Player> or the Remotion Studio.");
1430
+ }
1431
+ return useTimelinePositionFromContext(state);
1432
+ };
1433
+ var useTimelineSetFrame = () => {
1434
+ const { setFrame } = useContext10(SetTimelineContext);
1435
+ return setFrame;
1436
+ };
1437
+ var usePlayingState = () => {
1438
+ const { playing, imperativePlaying } = useTimelineContext();
1439
+ const { setPlaying } = useContext10(SetTimelineContext);
1440
+ return useMemo9(() => [playing, setPlaying, imperativePlaying], [imperativePlaying, playing, setPlaying]);
1441
+ };
1442
+
1078
1443
  // src/use-current-frame.ts
1444
+ import { useContext as useContext11 } from "react";
1079
1445
  var useCurrentFrame = () => {
1080
- const canUseRemotionHooks = useContext8(CanUseRemotionHooks);
1446
+ const canUseRemotionHooks = useContext11(CanUseRemotionHooks);
1081
1447
  const env = useRemotionEnvironment();
1082
1448
  if (!canUseRemotionHooks) {
1083
1449
  if (env.isPlayer) {
@@ -1086,23 +1452,23 @@ var useCurrentFrame = () => {
1086
1452
  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`);
1087
1453
  }
1088
1454
  const frame = useTimelinePosition();
1089
- const context = useContext8(SequenceContext);
1455
+ const context = useContext11(SequenceContext);
1090
1456
  const contextOffset = context ? context.cumulatedFrom + context.relativeFrom : 0;
1091
1457
  return frame - contextOffset;
1092
1458
  };
1093
1459
 
1094
1460
  // src/use-video-config.ts
1095
- import { useContext as useContext10 } from "react";
1461
+ import { useContext as useContext13 } from "react";
1096
1462
 
1097
1463
  // src/use-unsafe-video-config.ts
1098
- import { useContext as useContext9, useMemo as useMemo7 } from "react";
1464
+ import { useContext as useContext12, useMemo as useMemo10 } from "react";
1099
1465
  var useUnsafeVideoConfig = () => {
1100
- const context = useContext9(SequenceContext);
1466
+ const context = useContext12(SequenceContext);
1101
1467
  const ctxWidth = context?.width ?? null;
1102
1468
  const ctxHeight = context?.height ?? null;
1103
1469
  const ctxDuration = context?.durationInFrames ?? null;
1104
1470
  const video = useVideo();
1105
- return useMemo7(() => {
1471
+ return useMemo10(() => {
1106
1472
  if (!video) {
1107
1473
  return null;
1108
1474
  }
@@ -1140,7 +1506,7 @@ var useUnsafeVideoConfig = () => {
1140
1506
  // src/use-video-config.ts
1141
1507
  var useVideoConfig = () => {
1142
1508
  const videoConfig = useUnsafeVideoConfig();
1143
- const context = useContext10(CanUseRemotionHooks);
1509
+ const context = useContext13(CanUseRemotionHooks);
1144
1510
  const isPlayer = useIsPlayer();
1145
1511
  if (!videoConfig) {
1146
1512
  if (typeof window !== "undefined" && window.remotion_isPlayer || isPlayer) {
@@ -1159,7 +1525,7 @@ var useVideoConfig = () => {
1159
1525
  };
1160
1526
 
1161
1527
  // src/freeze.tsx
1162
- import { jsx as jsx6 } from "react/jsx-runtime";
1528
+ import { jsx as jsx9 } from "react/jsx-runtime";
1163
1529
  var Freeze = ({
1164
1530
  frame: frameToFreeze,
1165
1531
  children,
@@ -1179,7 +1545,7 @@ var Freeze = ({
1179
1545
  if (!Number.isFinite(frameToFreeze)) {
1180
1546
  throw new Error(`The 'frame' prop of <Freeze /> must be a finite number, but it is ${frameToFreeze}.`);
1181
1547
  }
1182
- const isActive = useMemo8(() => {
1548
+ const isActive = useMemo11(() => {
1183
1549
  if (typeof active === "boolean") {
1184
1550
  return active;
1185
1551
  }
@@ -1188,9 +1554,9 @@ var Freeze = ({
1188
1554
  }
1189
1555
  }, [active, frame]);
1190
1556
  const timelineContext = useTimelineContext();
1191
- const sequenceContext = useContext11(SequenceContext);
1557
+ const sequenceContext = useContext14(SequenceContext);
1192
1558
  const relativeFrom = sequenceContext?.relativeFrom ?? 0;
1193
- const timelineValue = useMemo8(() => {
1559
+ const timelineValue = useMemo11(() => {
1194
1560
  if (!isActive) {
1195
1561
  return timelineContext;
1196
1562
  }
@@ -1205,7 +1571,7 @@ var Freeze = ({
1205
1571
  }
1206
1572
  };
1207
1573
  }, [isActive, timelineContext, videoConfig.id, frameToFreeze, relativeFrom]);
1208
- const newSequenceContext = useMemo8(() => {
1574
+ const newSequenceContext = useMemo11(() => {
1209
1575
  if (!sequenceContext) {
1210
1576
  return null;
1211
1577
  }
@@ -1217,63 +1583,26 @@ var Freeze = ({
1217
1583
  cumulatedFrom: 0
1218
1584
  };
1219
1585
  }, [sequenceContext, isActive]);
1220
- return /* @__PURE__ */ jsx6(TimelineContext.Provider, {
1586
+ return /* @__PURE__ */ jsx9(TimelineContext.Provider, {
1221
1587
  value: timelineValue,
1222
- children: /* @__PURE__ */ jsx6(SequenceContext.Provider, {
1588
+ children: /* @__PURE__ */ jsx9(SequenceContext.Provider, {
1223
1589
  value: newSequenceContext,
1224
1590
  children
1225
1591
  })
1226
1592
  });
1227
1593
  };
1228
1594
 
1229
- // src/nonce.ts
1230
- import { createContext as createContext11, useCallback as useCallback3, useContext as useContext12, useMemo as useMemo9, useRef as useRef2 } from "react";
1231
- var NonceContext = createContext11({
1232
- getNonce: () => 0
1233
- });
1234
- var fastRefreshNonce = 0;
1235
- try {
1236
- if (typeof __webpack_module__ !== "undefined") {
1237
- if (__webpack_module__.hot) {
1238
- __webpack_module__.hot.addStatusHandler((status) => {
1239
- if (status === "idle") {
1240
- fastRefreshNonce++;
1241
- }
1242
- });
1243
- }
1244
- }
1245
- } catch {}
1246
- var useNonce = () => {
1247
- const context = useContext12(NonceContext);
1248
- const nonce = context.getNonce();
1249
- const nonceRef = useRef2(nonce);
1250
- nonceRef.current = nonce;
1251
- const history = useRef2([[fastRefreshNonce, nonce]]);
1252
- const get = useCallback3(() => {
1253
- if (fastRefreshNonce !== history.current[history.current.length - 1][0]) {
1254
- history.current = [
1255
- ...history.current,
1256
- [fastRefreshNonce, nonceRef.current]
1257
- ];
1258
- }
1259
- return history.current;
1260
- }, [history]);
1261
- return useMemo9(() => {
1262
- return { get };
1263
- }, [get]);
1264
- };
1265
-
1266
1595
  // src/PremountContext.tsx
1267
- import { createContext as createContext12 } from "react";
1268
- var PremountContext = createContext12({
1596
+ import { createContext as createContext13 } from "react";
1597
+ var PremountContext = createContext13({
1269
1598
  premountFramesRemaining: 0,
1270
1599
  playing: false
1271
1600
  });
1272
1601
 
1273
1602
  // src/SequenceManager.tsx
1274
- import React8, { useCallback as useCallback4, useMemo as useMemo10, useRef as useRef3, useState as useState3 } from "react";
1275
- import { jsx as jsx7 } from "react/jsx-runtime";
1276
- var SequenceManager = React8.createContext({
1603
+ import React10, { useCallback as useCallback4, useMemo as useMemo12, useRef as useRef4, useState as useState3 } from "react";
1604
+ import { jsx as jsx10 } from "react/jsx-runtime";
1605
+ var SequenceManager = React10.createContext({
1277
1606
  registerSequence: () => {
1278
1607
  throw new Error("SequenceManagerContext not initialized");
1279
1608
  },
@@ -1282,13 +1611,13 @@ var SequenceManager = React8.createContext({
1282
1611
  },
1283
1612
  sequences: []
1284
1613
  });
1285
- var SequenceVisibilityToggleContext = React8.createContext({
1614
+ var SequenceVisibilityToggleContext = React10.createContext({
1286
1615
  hidden: {},
1287
1616
  setHidden: () => {
1288
1617
  throw new Error("SequenceVisibilityToggle not initialized");
1289
1618
  }
1290
1619
  });
1291
- var VisualModeOverridesContext = React8.createContext({
1620
+ var VisualModeOverridesContext = React10.createContext({
1292
1621
  dragOverrides: {},
1293
1622
  setDragOverrides: () => {
1294
1623
  throw new Error("VisualModeOverridesContext not initialized");
@@ -1306,7 +1635,7 @@ var SequenceManagerProvider = ({ children, visualModeEnabled }) => {
1306
1635
  const [sequences, setSequences] = useState3([]);
1307
1636
  const [hidden, setHidden] = useState3({});
1308
1637
  const [dragOverrides, setControlOverrides] = useState3({});
1309
- const controlOverridesRef = useRef3(dragOverrides);
1638
+ const controlOverridesRef = useRef4(dragOverrides);
1310
1639
  controlOverridesRef.current = dragOverrides;
1311
1640
  const [codeValues, setCodeValuesMapState] = useState3({});
1312
1641
  const setDragOverrides = useCallback4((sequenceId, key, value) => {
@@ -1352,20 +1681,20 @@ var SequenceManagerProvider = ({ children, visualModeEnabled }) => {
1352
1681
  const unregisterSequence = useCallback4((seq) => {
1353
1682
  setSequences((seqs) => seqs.filter((s) => s.id !== seq));
1354
1683
  }, []);
1355
- const sequenceContext = useMemo10(() => {
1684
+ const sequenceContext = useMemo12(() => {
1356
1685
  return {
1357
1686
  registerSequence,
1358
1687
  sequences,
1359
1688
  unregisterSequence
1360
1689
  };
1361
1690
  }, [registerSequence, sequences, unregisterSequence]);
1362
- const hiddenContext = useMemo10(() => {
1691
+ const hiddenContext = useMemo12(() => {
1363
1692
  return {
1364
1693
  hidden,
1365
1694
  setHidden
1366
1695
  };
1367
1696
  }, [hidden]);
1368
- const overrideContext = useMemo10(() => {
1697
+ const overrideContext = useMemo12(() => {
1369
1698
  return {
1370
1699
  visualModeEnabled,
1371
1700
  dragOverrides,
@@ -1382,11 +1711,11 @@ var SequenceManagerProvider = ({ children, visualModeEnabled }) => {
1382
1711
  codeValues,
1383
1712
  setCodeValues
1384
1713
  ]);
1385
- return /* @__PURE__ */ jsx7(SequenceManager.Provider, {
1714
+ return /* @__PURE__ */ jsx10(SequenceManager.Provider, {
1386
1715
  value: sequenceContext,
1387
- children: /* @__PURE__ */ jsx7(SequenceVisibilityToggleContext.Provider, {
1716
+ children: /* @__PURE__ */ jsx10(SequenceVisibilityToggleContext.Provider, {
1388
1717
  value: hiddenContext,
1389
- children: /* @__PURE__ */ jsx7(VisualModeOverridesContext.Provider, {
1718
+ children: /* @__PURE__ */ jsx10(VisualModeOverridesContext.Provider, {
1390
1719
  value: overrideContext,
1391
1720
  children
1392
1721
  })
@@ -1398,7 +1727,7 @@ var SequenceManagerProvider = ({ children, visualModeEnabled }) => {
1398
1727
  var ENABLE_V5_BREAKING_CHANGES = false;
1399
1728
 
1400
1729
  // src/Sequence.tsx
1401
- import { jsx as jsx8 } from "react/jsx-runtime";
1730
+ import { jsx as jsx11 } from "react/jsx-runtime";
1402
1731
  var RegularSequenceRefForwardingFunction = ({
1403
1732
  from = 0,
1404
1733
  durationInFrames = Infinity,
@@ -1416,7 +1745,7 @@ var RegularSequenceRefForwardingFunction = ({
1416
1745
  }, ref) => {
1417
1746
  const { layout = "absolute-fill" } = other;
1418
1747
  const [id] = useState4(() => String(Math.random()));
1419
- const parentSequence = useContext13(SequenceContext);
1748
+ const parentSequence = useContext15(SequenceContext);
1420
1749
  const { rootId } = useTimelineContext();
1421
1750
  const cumulatedFrom = parentSequence ? parentSequence.cumulatedFrom + parentSequence.relativeFrom : 0;
1422
1751
  const nonce = useNonce();
@@ -1442,15 +1771,15 @@ var RegularSequenceRefForwardingFunction = ({
1442
1771
  const videoConfig = useVideoConfig();
1443
1772
  const parentSequenceDuration = parentSequence ? Math.min(parentSequence.durationInFrames - from, durationInFrames) : durationInFrames;
1444
1773
  const actualDurationInFrames = Math.max(0, Math.min(videoConfig.durationInFrames - from, parentSequenceDuration));
1445
- const { registerSequence, unregisterSequence } = useContext13(SequenceManager);
1446
- const { hidden } = useContext13(SequenceVisibilityToggleContext);
1447
- const premounting = useMemo11(() => {
1774
+ const { registerSequence, unregisterSequence } = useContext15(SequenceManager);
1775
+ const { hidden } = useContext15(SequenceVisibilityToggleContext);
1776
+ const premounting = useMemo13(() => {
1448
1777
  return parentSequence?.premounting || Boolean(other._remotionInternalIsPremounting);
1449
1778
  }, [other._remotionInternalIsPremounting, parentSequence?.premounting]);
1450
- const postmounting = useMemo11(() => {
1779
+ const postmounting = useMemo13(() => {
1451
1780
  return parentSequence?.postmounting || Boolean(other._remotionInternalIsPostmounting);
1452
1781
  }, [other._remotionInternalIsPostmounting, parentSequence?.postmounting]);
1453
- const contextValue = useMemo11(() => {
1782
+ const contextValue = useMemo13(() => {
1454
1783
  return {
1455
1784
  cumulatedFrom,
1456
1785
  relativeFrom: from,
@@ -1477,12 +1806,12 @@ var RegularSequenceRefForwardingFunction = ({
1477
1806
  premountDisplay,
1478
1807
  postmountDisplay
1479
1808
  ]);
1480
- const timelineClipName = useMemo11(() => {
1809
+ const timelineClipName = useMemo13(() => {
1481
1810
  return name ?? "";
1482
1811
  }, [name]);
1483
1812
  const env = useRemotionEnvironment();
1484
1813
  const inheritedStack = other?.stack ?? null;
1485
- useEffect(() => {
1814
+ useEffect3(() => {
1486
1815
  if (!env.isStudio) {
1487
1816
  return;
1488
1817
  }
@@ -1529,7 +1858,7 @@ var RegularSequenceRefForwardingFunction = ({
1529
1858
  const endThreshold = Math.ceil(cumulatedFrom + from + durationInFrames - 1);
1530
1859
  const content = absoluteFrame < cumulatedFrom + from ? null : absoluteFrame > endThreshold ? null : children;
1531
1860
  const styleIfThere = other.layout === "none" ? undefined : other.style;
1532
- const defaultStyle = useMemo11(() => {
1861
+ const defaultStyle = useMemo13(() => {
1533
1862
  return {
1534
1863
  flexDirection: undefined,
1535
1864
  ...width ? { width } : {},
@@ -1544,9 +1873,9 @@ var RegularSequenceRefForwardingFunction = ({
1544
1873
  if (isSequenceHidden) {
1545
1874
  return null;
1546
1875
  }
1547
- return /* @__PURE__ */ jsx8(SequenceContext.Provider, {
1876
+ return /* @__PURE__ */ jsx11(SequenceContext.Provider, {
1548
1877
  value: contextValue,
1549
- children: content === null ? null : other.layout === "none" ? content : /* @__PURE__ */ jsx8(AbsoluteFill, {
1878
+ children: content === null ? null : other.layout === "none" ? content : /* @__PURE__ */ jsx11(AbsoluteFill, {
1550
1879
  ref,
1551
1880
  style: defaultStyle,
1552
1881
  className: other.className,
@@ -1556,7 +1885,7 @@ var RegularSequenceRefForwardingFunction = ({
1556
1885
  };
1557
1886
  var RegularSequence = forwardRef2(RegularSequenceRefForwardingFunction);
1558
1887
  var PremountedPostmountedSequenceRefForwardingFunction = (props, ref) => {
1559
- const parentPremountContext = useContext13(PremountContext);
1888
+ const parentPremountContext = useContext15(PremountContext);
1560
1889
  const frame = useCurrentFrame() - parentPremountContext.premountFramesRemaining;
1561
1890
  if (props.layout === "none") {
1562
1891
  throw new Error('`<Sequence>` with `premountFor` and `postmountFor` props does not support layout="none"');
@@ -1576,7 +1905,7 @@ var PremountedPostmountedSequenceRefForwardingFunction = (props, ref) => {
1576
1905
  const postmountingActive = frame > endThreshold && frame <= endThreshold + postmountFor;
1577
1906
  const freezeFrame = premountingActive ? from : postmountingActive ? from + durationInFrames - 1 : 0;
1578
1907
  const isFreezingActive = premountingActive || postmountingActive;
1579
- const style = useMemo11(() => {
1908
+ const style = useMemo13(() => {
1580
1909
  return {
1581
1910
  ...passedStyle,
1582
1911
  opacity: premountingActive || postmountingActive ? 0 : 1,
@@ -1593,18 +1922,18 @@ var PremountedPostmountedSequenceRefForwardingFunction = (props, ref) => {
1593
1922
  ]);
1594
1923
  const { playing } = useTimelineContext();
1595
1924
  const premountFramesRemaining = premountingActive ? from - frame : 0;
1596
- const premountContextValue = useMemo11(() => {
1925
+ const premountContextValue = useMemo13(() => {
1597
1926
  return {
1598
1927
  premountFramesRemaining,
1599
1928
  playing: parentPremountContext.playing || playing
1600
1929
  };
1601
1930
  }, [premountFramesRemaining, parentPremountContext.playing, playing]);
1602
- return /* @__PURE__ */ jsx8(PremountContext.Provider, {
1931
+ return /* @__PURE__ */ jsx11(PremountContext.Provider, {
1603
1932
  value: premountContextValue,
1604
- children: /* @__PURE__ */ jsx8(Freeze, {
1933
+ children: /* @__PURE__ */ jsx11(Freeze, {
1605
1934
  frame: freezeFrame,
1606
1935
  active: isFreezingActive,
1607
- children: /* @__PURE__ */ jsx8(Sequence, {
1936
+ children: /* @__PURE__ */ jsx11(Sequence, {
1608
1937
  ref,
1609
1938
  from,
1610
1939
  durationInFrames,
@@ -1625,14 +1954,14 @@ var SequenceRefForwardingFunction = (props, ref) => {
1625
1954
  if (props.layout !== "none" && !env.isRendering) {
1626
1955
  const effectivePremountFor = ENABLE_V5_BREAKING_CHANGES ? props.premountFor ?? fps : props.premountFor;
1627
1956
  if (effectivePremountFor || props.postmountFor) {
1628
- return /* @__PURE__ */ jsx8(PremountedPostmountedSequence, {
1957
+ return /* @__PURE__ */ jsx11(PremountedPostmountedSequence, {
1629
1958
  ref,
1630
1959
  ...props,
1631
1960
  premountFor: effectivePremountFor
1632
1961
  });
1633
1962
  }
1634
1963
  }
1635
- return /* @__PURE__ */ jsx8(RegularSequence, {
1964
+ return /* @__PURE__ */ jsx11(RegularSequence, {
1636
1965
  ...props,
1637
1966
  ref
1638
1967
  });
@@ -1641,16 +1970,16 @@ var Sequence = forwardRef2(SequenceRefForwardingFunction);
1641
1970
  // src/animated-image/AnimatedImage.tsx
1642
1971
  import {
1643
1972
  forwardRef as forwardRef3,
1644
- useEffect as useEffect2,
1973
+ useEffect as useEffect4,
1645
1974
  useImperativeHandle as useImperativeHandle2,
1646
1975
  useLayoutEffect as useLayoutEffect2,
1647
- useRef as useRef5,
1976
+ useRef as useRef6,
1648
1977
  useState as useState5
1649
1978
  } from "react";
1650
1979
 
1651
1980
  // src/animated-image/canvas.tsx
1652
- import React10, { useCallback as useCallback5, useImperativeHandle, useRef as useRef4 } from "react";
1653
- import { jsx as jsx9 } from "react/jsx-runtime";
1981
+ import React12, { useCallback as useCallback5, useImperativeHandle, useRef as useRef5 } from "react";
1982
+ import { jsx as jsx12 } from "react/jsx-runtime";
1654
1983
  var calcArgs = (fit, frameSize, canvasSize) => {
1655
1984
  switch (fit) {
1656
1985
  case "fill": {
@@ -1700,7 +2029,7 @@ var calcArgs = (fit, frameSize, canvasSize) => {
1700
2029
  }
1701
2030
  };
1702
2031
  var CanvasRefForwardingFunction = ({ width, height, fit, className, style }, ref) => {
1703
- const canvasRef = useRef4(null);
2032
+ const canvasRef = useRef5(null);
1704
2033
  const draw = useCallback5((imageData) => {
1705
2034
  const canvas = canvasRef.current;
1706
2035
  const canvasWidth = width ?? imageData.displayWidth;
@@ -1740,13 +2069,13 @@ var CanvasRefForwardingFunction = ({ width, height, fit, className, style }, ref
1740
2069
  }
1741
2070
  };
1742
2071
  }, [draw]);
1743
- return /* @__PURE__ */ jsx9("canvas", {
2072
+ return /* @__PURE__ */ jsx12("canvas", {
1744
2073
  ref: canvasRef,
1745
2074
  className,
1746
2075
  style
1747
2076
  });
1748
2077
  };
1749
- var Canvas = React10.forwardRef(CanvasRefForwardingFunction);
2078
+ var Canvas = React12.forwardRef(CanvasRefForwardingFunction);
1750
2079
 
1751
2080
  // src/animated-image/decode-image.ts
1752
2081
  var CACHE_SIZE = 5;
@@ -1899,7 +2228,7 @@ var resolveAnimatedImageSource = (src) => {
1899
2228
  };
1900
2229
 
1901
2230
  // src/animated-image/AnimatedImage.tsx
1902
- import { jsx as jsx10 } from "react/jsx-runtime";
2231
+ import { jsx as jsx13 } from "react/jsx-runtime";
1903
2232
  var AnimatedImage = forwardRef3(({
1904
2233
  src,
1905
2234
  width,
@@ -1910,8 +2239,8 @@ var AnimatedImage = forwardRef3(({
1910
2239
  fit = "fill",
1911
2240
  ...props
1912
2241
  }, canvasRef) => {
1913
- const mountState = useRef5({ isMounted: true });
1914
- useEffect2(() => {
2242
+ const mountState = useRef6({ isMounted: true });
2243
+ useEffect4(() => {
1915
2244
  const { current } = mountState;
1916
2245
  current.isMounted = true;
1917
2246
  return () => {
@@ -1925,9 +2254,9 @@ var AnimatedImage = forwardRef3(({
1925
2254
  const frame = useCurrentFrame();
1926
2255
  const { fps } = useVideoConfig();
1927
2256
  const currentTime = frame / playbackRate / fps;
1928
- const currentTimeRef = useRef5(currentTime);
2257
+ const currentTimeRef = useRef6(currentTime);
1929
2258
  currentTimeRef.current = currentTime;
1930
- const ref = useRef5(null);
2259
+ const ref = useRef6(null);
1931
2260
  useImperativeHandle2(canvasRef, () => {
1932
2261
  const c = ref.current?.getCanvas();
1933
2262
  if (!c) {
@@ -1936,7 +2265,7 @@ var AnimatedImage = forwardRef3(({
1936
2265
  return c;
1937
2266
  }, []);
1938
2267
  const [initialLoopBehavior] = useState5(() => loopBehavior);
1939
- useEffect2(() => {
2268
+ useEffect4(() => {
1940
2269
  const controller = new AbortController;
1941
2270
  decodeImage({
1942
2271
  resolvedSrc,
@@ -1999,7 +2328,7 @@ var AnimatedImage = forwardRef3(({
1999
2328
  continueRender2,
2000
2329
  delayRender2
2001
2330
  ]);
2002
- return /* @__PURE__ */ jsx10(Canvas, {
2331
+ return /* @__PURE__ */ jsx13(Canvas, {
2003
2332
  ref,
2004
2333
  width,
2005
2334
  height,
@@ -2008,16 +2337,16 @@ var AnimatedImage = forwardRef3(({
2008
2337
  });
2009
2338
  });
2010
2339
  // src/Artifact.tsx
2011
- import { useContext as useContext14, useLayoutEffect as useLayoutEffect4, useState as useState7 } from "react";
2340
+ import { useContext as useContext16, useLayoutEffect as useLayoutEffect4, useState as useState7 } from "react";
2012
2341
 
2013
2342
  // src/RenderAssetManager.tsx
2014
2343
  import {
2015
- createContext as createContext13,
2344
+ createContext as createContext14,
2016
2345
  useCallback as useCallback6,
2017
2346
  useImperativeHandle as useImperativeHandle3,
2018
2347
  useLayoutEffect as useLayoutEffect3,
2019
- useMemo as useMemo12,
2020
- useRef as useRef6,
2348
+ useMemo as useMemo14,
2349
+ useRef as useRef7,
2021
2350
  useState as useState6
2022
2351
  } from "react";
2023
2352
 
@@ -2053,8 +2382,8 @@ var validateRenderAsset = (artifact) => {
2053
2382
  };
2054
2383
 
2055
2384
  // src/RenderAssetManager.tsx
2056
- import { jsx as jsx11 } from "react/jsx-runtime";
2057
- var RenderAssetManager = createContext13({
2385
+ import { jsx as jsx14 } from "react/jsx-runtime";
2386
+ var RenderAssetManager = createContext14({
2058
2387
  registerRenderAsset: () => {
2059
2388
  return;
2060
2389
  },
@@ -2065,7 +2394,7 @@ var RenderAssetManager = createContext13({
2065
2394
  });
2066
2395
  var RenderAssetManagerProvider = ({ children, collectAssets }) => {
2067
2396
  const [renderAssets, setRenderAssets] = useState6([]);
2068
- const renderAssetsRef = useRef6([]);
2397
+ const renderAssetsRef = useRef7([]);
2069
2398
  const registerRenderAsset = useCallback6((renderAsset) => {
2070
2399
  validateRenderAsset(renderAsset);
2071
2400
  renderAssetsRef.current = [...renderAssetsRef.current, renderAsset];
@@ -2097,14 +2426,14 @@ var RenderAssetManagerProvider = ({ children, collectAssets }) => {
2097
2426
  };
2098
2427
  }
2099
2428
  }, []);
2100
- const contextValue = useMemo12(() => {
2429
+ const contextValue = useMemo14(() => {
2101
2430
  return {
2102
2431
  registerRenderAsset,
2103
2432
  unregisterRenderAsset,
2104
2433
  renderAssets
2105
2434
  };
2106
2435
  }, [renderAssets, registerRenderAsset, unregisterRenderAsset]);
2107
- return /* @__PURE__ */ jsx11(RenderAssetManager.Provider, {
2436
+ return /* @__PURE__ */ jsx14(RenderAssetManager.Provider, {
2108
2437
  value: contextValue,
2109
2438
  children
2110
2439
  });
@@ -2113,7 +2442,7 @@ var RenderAssetManagerProvider = ({ children, collectAssets }) => {
2113
2442
  // src/Artifact.tsx
2114
2443
  var ArtifactThumbnail = Symbol("Thumbnail");
2115
2444
  var Artifact = ({ filename, content, downloadBehavior }) => {
2116
- const { registerRenderAsset, unregisterRenderAsset } = useContext14(RenderAssetManager);
2445
+ const { registerRenderAsset, unregisterRenderAsset } = useContext16(RenderAssetManager);
2117
2446
  const env = useRemotionEnvironment();
2118
2447
  const frame = useCurrentFrame();
2119
2448
  const [id] = useState7(() => {
@@ -2170,7 +2499,7 @@ var Artifact = ({ filename, content, downloadBehavior }) => {
2170
2499
  };
2171
2500
  Artifact.Thumbnail = ArtifactThumbnail;
2172
2501
  // src/audio/Audio.tsx
2173
- import { forwardRef as forwardRef6, useCallback as useCallback11, useContext as useContext26 } from "react";
2502
+ import { forwardRef as forwardRef6, useCallback as useCallback11, useContext as useContext28 } from "react";
2174
2503
 
2175
2504
  // src/absolute-src.ts
2176
2505
  var getAbsoluteSrc = (relativeSrc) => {
@@ -2202,11 +2531,11 @@ var calculateMediaDuration = ({
2202
2531
  };
2203
2532
 
2204
2533
  // src/loop/index.tsx
2205
- import React11, { createContext as createContext14, useMemo as useMemo13 } from "react";
2206
- import { jsx as jsx12 } from "react/jsx-runtime";
2207
- var LoopContext = createContext14(null);
2534
+ import React13, { createContext as createContext15, useMemo as useMemo15 } from "react";
2535
+ import { jsx as jsx15 } from "react/jsx-runtime";
2536
+ var LoopContext = createContext15(null);
2208
2537
  var useLoop = () => {
2209
- return React11.useContext(LoopContext);
2538
+ return React13.useContext(LoopContext);
2210
2539
  };
2211
2540
  var Loop = ({ durationInFrames, times = Infinity, children, name, ...props }) => {
2212
2541
  const currentFrame = useCurrentFrame();
@@ -2231,22 +2560,22 @@ var Loop = ({ durationInFrames, times = Infinity, children, name, ...props }) =>
2231
2560
  const iteration = Math.floor(currentFrame / durationInFrames);
2232
2561
  const start = iteration * durationInFrames;
2233
2562
  const from = Math.min(start, maxFrame);
2234
- const loopDisplay = useMemo13(() => {
2563
+ const loopDisplay = useMemo15(() => {
2235
2564
  return {
2236
2565
  numberOfTimes: Math.min(compDuration / durationInFrames, times),
2237
2566
  startOffset: -from,
2238
2567
  durationInFrames
2239
2568
  };
2240
2569
  }, [compDuration, durationInFrames, from, times]);
2241
- const loopContext = useMemo13(() => {
2570
+ const loopContext = useMemo15(() => {
2242
2571
  return {
2243
2572
  iteration: Math.floor(currentFrame / durationInFrames),
2244
2573
  durationInFrames
2245
2574
  };
2246
2575
  }, [currentFrame, durationInFrames]);
2247
- return /* @__PURE__ */ jsx12(LoopContext.Provider, {
2576
+ return /* @__PURE__ */ jsx15(LoopContext.Provider, {
2248
2577
  value: loopContext,
2249
- children: /* @__PURE__ */ jsx12(Sequence, {
2578
+ children: /* @__PURE__ */ jsx15(Sequence, {
2250
2579
  durationInFrames,
2251
2580
  from,
2252
2581
  name: name ?? "<Loop>",
@@ -2260,7 +2589,7 @@ var Loop = ({ durationInFrames, times = Infinity, children, name, ...props }) =>
2260
2589
  Loop.useLoop = useLoop;
2261
2590
 
2262
2591
  // src/prefetch.ts
2263
- import { useContext as useContext15 } from "react";
2592
+ import { useContext as useContext17 } from "react";
2264
2593
 
2265
2594
  // src/playback-logging.ts
2266
2595
  var playbackLogging = ({
@@ -2274,9 +2603,9 @@ var playbackLogging = ({
2274
2603
  };
2275
2604
 
2276
2605
  // src/prefetch-state.tsx
2277
- import { createContext as createContext15, useEffect as useEffect3, useState as useState8 } from "react";
2278
- import { jsx as jsx13 } from "react/jsx-runtime";
2279
- var PreloadContext = createContext15({});
2606
+ import { createContext as createContext16, useEffect as useEffect5, useState as useState8 } from "react";
2607
+ import { jsx as jsx16 } from "react/jsx-runtime";
2608
+ var PreloadContext = createContext16({});
2280
2609
  var preloads = {};
2281
2610
  var updaters = [];
2282
2611
  var setPreloads = (updater) => {
@@ -2285,7 +2614,7 @@ var setPreloads = (updater) => {
2285
2614
  };
2286
2615
  var PrefetchProvider = ({ children }) => {
2287
2616
  const [_preloads, _setPreloads] = useState8(() => preloads);
2288
- useEffect3(() => {
2617
+ useEffect5(() => {
2289
2618
  const updaterFunction = () => {
2290
2619
  _setPreloads(preloads);
2291
2620
  };
@@ -2294,7 +2623,7 @@ var PrefetchProvider = ({ children }) => {
2294
2623
  updaters = updaters.filter((u) => u !== updaterFunction);
2295
2624
  };
2296
2625
  }, []);
2297
- return /* @__PURE__ */ jsx13(PreloadContext.Provider, {
2626
+ return /* @__PURE__ */ jsx16(PreloadContext.Provider, {
2298
2627
  value: _preloads,
2299
2628
  children
2300
2629
  });
@@ -2316,7 +2645,7 @@ var getSrcWithoutHash = (src) => {
2316
2645
  return src.slice(0, hashIndex);
2317
2646
  };
2318
2647
  var usePreload = (src) => {
2319
- const preloads2 = useContext15(PreloadContext);
2648
+ const preloads2 = useContext17(PreloadContext);
2320
2649
  const hashFragmentIndex = removeAndGetHashFragment(src);
2321
2650
  const withoutHashFragment = getSrcWithoutHash(src);
2322
2651
  if (!preloads2[withoutHashFragment]) {
@@ -2589,8 +2918,8 @@ var resolveTrimProps = ({
2589
2918
  };
2590
2919
 
2591
2920
  // src/video/duration-state.tsx
2592
- import { createContext as createContext16, useMemo as useMemo14, useReducer } from "react";
2593
- import { jsx as jsx14 } from "react/jsx-runtime";
2921
+ import { createContext as createContext17, useMemo as useMemo16, useReducer } from "react";
2922
+ import { jsx as jsx17 } from "react/jsx-runtime";
2594
2923
  var durationReducer = (state, action) => {
2595
2924
  switch (action.type) {
2596
2925
  case "got-duration": {
@@ -2607,7 +2936,7 @@ var durationReducer = (state, action) => {
2607
2936
  return state;
2608
2937
  }
2609
2938
  };
2610
- var DurationsContext = createContext16({
2939
+ var DurationsContext = createContext17({
2611
2940
  durations: {},
2612
2941
  setDurations: () => {
2613
2942
  throw new Error("context missing");
@@ -2615,26 +2944,26 @@ var DurationsContext = createContext16({
2615
2944
  });
2616
2945
  var DurationsContextProvider = ({ children }) => {
2617
2946
  const [durations, setDurations] = useReducer(durationReducer, {});
2618
- const value = useMemo14(() => {
2947
+ const value = useMemo16(() => {
2619
2948
  return {
2620
2949
  durations,
2621
2950
  setDurations
2622
2951
  };
2623
2952
  }, [durations]);
2624
- return /* @__PURE__ */ jsx14(DurationsContext.Provider, {
2953
+ return /* @__PURE__ */ jsx17(DurationsContext.Provider, {
2625
2954
  value,
2626
2955
  children
2627
2956
  });
2628
2957
  };
2629
2958
 
2630
2959
  // src/audio/AudioForPreview.tsx
2631
- import React17, {
2960
+ import React19, {
2632
2961
  forwardRef as forwardRef4,
2633
- useContext as useContext24,
2634
- useEffect as useEffect10,
2962
+ useContext as useContext26,
2963
+ useEffect as useEffect12,
2635
2964
  useImperativeHandle as useImperativeHandle4,
2636
- useMemo as useMemo22,
2637
- useRef as useRef14,
2965
+ useMemo as useMemo24,
2966
+ useRef as useRef15,
2638
2967
  useState as useState13
2639
2968
  } from "react";
2640
2969
 
@@ -2657,16 +2986,16 @@ var getCrossOriginValue = ({
2657
2986
  };
2658
2987
 
2659
2988
  // src/use-amplification.ts
2660
- import { useContext as useContext17, useLayoutEffect as useLayoutEffect5, useRef as useRef9 } from "react";
2989
+ import { useContext as useContext19, useLayoutEffect as useLayoutEffect5, useRef as useRef10 } from "react";
2661
2990
 
2662
2991
  // src/audio/shared-audio-tags.tsx
2663
- import React14, {
2664
- createContext as createContext17,
2992
+ import React16, {
2993
+ createContext as createContext18,
2665
2994
  createRef as createRef2,
2666
2995
  useCallback as useCallback7,
2667
- useContext as useContext16,
2668
- useMemo as useMemo16,
2669
- useRef as useRef7,
2996
+ useContext as useContext18,
2997
+ useMemo as useMemo18,
2998
+ useRef as useRef8,
2670
2999
  useState as useState9
2671
3000
  } from "react";
2672
3001
 
@@ -2766,7 +3095,7 @@ var makeSharedElementSourceNode = ({
2766
3095
  };
2767
3096
 
2768
3097
  // src/audio/use-audio-context.ts
2769
- import { useMemo as useMemo15 } from "react";
3098
+ import { useMemo as useMemo17 } from "react";
2770
3099
  var warned = false;
2771
3100
  var warnOnce = (logLevel) => {
2772
3101
  if (warned) {
@@ -2783,7 +3112,7 @@ var useSingletonAudioContext = ({
2783
3112
  audioEnabled
2784
3113
  }) => {
2785
3114
  const env = useRemotionEnvironment();
2786
- const audioContext = useMemo15(() => {
3115
+ const audioContext = useMemo17(() => {
2787
3116
  if (env.isRendering) {
2788
3117
  return null;
2789
3118
  }
@@ -2803,7 +3132,7 @@ var useSingletonAudioContext = ({
2803
3132
  };
2804
3133
 
2805
3134
  // src/audio/shared-audio-tags.tsx
2806
- import { jsx as jsx15, jsxs } from "react/jsx-runtime";
3135
+ import { jsx as jsx18, jsxs as jsxs2 } from "react/jsx-runtime";
2807
3136
  var EMPTY_AUDIO = "data:audio/mp3;base64,/+MYxAAJcAV8AAgAABn//////+/gQ5BAMA+D4Pg+BAQBAEAwD4Pg+D4EBAEAQDAPg++hYBH///hUFQVBUFREDQNHmf///////+MYxBUGkAGIMAAAAP/29Xt6lUxBTUUzLjEwMFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV/+MYxDUAAANIAAAAAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV";
2808
3137
  var compareProps = (obj1, obj2) => {
2809
3138
  const keysA = Object.keys(obj1).sort();
@@ -2830,9 +3159,9 @@ var didPropChange = (key, newProp, prevProp) => {
2830
3159
  }
2831
3160
  return true;
2832
3161
  };
2833
- var SharedAudioContext = createContext17(null);
3162
+ var SharedAudioContext = createContext18(null);
2834
3163
  var SharedAudioContextProvider = ({ children, numberOfAudioTags, audioLatencyHint, audioEnabled }) => {
2835
- const audios = useRef7([]);
3164
+ const audios = useRef8([]);
2836
3165
  const [initialNumberOfAudioTags] = useState9(numberOfAudioTags);
2837
3166
  if (numberOfAudioTags !== initialNumberOfAudioTags) {
2838
3167
  throw new Error("The number of shared audio tags has changed dynamically. Once you have set this property, you cannot change it afterwards.");
@@ -2843,9 +3172,9 @@ var SharedAudioContextProvider = ({ children, numberOfAudioTags, audioLatencyHin
2843
3172
  latencyHint: audioLatencyHint,
2844
3173
  audioEnabled
2845
3174
  });
2846
- const audioSyncAnchor = useMemo16(() => ({ value: 0 }), []);
2847
- const prevEndTimes = useRef7({ scheduledEndTime: null, mediaEndTime: null });
2848
- const scheduleAudioNode = useMemo16(() => {
3175
+ const audioSyncAnchor = useMemo18(() => ({ value: 0 }), []);
3176
+ const prevEndTimes = useRef8({ scheduledEndTime: null, mediaEndTime: null });
3177
+ const scheduleAudioNode = useMemo18(() => {
2849
3178
  return ({
2850
3179
  node,
2851
3180
  mediaTimestamp,
@@ -2900,7 +3229,7 @@ var SharedAudioContextProvider = ({ children, numberOfAudioTags, audioLatencyHin
2900
3229
  };
2901
3230
  };
2902
3231
  }, [audioContext, logLevel]);
2903
- const refs = useMemo16(() => {
3232
+ const refs = useMemo18(() => {
2904
3233
  return new Array(numberOfAudioTags).fill(true).map(() => {
2905
3234
  const ref = createRef2();
2906
3235
  return {
@@ -2913,7 +3242,7 @@ var SharedAudioContextProvider = ({ children, numberOfAudioTags, audioLatencyHin
2913
3242
  };
2914
3243
  });
2915
3244
  }, [audioContext, numberOfAudioTags]);
2916
- const effectToUse = React14.useInsertionEffect ?? React14.useLayoutEffect;
3245
+ const effectToUse = React16.useInsertionEffect ?? React16.useLayoutEffect;
2917
3246
  effectToUse(() => {
2918
3247
  return () => {
2919
3248
  requestAnimationFrame(() => {
@@ -2923,7 +3252,7 @@ var SharedAudioContextProvider = ({ children, numberOfAudioTags, audioLatencyHin
2923
3252
  });
2924
3253
  };
2925
3254
  }, [refs]);
2926
- const takenAudios = useRef7(new Array(numberOfAudioTags).fill(false));
3255
+ const takenAudios = useRef8(new Array(numberOfAudioTags).fill(false));
2927
3256
  const rerenderAudios = useCallback7(() => {
2928
3257
  refs.forEach(({ ref, id }) => {
2929
3258
  const data = audios.current?.find((a) => a.id === id);
@@ -3039,7 +3368,7 @@ var SharedAudioContextProvider = ({ children, numberOfAudioTags, audioLatencyHin
3039
3368
  });
3040
3369
  audioContext?.resume();
3041
3370
  }, [audioContext, logLevel, mountTime, refs, env.isPlayer]);
3042
- const value = useMemo16(() => {
3371
+ const value = useMemo18(() => {
3043
3372
  return {
3044
3373
  registerAudio,
3045
3374
  unregisterAudio,
@@ -3060,11 +3389,11 @@ var SharedAudioContextProvider = ({ children, numberOfAudioTags, audioLatencyHin
3060
3389
  audioSyncAnchor,
3061
3390
  scheduleAudioNode
3062
3391
  ]);
3063
- return /* @__PURE__ */ jsxs(SharedAudioContext.Provider, {
3392
+ return /* @__PURE__ */ jsxs2(SharedAudioContext.Provider, {
3064
3393
  value,
3065
3394
  children: [
3066
3395
  refs.map(({ id, ref }) => {
3067
- return /* @__PURE__ */ jsx15("audio", {
3396
+ return /* @__PURE__ */ jsx18("audio", {
3068
3397
  ref,
3069
3398
  preload: "metadata",
3070
3399
  src: EMPTY_AUDIO
@@ -3080,12 +3409,12 @@ var useSharedAudio = ({
3080
3409
  premounting,
3081
3410
  postmounting
3082
3411
  }) => {
3083
- const ctx = useContext16(SharedAudioContext);
3412
+ const ctx = useContext18(SharedAudioContext);
3084
3413
  const [elem] = useState9(() => {
3085
3414
  if (ctx && ctx.numberOfAudioTags > 0) {
3086
3415
  return ctx.registerAudio({ aud, audioId, premounting, postmounting });
3087
3416
  }
3088
- const el = React14.createRef();
3417
+ const el = React16.createRef();
3089
3418
  const mediaElementSourceNode = ctx?.audioContext ? makeSharedElementSourceNode({
3090
3419
  audioContext: ctx.audioContext,
3091
3420
  ref: el
@@ -3104,7 +3433,7 @@ var useSharedAudio = ({
3104
3433
  }
3105
3434
  };
3106
3435
  });
3107
- const effectToUse = React14.useInsertionEffect ?? React14.useLayoutEffect;
3436
+ const effectToUse = React16.useInsertionEffect ?? React16.useLayoutEffect;
3108
3437
  if (typeof document !== "undefined") {
3109
3438
  effectToUse(() => {
3110
3439
  if (ctx && ctx.numberOfAudioTags > 0) {
@@ -3129,7 +3458,7 @@ var isApproximatelyTheSame = (num1, num2) => {
3129
3458
  };
3130
3459
 
3131
3460
  // src/video/video-fragment.ts
3132
- import { useRef as useRef8 } from "react";
3461
+ import { useRef as useRef9 } from "react";
3133
3462
  var toSeconds = (time, fps) => {
3134
3463
  return Math.round(time / fps * 100) / 100;
3135
3464
  };
@@ -3216,9 +3545,9 @@ var useAppendVideoFragment = ({
3216
3545
  duration: initialDuration,
3217
3546
  fps
3218
3547
  }) => {
3219
- const actualFromRef = useRef8(initialActualFrom);
3220
- const actualDuration = useRef8(initialDuration);
3221
- const actualSrc = useRef8(initialActualSrc);
3548
+ const actualFromRef = useRef9(initialActualFrom);
3549
+ const actualDuration = useRef9(initialDuration);
3550
+ const actualSrc = useRef9(initialActualSrc);
3222
3551
  if (!isSubsetOfDuration({
3223
3552
  prevStartFrom: actualFromRef.current,
3224
3553
  newStartFrom: initialActualFrom,
@@ -3257,10 +3586,10 @@ var useVolume = ({
3257
3586
  source,
3258
3587
  shouldUseWebAudioApi
3259
3588
  }) => {
3260
- const audioStuffRef = useRef9(null);
3261
- const currentVolumeRef = useRef9(volume);
3589
+ const audioStuffRef = useRef10(null);
3590
+ const currentVolumeRef = useRef10(volume);
3262
3591
  currentVolumeRef.current = volume;
3263
- const sharedAudioContext = useContext17(SharedAudioContext);
3592
+ const sharedAudioContext = useContext19(SharedAudioContext);
3264
3593
  if (!sharedAudioContext) {
3265
3594
  throw new Error("useAmplification must be used within a SharedAudioContext");
3266
3595
  }
@@ -3316,12 +3645,12 @@ var useVolume = ({
3316
3645
  };
3317
3646
 
3318
3647
  // src/use-media-in-timeline.ts
3319
- import { useContext as useContext19, useEffect as useEffect4, useMemo as useMemo17, useState as useState10 } from "react";
3648
+ import { useContext as useContext21, useEffect as useEffect6, useMemo as useMemo19, useState as useState10 } from "react";
3320
3649
 
3321
3650
  // src/audio/use-audio-frame.ts
3322
- import { useContext as useContext18 } from "react";
3651
+ import { useContext as useContext20 } from "react";
3323
3652
  var useMediaStartsAt = () => {
3324
- const parentSequence = useContext18(SequenceContext);
3653
+ const parentSequence = useContext20(SequenceContext);
3325
3654
  const startsAt = Math.min(0, parentSequence?.relativeFrom ?? 0);
3326
3655
  return startsAt;
3327
3656
  };
@@ -3392,7 +3721,7 @@ var useBasicMediaInTimeline = ({
3392
3721
  throw new Error("No src passed");
3393
3722
  }
3394
3723
  const startsAt = useMediaStartsAt();
3395
- const parentSequence = useContext19(SequenceContext);
3724
+ const parentSequence = useContext21(SequenceContext);
3396
3725
  const videoConfig = useVideoConfig();
3397
3726
  const [initialVolume] = useState10(() => volume);
3398
3727
  const mediaDuration = calculateMediaDuration({
@@ -3402,7 +3731,7 @@ var useBasicMediaInTimeline = ({
3402
3731
  trimAfter
3403
3732
  });
3404
3733
  const duration = parentSequence ? Math.min(parentSequence.durationInFrames, mediaDuration) : mediaDuration;
3405
- const volumes = useMemo17(() => {
3734
+ const volumes = useMemo19(() => {
3406
3735
  if (typeof volume === "number") {
3407
3736
  return volume;
3408
3737
  }
@@ -3414,7 +3743,7 @@ var useBasicMediaInTimeline = ({
3414
3743
  });
3415
3744
  }).join(",");
3416
3745
  }, [duration, startsAt, volume, mediaVolume]);
3417
- useEffect4(() => {
3746
+ useEffect6(() => {
3418
3747
  if (typeof volume === "number" && volume !== initialVolume) {
3419
3748
  warnOnce2(`Remotion: The ${mediaType} with src ${src} has changed it's volume. Prefer the callback syntax for setting volume to get better timeline display: https://www.remotion.dev/docs/audio/volume`);
3420
3749
  }
@@ -3441,10 +3770,11 @@ var useImageInTimeline = ({
3441
3770
  showInTimeline,
3442
3771
  premountDisplay,
3443
3772
  postmountDisplay,
3444
- loopDisplay
3773
+ loopDisplay,
3774
+ controls
3445
3775
  }) => {
3446
- const parentSequence = useContext19(SequenceContext);
3447
- const { registerSequence, unregisterSequence } = useContext19(SequenceManager);
3776
+ const parentSequence = useContext21(SequenceContext);
3777
+ const { registerSequence, unregisterSequence } = useContext21(SequenceManager);
3448
3778
  const { duration, nonce, rootId, isStudio, finalDisplayName } = useBasicMediaInTimeline({
3449
3779
  volume: undefined,
3450
3780
  mediaVolume: 0,
@@ -3455,7 +3785,7 @@ var useImageInTimeline = ({
3455
3785
  trimBefore: undefined,
3456
3786
  playbackRate: 1
3457
3787
  });
3458
- useEffect4(() => {
3788
+ useEffect6(() => {
3459
3789
  if (!src) {
3460
3790
  throw new Error("No src passed");
3461
3791
  }
@@ -3480,7 +3810,7 @@ var useImageInTimeline = ({
3480
3810
  stack,
3481
3811
  premountDisplay,
3482
3812
  postmountDisplay,
3483
- controls: null
3813
+ controls
3484
3814
  });
3485
3815
  return () => {
3486
3816
  unregisterSequence(id);
@@ -3500,7 +3830,8 @@ var useImageInTimeline = ({
3500
3830
  isStudio,
3501
3831
  loopDisplay,
3502
3832
  rootId,
3503
- finalDisplayName
3833
+ finalDisplayName,
3834
+ controls
3504
3835
  ]);
3505
3836
  };
3506
3837
  var useMediaInTimeline = ({
@@ -3517,9 +3848,9 @@ var useMediaInTimeline = ({
3517
3848
  postmountDisplay,
3518
3849
  loopDisplay
3519
3850
  }) => {
3520
- const parentSequence = useContext19(SequenceContext);
3851
+ const parentSequence = useContext21(SequenceContext);
3521
3852
  const startsAt = useMediaStartsAt();
3522
- const { registerSequence, unregisterSequence } = useContext19(SequenceManager);
3853
+ const { registerSequence, unregisterSequence } = useContext21(SequenceManager);
3523
3854
  const {
3524
3855
  volumes,
3525
3856
  duration,
@@ -3538,7 +3869,7 @@ var useMediaInTimeline = ({
3538
3869
  trimBefore: undefined,
3539
3870
  playbackRate
3540
3871
  });
3541
- useEffect4(() => {
3872
+ useEffect6(() => {
3542
3873
  if (!src) {
3543
3874
  throw new Error("No src passed");
3544
3875
  }
@@ -3599,36 +3930,36 @@ var useMediaInTimeline = ({
3599
3930
  // src/use-media-playback.ts
3600
3931
  import {
3601
3932
  useCallback as useCallback10,
3602
- useContext as useContext22,
3603
- useEffect as useEffect8,
3933
+ useContext as useContext24,
3934
+ useEffect as useEffect10,
3604
3935
  useLayoutEffect as useLayoutEffect7,
3605
- useRef as useRef13
3936
+ useRef as useRef14
3606
3937
  } from "react";
3607
3938
 
3608
3939
  // src/buffer-until-first-frame.ts
3609
- import { useCallback as useCallback9, useMemo as useMemo20, useRef as useRef11 } from "react";
3940
+ import { useCallback as useCallback9, useMemo as useMemo22, useRef as useRef12 } from "react";
3610
3941
 
3611
3942
  // src/use-buffer-state.ts
3612
- import { useContext as useContext21, useMemo as useMemo19 } from "react";
3943
+ import { useContext as useContext23, useMemo as useMemo21 } from "react";
3613
3944
 
3614
3945
  // src/buffering.tsx
3615
- import React15, {
3946
+ import React17, {
3616
3947
  useCallback as useCallback8,
3617
- useContext as useContext20,
3618
- useEffect as useEffect5,
3948
+ useContext as useContext22,
3949
+ useEffect as useEffect7,
3619
3950
  useLayoutEffect as useLayoutEffect6,
3620
- useMemo as useMemo18,
3621
- useRef as useRef10,
3951
+ useMemo as useMemo20,
3952
+ useRef as useRef11,
3622
3953
  useState as useState11
3623
3954
  } from "react";
3624
- import { jsx as jsx16 } from "react/jsx-runtime";
3955
+ import { jsx as jsx19 } from "react/jsx-runtime";
3625
3956
  var useBufferManager = (logLevel, mountTime) => {
3626
3957
  const [blocks, setBlocks] = useState11([]);
3627
3958
  const [onBufferingCallbacks, setOnBufferingCallbacks] = useState11([]);
3628
3959
  const [onResumeCallbacks, setOnResumeCallbacks] = useState11([]);
3629
3960
  const env = useRemotionEnvironment();
3630
3961
  const rendering = env.isRendering;
3631
- const buffering = useRef10(false);
3962
+ const buffering = useRef11(false);
3632
3963
  const addBlock = useCallback8((block) => {
3633
3964
  if (rendering) {
3634
3965
  return {
@@ -3666,7 +3997,7 @@ var useBufferManager = (logLevel, mountTime) => {
3666
3997
  }
3667
3998
  };
3668
3999
  }, []);
3669
- useEffect5(() => {
4000
+ useEffect7(() => {
3670
4001
  if (rendering) {
3671
4002
  return;
3672
4003
  }
@@ -3696,22 +4027,22 @@ var useBufferManager = (logLevel, mountTime) => {
3696
4027
  }
3697
4028
  }, [blocks]);
3698
4029
  }
3699
- return useMemo18(() => {
4030
+ return useMemo20(() => {
3700
4031
  return { addBlock, listenForBuffering, listenForResume, buffering };
3701
4032
  }, [addBlock, buffering, listenForBuffering, listenForResume]);
3702
4033
  };
3703
- var BufferingContextReact = React15.createContext(null);
4034
+ var BufferingContextReact = React17.createContext(null);
3704
4035
  var BufferingProvider = ({ children }) => {
3705
- const { logLevel, mountTime } = useContext20(LogLevelContext);
4036
+ const { logLevel, mountTime } = useContext22(LogLevelContext);
3706
4037
  const bufferManager = useBufferManager(logLevel ?? "info", mountTime);
3707
- return /* @__PURE__ */ jsx16(BufferingContextReact.Provider, {
4038
+ return /* @__PURE__ */ jsx19(BufferingContextReact.Provider, {
3708
4039
  value: bufferManager,
3709
4040
  children
3710
4041
  });
3711
4042
  };
3712
4043
  var useIsPlayerBuffering = (bufferManager) => {
3713
4044
  const [isBuffering, setIsBuffering] = useState11(bufferManager.buffering.current);
3714
- useEffect5(() => {
4045
+ useEffect7(() => {
3715
4046
  const onBuffer = () => {
3716
4047
  setIsBuffering(true);
3717
4048
  };
@@ -3734,9 +4065,9 @@ var useIsPlayerBuffering = (bufferManager) => {
3734
4065
 
3735
4066
  // src/use-buffer-state.ts
3736
4067
  var useBufferState = () => {
3737
- const buffer = useContext21(BufferingContextReact);
4068
+ const buffer = useContext23(BufferingContextReact);
3738
4069
  const addBlock = buffer ? buffer.addBlock : null;
3739
- return useMemo19(() => ({
4070
+ return useMemo21(() => ({
3740
4071
  delayPlayback: () => {
3741
4072
  if (!addBlock) {
3742
4073
  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");
@@ -3762,7 +4093,7 @@ var useBufferUntilFirstFrame = ({
3762
4093
  logLevel,
3763
4094
  mountTime
3764
4095
  }) => {
3765
- const bufferingRef = useRef11(false);
4096
+ const bufferingRef = useRef12(false);
3766
4097
  const { delayPlayback } = useBufferState();
3767
4098
  const bufferUntilFirstFrame = useCallback9((requestedTime) => {
3768
4099
  if (mediaType !== "video") {
@@ -3835,7 +4166,7 @@ var useBufferUntilFirstFrame = ({
3835
4166
  onVariableFpsVideoDetected,
3836
4167
  pauseWhenBuffering
3837
4168
  ]);
3838
- return useMemo20(() => {
4169
+ return useMemo22(() => {
3839
4170
  return {
3840
4171
  isBuffering: () => bufferingRef.current,
3841
4172
  bufferUntilFirstFrame
@@ -3844,9 +4175,9 @@ var useBufferUntilFirstFrame = ({
3844
4175
  };
3845
4176
 
3846
4177
  // src/media-tag-current-time-timestamp.ts
3847
- import React16 from "react";
4178
+ import React18 from "react";
3848
4179
  var useCurrentTimeOfMediaTagWithUpdateTimeStamp = (mediaRef) => {
3849
- const lastUpdate = React16.useRef({
4180
+ const lastUpdate = React18.useRef({
3850
4181
  time: mediaRef.current?.currentTime ?? 0,
3851
4182
  lastUpdate: performance.now()
3852
4183
  });
@@ -3880,7 +4211,7 @@ var seek = ({
3880
4211
  };
3881
4212
 
3882
4213
  // src/use-media-buffering.ts
3883
- import { useEffect as useEffect6, useState as useState12 } from "react";
4214
+ import { useEffect as useEffect8, useState as useState12 } from "react";
3884
4215
  var useMediaBuffering = ({
3885
4216
  element,
3886
4217
  shouldBuffer,
@@ -3892,7 +4223,7 @@ var useMediaBuffering = ({
3892
4223
  }) => {
3893
4224
  const buffer = useBufferState();
3894
4225
  const [isBuffering, setIsBuffering] = useState12(false);
3895
- useEffect6(() => {
4226
+ useEffect8(() => {
3896
4227
  let cleanupFns = [];
3897
4228
  const { current } = element;
3898
4229
  if (!current) {
@@ -4020,15 +4351,15 @@ var useMediaBuffering = ({
4020
4351
  };
4021
4352
 
4022
4353
  // src/use-request-video-callback-time.ts
4023
- import { useEffect as useEffect7, useRef as useRef12 } from "react";
4354
+ import { useEffect as useEffect9, useRef as useRef13 } from "react";
4024
4355
  var useRequestVideoCallbackTime = ({
4025
4356
  mediaRef,
4026
4357
  mediaType,
4027
4358
  lastSeek,
4028
4359
  onVariableFpsVideoDetected
4029
4360
  }) => {
4030
- const currentTime = useRef12(null);
4031
- useEffect7(() => {
4361
+ const currentTime = useRef13(null);
4362
+ useEffect9(() => {
4032
4363
  const { current } = mediaRef;
4033
4364
  if (current) {
4034
4365
  currentTime.current = {
@@ -4260,17 +4591,17 @@ var useMediaPlayback = ({
4260
4591
  const frame = useCurrentFrame();
4261
4592
  const absoluteFrame = useTimelinePosition();
4262
4593
  const [playing] = usePlayingState();
4263
- const buffering = useContext22(BufferingContextReact);
4594
+ const buffering = useContext24(BufferingContextReact);
4264
4595
  const { fps } = useVideoConfig();
4265
4596
  const mediaStartsAt = useMediaStartsAt();
4266
- const lastSeekDueToShift = useRef13(null);
4267
- const lastSeek = useRef13(null);
4597
+ const lastSeekDueToShift = useRef14(null);
4598
+ const lastSeek = useRef14(null);
4268
4599
  const logLevel = useLogLevel();
4269
4600
  const mountTime = useMountTime();
4270
4601
  if (!buffering) {
4271
4602
  throw new Error("useMediaPlayback must be used inside a <BufferingContext>");
4272
4603
  }
4273
- const isVariableFpsVideoMap = useRef13({});
4604
+ const isVariableFpsVideoMap = useRef14({});
4274
4605
  const onVariableFpsVideoDetected = useCallback10(() => {
4275
4606
  if (!src) {
4276
4607
  return;
@@ -4322,7 +4653,7 @@ var useMediaPlayback = ({
4322
4653
  return acceptableTimeshift ?? defaultAcceptableTimeshift;
4323
4654
  })();
4324
4655
  const isPlayerBuffering = useIsPlayerBuffering(buffering);
4325
- useEffect8(() => {
4656
+ useEffect10(() => {
4326
4657
  if (mediaRef.current?.paused) {
4327
4658
  return;
4328
4659
  }
@@ -4367,7 +4698,7 @@ var useMediaPlayback = ({
4367
4698
  mediaRef.current.playbackRate = playbackRateToSet;
4368
4699
  }
4369
4700
  }, [mediaRef, playbackRate]);
4370
- useEffect8(() => {
4701
+ useEffect10(() => {
4371
4702
  const tagName = mediaType === "audio" ? "<Html5Audio>" : "<Html5Video>";
4372
4703
  if (!mediaRef.current) {
4373
4704
  throw new Error(`No ${mediaType} ref found`);
@@ -4486,7 +4817,7 @@ var useMediaPlayback = ({
4486
4817
  };
4487
4818
 
4488
4819
  // src/use-media-tag.ts
4489
- import { useEffect as useEffect9 } from "react";
4820
+ import { useEffect as useEffect11 } from "react";
4490
4821
  var useMediaTag = ({
4491
4822
  mediaRef,
4492
4823
  id,
@@ -4499,7 +4830,7 @@ var useMediaTag = ({
4499
4830
  const logLevel = useLogLevel();
4500
4831
  const mountTime = useMountTime();
4501
4832
  const env = useRemotionEnvironment();
4502
- useEffect9(() => {
4833
+ useEffect11(() => {
4503
4834
  const tag = {
4504
4835
  id,
4505
4836
  play: (reason) => {
@@ -4540,12 +4871,12 @@ var useMediaTag = ({
4540
4871
  };
4541
4872
 
4542
4873
  // src/volume-position-state.ts
4543
- import { createContext as createContext18, useContext as useContext23, useMemo as useMemo21 } from "react";
4544
- var MediaVolumeContext = createContext18({
4874
+ import { createContext as createContext19, useContext as useContext25, useMemo as useMemo23 } from "react";
4875
+ var MediaVolumeContext = createContext19({
4545
4876
  mediaMuted: false,
4546
4877
  mediaVolume: 1
4547
4878
  });
4548
- var SetMediaVolumeContext = createContext18({
4879
+ var SetMediaVolumeContext = createContext19({
4549
4880
  setMediaMuted: () => {
4550
4881
  throw new Error("default");
4551
4882
  },
@@ -4554,16 +4885,16 @@ var SetMediaVolumeContext = createContext18({
4554
4885
  }
4555
4886
  });
4556
4887
  var useMediaVolumeState = () => {
4557
- const { mediaVolume } = useContext23(MediaVolumeContext);
4558
- const { setMediaVolume } = useContext23(SetMediaVolumeContext);
4559
- return useMemo21(() => {
4888
+ const { mediaVolume } = useContext25(MediaVolumeContext);
4889
+ const { setMediaVolume } = useContext25(SetMediaVolumeContext);
4890
+ return useMemo23(() => {
4560
4891
  return [mediaVolume, setMediaVolume];
4561
4892
  }, [mediaVolume, setMediaVolume]);
4562
4893
  };
4563
4894
  var useMediaMutedState = () => {
4564
- const { mediaMuted } = useContext23(MediaVolumeContext);
4565
- const { setMediaMuted } = useContext23(SetMediaVolumeContext);
4566
- return useMemo21(() => {
4895
+ const { mediaMuted } = useContext25(MediaVolumeContext);
4896
+ const { setMediaMuted } = useContext25(SetMediaVolumeContext);
4897
+ return useMemo23(() => {
4567
4898
  return [mediaMuted, setMediaMuted];
4568
4899
  }, [mediaMuted, setMediaMuted]);
4569
4900
  };
@@ -4576,7 +4907,7 @@ var warnAboutTooHighVolume = (volume) => {
4576
4907
  };
4577
4908
 
4578
4909
  // src/audio/AudioForPreview.tsx
4579
- import { jsx as jsx17 } from "react/jsx-runtime";
4910
+ import { jsx as jsx20 } from "react/jsx-runtime";
4580
4911
  var AudioForDevelopmentForwardRefFunction = (props, ref) => {
4581
4912
  const [initialShouldPreMountAudioElements] = useState13(props.shouldPreMountAudioTags);
4582
4913
  if (props.shouldPreMountAudioTags !== initialShouldPreMountAudioElements) {
@@ -4617,12 +4948,12 @@ var AudioForDevelopmentForwardRefFunction = (props, ref) => {
4617
4948
  const [mediaVolume] = useMediaVolumeState();
4618
4949
  const [mediaMuted] = useMediaMutedState();
4619
4950
  const volumePropFrame = useFrameForVolumeProp(loopVolumeCurveBehavior ?? "repeat");
4620
- const { hidden } = useContext24(SequenceVisibilityToggleContext);
4951
+ const { hidden } = useContext26(SequenceVisibilityToggleContext);
4621
4952
  if (!src) {
4622
4953
  throw new TypeError("No 'src' was passed to <Html5Audio>.");
4623
4954
  }
4624
4955
  const preloadedSrc = usePreload(src);
4625
- const sequenceContext = useContext24(SequenceContext);
4956
+ const sequenceContext = useContext26(SequenceContext);
4626
4957
  const [timelineId] = useState13(() => String(Math.random()));
4627
4958
  const isSequenceHidden = hidden[timelineId] ?? false;
4628
4959
  const userPreferredVolume = evaluateVolume({
@@ -4636,7 +4967,7 @@ var AudioForDevelopmentForwardRefFunction = (props, ref) => {
4636
4967
  requestsVideoFrame: false,
4637
4968
  isClientSideRendering: false
4638
4969
  });
4639
- const propsToPass = useMemo22(() => {
4970
+ const propsToPass = useMemo24(() => {
4640
4971
  return {
4641
4972
  muted: muted || mediaMuted || isSequenceHidden || userPreferredVolume <= 0,
4642
4973
  src: preloadedSrc,
@@ -4654,7 +4985,7 @@ var AudioForDevelopmentForwardRefFunction = (props, ref) => {
4654
4985
  userPreferredVolume,
4655
4986
  crossOriginValue
4656
4987
  ]);
4657
- const id = useMemo22(() => `audio-${random(src ?? "")}-${sequenceContext?.relativeFrom}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.durationInFrames}-muted:${props.muted}-loop:${props.loop}`, [
4988
+ const id = useMemo24(() => `audio-${random(src ?? "")}-${sequenceContext?.relativeFrom}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.durationInFrames}-muted:${props.muted}-loop:${props.loop}`, [
4658
4989
  src,
4659
4990
  sequenceContext?.relativeFrom,
4660
4991
  sequenceContext?.cumulatedFrom,
@@ -4713,7 +5044,7 @@ var AudioForDevelopmentForwardRefFunction = (props, ref) => {
4713
5044
  volume: userPreferredVolume,
4714
5045
  shouldUseWebAudioApi: useWebAudioApi ?? false
4715
5046
  });
4716
- const effectToUse = React17.useInsertionEffect ?? React17.useLayoutEffect;
5047
+ const effectToUse = React19.useInsertionEffect ?? React19.useLayoutEffect;
4717
5048
  effectToUse(() => {
4718
5049
  return () => {
4719
5050
  requestAnimationFrame(() => {
@@ -4724,627 +5055,298 @@ var AudioForDevelopmentForwardRefFunction = (props, ref) => {
4724
5055
  useImperativeHandle4(ref, () => {
4725
5056
  return audioRef.current;
4726
5057
  }, [audioRef]);
4727
- const currentOnDurationCallback = useRef14(onDuration);
5058
+ const currentOnDurationCallback = useRef15(onDuration);
4728
5059
  currentOnDurationCallback.current = onDuration;
4729
- useEffect10(() => {
5060
+ useEffect12(() => {
4730
5061
  const { current } = audioRef;
4731
5062
  if (!current) {
4732
5063
  return;
4733
5064
  }
4734
- if (current.duration) {
4735
- currentOnDurationCallback.current?.(current.src, current.duration);
4736
- return;
4737
- }
4738
- const onLoadedMetadata = () => {
4739
- currentOnDurationCallback.current?.(current.src, current.duration);
4740
- };
4741
- current.addEventListener("loadedmetadata", onLoadedMetadata);
4742
- return () => {
4743
- current.removeEventListener("loadedmetadata", onLoadedMetadata);
4744
- };
4745
- }, [audioRef, src]);
4746
- if (initialShouldPreMountAudioElements) {
4747
- return null;
4748
- }
4749
- return /* @__PURE__ */ jsx17("audio", {
4750
- ref: audioRef,
4751
- preload: "metadata",
4752
- crossOrigin: crossOriginValue,
4753
- ...propsToPass
4754
- });
4755
- };
4756
- var AudioForPreview = forwardRef4(AudioForDevelopmentForwardRefFunction);
4757
-
4758
- // src/audio/AudioForRendering.tsx
4759
- import {
4760
- forwardRef as forwardRef5,
4761
- useContext as useContext25,
4762
- useEffect as useEffect11,
4763
- useImperativeHandle as useImperativeHandle5,
4764
- useLayoutEffect as useLayoutEffect8,
4765
- useMemo as useMemo23,
4766
- useRef as useRef15
4767
- } from "react";
4768
- import { jsx as jsx18 } from "react/jsx-runtime";
4769
- var AudioForRenderingRefForwardingFunction = (props, ref) => {
4770
- const audioRef = useRef15(null);
4771
- const {
4772
- volume: volumeProp,
4773
- playbackRate,
4774
- allowAmplificationDuringRender,
4775
- onDuration,
4776
- toneFrequency,
4777
- _remotionInternalNeedsDurationCalculation,
4778
- _remotionInternalNativeLoopPassed,
4779
- acceptableTimeShiftInSeconds,
4780
- name,
4781
- onNativeError,
4782
- delayRenderRetries,
4783
- delayRenderTimeoutInMilliseconds,
4784
- loopVolumeCurveBehavior,
4785
- pauseWhenBuffering,
4786
- audioStreamIndex,
4787
- ...nativeProps
4788
- } = props;
4789
- const absoluteFrame = useTimelinePosition();
4790
- const volumePropFrame = useFrameForVolumeProp(loopVolumeCurveBehavior ?? "repeat");
4791
- const frame = useCurrentFrame();
4792
- const sequenceContext = useContext25(SequenceContext);
4793
- const { registerRenderAsset, unregisterRenderAsset } = useContext25(RenderAssetManager);
4794
- const { delayRender: delayRender2, continueRender: continueRender2 } = useDelayRender();
4795
- const id = useMemo23(() => `audio-${random(props.src ?? "")}-${sequenceContext?.relativeFrom}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.durationInFrames}`, [
4796
- props.src,
4797
- sequenceContext?.relativeFrom,
4798
- sequenceContext?.cumulatedFrom,
4799
- sequenceContext?.durationInFrames
4800
- ]);
4801
- const volume = evaluateVolume({
4802
- volume: volumeProp,
4803
- frame: volumePropFrame,
4804
- mediaVolume: 1
4805
- });
4806
- warnAboutTooHighVolume(volume);
4807
- useImperativeHandle5(ref, () => {
4808
- return audioRef.current;
4809
- }, []);
4810
- useEffect11(() => {
4811
- if (!props.src) {
4812
- throw new Error("No src passed");
4813
- }
4814
- if (!window.remotion_audioEnabled) {
4815
- return;
4816
- }
4817
- if (props.muted) {
4818
- return;
4819
- }
4820
- if (volume <= 0) {
4821
- return;
4822
- }
4823
- registerRenderAsset({
4824
- type: "audio",
4825
- src: getAbsoluteSrc(props.src),
4826
- id,
4827
- frame: absoluteFrame,
4828
- volume,
4829
- mediaFrame: frame,
4830
- playbackRate: props.playbackRate ?? 1,
4831
- toneFrequency: toneFrequency ?? 1,
4832
- audioStartFrame: Math.max(0, -(sequenceContext?.relativeFrom ?? 0)),
4833
- audioStreamIndex: audioStreamIndex ?? 0
4834
- });
4835
- return () => unregisterRenderAsset(id);
4836
- }, [
4837
- props.muted,
4838
- props.src,
4839
- registerRenderAsset,
4840
- absoluteFrame,
4841
- id,
4842
- unregisterRenderAsset,
4843
- volume,
4844
- volumePropFrame,
4845
- frame,
4846
- playbackRate,
4847
- props.playbackRate,
4848
- toneFrequency,
4849
- sequenceContext?.relativeFrom,
4850
- audioStreamIndex
4851
- ]);
4852
- const { src } = props;
4853
- const needsToRenderAudioTag = ref || _remotionInternalNeedsDurationCalculation;
4854
- useLayoutEffect8(() => {
4855
- if (window.process?.env?.NODE_ENV === "test") {
4856
- return;
4857
- }
4858
- if (!needsToRenderAudioTag) {
4859
- return;
4860
- }
4861
- const newHandle = delayRender2("Loading <Html5Audio> duration with src=" + src, {
4862
- retries: delayRenderRetries ?? undefined,
4863
- timeoutInMilliseconds: delayRenderTimeoutInMilliseconds ?? undefined
4864
- });
4865
- const { current } = audioRef;
4866
- const didLoad = () => {
4867
- if (current?.duration) {
4868
- onDuration(current.src, current.duration);
4869
- }
4870
- continueRender2(newHandle);
4871
- };
4872
- if (current?.duration) {
4873
- onDuration(current.src, current.duration);
4874
- continueRender2(newHandle);
4875
- } else {
4876
- current?.addEventListener("loadedmetadata", didLoad, { once: true });
4877
- }
4878
- return () => {
4879
- current?.removeEventListener("loadedmetadata", didLoad);
4880
- continueRender2(newHandle);
4881
- };
4882
- }, [
4883
- src,
4884
- onDuration,
4885
- needsToRenderAudioTag,
4886
- delayRenderRetries,
4887
- delayRenderTimeoutInMilliseconds,
4888
- continueRender2,
4889
- delayRender2
4890
- ]);
4891
- if (!needsToRenderAudioTag) {
4892
- return null;
4893
- }
4894
- return /* @__PURE__ */ jsx18("audio", {
4895
- ref: audioRef,
4896
- ...nativeProps,
4897
- onError: onNativeError
4898
- });
4899
- };
4900
- var AudioForRendering = forwardRef5(AudioForRenderingRefForwardingFunction);
4901
-
4902
- // src/audio/Audio.tsx
4903
- import { jsx as jsx19 } from "react/jsx-runtime";
4904
- var AudioRefForwardingFunction = (props, ref) => {
4905
- const audioContext = useContext26(SharedAudioContext);
4906
- const {
4907
- startFrom,
4908
- endAt,
4909
- trimBefore,
4910
- trimAfter,
4911
- name,
4912
- stack,
4913
- pauseWhenBuffering,
4914
- showInTimeline,
4915
- onError: onRemotionError,
4916
- ...otherProps
4917
- } = props;
4918
- const { loop, ...propsOtherThanLoop } = props;
4919
- const { fps } = useVideoConfig();
4920
- const environment = useRemotionEnvironment();
4921
- if (environment.isClientSideRendering) {
4922
- throw new Error("<Html5Audio> is not supported in @remotion/web-renderer. Use <Audio> from @remotion/media instead. See https://remotion.dev/docs/client-side-rendering/limitations");
4923
- }
4924
- const { durations, setDurations } = useContext26(DurationsContext);
4925
- if (typeof props.src !== "string") {
4926
- throw new TypeError(`The \`<Html5Audio>\` tag requires a string for \`src\`, but got ${JSON.stringify(props.src)} instead.`);
4927
- }
4928
- const preloadedSrc = usePreload(props.src);
4929
- const onError = useCallback11((e) => {
4930
- console.log(e.currentTarget.error);
4931
- const errMessage = `Could not play audio with src ${preloadedSrc}: ${e.currentTarget.error}. See https://remotion.dev/docs/media-playback-error for help.`;
4932
- if (loop) {
4933
- if (onRemotionError) {
4934
- onRemotionError(new Error(errMessage));
4935
- return;
4936
- }
4937
- cancelRender(new Error(errMessage));
4938
- } else {
4939
- onRemotionError?.(new Error(errMessage));
4940
- console.warn(errMessage);
4941
- }
4942
- }, [loop, onRemotionError, preloadedSrc]);
4943
- const onDuration = useCallback11((src, durationInSeconds) => {
4944
- setDurations({ type: "got-duration", durationInSeconds, src });
4945
- }, [setDurations]);
4946
- const durationFetched = durations[getAbsoluteSrc(preloadedSrc)] ?? durations[getAbsoluteSrc(props.src)];
4947
- validateMediaTrimProps({ startFrom, endAt, trimBefore, trimAfter });
4948
- const { trimBeforeValue, trimAfterValue } = resolveTrimProps({
4949
- startFrom,
4950
- endAt,
4951
- trimBefore,
4952
- trimAfter
4953
- });
4954
- if (loop && durationFetched !== undefined) {
4955
- if (!Number.isFinite(durationFetched)) {
4956
- return /* @__PURE__ */ jsx19(Html5Audio, {
4957
- ...propsOtherThanLoop,
4958
- ref,
4959
- _remotionInternalNativeLoopPassed: true
4960
- });
4961
- }
4962
- const duration = durationFetched * fps;
4963
- return /* @__PURE__ */ jsx19(Loop, {
4964
- layout: "none",
4965
- durationInFrames: calculateMediaDuration({
4966
- trimAfter: trimAfterValue,
4967
- mediaDurationInFrames: duration,
4968
- playbackRate: props.playbackRate ?? 1,
4969
- trimBefore: trimBeforeValue
4970
- }),
4971
- children: /* @__PURE__ */ jsx19(Html5Audio, {
4972
- ...propsOtherThanLoop,
4973
- ref,
4974
- _remotionInternalNativeLoopPassed: true
4975
- })
4976
- });
4977
- }
4978
- if (typeof trimBeforeValue !== "undefined" || typeof trimAfterValue !== "undefined") {
4979
- return /* @__PURE__ */ jsx19(Sequence, {
4980
- layout: "none",
4981
- from: 0 - (trimBeforeValue ?? 0),
4982
- showInTimeline: false,
4983
- durationInFrames: trimAfterValue,
4984
- name,
4985
- children: /* @__PURE__ */ jsx19(Html5Audio, {
4986
- _remotionInternalNeedsDurationCalculation: Boolean(loop),
4987
- pauseWhenBuffering: pauseWhenBuffering ?? false,
4988
- ...otherProps,
4989
- ref
4990
- })
4991
- });
4992
- }
4993
- validateMediaProps({ playbackRate: props.playbackRate, volume: props.volume }, "Html5Audio");
4994
- if (environment.isRendering) {
4995
- return /* @__PURE__ */ jsx19(AudioForRendering, {
4996
- onDuration,
4997
- ...props,
4998
- ref,
4999
- onNativeError: onError,
5000
- _remotionInternalNeedsDurationCalculation: Boolean(loop)
5001
- });
5002
- }
5003
- return /* @__PURE__ */ jsx19(AudioForPreview, {
5004
- _remotionInternalNativeLoopPassed: props._remotionInternalNativeLoopPassed ?? false,
5005
- _remotionInternalStack: stack ?? null,
5006
- shouldPreMountAudioTags: audioContext !== null && audioContext.numberOfAudioTags > 0,
5007
- ...props,
5008
- ref,
5009
- onNativeError: onError,
5010
- onDuration,
5011
- pauseWhenBuffering: pauseWhenBuffering ?? false,
5012
- _remotionInternalNeedsDurationCalculation: Boolean(loop),
5013
- showInTimeline: showInTimeline ?? true
5014
- });
5015
- };
5016
- var Html5Audio = forwardRef6(AudioRefForwardingFunction);
5017
- addSequenceStackTraces(Html5Audio);
5018
- var Audio = Html5Audio;
5019
- // src/Composition.tsx
5020
- import { Suspense, useContext as useContext28, useEffect as useEffect13 } from "react";
5021
- import { createPortal } from "react-dom";
5022
-
5023
- // src/Folder.tsx
5024
- import { createContext as createContext19, useContext as useContext27, useEffect as useEffect12, useMemo as useMemo24 } from "react";
5025
-
5026
- // src/validation/validate-folder-name.ts
5027
- var getRegex = () => /^([a-zA-Z0-9-\u4E00-\u9FFF])+$/g;
5028
- var isFolderNameValid = (name) => name.match(getRegex());
5029
- var validateFolderName = (name) => {
5030
- if (name === undefined || name === null) {
5031
- throw new TypeError("You must pass a name to a <Folder />.");
5032
- }
5033
- if (typeof name !== "string") {
5034
- throw new TypeError(`The "name" you pass into <Folder /> must be a string. Got: ${typeof name}`);
5035
- }
5036
- if (!isFolderNameValid(name)) {
5037
- throw new Error(`Folder name can only contain a-z, A-Z, 0-9 and -. You passed ${name}`);
5038
- }
5039
- };
5040
- var invalidFolderNameErrorMessage = `Folder name must match ${String(getRegex())}`;
5041
-
5042
- // src/Folder.tsx
5043
- import { jsx as jsx20 } from "react/jsx-runtime";
5044
- var FolderContext = createContext19({
5045
- folderName: null,
5046
- parentName: null
5047
- });
5048
- var Folder = ({ name, children }) => {
5049
- const parent = useContext27(FolderContext);
5050
- const { registerFolder, unregisterFolder } = useContext27(CompositionSetters);
5051
- const nonce = useNonce();
5052
- validateFolderName(name);
5053
- const parentNameArr = [parent.parentName, parent.folderName].filter(truthy);
5054
- const parentName = parentNameArr.length === 0 ? null : parentNameArr.join("/");
5055
- const value = useMemo24(() => {
5056
- return {
5057
- folderName: name,
5058
- parentName
5059
- };
5060
- }, [name, parentName]);
5061
- useEffect12(() => {
5062
- registerFolder(name, parentName, nonce.get());
5063
- return () => {
5064
- unregisterFolder(name, parentName);
5065
- };
5066
- }, [
5067
- name,
5068
- parent.folderName,
5069
- parentName,
5070
- registerFolder,
5071
- unregisterFolder,
5072
- nonce
5073
- ]);
5074
- return /* @__PURE__ */ jsx20(FolderContext.Provider, {
5075
- value,
5076
- children
5077
- });
5078
- };
5079
-
5080
- // src/loading-indicator.tsx
5081
- import { jsx as jsx21, jsxs as jsxs2 } from "react/jsx-runtime";
5082
- var rotate = {
5083
- transform: `rotate(90deg)`
5084
- };
5085
- var ICON_SIZE = 40;
5086
- var label = {
5087
- color: "white",
5088
- fontSize: 14,
5089
- fontFamily: "sans-serif"
5090
- };
5091
- var container = {
5092
- justifyContent: "center",
5093
- alignItems: "center"
5094
- };
5095
- var Loading = () => {
5096
- return /* @__PURE__ */ jsxs2(AbsoluteFill, {
5097
- style: container,
5098
- id: "remotion-comp-loading",
5099
- children: [
5100
- /* @__PURE__ */ jsx21("style", {
5101
- type: "text/css",
5102
- children: `
5103
- @keyframes anim {
5104
- from {
5105
- opacity: 0
5106
- }
5107
- to {
5108
- opacity: 1
5109
- }
5110
- }
5111
- #remotion-comp-loading {
5112
- animation: anim 2s;
5113
- animation-fill-mode: forwards;
5114
- }
5115
- `
5116
- }),
5117
- /* @__PURE__ */ jsx21("svg", {
5118
- width: ICON_SIZE,
5119
- height: ICON_SIZE,
5120
- viewBox: "-100 -100 400 400",
5121
- style: rotate,
5122
- children: /* @__PURE__ */ jsx21("path", {
5123
- fill: "#555",
5124
- stroke: "#555",
5125
- strokeWidth: "100",
5126
- strokeLinejoin: "round",
5127
- d: "M 2 172 a 196 100 0 0 0 195 5 A 196 240 0 0 0 100 2.259 A 196 240 0 0 0 2 172 z"
5128
- })
5129
- }),
5130
- /* @__PURE__ */ jsxs2("p", {
5131
- style: label,
5132
- children: [
5133
- "Resolving ",
5134
- "<Suspense>",
5135
- "..."
5136
- ]
5137
- })
5138
- ]
5139
- });
5140
- };
5141
-
5142
- // src/portal-node.ts
5143
- var _portalNode = null;
5144
- var portalNode = () => {
5145
- if (!_portalNode) {
5146
- if (typeof document === "undefined") {
5147
- throw new Error("Tried to call an API that only works in the browser from outside the browser");
5148
- }
5149
- _portalNode = document.createElement("div");
5150
- _portalNode.style.position = "absolute";
5151
- _portalNode.style.top = "0px";
5152
- _portalNode.style.left = "0px";
5153
- _portalNode.style.right = "0px";
5154
- _portalNode.style.bottom = "0px";
5155
- _portalNode.style.width = "100%";
5156
- _portalNode.style.height = "100%";
5157
- _portalNode.style.display = "flex";
5158
- _portalNode.style.flexDirection = "column";
5159
- const containerNode = document.createElement("div");
5160
- containerNode.style.position = "fixed";
5161
- containerNode.style.top = -999999 + "px";
5162
- containerNode.appendChild(_portalNode);
5163
- document.body.appendChild(containerNode);
5164
- }
5165
- return _portalNode;
5166
- };
5167
-
5168
- // src/use-lazy-component.ts
5169
- import React20, { useMemo as useMemo25, useRef as useRef16 } from "react";
5170
- var useLazyComponent = ({
5171
- compProps,
5172
- componentName,
5173
- noSuspense
5174
- }) => {
5175
- const componentRef = useRef16(null);
5176
- if ("component" in compProps) {
5177
- componentRef.current = compProps.component;
5178
- }
5179
- const lazy = useMemo25(() => {
5180
- if ("component" in compProps) {
5181
- if (typeof document === "undefined" || noSuspense) {
5182
- return compProps.component;
5183
- }
5184
- if (typeof compProps.component === "undefined") {
5185
- throw new Error(`A value of \`undefined\` was passed to the \`component\` prop. Check the value you are passing to the <${componentName}/> component.`);
5186
- }
5187
- const Wrapper = (props2) => {
5188
- const Comp = componentRef.current;
5189
- return React20.createElement(Comp, props2);
5190
- };
5191
- return Wrapper;
5192
- }
5193
- if ("lazyComponent" in compProps && typeof compProps.lazyComponent !== "undefined") {
5194
- if (typeof compProps.lazyComponent === "undefined") {
5195
- throw new Error(`A value of \`undefined\` was passed to the \`lazyComponent\` prop. Check the value you are passing to the <${componentName}/> component.`);
5196
- }
5197
- return React20.lazy(compProps.lazyComponent);
5065
+ if (current.duration) {
5066
+ currentOnDurationCallback.current?.(current.src, current.duration);
5067
+ return;
5198
5068
  }
5199
- throw new Error("You must pass either 'component' or 'lazyComponent'");
5200
- }, [compProps.lazyComponent]);
5201
- return lazy;
5202
- };
5203
-
5204
- // src/validation/validate-composition-id.ts
5205
- var getRegex2 = () => /^([a-zA-Z0-9-\u4E00-\u9FFF])+$/g;
5206
- var isCompositionIdValid = (id) => id.match(getRegex2());
5207
- var validateCompositionId = (id) => {
5208
- if (!isCompositionIdValid(id)) {
5209
- throw new Error(`Composition id can only contain a-z, A-Z, 0-9, CJK characters and -. You passed ${id}`);
5210
- }
5211
- };
5212
- var invalidCompositionErrorMessage = `Composition ID must match ${String(getRegex2())}`;
5213
-
5214
- // src/validation/validate-default-props.ts
5215
- var validateDefaultAndInputProps = (defaultProps, name, compositionId) => {
5216
- if (!defaultProps) {
5217
- return;
5218
- }
5219
- if (typeof defaultProps !== "object") {
5220
- throw new Error(`"${name}" must be an object, but you passed a value of type ${typeof defaultProps}`);
5221
- }
5222
- if (Array.isArray(defaultProps)) {
5223
- throw new Error(`"${name}" must be an object, an array was passed ${compositionId ? `for composition "${compositionId}"` : ""}`);
5069
+ const onLoadedMetadata = () => {
5070
+ currentOnDurationCallback.current?.(current.src, current.duration);
5071
+ };
5072
+ current.addEventListener("loadedmetadata", onLoadedMetadata);
5073
+ return () => {
5074
+ current.removeEventListener("loadedmetadata", onLoadedMetadata);
5075
+ };
5076
+ }, [audioRef, src]);
5077
+ if (initialShouldPreMountAudioElements) {
5078
+ return null;
5224
5079
  }
5080
+ return /* @__PURE__ */ jsx20("audio", {
5081
+ ref: audioRef,
5082
+ preload: "metadata",
5083
+ crossOrigin: crossOriginValue,
5084
+ ...propsToPass
5085
+ });
5225
5086
  };
5087
+ var AudioForPreview = forwardRef4(AudioForDevelopmentForwardRefFunction);
5226
5088
 
5227
- // src/Composition.tsx
5228
- import { jsx as jsx22 } from "react/jsx-runtime";
5229
- var Fallback = () => {
5230
- const { continueRender: continueRender2, delayRender: delayRender2 } = useDelayRender();
5231
- useEffect13(() => {
5232
- const fallback = delayRender2("Waiting for Root component to unsuspend");
5233
- return () => continueRender2(fallback);
5234
- }, [continueRender2, delayRender2]);
5235
- return null;
5236
- };
5237
- var InnerComposition = ({
5238
- width,
5239
- height,
5240
- fps,
5241
- durationInFrames,
5242
- id,
5243
- defaultProps,
5244
- schema,
5245
- ...compProps
5246
- }) => {
5247
- const compManager = useContext28(CompositionSetters);
5248
- const { registerComposition, unregisterComposition } = compManager;
5249
- const video = useVideo();
5250
- const lazy = useLazyComponent({
5251
- compProps,
5252
- componentName: "Composition",
5253
- noSuspense: false
5089
+ // src/audio/AudioForRendering.tsx
5090
+ import {
5091
+ forwardRef as forwardRef5,
5092
+ useContext as useContext27,
5093
+ useEffect as useEffect13,
5094
+ useImperativeHandle as useImperativeHandle5,
5095
+ useLayoutEffect as useLayoutEffect8,
5096
+ useMemo as useMemo25,
5097
+ useRef as useRef16
5098
+ } from "react";
5099
+ import { jsx as jsx21 } from "react/jsx-runtime";
5100
+ var AudioForRenderingRefForwardingFunction = (props, ref) => {
5101
+ const audioRef = useRef16(null);
5102
+ const {
5103
+ volume: volumeProp,
5104
+ playbackRate,
5105
+ allowAmplificationDuringRender,
5106
+ onDuration,
5107
+ toneFrequency,
5108
+ _remotionInternalNeedsDurationCalculation,
5109
+ _remotionInternalNativeLoopPassed,
5110
+ acceptableTimeShiftInSeconds,
5111
+ name,
5112
+ onNativeError,
5113
+ delayRenderRetries,
5114
+ delayRenderTimeoutInMilliseconds,
5115
+ loopVolumeCurveBehavior,
5116
+ pauseWhenBuffering,
5117
+ audioStreamIndex,
5118
+ ...nativeProps
5119
+ } = props;
5120
+ const absoluteFrame = useTimelinePosition();
5121
+ const volumePropFrame = useFrameForVolumeProp(loopVolumeCurveBehavior ?? "repeat");
5122
+ const frame = useCurrentFrame();
5123
+ const sequenceContext = useContext27(SequenceContext);
5124
+ const { registerRenderAsset, unregisterRenderAsset } = useContext27(RenderAssetManager);
5125
+ const { delayRender: delayRender2, continueRender: continueRender2 } = useDelayRender();
5126
+ const id = useMemo25(() => `audio-${random(props.src ?? "")}-${sequenceContext?.relativeFrom}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.durationInFrames}`, [
5127
+ props.src,
5128
+ sequenceContext?.relativeFrom,
5129
+ sequenceContext?.cumulatedFrom,
5130
+ sequenceContext?.durationInFrames
5131
+ ]);
5132
+ const volume = evaluateVolume({
5133
+ volume: volumeProp,
5134
+ frame: volumePropFrame,
5135
+ mediaVolume: 1
5254
5136
  });
5255
- const nonce = useNonce();
5256
- const isPlayer = useIsPlayer();
5257
- const environment = useRemotionEnvironment();
5258
- const canUseComposition = useContext28(CanUseRemotionHooks);
5259
- if (typeof window !== "undefined") {
5260
- window.remotion_seenCompositionIds = Array.from(new Set([...window.remotion_seenCompositionIds ?? [], id]));
5261
- }
5262
- if (canUseComposition) {
5263
- if (isPlayer) {
5264
- throw new Error("<Composition> was mounted inside the `component` that was passed to the <Player>. See https://remotion.dev/docs/wrong-composition-mount for help.");
5265
- }
5266
- throw new Error("<Composition> mounted inside another composition. See https://remotion.dev/docs/wrong-composition-mount for help.");
5267
- }
5268
- const { folderName, parentName } = useContext28(FolderContext);
5137
+ warnAboutTooHighVolume(volume);
5138
+ useImperativeHandle5(ref, () => {
5139
+ return audioRef.current;
5140
+ }, []);
5269
5141
  useEffect13(() => {
5270
- if (!id) {
5271
- throw new Error("No id for composition passed.");
5142
+ if (!props.src) {
5143
+ throw new Error("No src passed");
5272
5144
  }
5273
- validateCompositionId(id);
5274
- validateDefaultAndInputProps(defaultProps, "defaultProps", id);
5275
- registerComposition({
5276
- durationInFrames: durationInFrames ?? undefined,
5277
- fps: fps ?? undefined,
5278
- height: height ?? undefined,
5279
- width: width ?? undefined,
5145
+ if (!window.remotion_audioEnabled) {
5146
+ return;
5147
+ }
5148
+ if (props.muted) {
5149
+ return;
5150
+ }
5151
+ if (volume <= 0) {
5152
+ return;
5153
+ }
5154
+ registerRenderAsset({
5155
+ type: "audio",
5156
+ src: getAbsoluteSrc(props.src),
5280
5157
  id,
5281
- folderName,
5282
- component: lazy,
5283
- defaultProps: serializeThenDeserializeInStudio(defaultProps ?? {}),
5284
- nonce: nonce.get(),
5285
- parentFolderName: parentName,
5286
- schema: schema ?? null,
5287
- calculateMetadata: compProps.calculateMetadata ?? null
5158
+ frame: absoluteFrame,
5159
+ volume,
5160
+ mediaFrame: frame,
5161
+ playbackRate: props.playbackRate ?? 1,
5162
+ toneFrequency: toneFrequency ?? 1,
5163
+ audioStartFrame: Math.max(0, -(sequenceContext?.relativeFrom ?? 0)),
5164
+ audioStreamIndex: audioStreamIndex ?? 0
5165
+ });
5166
+ return () => unregisterRenderAsset(id);
5167
+ }, [
5168
+ props.muted,
5169
+ props.src,
5170
+ registerRenderAsset,
5171
+ absoluteFrame,
5172
+ id,
5173
+ unregisterRenderAsset,
5174
+ volume,
5175
+ volumePropFrame,
5176
+ frame,
5177
+ playbackRate,
5178
+ props.playbackRate,
5179
+ toneFrequency,
5180
+ sequenceContext?.relativeFrom,
5181
+ audioStreamIndex
5182
+ ]);
5183
+ const { src } = props;
5184
+ const needsToRenderAudioTag = ref || _remotionInternalNeedsDurationCalculation;
5185
+ useLayoutEffect8(() => {
5186
+ if (window.process?.env?.NODE_ENV === "test") {
5187
+ return;
5188
+ }
5189
+ if (!needsToRenderAudioTag) {
5190
+ return;
5191
+ }
5192
+ const newHandle = delayRender2("Loading <Html5Audio> duration with src=" + src, {
5193
+ retries: delayRenderRetries ?? undefined,
5194
+ timeoutInMilliseconds: delayRenderTimeoutInMilliseconds ?? undefined
5288
5195
  });
5196
+ const { current } = audioRef;
5197
+ const didLoad = () => {
5198
+ if (current?.duration) {
5199
+ onDuration(current.src, current.duration);
5200
+ }
5201
+ continueRender2(newHandle);
5202
+ };
5203
+ if (current?.duration) {
5204
+ onDuration(current.src, current.duration);
5205
+ continueRender2(newHandle);
5206
+ } else {
5207
+ current?.addEventListener("loadedmetadata", didLoad, { once: true });
5208
+ }
5289
5209
  return () => {
5290
- unregisterComposition(id);
5210
+ current?.removeEventListener("loadedmetadata", didLoad);
5211
+ continueRender2(newHandle);
5291
5212
  };
5292
5213
  }, [
5293
- durationInFrames,
5294
- fps,
5295
- height,
5296
- lazy,
5297
- id,
5298
- folderName,
5299
- defaultProps,
5300
- width,
5301
- nonce,
5302
- parentName,
5303
- schema,
5304
- compProps.calculateMetadata,
5305
- registerComposition,
5306
- unregisterComposition
5214
+ src,
5215
+ onDuration,
5216
+ needsToRenderAudioTag,
5217
+ delayRenderRetries,
5218
+ delayRenderTimeoutInMilliseconds,
5219
+ continueRender2,
5220
+ delayRender2
5307
5221
  ]);
5308
- const resolved = useResolvedVideoConfig(id);
5309
- if (environment.isStudio && video && video.component === lazy && video.id === id) {
5310
- const Comp = lazy;
5311
- if (resolved === null || resolved.type !== "success" && resolved.type !== "success-and-refreshing") {
5312
- return null;
5222
+ if (!needsToRenderAudioTag) {
5223
+ return null;
5224
+ }
5225
+ return /* @__PURE__ */ jsx21("audio", {
5226
+ ref: audioRef,
5227
+ ...nativeProps,
5228
+ onError: onNativeError
5229
+ });
5230
+ };
5231
+ var AudioForRendering = forwardRef5(AudioForRenderingRefForwardingFunction);
5232
+
5233
+ // src/audio/Audio.tsx
5234
+ import { jsx as jsx22 } from "react/jsx-runtime";
5235
+ var AudioRefForwardingFunction = (props, ref) => {
5236
+ const audioContext = useContext28(SharedAudioContext);
5237
+ const {
5238
+ startFrom,
5239
+ endAt,
5240
+ trimBefore,
5241
+ trimAfter,
5242
+ name,
5243
+ stack,
5244
+ pauseWhenBuffering,
5245
+ showInTimeline,
5246
+ onError: onRemotionError,
5247
+ ...otherProps
5248
+ } = props;
5249
+ const { loop, ...propsOtherThanLoop } = props;
5250
+ const { fps } = useVideoConfig();
5251
+ const environment = useRemotionEnvironment();
5252
+ if (environment.isClientSideRendering) {
5253
+ throw new Error("<Html5Audio> is not supported in @remotion/web-renderer. Use <Audio> from @remotion/media instead. See https://remotion.dev/docs/client-side-rendering/limitations");
5254
+ }
5255
+ const { durations, setDurations } = useContext28(DurationsContext);
5256
+ if (typeof props.src !== "string") {
5257
+ throw new TypeError(`The \`<Html5Audio>\` tag requires a string for \`src\`, but got ${JSON.stringify(props.src)} instead.`);
5258
+ }
5259
+ const preloadedSrc = usePreload(props.src);
5260
+ const onError = useCallback11((e) => {
5261
+ console.log(e.currentTarget.error);
5262
+ const errMessage = `Could not play audio with src ${preloadedSrc}: ${e.currentTarget.error}. See https://remotion.dev/docs/media-playback-error for help.`;
5263
+ if (loop) {
5264
+ if (onRemotionError) {
5265
+ onRemotionError(new Error(errMessage));
5266
+ return;
5267
+ }
5268
+ cancelRender(new Error(errMessage));
5269
+ } else {
5270
+ onRemotionError?.(new Error(errMessage));
5271
+ console.warn(errMessage);
5313
5272
  }
5314
- return createPortal(/* @__PURE__ */ jsx22(CanUseRemotionHooksProvider, {
5315
- children: /* @__PURE__ */ jsx22(Suspense, {
5316
- fallback: /* @__PURE__ */ jsx22(Loading, {}),
5317
- children: /* @__PURE__ */ jsx22(Comp, {
5318
- ...resolved.result.props ?? {}
5319
- })
5273
+ }, [loop, onRemotionError, preloadedSrc]);
5274
+ const onDuration = useCallback11((src, durationInSeconds) => {
5275
+ setDurations({ type: "got-duration", durationInSeconds, src });
5276
+ }, [setDurations]);
5277
+ const durationFetched = durations[getAbsoluteSrc(preloadedSrc)] ?? durations[getAbsoluteSrc(props.src)];
5278
+ validateMediaTrimProps({ startFrom, endAt, trimBefore, trimAfter });
5279
+ const { trimBeforeValue, trimAfterValue } = resolveTrimProps({
5280
+ startFrom,
5281
+ endAt,
5282
+ trimBefore,
5283
+ trimAfter
5284
+ });
5285
+ if (loop && durationFetched !== undefined) {
5286
+ if (!Number.isFinite(durationFetched)) {
5287
+ return /* @__PURE__ */ jsx22(Html5Audio, {
5288
+ ...propsOtherThanLoop,
5289
+ ref,
5290
+ _remotionInternalNativeLoopPassed: true
5291
+ });
5292
+ }
5293
+ const duration = durationFetched * fps;
5294
+ return /* @__PURE__ */ jsx22(Loop, {
5295
+ layout: "none",
5296
+ durationInFrames: calculateMediaDuration({
5297
+ trimAfter: trimAfterValue,
5298
+ mediaDurationInFrames: duration,
5299
+ playbackRate: props.playbackRate ?? 1,
5300
+ trimBefore: trimBeforeValue
5301
+ }),
5302
+ children: /* @__PURE__ */ jsx22(Html5Audio, {
5303
+ ...propsOtherThanLoop,
5304
+ ref,
5305
+ _remotionInternalNativeLoopPassed: true
5320
5306
  })
5321
- }), portalNode());
5307
+ });
5322
5308
  }
5323
- if (environment.isRendering && video && video.component === lazy && video.id === id) {
5324
- const Comp = lazy;
5325
- if (resolved === null || resolved.type !== "success" && resolved.type !== "success-and-refreshing") {
5326
- return null;
5327
- }
5328
- return createPortal(/* @__PURE__ */ jsx22(CanUseRemotionHooksProvider, {
5329
- children: /* @__PURE__ */ jsx22(Suspense, {
5330
- fallback: /* @__PURE__ */ jsx22(Fallback, {}),
5331
- children: /* @__PURE__ */ jsx22(Comp, {
5332
- ...resolved.result.props ?? {}
5333
- })
5309
+ if (typeof trimBeforeValue !== "undefined" || typeof trimAfterValue !== "undefined") {
5310
+ return /* @__PURE__ */ jsx22(Sequence, {
5311
+ layout: "none",
5312
+ from: 0 - (trimBeforeValue ?? 0),
5313
+ showInTimeline: false,
5314
+ durationInFrames: trimAfterValue,
5315
+ name,
5316
+ children: /* @__PURE__ */ jsx22(Html5Audio, {
5317
+ _remotionInternalNeedsDurationCalculation: Boolean(loop),
5318
+ pauseWhenBuffering: pauseWhenBuffering ?? false,
5319
+ ...otherProps,
5320
+ ref
5334
5321
  })
5335
- }), portalNode());
5322
+ });
5336
5323
  }
5337
- return null;
5338
- };
5339
- var Composition = (props2) => {
5340
- const { onlyRenderComposition } = useContext28(CompositionSetters);
5341
- if (onlyRenderComposition && onlyRenderComposition !== props2.id) {
5342
- return null;
5324
+ validateMediaProps({ playbackRate: props.playbackRate, volume: props.volume }, "Html5Audio");
5325
+ if (environment.isRendering) {
5326
+ return /* @__PURE__ */ jsx22(AudioForRendering, {
5327
+ onDuration,
5328
+ ...props,
5329
+ ref,
5330
+ onNativeError: onError,
5331
+ _remotionInternalNeedsDurationCalculation: Boolean(loop)
5332
+ });
5343
5333
  }
5344
- return /* @__PURE__ */ jsx22(InnerComposition, {
5345
- ...props2
5334
+ return /* @__PURE__ */ jsx22(AudioForPreview, {
5335
+ _remotionInternalNativeLoopPassed: props._remotionInternalNativeLoopPassed ?? false,
5336
+ _remotionInternalStack: stack ?? null,
5337
+ shouldPreMountAudioTags: audioContext !== null && audioContext.numberOfAudioTags > 0,
5338
+ ...props,
5339
+ ref,
5340
+ onNativeError: onError,
5341
+ onDuration,
5342
+ pauseWhenBuffering: pauseWhenBuffering ?? false,
5343
+ _remotionInternalNeedsDurationCalculation: Boolean(loop),
5344
+ showInTimeline: showInTimeline ?? true
5346
5345
  });
5347
5346
  };
5347
+ var Html5Audio = forwardRef6(AudioRefForwardingFunction);
5348
+ addSequenceStackTraces(Html5Audio);
5349
+ var Audio = Html5Audio;
5348
5350
  // src/bezier.ts
5349
5351
  var NEWTON_ITERATIONS = 4;
5350
5352
  var NEWTON_MIN_SLOPE = 0.001;
@@ -5553,59 +5555,254 @@ var getStaticFiles = () => {
5553
5555
  warnPlayerOnce();
5554
5556
  return [];
5555
5557
  }
5556
- return window.remotion_staticFiles;
5558
+ return window.remotion_staticFiles;
5559
+ };
5560
+ // src/IFrame.tsx
5561
+ import { forwardRef as forwardRef7, useCallback as useCallback12, useState as useState14 } from "react";
5562
+ import { jsx as jsx23 } from "react/jsx-runtime";
5563
+ var IFrameRefForwarding = ({
5564
+ onLoad,
5565
+ onError,
5566
+ delayRenderRetries,
5567
+ delayRenderTimeoutInMilliseconds,
5568
+ ...props2
5569
+ }, ref) => {
5570
+ const { delayRender: delayRender2, continueRender: continueRender2 } = useDelayRender();
5571
+ const [handle] = useState14(() => delayRender2(`Loading <IFrame> with source ${props2.src}`, {
5572
+ retries: delayRenderRetries ?? undefined,
5573
+ timeoutInMilliseconds: delayRenderTimeoutInMilliseconds ?? undefined
5574
+ }));
5575
+ const didLoad = useCallback12((e) => {
5576
+ continueRender2(handle);
5577
+ onLoad?.(e);
5578
+ }, [handle, onLoad, continueRender2]);
5579
+ const didGetError = useCallback12((e) => {
5580
+ continueRender2(handle);
5581
+ if (onError) {
5582
+ onError(e);
5583
+ } else {
5584
+ console.error("Error loading iframe:", e, "Handle the event using the onError() prop to make this message disappear.");
5585
+ }
5586
+ }, [handle, onError, continueRender2]);
5587
+ return /* @__PURE__ */ jsx23("iframe", {
5588
+ referrerPolicy: "strict-origin-when-cross-origin",
5589
+ ...props2,
5590
+ ref,
5591
+ onError: didGetError,
5592
+ onLoad: didLoad
5593
+ });
5594
+ };
5595
+ var IFrame = forwardRef7(IFrameRefForwarding);
5596
+ // src/Img.tsx
5597
+ import {
5598
+ useCallback as useCallback13,
5599
+ useContext as useContext30,
5600
+ useImperativeHandle as useImperativeHandle6,
5601
+ useLayoutEffect as useLayoutEffect9,
5602
+ useRef as useRef17,
5603
+ useState as useState16
5604
+ } from "react";
5605
+
5606
+ // src/wrap-in-schema.ts
5607
+ import React23, { forwardRef as forwardRef8, useMemo as useMemo27 } from "react";
5608
+
5609
+ // src/use-schema.ts
5610
+ import { useContext as useContext29, useMemo as useMemo26, useState as useState15 } from "react";
5611
+
5612
+ // src/get-effective-visual-mode-value.ts
5613
+ var getEffectiveVisualModeValue = ({
5614
+ codeValue,
5615
+ runtimeValue,
5616
+ dragOverrideValue,
5617
+ defaultValue,
5618
+ shouldResortToDefaultValueIfUndefined = false
5619
+ }) => {
5620
+ if (dragOverrideValue !== undefined) {
5621
+ return dragOverrideValue;
5622
+ }
5623
+ if (!codeValue) {
5624
+ return runtimeValue;
5625
+ }
5626
+ if (!codeValue.canUpdate) {
5627
+ return runtimeValue;
5628
+ }
5629
+ if (codeValue.codeValue === undefined && shouldResortToDefaultValueIfUndefined) {
5630
+ return defaultValue;
5631
+ }
5632
+ return codeValue.codeValue;
5633
+ };
5634
+
5635
+ // src/use-schema.ts
5636
+ var useSchema = (schema, currentValue) => {
5637
+ const env = useRemotionEnvironment();
5638
+ const earlyReturn = useMemo26(() => {
5639
+ if (!env.isStudio || env.isReadOnlyStudio) {
5640
+ return {
5641
+ controls: undefined,
5642
+ values: currentValue ?? {}
5643
+ };
5644
+ }
5645
+ return;
5646
+ }, [env.isStudio, env.isReadOnlyStudio, currentValue]);
5647
+ if (earlyReturn) {
5648
+ return earlyReturn;
5649
+ }
5650
+ const [overrideId] = useState15(() => String(Math.random()));
5651
+ const {
5652
+ visualModeEnabled,
5653
+ dragOverrides: overrides,
5654
+ codeValues
5655
+ } = useContext29(VisualModeOverridesContext);
5656
+ const controls = useMemo26(() => {
5657
+ if (!visualModeEnabled) {
5658
+ return;
5659
+ }
5660
+ if (schema === null || currentValue === null) {
5661
+ return;
5662
+ }
5663
+ return {
5664
+ schema,
5665
+ currentValue,
5666
+ overrideId
5667
+ };
5668
+ }, [schema, currentValue, overrideId, visualModeEnabled]);
5669
+ return useMemo26(() => {
5670
+ if (controls === undefined || currentValue === null || schema === null || !visualModeEnabled) {
5671
+ return {
5672
+ controls: undefined,
5673
+ values: currentValue ?? {}
5674
+ };
5675
+ }
5676
+ const overrideValues = overrides[overrideId] ?? {};
5677
+ const propStatus = codeValues[overrideId];
5678
+ const currentValueKeys = Object.keys(currentValue);
5679
+ const keysToUpdate = [...new Set(currentValueKeys)];
5680
+ const merged = {};
5681
+ for (const key of keysToUpdate) {
5682
+ const codeValueStatus = propStatus?.[key] ?? null;
5683
+ merged[key] = getEffectiveVisualModeValue({
5684
+ codeValue: codeValueStatus,
5685
+ runtimeValue: currentValue[key],
5686
+ dragOverrideValue: overrideValues[key],
5687
+ defaultValue: schema[key]?.default,
5688
+ shouldResortToDefaultValueIfUndefined: false
5689
+ });
5690
+ }
5691
+ return {
5692
+ controls,
5693
+ values: merged
5694
+ };
5695
+ }, [
5696
+ controls,
5697
+ currentValue,
5698
+ overrideId,
5699
+ overrides,
5700
+ codeValues,
5701
+ schema,
5702
+ visualModeEnabled
5703
+ ]);
5704
+ };
5705
+
5706
+ // src/wrap-in-schema.ts
5707
+ var getNestedValue = (obj, key) => {
5708
+ const parts = key.split(".");
5709
+ let current = obj;
5710
+ for (const part of parts) {
5711
+ if (current === null || current === undefined || typeof current !== "object")
5712
+ return;
5713
+ current = current[part];
5714
+ }
5715
+ return current;
5716
+ };
5717
+ var mergeValues = (props2, values, schemaKeys) => {
5718
+ const merged = { ...props2 };
5719
+ for (const key of schemaKeys) {
5720
+ const value = values[key];
5721
+ const parts = key.split(".");
5722
+ if (parts.length === 1) {
5723
+ merged[key] = value;
5724
+ continue;
5725
+ }
5726
+ let current = merged;
5727
+ for (let i = 0;i < parts.length - 1; i++) {
5728
+ const part = parts[i];
5729
+ if (typeof current[part] === "object" && current[part] !== null) {
5730
+ current[part] = { ...current[part] };
5731
+ } else {
5732
+ current[part] = {};
5733
+ }
5734
+ current = current[part];
5735
+ }
5736
+ current[parts[parts.length - 1]] = value;
5737
+ }
5738
+ return merged;
5557
5739
  };
5558
- // src/IFrame.tsx
5559
- import { forwardRef as forwardRef7, useCallback as useCallback12, useState as useState14 } from "react";
5560
- import { jsx as jsx23 } from "react/jsx-runtime";
5561
- var IFrameRefForwarding = ({
5562
- onLoad,
5563
- onError,
5564
- delayRenderRetries,
5565
- delayRenderTimeoutInMilliseconds,
5566
- ...props2
5567
- }, ref) => {
5568
- const { delayRender: delayRender2, continueRender: continueRender2 } = useDelayRender();
5569
- const [handle] = useState14(() => delayRender2(`Loading <IFrame> with source ${props2.src}`, {
5570
- retries: delayRenderRetries ?? undefined,
5571
- timeoutInMilliseconds: delayRenderTimeoutInMilliseconds ?? undefined
5572
- }));
5573
- const didLoad = useCallback12((e) => {
5574
- continueRender2(handle);
5575
- onLoad?.(e);
5576
- }, [handle, onLoad, continueRender2]);
5577
- const didGetError = useCallback12((e) => {
5578
- continueRender2(handle);
5579
- if (onError) {
5580
- onError(e);
5581
- } else {
5582
- console.error("Error loading iframe:", e, "Handle the event using the onError() prop to make this message disappear.");
5740
+ var wrapInSchema = (Component, schema) => {
5741
+ const schemaKeys = Object.keys(schema);
5742
+ const Wrapped = forwardRef8((props2, ref) => {
5743
+ const env = useRemotionEnvironment();
5744
+ if (!env.isStudio || env.isReadOnlyStudio || env.isRendering || !process.env.EXPERIMENTAL_VISUAL_MODE_ENABLED) {
5745
+ return React23.createElement(Component, {
5746
+ ...props2,
5747
+ controls: null,
5748
+ ref
5749
+ });
5583
5750
  }
5584
- }, [handle, onError, continueRender2]);
5585
- return /* @__PURE__ */ jsx23("iframe", {
5586
- referrerPolicy: "strict-origin-when-cross-origin",
5587
- ...props2,
5588
- ref,
5589
- onError: didGetError,
5590
- onLoad: didLoad
5751
+ const schemaInput = useMemo27(() => {
5752
+ const input = {};
5753
+ for (const key of schemaKeys) {
5754
+ input[key] = getNestedValue(props2, key);
5755
+ }
5756
+ return input;
5757
+ }, schemaKeys.map((key) => getNestedValue(props2, key)));
5758
+ const { controls, values } = useSchema(schema, schemaInput);
5759
+ const mergedProps = mergeValues(props2, values, schemaKeys);
5760
+ return React23.createElement(Component, {
5761
+ ...mergedProps,
5762
+ controls,
5763
+ ref
5764
+ });
5591
5765
  });
5766
+ Wrapped.displayName = `wrapInSchema(${Component.displayName || Component.name || "Component"})`;
5767
+ return Wrapped;
5592
5768
  };
5593
- var IFrame = forwardRef7(IFrameRefForwarding);
5769
+
5594
5770
  // src/Img.tsx
5595
- import {
5596
- forwardRef as forwardRef8,
5597
- useCallback as useCallback13,
5598
- useContext as useContext29,
5599
- useImperativeHandle as useImperativeHandle6,
5600
- useLayoutEffect as useLayoutEffect9,
5601
- useRef as useRef17,
5602
- useState as useState15
5603
- } from "react";
5604
5771
  import { jsx as jsx24 } from "react/jsx-runtime";
5605
5772
  function exponentialBackoff(errorCount) {
5606
5773
  return 1000 * 2 ** (errorCount - 1);
5607
5774
  }
5608
- var ImgRefForwarding = ({
5775
+ var imgSchema = {
5776
+ "style.translate": {
5777
+ type: "translate",
5778
+ step: 1,
5779
+ default: "0px 0px",
5780
+ description: "Position"
5781
+ },
5782
+ "style.scale": {
5783
+ type: "number",
5784
+ min: 0.05,
5785
+ max: 100,
5786
+ step: 0.01,
5787
+ default: 1,
5788
+ description: "Scale"
5789
+ },
5790
+ "style.rotate": {
5791
+ type: "rotation",
5792
+ step: 1,
5793
+ default: "0deg",
5794
+ description: "Rotation"
5795
+ },
5796
+ "style.opacity": {
5797
+ type: "number",
5798
+ min: 0,
5799
+ max: 1,
5800
+ step: 0.01,
5801
+ default: 1,
5802
+ description: "Opacity"
5803
+ }
5804
+ };
5805
+ var ImgInner = ({
5609
5806
  onError,
5610
5807
  maxRetries = 2,
5611
5808
  src,
@@ -5617,13 +5814,15 @@ var ImgRefForwarding = ({
5617
5814
  showInTimeline,
5618
5815
  name,
5619
5816
  stack,
5817
+ ref,
5818
+ controls,
5620
5819
  ...props2
5621
- }, ref) => {
5820
+ }) => {
5622
5821
  const imageRef = useRef17(null);
5623
5822
  const errors = useRef17({});
5624
5823
  const { delayPlayback } = useBufferState();
5625
- const sequenceContext = useContext29(SequenceContext);
5626
- const [timelineId] = useState15(() => String(Math.random()));
5824
+ const sequenceContext = useContext30(SequenceContext);
5825
+ const [timelineId] = useState16(() => String(Math.random()));
5627
5826
  if (!src) {
5628
5827
  throw new Error('No "src" prop was passed to <Img>.');
5629
5828
  }
@@ -5642,7 +5841,8 @@ var ImgRefForwarding = ({
5642
5841
  showInTimeline: showInTimeline ?? true,
5643
5842
  premountDisplay: sequenceContext?.premountDisplay ?? null,
5644
5843
  postmountDisplay: sequenceContext?.postmountDisplay ?? null,
5645
- loopDisplay: undefined
5844
+ loopDisplay: undefined,
5845
+ controls: controls ?? null
5646
5846
  });
5647
5847
  const actualSrc = usePreload(src);
5648
5848
  const retryIn = useCallback13((timeout) => {
@@ -5765,22 +5965,22 @@ var ImgRefForwarding = ({
5765
5965
  decoding: "sync"
5766
5966
  });
5767
5967
  };
5768
- var Img = forwardRef8(ImgRefForwarding);
5968
+ var Img = wrapInSchema(ImgInner, imgSchema);
5769
5969
  addSequenceStackTraces(Img);
5770
5970
  // src/internals.ts
5771
5971
  import { createRef as createRef3 } from "react";
5772
5972
 
5773
5973
  // src/CompositionManager.tsx
5774
- import React24 from "react";
5775
- var compositionsRef = React24.createRef();
5974
+ import React25 from "react";
5975
+ var compositionsRef = React25.createRef();
5776
5976
 
5777
5977
  // src/CompositionManagerProvider.tsx
5778
5978
  import {
5779
5979
  useCallback as useCallback14,
5780
5980
  useImperativeHandle as useImperativeHandle7,
5781
- useMemo as useMemo26,
5981
+ useMemo as useMemo28,
5782
5982
  useRef as useRef18,
5783
- useState as useState16
5983
+ useState as useState17
5784
5984
  } from "react";
5785
5985
  import { jsx as jsx25 } from "react/jsx-runtime";
5786
5986
  var CompositionManagerProvider = ({
@@ -5790,9 +5990,9 @@ var CompositionManagerProvider = ({
5790
5990
  initialCompositions,
5791
5991
  initialCanvasContent
5792
5992
  }) => {
5793
- const [folders, setFolders] = useState16([]);
5794
- const [canvasContent, setCanvasContent] = useState16(initialCanvasContent);
5795
- const [compositions, setCompositions] = useState16(initialCompositions);
5993
+ const [folders, setFolders] = useState17([]);
5994
+ const [canvasContent, setCanvasContent] = useState17(initialCanvasContent);
5995
+ const [compositions, setCompositions] = useState17(initialCompositions);
5796
5996
  const currentcompositionsRef = useRef18(compositions);
5797
5997
  const updateCompositions = useCallback14((updateComps) => {
5798
5998
  setCompositions((comps) => {
@@ -5836,7 +6036,7 @@ var CompositionManagerProvider = ({
5836
6036
  getCompositions: () => currentcompositionsRef.current
5837
6037
  };
5838
6038
  }, []);
5839
- const compositionManagerSetters = useMemo26(() => {
6039
+ const compositionManagerSetters = useMemo28(() => {
5840
6040
  return {
5841
6041
  registerComposition,
5842
6042
  unregisterComposition,
@@ -5852,7 +6052,7 @@ var CompositionManagerProvider = ({
5852
6052
  unregisterFolder,
5853
6053
  onlyRenderComposition
5854
6054
  ]);
5855
- const compositionManagerContextValue = useMemo26(() => {
6055
+ const compositionManagerContextValue = useMemo28(() => {
5856
6056
  return {
5857
6057
  compositions,
5858
6058
  folders,
@@ -5929,29 +6129,6 @@ var makeDefaultPreviewCSS = (scope, backgroundColor) => {
5929
6129
  `;
5930
6130
  };
5931
6131
 
5932
- // src/get-effective-visual-mode-value.ts
5933
- var getEffectiveVisualModeValue = ({
5934
- codeValue,
5935
- runtimeValue,
5936
- dragOverrideValue,
5937
- defaultValue,
5938
- shouldResortToDefaultValueIfUndefined = false
5939
- }) => {
5940
- if (dragOverrideValue !== undefined) {
5941
- return dragOverrideValue;
5942
- }
5943
- if (!codeValue) {
5944
- return runtimeValue;
5945
- }
5946
- if (!codeValue.canUpdate) {
5947
- return runtimeValue;
5948
- }
5949
- if (codeValue.codeValue === undefined && shouldResortToDefaultValueIfUndefined) {
5950
- return defaultValue;
5951
- }
5952
- return codeValue.codeValue;
5953
- };
5954
-
5955
6132
  // src/get-preview-dom-element.ts
5956
6133
  var REMOTION_STUDIO_CONTAINER_ELEMENT = "__remotion-studio-container";
5957
6134
  var getPreviewDomElement = () => {
@@ -5959,8 +6136,8 @@ var getPreviewDomElement = () => {
5959
6136
  };
5960
6137
 
5961
6138
  // src/max-video-cache-size.ts
5962
- import React25 from "react";
5963
- var MaxMediaCacheSizeContext = React25.createContext(null);
6139
+ import React26 from "react";
6140
+ var MaxMediaCacheSizeContext = React26.createContext(null);
5964
6141
 
5965
6142
  // src/register-root.ts
5966
6143
  var Root = null;
@@ -5994,14 +6171,14 @@ var waitForRoot = (fn) => {
5994
6171
  };
5995
6172
 
5996
6173
  // src/RemotionRoot.tsx
5997
- import { useMemo as useMemo28 } from "react";
6174
+ import { useMemo as useMemo30 } from "react";
5998
6175
 
5999
6176
  // src/use-media-enabled.tsx
6000
- import { createContext as createContext20, useContext as useContext30, useMemo as useMemo27 } from "react";
6177
+ import { createContext as createContext20, useContext as useContext31, useMemo as useMemo29 } from "react";
6001
6178
  import { jsx as jsx26 } from "react/jsx-runtime";
6002
6179
  var MediaEnabledContext = createContext20(null);
6003
6180
  var useVideoEnabled = () => {
6004
- const context = useContext30(MediaEnabledContext);
6181
+ const context = useContext31(MediaEnabledContext);
6005
6182
  if (!context) {
6006
6183
  return window.remotion_videoEnabled;
6007
6184
  }
@@ -6011,7 +6188,7 @@ var useVideoEnabled = () => {
6011
6188
  return context.videoEnabled;
6012
6189
  };
6013
6190
  var useAudioEnabled = () => {
6014
- const context = useContext30(MediaEnabledContext);
6191
+ const context = useContext31(MediaEnabledContext);
6015
6192
  if (!context) {
6016
6193
  return window.remotion_audioEnabled;
6017
6194
  }
@@ -6025,7 +6202,7 @@ var MediaEnabledProvider = ({
6025
6202
  videoEnabled,
6026
6203
  audioEnabled
6027
6204
  }) => {
6028
- const value = useMemo27(() => ({ videoEnabled, audioEnabled }), [videoEnabled, audioEnabled]);
6205
+ const value = useMemo29(() => ({ videoEnabled, audioEnabled }), [videoEnabled, audioEnabled]);
6029
6206
  return /* @__PURE__ */ jsx26(MediaEnabledContext.Provider, {
6030
6207
  value,
6031
6208
  children
@@ -6044,13 +6221,13 @@ var RemotionRootContexts = ({
6044
6221
  frameState,
6045
6222
  visualModeEnabled
6046
6223
  }) => {
6047
- const nonceContext = useMemo28(() => {
6224
+ const nonceContext = useMemo30(() => {
6048
6225
  let counter = 0;
6049
6226
  return {
6050
6227
  getNonce: () => counter++
6051
6228
  };
6052
6229
  }, []);
6053
- const logging = useMemo28(() => {
6230
+ const logging = useMemo30(() => {
6054
6231
  return { logLevel, mountTime: Date.now() };
6055
6232
  }, [logLevel]);
6056
6233
  return /* @__PURE__ */ jsx27(LogLevelContext.Provider, {
@@ -6257,8 +6434,8 @@ var resolveVideoConfigOrCatch = (params) => {
6257
6434
  };
6258
6435
 
6259
6436
  // src/sequence-stack-traces.ts
6260
- import React27 from "react";
6261
- var SequenceStackTracesUpdateContext = React27.createContext(() => {});
6437
+ import React28 from "react";
6438
+ var SequenceStackTracesUpdateContext = React28.createContext(() => {});
6262
6439
 
6263
6440
  // src/setup-env-variables.ts
6264
6441
  var getEnvVariables = () => {
@@ -6288,8 +6465,8 @@ var setupEnvVariables = () => {
6288
6465
  };
6289
6466
 
6290
6467
  // src/use-current-scale.ts
6291
- import React28, { createContext as createContext21 } from "react";
6292
- var CurrentScaleContext = React28.createContext(null);
6468
+ import React29, { createContext as createContext21 } from "react";
6469
+ var CurrentScaleContext = React29.createContext(null);
6293
6470
  var PreviewSizeContext = createContext21({
6294
6471
  setSize: () => {
6295
6472
  return;
@@ -6314,8 +6491,8 @@ var calculateScale = ({
6314
6491
  return Number(previewSize);
6315
6492
  };
6316
6493
  var useCurrentScale = (options) => {
6317
- const hasContext = React28.useContext(CurrentScaleContext);
6318
- const zoomContext = React28.useContext(PreviewSizeContext);
6494
+ const hasContext = React29.useContext(CurrentScaleContext);
6495
+ const zoomContext = React29.useContext(PreviewSizeContext);
6319
6496
  const config = useUnsafeVideoConfig();
6320
6497
  const env = useRemotionEnvironment();
6321
6498
  if (hasContext === null || config === null || zoomContext === null) {
@@ -6344,78 +6521,6 @@ var useCurrentScale = (options) => {
6344
6521
  });
6345
6522
  };
6346
6523
 
6347
- // src/use-schema.ts
6348
- import { useContext as useContext31, useMemo as useMemo29, useState as useState17 } from "react";
6349
- var useSchema = (schema, currentValue) => {
6350
- const env = useRemotionEnvironment();
6351
- const earlyReturn = useMemo29(() => {
6352
- if (!env.isStudio || env.isReadOnlyStudio) {
6353
- return {
6354
- controls: undefined,
6355
- values: currentValue ?? {}
6356
- };
6357
- }
6358
- return;
6359
- }, [env.isStudio, env.isReadOnlyStudio, currentValue]);
6360
- if (earlyReturn) {
6361
- return earlyReturn;
6362
- }
6363
- const [overrideId] = useState17(() => String(Math.random()));
6364
- const {
6365
- visualModeEnabled,
6366
- dragOverrides: overrides,
6367
- codeValues
6368
- } = useContext31(VisualModeOverridesContext);
6369
- const controls = useMemo29(() => {
6370
- if (!visualModeEnabled) {
6371
- return;
6372
- }
6373
- if (schema === null || currentValue === null) {
6374
- return;
6375
- }
6376
- return {
6377
- schema,
6378
- currentValue,
6379
- overrideId
6380
- };
6381
- }, [schema, currentValue, overrideId, visualModeEnabled]);
6382
- return useMemo29(() => {
6383
- if (controls === undefined || currentValue === null || schema === null || !visualModeEnabled) {
6384
- return {
6385
- controls: undefined,
6386
- values: currentValue ?? {}
6387
- };
6388
- }
6389
- const overrideValues = overrides[overrideId] ?? {};
6390
- const propStatus = codeValues[overrideId];
6391
- const currentValueKeys = Object.keys(currentValue);
6392
- const keysToUpdate = [...new Set(currentValueKeys)];
6393
- const merged = {};
6394
- for (const key of keysToUpdate) {
6395
- const codeValueStatus = propStatus?.[key] ?? null;
6396
- merged[key] = getEffectiveVisualModeValue({
6397
- codeValue: codeValueStatus,
6398
- runtimeValue: currentValue[key],
6399
- dragOverrideValue: overrideValues[key],
6400
- defaultValue: schema[key]?.default,
6401
- shouldResortToDefaultValueIfUndefined: false
6402
- });
6403
- }
6404
- return {
6405
- controls,
6406
- values: merged
6407
- };
6408
- }, [
6409
- controls,
6410
- currentValue,
6411
- overrideId,
6412
- overrides,
6413
- codeValues,
6414
- schema,
6415
- visualModeEnabled
6416
- ]);
6417
- };
6418
-
6419
6524
  // src/use-sequence-control-override.ts
6420
6525
  import { useContext as useContext32 } from "react";
6421
6526
  var useSequenceControlOverride = (key) => {
@@ -6436,7 +6541,7 @@ import {
6436
6541
  useContext as useContext33,
6437
6542
  useEffect as useEffect14,
6438
6543
  useLayoutEffect as useLayoutEffect10,
6439
- useMemo as useMemo30,
6544
+ useMemo as useMemo31,
6440
6545
  useState as useState18
6441
6546
  } from "react";
6442
6547
 
@@ -6481,7 +6586,7 @@ var OffthreadVideoForRendering = ({
6481
6586
  if (!src) {
6482
6587
  throw new TypeError("No `src` was passed to <OffthreadVideo>.");
6483
6588
  }
6484
- const id = useMemo30(() => `offthreadvideo-${random(src)}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.relativeFrom}-${sequenceContext?.durationInFrames}`, [
6589
+ const id = useMemo31(() => `offthreadvideo-${random(src)}-${sequenceContext?.cumulatedFrom}-${sequenceContext?.relativeFrom}-${sequenceContext?.durationInFrames}`, [
6485
6590
  src,
6486
6591
  sequenceContext?.cumulatedFrom,
6487
6592
  sequenceContext?.relativeFrom,
@@ -6536,14 +6641,14 @@ var OffthreadVideoForRendering = ({
6536
6641
  sequenceContext?.relativeFrom,
6537
6642
  audioStreamIndex
6538
6643
  ]);
6539
- const currentTime = useMemo30(() => {
6644
+ const currentTime = useMemo31(() => {
6540
6645
  return getExpectedMediaFrameUncorrected({
6541
6646
  frame,
6542
6647
  playbackRate: playbackRate || 1,
6543
6648
  startFrom: -mediaStartsAt
6544
6649
  }) / videoConfig.fps;
6545
6650
  }, [frame, mediaStartsAt, playbackRate, videoConfig.fps]);
6546
- const actualSrc = useMemo30(() => {
6651
+ const actualSrc = useMemo31(() => {
6547
6652
  return getOffthreadVideoSource({
6548
6653
  src,
6549
6654
  currentTime,
@@ -6631,7 +6736,7 @@ var OffthreadVideoForRendering = ({
6631
6736
  cancelRender("Failed to load image with src " + imageSrc);
6632
6737
  }
6633
6738
  }, [imageSrc, onError]);
6634
- const className = useMemo30(() => {
6739
+ const className = useMemo31(() => {
6635
6740
  return [OBJECTFIT_CONTAIN_CLASS_NAME, props2.className].filter(truthy).join(" ");
6636
6741
  }, [props2.className]);
6637
6742
  const onImageFrame = useCallback15((img) => {
@@ -6655,12 +6760,12 @@ var OffthreadVideoForRendering = ({
6655
6760
  };
6656
6761
 
6657
6762
  // src/video/VideoForPreview.tsx
6658
- import React30, {
6763
+ import React31, {
6659
6764
  forwardRef as forwardRef9,
6660
6765
  useContext as useContext34,
6661
6766
  useEffect as useEffect16,
6662
6767
  useImperativeHandle as useImperativeHandle8,
6663
- useMemo as useMemo31,
6768
+ useMemo as useMemo32,
6664
6769
  useRef as useRef19,
6665
6770
  useState as useState19
6666
6771
  } from "react";
@@ -6702,7 +6807,7 @@ var VideoForDevelopmentRefForwardingFunction = (props2, ref) => {
6702
6807
  throw new Error("SharedAudioContext not found");
6703
6808
  }
6704
6809
  const videoRef = useRef19(null);
6705
- const sharedSource = useMemo31(() => {
6810
+ const sharedSource = useMemo32(() => {
6706
6811
  if (!context.audioContext) {
6707
6812
  return null;
6708
6813
  }
@@ -6711,7 +6816,7 @@ var VideoForDevelopmentRefForwardingFunction = (props2, ref) => {
6711
6816
  ref: videoRef
6712
6817
  });
6713
6818
  }, [context.audioContext]);
6714
- const effectToUse = React30.useInsertionEffect ?? React30.useLayoutEffect;
6819
+ const effectToUse = React31.useInsertionEffect ?? React31.useLayoutEffect;
6715
6820
  effectToUse(() => {
6716
6821
  return () => {
6717
6822
  requestAnimationFrame(() => {
@@ -6888,7 +6993,7 @@ var VideoForDevelopmentRefForwardingFunction = (props2, ref) => {
6888
6993
  current.preload = "auto";
6889
6994
  }
6890
6995
  }, []);
6891
- const actualStyle = useMemo31(() => {
6996
+ const actualStyle = useMemo32(() => {
6892
6997
  return {
6893
6998
  ...style,
6894
6999
  opacity: isSequenceHidden ? 0 : style?.opacity ?? 1
@@ -7109,71 +7214,6 @@ var watchStaticFile = (fileName, callback) => {
7109
7214
  return { cancel };
7110
7215
  };
7111
7216
 
7112
- // src/wrap-in-schema.ts
7113
- import React32, { forwardRef as forwardRef10, useMemo as useMemo32 } from "react";
7114
- var getNestedValue = (obj, key) => {
7115
- const parts = key.split(".");
7116
- let current = obj;
7117
- for (const part of parts) {
7118
- if (current === null || current === undefined || typeof current !== "object")
7119
- return;
7120
- current = current[part];
7121
- }
7122
- return current;
7123
- };
7124
- var mergeValues = (props2, values, schemaKeys) => {
7125
- const merged = { ...props2 };
7126
- for (const key of schemaKeys) {
7127
- const value = values[key];
7128
- const parts = key.split(".");
7129
- if (parts.length === 1) {
7130
- merged[key] = value;
7131
- continue;
7132
- }
7133
- let current = merged;
7134
- for (let i = 0;i < parts.length - 1; i++) {
7135
- const part = parts[i];
7136
- if (typeof current[part] === "object" && current[part] !== null) {
7137
- current[part] = { ...current[part] };
7138
- } else {
7139
- current[part] = {};
7140
- }
7141
- current = current[part];
7142
- }
7143
- current[parts[parts.length - 1]] = value;
7144
- }
7145
- return merged;
7146
- };
7147
- var wrapInSchema = (Component, schema) => {
7148
- const schemaKeys = Object.keys(schema);
7149
- const Wrapped = forwardRef10((props2, ref) => {
7150
- const env = useRemotionEnvironment();
7151
- if (!env.isStudio || env.isReadOnlyStudio || env.isRendering || !process.env.EXPERIMENTAL_VISUAL_MODE_ENABLED) {
7152
- return React32.createElement(Component, {
7153
- ...props2,
7154
- controls: null,
7155
- ref
7156
- });
7157
- }
7158
- const schemaInput = useMemo32(() => {
7159
- const input = {};
7160
- for (const key of schemaKeys) {
7161
- input[key] = getNestedValue(props2, key);
7162
- }
7163
- return input;
7164
- }, schemaKeys.map((key) => getNestedValue(props2, key)));
7165
- const { controls, values } = useSchema(schema, schemaInput);
7166
- const mergedProps = mergeValues(props2, values, schemaKeys);
7167
- return React32.createElement(Component, {
7168
- ...mergedProps,
7169
- controls,
7170
- ref
7171
- });
7172
- });
7173
- Wrapped.displayName = `wrapInSchema(${Component.displayName || Component.name || "Component"})`;
7174
- return Wrapped;
7175
- };
7176
-
7177
7217
  // src/wrap-remotion-context.tsx
7178
7218
  import React33, { useMemo as useMemo33 } from "react";
7179
7219
  import { jsx as jsx31 } from "react/jsx-runtime";
@@ -7886,7 +7926,7 @@ var validateFrame = ({
7886
7926
  }
7887
7927
  };
7888
7928
  // src/series/index.tsx
7889
- import { Children, forwardRef as forwardRef11, useMemo as useMemo34 } from "react";
7929
+ import { Children, forwardRef as forwardRef10, useMemo as useMemo34 } from "react";
7890
7930
 
7891
7931
  // src/series/flatten-children.tsx
7892
7932
  import React34 from "react";
@@ -7932,7 +7972,7 @@ var SeriesSequenceRefForwardingFunction = ({ children }, _ref) => {
7932
7972
  children
7933
7973
  });
7934
7974
  };
7935
- var SeriesSequence = forwardRef11(SeriesSequenceRefForwardingFunction);
7975
+ var SeriesSequence = forwardRef10(SeriesSequenceRefForwardingFunction);
7936
7976
  var Series = (props2) => {
7937
7977
  const childrenValue = useMemo34(() => {
7938
7978
  let startFrame = 0;
@@ -7988,19 +8028,17 @@ var Series = (props2) => {
7988
8028
  });
7989
8029
  });
7990
8030
  }, [props2.children]);
7991
- if (ENABLE_V5_BREAKING_CHANGES) {
7992
- return /* @__PURE__ */ jsx33(IsInsideSeriesContainer, {
7993
- children: /* @__PURE__ */ jsx33(Sequence, {
7994
- ...props2,
7995
- children: childrenValue
7996
- })
7997
- });
7998
- }
7999
8031
  return /* @__PURE__ */ jsx33(IsInsideSeriesContainer, {
8000
- children: childrenValue
8032
+ children: /* @__PURE__ */ jsx33(Sequence, {
8033
+ layout: "none",
8034
+ name: "<Series>",
8035
+ ...props2,
8036
+ children: childrenValue
8037
+ })
8001
8038
  });
8002
8039
  };
8003
8040
  Series.Sequence = SeriesSequence;
8041
+ addSequenceStackTraces(Series);
8004
8042
  addSequenceStackTraces(SeriesSequence);
8005
8043
  // src/validation/validation-spring-duration.ts
8006
8044
  var validateSpringDuration = (dur) => {
@@ -8343,11 +8381,11 @@ var Still = (props2) => {
8343
8381
  return React37.createElement(Composition, newProps);
8344
8382
  };
8345
8383
  // src/video/Video.tsx
8346
- import { forwardRef as forwardRef13, useCallback as useCallback17, useContext as useContext36 } from "react";
8384
+ import { forwardRef as forwardRef12, useCallback as useCallback17, useContext as useContext36 } from "react";
8347
8385
 
8348
8386
  // src/video/VideoForRendering.tsx
8349
8387
  import {
8350
- forwardRef as forwardRef12,
8388
+ forwardRef as forwardRef11,
8351
8389
  useContext as useContext35,
8352
8390
  useEffect as useEffect17,
8353
8391
  useImperativeHandle as useImperativeHandle9,
@@ -8692,7 +8730,7 @@ var VideoForRenderingForwardFunction = ({
8692
8730
  ...props2
8693
8731
  });
8694
8732
  };
8695
- var VideoForRendering = forwardRef12(VideoForRenderingForwardFunction);
8733
+ var VideoForRendering = forwardRef11(VideoForRenderingForwardFunction);
8696
8734
 
8697
8735
  // src/video/Video.tsx
8698
8736
  import { jsx as jsx35 } from "react/jsx-runtime";
@@ -8800,7 +8838,7 @@ var VideoForwardingFunction = (props2, ref) => {
8800
8838
  onAutoPlayError: onAutoPlayError ?? undefined
8801
8839
  });
8802
8840
  };
8803
- var Html5Video = forwardRef13(VideoForwardingFunction);
8841
+ var Html5Video = forwardRef12(VideoForwardingFunction);
8804
8842
  addSequenceStackTraces(Html5Video);
8805
8843
  var Video = Html5Video;
8806
8844
  // src/index.ts
@@ -8832,6 +8870,7 @@ var Config = new Proxy(proxyObj, {
8832
8870
  });
8833
8871
  Sequence.displayName = "Sequence";
8834
8872
  addSequenceStackTraces(Sequence);
8873
+ addSequenceStackTraces(Composition);
8835
8874
  export {
8836
8875
  watchStaticFile,
8837
8876
  useVideoConfig,