remotion 4.0.390 → 4.0.392

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.
@@ -89,6 +89,7 @@ const AudioForDevelopmentForwardRefFunction = (props, ref) => {
89
89
  aud: propsToPass,
90
90
  audioId: id,
91
91
  premounting: Boolean(sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.premounting),
92
+ postmounting: Boolean(sequenceContext === null || sequenceContext === void 0 ? void 0 : sequenceContext.postmounting),
92
93
  });
93
94
  (0, use_media_in_timeline_js_1.useMediaInTimeline)({
94
95
  volume,
@@ -19,12 +19,15 @@ type AudioElem = {
19
19
  audioId: string;
20
20
  mediaElementSourceNode: SharedElementSourceNode | null;
21
21
  premounting: boolean;
22
+ postmounting: boolean;
23
+ audioMounted: boolean;
22
24
  };
23
25
  type SharedContext = {
24
26
  registerAudio: (options: {
25
27
  aud: AudioHTMLAttributes<HTMLAudioElement>;
26
28
  audioId: string;
27
29
  premounting: boolean;
30
+ postmounting: boolean;
28
31
  }) => AudioElem;
29
32
  unregisterAudio: (id: number) => void;
30
33
  updateAudio: (options: {
@@ -32,6 +35,7 @@ type SharedContext = {
32
35
  aud: AudioHTMLAttributes<HTMLAudioElement>;
33
36
  audioId: string;
34
37
  premounting: boolean;
38
+ postmounting: boolean;
35
39
  }) => void;
36
40
  playAllAudios: () => void;
37
41
  numberOfAudioTags: number;
@@ -43,9 +47,10 @@ export declare const SharedAudioContextProvider: React.FC<{
43
47
  readonly children: React.ReactNode;
44
48
  readonly audioLatencyHint: AudioContextLatencyCategory;
45
49
  }>;
46
- export declare const useSharedAudio: ({ aud, audioId, premounting, }: {
50
+ export declare const useSharedAudio: ({ aud, audioId, premounting, postmounting, }: {
47
51
  aud: AudioHTMLAttributes<HTMLAudioElement>;
48
52
  audioId: string;
49
53
  premounting: boolean;
54
+ postmounting: boolean;
50
55
  }) => AudioElem;
51
56
  export {};
@@ -126,7 +126,7 @@ const SharedAudioContextProvider = ({ children, numberOfAudioTags, audioLatencyH
126
126
  }, [refs]);
127
127
  const registerAudio = (0, react_1.useCallback)((options) => {
128
128
  var _a, _b;
129
- const { aud, audioId, premounting } = options;
129
+ const { aud, audioId, premounting, postmounting } = options;
130
130
  const found = (_a = audios.current) === null || _a === void 0 ? void 0 : _a.find((a) => a.audioId === audioId);
131
131
  if (found) {
132
132
  return found;
@@ -146,6 +146,8 @@ const SharedAudioContextProvider = ({ children, numberOfAudioTags, audioLatencyH
146
146
  audioId,
147
147
  mediaElementSourceNode,
148
148
  premounting,
149
+ audioMounted: Boolean(ref.current),
150
+ postmounting,
149
151
  };
150
152
  (_b = audios.current) === null || _b === void 0 ? void 0 : _b.push(newElem);
151
153
  rerenderAudios();
@@ -163,12 +165,18 @@ const SharedAudioContextProvider = ({ children, numberOfAudioTags, audioLatencyH
163
165
  audios.current = (_a = audios.current) === null || _a === void 0 ? void 0 : _a.filter((a) => a.id !== id);
164
166
  rerenderAudios();
165
167
  }, [refs, rerenderAudios]);
166
- const updateAudio = (0, react_1.useCallback)(({ aud, audioId, id, premounting, }) => {
168
+ const updateAudio = (0, react_1.useCallback)(({ aud, audioId, id, premounting, postmounting, }) => {
167
169
  var _a;
168
170
  let changed = false;
169
171
  audios.current = (_a = audios.current) === null || _a === void 0 ? void 0 : _a.map((prevA) => {
172
+ const audioMounted = Boolean(prevA.el.current);
173
+ if (prevA.audioMounted !== audioMounted) {
174
+ changed = true;
175
+ }
170
176
  if (prevA.id === id) {
171
- const isTheSame = compareProps(aud, prevA.props) && prevA.premounting === premounting;
177
+ const isTheSame = compareProps(aud, prevA.props) &&
178
+ prevA.premounting === premounting &&
179
+ prevA.postmounting === postmounting;
172
180
  if (isTheSame) {
173
181
  return prevA;
174
182
  }
@@ -177,7 +185,9 @@ const SharedAudioContextProvider = ({ children, numberOfAudioTags, audioLatencyH
177
185
  ...prevA,
178
186
  props: aud,
179
187
  premounting,
188
+ postmounting,
180
189
  audioId,
190
+ audioMounted,
181
191
  };
182
192
  }
183
193
  return prevA;
@@ -232,7 +242,7 @@ const SharedAudioContextProvider = ({ children, numberOfAudioTags, audioLatencyH
232
242
  }), children] }));
233
243
  };
234
244
  exports.SharedAudioContextProvider = SharedAudioContextProvider;
235
- const useSharedAudio = ({ aud, audioId, premounting, }) => {
245
+ const useSharedAudio = ({ aud, audioId, premounting, postmounting, }) => {
236
246
  var _a;
237
247
  const ctx = (0, react_1.useContext)(exports.SharedAudioContext);
238
248
  /**
@@ -240,7 +250,7 @@ const useSharedAudio = ({ aud, audioId, premounting, }) => {
240
250
  */
241
251
  const [elem] = (0, react_1.useState)(() => {
242
252
  if (ctx && ctx.numberOfAudioTags > 0) {
243
- return ctx.registerAudio({ aud, audioId, premounting });
253
+ return ctx.registerAudio({ aud, audioId, premounting, postmounting });
244
254
  }
245
255
  const el = react_1.default.createRef();
246
256
  const mediaElementSourceNode = (ctx === null || ctx === void 0 ? void 0 : ctx.audioContext)
@@ -256,6 +266,8 @@ const useSharedAudio = ({ aud, audioId, premounting, }) => {
256
266
  audioId,
257
267
  mediaElementSourceNode,
258
268
  premounting,
269
+ audioMounted: Boolean(el.current),
270
+ postmounting,
259
271
  };
260
272
  });
261
273
  /**
@@ -269,9 +281,9 @@ const useSharedAudio = ({ aud, audioId, premounting, }) => {
269
281
  if (typeof document !== 'undefined') {
270
282
  effectToUse(() => {
271
283
  if (ctx && ctx.numberOfAudioTags > 0) {
272
- ctx.updateAudio({ id: elem.id, aud, audioId, premounting });
284
+ ctx.updateAudio({ id: elem.id, aud, audioId, premounting, postmounting });
273
285
  }
274
- }, [aud, ctx, elem.id, audioId, premounting]);
286
+ }, [aud, ctx, elem.id, audioId, premounting, postmounting]);
275
287
  effectToUse(() => {
276
288
  return () => {
277
289
  if (ctx && ctx.numberOfAudioTags > 0) {
@@ -0,0 +1,6 @@
1
+ export declare const calculateLoopDuration: ({ endAt, mediaDuration, playbackRate, startFrom, }: {
2
+ mediaDuration: number;
3
+ playbackRate: number;
4
+ startFrom: number | undefined;
5
+ endAt: number | undefined;
6
+ }) => number;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.calculateLoopDuration = void 0;
4
+ const calculateLoopDuration = ({ endAt, mediaDuration, playbackRate, startFrom, }) => {
5
+ let duration = mediaDuration;
6
+ // Account for endAt
7
+ if (typeof endAt !== 'undefined') {
8
+ duration = endAt;
9
+ }
10
+ // Account for startFrom
11
+ if (typeof startFrom !== 'undefined') {
12
+ duration -= startFrom;
13
+ }
14
+ const actualDuration = duration / playbackRate;
15
+ return Math.floor(actualDuration);
16
+ };
17
+ exports.calculateLoopDuration = calculateLoopDuration;
@@ -11,6 +11,7 @@ export type DelayRenderScope = {
11
11
  };
12
12
  remotion_puppeteerTimeout: number;
13
13
  remotion_attempt: number;
14
+ remotion_delayRenderHandles: number[];
14
15
  remotion_cancelledError?: string;
15
16
  };
16
17
  export declare const DELAY_RENDER_CALLSTACK_TOKEN = "The delayRender was called:";
@@ -27,7 +28,7 @@ export type DelayRenderOptions = {
27
28
  * @private
28
29
  */
29
30
  export declare const delayRenderInternal: ({ scope, environment, label, options, }: {
30
- scope: DelayRenderScope | undefined;
31
+ scope: DelayRenderScope;
31
32
  environment: RemotionEnvironment;
32
33
  label: string | null;
33
34
  options: DelayRenderOptions;
@@ -38,7 +39,7 @@ export declare const delayRender: (label?: string, options?: DelayRenderOptions)
38
39
  * @private
39
40
  */
40
41
  export declare const continueRenderInternal: ({ scope, handle, environment, logLevel, }: {
41
- scope: DelayRenderScope | undefined;
42
+ scope: DelayRenderScope;
42
43
  handle: number;
43
44
  environment: RemotionEnvironment;
44
45
  logLevel: LogLevel;
@@ -5,12 +5,12 @@ const cancel_render_js_1 = require("./cancel-render.js");
5
5
  const get_remotion_environment_js_1 = require("./get-remotion-environment.js");
6
6
  const log_js_1 = require("./log.js");
7
7
  const truthy_js_1 = require("./truthy.js");
8
- let handles = [];
9
8
  if (typeof window !== 'undefined') {
10
9
  window.remotion_renderReady = false;
11
10
  if (!window.remotion_delayRenderTimeouts) {
12
11
  window.remotion_delayRenderTimeouts = {};
13
12
  }
13
+ window.remotion_delayRenderHandles = [];
14
14
  }
15
15
  exports.DELAY_RENDER_CALLSTACK_TOKEN = 'The delayRender was called:';
16
16
  exports.DELAY_RENDER_RETRIES_LEFT = 'Retries left: ';
@@ -29,37 +29,31 @@ const delayRenderInternal = ({ scope, environment, label, options, }) => {
29
29
  JSON.stringify(label));
30
30
  }
31
31
  const handle = Math.random();
32
- handles.push(handle);
32
+ scope.remotion_delayRenderHandles.push(handle);
33
33
  const called = (_b = (_a = Error().stack) === null || _a === void 0 ? void 0 : _a.replace(/^Error/g, '')) !== null && _b !== void 0 ? _b : '';
34
34
  if (environment.isRendering) {
35
- const timeoutToUse = ((_c = options === null || options === void 0 ? void 0 : options.timeoutInMilliseconds) !== null && _c !== void 0 ? _c : (typeof scope === 'undefined'
36
- ? defaultTimeout
37
- : ((_d = scope.remotion_puppeteerTimeout) !== null && _d !== void 0 ? _d : defaultTimeout))) - 2000;
38
- if (typeof scope !== 'undefined') {
39
- const retriesLeft = ((_e = options === null || options === void 0 ? void 0 : options.retries) !== null && _e !== void 0 ? _e : 0) - (scope.remotion_attempt - 1);
40
- scope.remotion_delayRenderTimeouts[handle] = {
41
- label: label !== null && label !== void 0 ? label : null,
42
- startTime: Date.now(),
43
- timeout: setTimeout(() => {
44
- const message = [
45
- `A delayRender()`,
46
- label ? `"${label}"` : null,
47
- `was called but not cleared after ${timeoutToUse}ms. See https://remotion.dev/docs/timeout for help.`,
48
- retriesLeft > 0 ? exports.DELAY_RENDER_RETRIES_LEFT + retriesLeft : null,
49
- retriesLeft > 0 ? exports.DELAY_RENDER_RETRY_TOKEN : null,
50
- exports.DELAY_RENDER_CALLSTACK_TOKEN,
51
- called,
52
- ]
53
- .filter(truthy_js_1.truthy)
54
- .join(' ');
55
- (0, cancel_render_js_1.cancelRenderInternal)(scope, Error(message));
56
- }, timeoutToUse),
57
- };
58
- }
59
- }
60
- if (typeof scope !== 'undefined') {
61
- scope.remotion_renderReady = false;
35
+ const timeoutToUse = ((_d = (_c = options === null || options === void 0 ? void 0 : options.timeoutInMilliseconds) !== null && _c !== void 0 ? _c : scope.remotion_puppeteerTimeout) !== null && _d !== void 0 ? _d : defaultTimeout) - 2000;
36
+ const retriesLeft = ((_e = options === null || options === void 0 ? void 0 : options.retries) !== null && _e !== void 0 ? _e : 0) - (scope.remotion_attempt - 1);
37
+ scope.remotion_delayRenderTimeouts[handle] = {
38
+ label: label !== null && label !== void 0 ? label : null,
39
+ startTime: Date.now(),
40
+ timeout: setTimeout(() => {
41
+ const message = [
42
+ `A delayRender()`,
43
+ label ? `"${label}"` : null,
44
+ `was called but not cleared after ${timeoutToUse}ms. See https://remotion.dev/docs/timeout for help.`,
45
+ retriesLeft > 0 ? exports.DELAY_RENDER_RETRIES_LEFT + retriesLeft : null,
46
+ retriesLeft > 0 ? exports.DELAY_RENDER_RETRY_TOKEN : null,
47
+ exports.DELAY_RENDER_CALLSTACK_TOKEN,
48
+ called,
49
+ ]
50
+ .filter(truthy_js_1.truthy)
51
+ .join(' ');
52
+ (0, cancel_render_js_1.cancelRenderInternal)(scope, Error(message));
53
+ }, timeoutToUse),
54
+ };
62
55
  }
56
+ scope.remotion_renderReady = false;
63
57
  return handle;
64
58
  };
65
59
  exports.delayRenderInternal = delayRenderInternal;
@@ -68,8 +62,11 @@ exports.delayRenderInternal = delayRenderInternal;
68
62
  * @see [Documentation](https://remotion.dev/docs/delay-render)
69
63
  */
70
64
  const delayRender = (label, options) => {
65
+ if (typeof window === 'undefined') {
66
+ return Math.random();
67
+ }
71
68
  return (0, exports.delayRenderInternal)({
72
- scope: typeof window !== 'undefined' ? window : undefined,
69
+ scope: window,
73
70
  environment: (0, get_remotion_environment_js_1.getRemotionEnvironment)(),
74
71
  label: label !== null && label !== void 0 ? label : null,
75
72
  options: options !== null && options !== void 0 ? options : {},
@@ -88,7 +85,7 @@ const continueRenderInternal = ({ scope, handle, environment, logLevel, }) => {
88
85
  throw new TypeError('The parameter passed into continueRender() must be the return value of delayRender() which is a number. Got: ' +
89
86
  JSON.stringify(handle));
90
87
  }
91
- handles = handles.filter((h) => {
88
+ scope.remotion_delayRenderHandles = scope.remotion_delayRenderHandles.filter((h) => {
92
89
  if (h === handle) {
93
90
  if (environment.isRendering && scope !== undefined) {
94
91
  if (!scope.remotion_delayRenderTimeouts[handle]) {
@@ -110,7 +107,7 @@ const continueRenderInternal = ({ scope, handle, environment, logLevel, }) => {
110
107
  }
111
108
  return true;
112
109
  });
113
- if (handles.length === 0 && typeof scope !== 'undefined') {
110
+ if (scope.remotion_delayRenderHandles.length === 0) {
114
111
  scope.remotion_renderReady = true;
115
112
  }
116
113
  };
@@ -121,13 +118,14 @@ exports.continueRenderInternal = continueRenderInternal;
121
118
  */
122
119
  const continueRender = (handle) => {
123
120
  var _a;
121
+ if (typeof window === 'undefined') {
122
+ return;
123
+ }
124
124
  (0, exports.continueRenderInternal)({
125
- scope: typeof window !== 'undefined' ? window : undefined,
125
+ scope: window,
126
126
  handle,
127
127
  environment: (0, get_remotion_environment_js_1.getRemotionEnvironment)(),
128
- logLevel: typeof window !== 'undefined'
129
- ? ((_a = window.remotion_logLevel) !== null && _a !== void 0 ? _a : 'info')
130
- : 'info',
128
+ logLevel: (_a = window.remotion_logLevel) !== null && _a !== void 0 ? _a : 'info',
131
129
  });
132
130
  };
133
131
  exports.continueRender = continueRender;
@@ -22,6 +22,7 @@ declare global {
22
22
  startTime: number;
23
23
  };
24
24
  };
25
+ remotion_delayRenderHandles: number[];
25
26
  remotion_cancelledError: string | undefined;
26
27
  remotion_getCompositionNames: () => string[];
27
28
  remotion_seenCompositionIds: string[];
@@ -129,6 +129,7 @@ export declare const Internals: {
129
129
  aud: import("react").AudioHTMLAttributes<HTMLAudioElement>;
130
130
  audioId: string;
131
131
  premounting: boolean;
132
+ postmounting: boolean;
132
133
  }) => {
133
134
  id: number;
134
135
  props: import("react").AudioHTMLAttributes<HTMLAudioElement>;
@@ -136,6 +137,8 @@ export declare const Internals: {
136
137
  audioId: string;
137
138
  mediaElementSourceNode: import("./audio/shared-element-source-node.js").SharedElementSourceNode | null;
138
139
  premounting: boolean;
140
+ postmounting: boolean;
141
+ audioMounted: boolean;
139
142
  };
140
143
  unregisterAudio: (id: number) => void;
141
144
  updateAudio: (options: {
@@ -143,6 +146,7 @@ export declare const Internals: {
143
146
  aud: import("react").AudioHTMLAttributes<HTMLAudioElement>;
144
147
  audioId: string;
145
148
  premounting: boolean;
149
+ postmounting: boolean;
146
150
  }) => void;
147
151
  playAllAudios: () => void;
148
152
  numberOfAudioTags: number;
@@ -8,20 +8,27 @@ const log_level_context_js_1 = require("./log-level-context.js");
8
8
  const use_remotion_environment_js_1 = require("./use-remotion-environment.js");
9
9
  exports.DelayRenderContextType = (0, react_1.createContext)(null);
10
10
  const useDelayRender = () => {
11
+ var _a;
11
12
  const environment = (0, use_remotion_environment_js_1.useRemotionEnvironment)();
12
- const scope = (0, react_1.useContext)(exports.DelayRenderContextType);
13
+ const scope = (_a = (0, react_1.useContext)(exports.DelayRenderContextType)) !== null && _a !== void 0 ? _a : (typeof window !== 'undefined' ? window : undefined);
13
14
  const logLevel = (0, log_level_context_js_1.useLogLevel)();
14
15
  const delayRender = (0, react_1.useCallback)((label, options) => {
16
+ if (!scope) {
17
+ return Math.random();
18
+ }
15
19
  return (0, delay_render_js_1.delayRenderInternal)({
16
- scope: scope !== null && scope !== void 0 ? scope : (typeof window !== 'undefined' ? window : undefined),
20
+ scope,
17
21
  environment,
18
22
  label: label !== null && label !== void 0 ? label : null,
19
23
  options: options !== null && options !== void 0 ? options : {},
20
24
  });
21
25
  }, [environment, scope]);
22
26
  const continueRender = (0, react_1.useCallback)((handle) => {
27
+ if (!scope) {
28
+ return;
29
+ }
23
30
  (0, delay_render_js_1.continueRenderInternal)({
24
- scope: scope !== null && scope !== void 0 ? scope : (typeof window !== 'undefined' ? window : undefined),
31
+ scope,
25
32
  handle,
26
33
  environment,
27
34
  logLevel,
@@ -3,4 +3,4 @@
3
3
  * @see [Documentation](https://remotion.dev/docs/version)
4
4
  * @returns {string} The current version of the remotion package
5
5
  */
6
- export declare const VERSION = "4.0.390";
6
+ export declare const VERSION = "4.0.392";
@@ -7,4 +7,4 @@ exports.VERSION = void 0;
7
7
  * @see [Documentation](https://remotion.dev/docs/version)
8
8
  * @returns {string} The current version of the remotion package
9
9
  */
10
- exports.VERSION = '4.0.390';
10
+ exports.VERSION = '4.0.392';
@@ -0,0 +1,4 @@
1
+ export declare const useAudioChannelIndex: ({ ref, audioChannelIndex, }: {
2
+ ref: React.RefObject<HTMLVideoElement | HTMLAudioElement | null>;
3
+ audioChannelIndex: number;
4
+ }) => void;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useAudioChannelIndex = void 0;
4
+ const react_1 = require("react");
5
+ const useAudioChannelIndex = ({ ref, audioChannelIndex, }) => {
6
+ (0, react_1.useEffect)(() => {
7
+ var _a;
8
+ // @ts-expect-error
9
+ const audioChannels = (_a = ref === null || ref === void 0 ? void 0 : ref.current) === null || _a === void 0 ? void 0 : _a.audioTracks;
10
+ console.log({ audioChannels, audioChannelIndex });
11
+ }, [ref, audioChannelIndex]);
12
+ };
13
+ exports.useAudioChannelIndex = useAudioChannelIndex;
@@ -110,7 +110,7 @@ function truthy(value) {
110
110
  }
111
111
 
112
112
  // src/version.ts
113
- var VERSION = "4.0.390";
113
+ var VERSION = "4.0.392";
114
114
 
115
115
  // src/multiple-versions-warning.ts
116
116
  var checkMultipleRemotionVersions = () => {
@@ -1356,12 +1356,12 @@ var Log = {
1356
1356
  };
1357
1357
 
1358
1358
  // src/delay-render.ts
1359
- var handles = [];
1360
1359
  if (typeof window !== "undefined") {
1361
1360
  window.remotion_renderReady = false;
1362
1361
  if (!window.remotion_delayRenderTimeouts) {
1363
1362
  window.remotion_delayRenderTimeouts = {};
1364
1363
  }
1364
+ window.remotion_delayRenderHandles = [];
1365
1365
  }
1366
1366
  var DELAY_RENDER_CALLSTACK_TOKEN = "The delayRender was called:";
1367
1367
  var DELAY_RENDER_RETRIES_LEFT = "Retries left: ";
@@ -1378,38 +1378,37 @@ var delayRenderInternal = ({
1378
1378
  throw new Error("The label parameter of delayRender() must be a string or undefined, got: " + JSON.stringify(label));
1379
1379
  }
1380
1380
  const handle = Math.random();
1381
- handles.push(handle);
1381
+ scope.remotion_delayRenderHandles.push(handle);
1382
1382
  const called = Error().stack?.replace(/^Error/g, "") ?? "";
1383
1383
  if (environment.isRendering) {
1384
- const timeoutToUse = (options?.timeoutInMilliseconds ?? (typeof scope === "undefined" ? defaultTimeout : scope.remotion_puppeteerTimeout ?? defaultTimeout)) - 2000;
1385
- if (typeof scope !== "undefined") {
1386
- const retriesLeft = (options?.retries ?? 0) - (scope.remotion_attempt - 1);
1387
- scope.remotion_delayRenderTimeouts[handle] = {
1388
- label: label ?? null,
1389
- startTime: Date.now(),
1390
- timeout: setTimeout(() => {
1391
- const message = [
1392
- `A delayRender()`,
1393
- label ? `"${label}"` : null,
1394
- `was called but not cleared after ${timeoutToUse}ms. See https://remotion.dev/docs/timeout for help.`,
1395
- retriesLeft > 0 ? DELAY_RENDER_RETRIES_LEFT + retriesLeft : null,
1396
- retriesLeft > 0 ? DELAY_RENDER_RETRY_TOKEN : null,
1397
- DELAY_RENDER_CALLSTACK_TOKEN,
1398
- called
1399
- ].filter(truthy).join(" ");
1400
- cancelRenderInternal(scope, Error(message));
1401
- }, timeoutToUse)
1402
- };
1403
- }
1404
- }
1405
- if (typeof scope !== "undefined") {
1406
- scope.remotion_renderReady = false;
1384
+ const timeoutToUse = (options?.timeoutInMilliseconds ?? scope.remotion_puppeteerTimeout ?? defaultTimeout) - 2000;
1385
+ const retriesLeft = (options?.retries ?? 0) - (scope.remotion_attempt - 1);
1386
+ scope.remotion_delayRenderTimeouts[handle] = {
1387
+ label: label ?? null,
1388
+ startTime: Date.now(),
1389
+ timeout: setTimeout(() => {
1390
+ const message = [
1391
+ `A delayRender()`,
1392
+ label ? `"${label}"` : null,
1393
+ `was called but not cleared after ${timeoutToUse}ms. See https://remotion.dev/docs/timeout for help.`,
1394
+ retriesLeft > 0 ? DELAY_RENDER_RETRIES_LEFT + retriesLeft : null,
1395
+ retriesLeft > 0 ? DELAY_RENDER_RETRY_TOKEN : null,
1396
+ DELAY_RENDER_CALLSTACK_TOKEN,
1397
+ called
1398
+ ].filter(truthy).join(" ");
1399
+ cancelRenderInternal(scope, Error(message));
1400
+ }, timeoutToUse)
1401
+ };
1407
1402
  }
1403
+ scope.remotion_renderReady = false;
1408
1404
  return handle;
1409
1405
  };
1410
1406
  var delayRender = (label, options) => {
1407
+ if (typeof window === "undefined") {
1408
+ return Math.random();
1409
+ }
1411
1410
  return delayRenderInternal({
1412
- scope: typeof window !== "undefined" ? window : undefined,
1411
+ scope: window,
1413
1412
  environment: getRemotionEnvironment(),
1414
1413
  label: label ?? null,
1415
1414
  options: options ?? {}
@@ -1427,7 +1426,7 @@ var continueRenderInternal = ({
1427
1426
  if (typeof handle !== "number") {
1428
1427
  throw new TypeError("The parameter passed into continueRender() must be the return value of delayRender() which is a number. Got: " + JSON.stringify(handle));
1429
1428
  }
1430
- handles = handles.filter((h) => {
1429
+ scope.remotion_delayRenderHandles = scope.remotion_delayRenderHandles.filter((h) => {
1431
1430
  if (h === handle) {
1432
1431
  if (environment.isRendering && scope !== undefined) {
1433
1432
  if (!scope.remotion_delayRenderTimeouts[handle]) {
@@ -1447,16 +1446,19 @@ var continueRenderInternal = ({
1447
1446
  }
1448
1447
  return true;
1449
1448
  });
1450
- if (handles.length === 0 && typeof scope !== "undefined") {
1449
+ if (scope.remotion_delayRenderHandles.length === 0) {
1451
1450
  scope.remotion_renderReady = true;
1452
1451
  }
1453
1452
  };
1454
1453
  var continueRender = (handle) => {
1454
+ if (typeof window === "undefined") {
1455
+ return;
1456
+ }
1455
1457
  continueRenderInternal({
1456
- scope: typeof window !== "undefined" ? window : undefined,
1458
+ scope: window,
1457
1459
  handle,
1458
1460
  environment: getRemotionEnvironment(),
1459
- logLevel: typeof window !== "undefined" ? window.remotion_logLevel ?? "info" : "info"
1461
+ logLevel: window.remotion_logLevel ?? "info"
1460
1462
  });
1461
1463
  };
1462
1464
 
@@ -1486,19 +1488,25 @@ var useMountTime = () => {
1486
1488
  var DelayRenderContextType = createContext9(null);
1487
1489
  var useDelayRender = () => {
1488
1490
  const environment = useRemotionEnvironment();
1489
- const scope = useContext8(DelayRenderContextType);
1491
+ const scope = useContext8(DelayRenderContextType) ?? (typeof window !== "undefined" ? window : undefined);
1490
1492
  const logLevel = useLogLevel();
1491
1493
  const delayRender2 = useCallback4((label, options) => {
1494
+ if (!scope) {
1495
+ return Math.random();
1496
+ }
1492
1497
  return delayRenderInternal({
1493
- scope: scope ?? (typeof window !== "undefined" ? window : undefined),
1498
+ scope,
1494
1499
  environment,
1495
1500
  label: label ?? null,
1496
1501
  options: options ?? {}
1497
1502
  });
1498
1503
  }, [environment, scope]);
1499
1504
  const continueRender2 = useCallback4((handle) => {
1505
+ if (!scope) {
1506
+ return;
1507
+ }
1500
1508
  continueRenderInternal({
1501
- scope: scope ?? (typeof window !== "undefined" ? window : undefined),
1509
+ scope,
1502
1510
  handle,
1503
1511
  environment,
1504
1512
  logLevel
@@ -3196,7 +3204,7 @@ var SharedAudioContextProvider = ({ children, numberOfAudioTags, audioLatencyHin
3196
3204
  });
3197
3205
  }, [refs]);
3198
3206
  const registerAudio = useCallback7((options) => {
3199
- const { aud, audioId, premounting } = options;
3207
+ const { aud, audioId, premounting, postmounting } = options;
3200
3208
  const found = audios.current?.find((a) => a.audioId === audioId);
3201
3209
  if (found) {
3202
3210
  return found;
@@ -3215,7 +3223,9 @@ var SharedAudioContextProvider = ({ children, numberOfAudioTags, audioLatencyHin
3215
3223
  el: ref,
3216
3224
  audioId,
3217
3225
  mediaElementSourceNode,
3218
- premounting
3226
+ premounting,
3227
+ audioMounted: Boolean(ref.current),
3228
+ postmounting
3219
3229
  };
3220
3230
  audios.current?.push(newElem);
3221
3231
  rerenderAudios();
@@ -3236,12 +3246,17 @@ var SharedAudioContextProvider = ({ children, numberOfAudioTags, audioLatencyHin
3236
3246
  aud,
3237
3247
  audioId,
3238
3248
  id,
3239
- premounting
3249
+ premounting,
3250
+ postmounting
3240
3251
  }) => {
3241
3252
  let changed = false;
3242
3253
  audios.current = audios.current?.map((prevA) => {
3254
+ const audioMounted = Boolean(prevA.el.current);
3255
+ if (prevA.audioMounted !== audioMounted) {
3256
+ changed = true;
3257
+ }
3243
3258
  if (prevA.id === id) {
3244
- const isTheSame = compareProps(aud, prevA.props) && prevA.premounting === premounting;
3259
+ const isTheSame = compareProps(aud, prevA.props) && prevA.premounting === premounting && prevA.postmounting === postmounting;
3245
3260
  if (isTheSame) {
3246
3261
  return prevA;
3247
3262
  }
@@ -3250,7 +3265,9 @@ var SharedAudioContextProvider = ({ children, numberOfAudioTags, audioLatencyHin
3250
3265
  ...prevA,
3251
3266
  props: aud,
3252
3267
  premounting,
3253
- audioId
3268
+ postmounting,
3269
+ audioId,
3270
+ audioMounted
3254
3271
  };
3255
3272
  }
3256
3273
  return prevA;
@@ -3313,12 +3330,13 @@ var SharedAudioContextProvider = ({ children, numberOfAudioTags, audioLatencyHin
3313
3330
  var useSharedAudio = ({
3314
3331
  aud,
3315
3332
  audioId,
3316
- premounting
3333
+ premounting,
3334
+ postmounting
3317
3335
  }) => {
3318
3336
  const ctx = useContext16(SharedAudioContext);
3319
3337
  const [elem] = useState11(() => {
3320
3338
  if (ctx && ctx.numberOfAudioTags > 0) {
3321
- return ctx.registerAudio({ aud, audioId, premounting });
3339
+ return ctx.registerAudio({ aud, audioId, premounting, postmounting });
3322
3340
  }
3323
3341
  const el = React15.createRef();
3324
3342
  const mediaElementSourceNode = ctx?.audioContext ? makeSharedElementSourceNode({
@@ -3331,16 +3349,18 @@ var useSharedAudio = ({
3331
3349
  props: aud,
3332
3350
  audioId,
3333
3351
  mediaElementSourceNode,
3334
- premounting
3352
+ premounting,
3353
+ audioMounted: Boolean(el.current),
3354
+ postmounting
3335
3355
  };
3336
3356
  });
3337
3357
  const effectToUse = React15.useInsertionEffect ?? React15.useLayoutEffect;
3338
3358
  if (typeof document !== "undefined") {
3339
3359
  effectToUse(() => {
3340
3360
  if (ctx && ctx.numberOfAudioTags > 0) {
3341
- ctx.updateAudio({ id: elem.id, aud, audioId, premounting });
3361
+ ctx.updateAudio({ id: elem.id, aud, audioId, premounting, postmounting });
3342
3362
  }
3343
- }, [aud, ctx, elem.id, audioId, premounting]);
3363
+ }, [aud, ctx, elem.id, audioId, premounting, postmounting]);
3344
3364
  effectToUse(() => {
3345
3365
  return () => {
3346
3366
  if (ctx && ctx.numberOfAudioTags > 0) {
@@ -4812,7 +4832,8 @@ var AudioForDevelopmentForwardRefFunction = (props, ref) => {
4812
4832
  const { el: audioRef, mediaElementSourceNode } = useSharedAudio({
4813
4833
  aud: propsToPass,
4814
4834
  audioId: id,
4815
- premounting: Boolean(sequenceContext?.premounting)
4835
+ premounting: Boolean(sequenceContext?.premounting),
4836
+ postmounting: Boolean(sequenceContext?.postmounting)
4816
4837
  });
4817
4838
  useMediaInTimeline({
4818
4839
  volume,