@remotion/player 4.0.451 → 4.0.453

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.
@@ -61,6 +61,7 @@ export type PlayerProps<Schema extends AnyZodObject, Props extends Record<string
61
61
  readonly acknowledgeRemotionLicense?: boolean;
62
62
  readonly audioLatencyHint?: AudioContextLatencyCategory;
63
63
  readonly volumePersistenceKey?: string;
64
+ readonly initialVolume?: number;
64
65
  } & CompProps<Props> & PropsIfHasProps<Schema, Props>;
65
66
  export type PlayerPropsWithoutZod<Props extends Record<string, unknown>> = PlayerProps<AnyZodObject, Props>;
66
67
  export declare const componentOrNullIfLazy: <Props>(props: CompProps<Props>) => ComponentType<Props> | null;
@@ -23,7 +23,7 @@ const componentOrNullIfLazy = (props) => {
23
23
  return null;
24
24
  };
25
25
  exports.componentOrNullIfLazy = componentOrNullIfLazy;
26
- const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps, inputProps, style, controls = false, loop = false, autoPlay = false, showVolumeControls = true, allowFullscreen = true, clickToPlay, doubleClickToFullscreen = false, spaceKeyToPlayOrPause = true, moveToBeginningWhenEnded = true, numberOfSharedAudioTags = 5, errorFallback = () => '⚠️', playbackRate = 1, renderLoading, className, showPosterWhenUnplayed, showPosterWhenEnded, showPosterWhenPaused, showPosterWhenBuffering, showPosterWhenBufferingAndPaused, initialFrame, renderPoster, inFrame, outFrame, initiallyShowControls, renderFullscreenButton, renderPlayPauseButton, renderVolumeSlider, renderCustomControls, alwaysShowControls = false, initiallyMuted = false, showPlaybackRateControl = false, posterFillMode = 'player-size', bufferStateDelayInMilliseconds, hideControlsWhenPointerDoesntMove = true, overflowVisible = false, renderMuteButton, browserMediaControlsBehavior: passedBrowserMediaControlsBehavior, overrideInternalClassName, logLevel = 'info', noSuspense, acknowledgeRemotionLicense, audioLatencyHint = 'interactive', volumePersistenceKey, ...componentProps }, ref) => {
26
+ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps, inputProps, style, controls = false, loop = false, autoPlay = false, showVolumeControls = true, allowFullscreen = true, clickToPlay, doubleClickToFullscreen = false, spaceKeyToPlayOrPause = true, moveToBeginningWhenEnded = true, numberOfSharedAudioTags = 5, errorFallback = () => '⚠️', playbackRate = 1, renderLoading, className, showPosterWhenUnplayed, showPosterWhenEnded, showPosterWhenPaused, showPosterWhenBuffering, showPosterWhenBufferingAndPaused, initialFrame, renderPoster, inFrame, outFrame, initiallyShowControls, renderFullscreenButton, renderPlayPauseButton, renderVolumeSlider, renderCustomControls, alwaysShowControls = false, initiallyMuted = false, showPlaybackRateControl = false, posterFillMode = 'player-size', bufferStateDelayInMilliseconds, hideControlsWhenPointerDoesntMove = true, overflowVisible = false, renderMuteButton, browserMediaControlsBehavior: passedBrowserMediaControlsBehavior, overrideInternalClassName, logLevel = 'info', noSuspense, acknowledgeRemotionLicense, audioLatencyHint = 'playback', volumePersistenceKey, initialVolume, ...componentProps }, ref) => {
27
27
  if (typeof window !== 'undefined') {
28
28
  window.remotion_isPlayer = true;
29
29
  }
@@ -102,6 +102,17 @@ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps,
102
102
  typeof spaceKeyToPlayOrPause !== 'undefined') {
103
103
  throw new TypeError(`'spaceKeyToPlayOrPause' must be a boolean or undefined but got '${typeof spaceKeyToPlayOrPause}' instead`);
104
104
  }
105
+ if (typeof initialVolume !== 'undefined' &&
106
+ typeof initialVolume !== 'number') {
107
+ throw new TypeError(`'initialVolume' must be a number or undefined but got '${typeof initialVolume}' instead`);
108
+ }
109
+ if (typeof initialVolume === 'number' &&
110
+ (!Number.isFinite(initialVolume) ||
111
+ Number.isNaN(initialVolume) ||
112
+ initialVolume < 0 ||
113
+ initialVolume > 1)) {
114
+ throw new TypeError(`'initialVolume' must be between 0 and 1 but got '${initialVolume}' instead`);
115
+ }
105
116
  if (typeof numberOfSharedAudioTags !== 'number' ||
106
117
  numberOfSharedAudioTags % 1 !== 0 ||
107
118
  !Number.isFinite(numberOfSharedAudioTags) ||
@@ -154,7 +165,7 @@ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps,
154
165
  mode: 'prevent-media-session',
155
166
  });
156
167
  }, [passedBrowserMediaControlsBehavior]);
157
- return (jsx_runtime_1.jsx(remotion_1.Internals.IsPlayerContextProvider, { children: jsx_runtime_1.jsx(SharedPlayerContext_js_1.SharedPlayerContexts, { timelineContext: timelineContextValue, component: component, compositionHeight: compositionHeight, compositionWidth: compositionWidth, durationInFrames: durationInFrames, fps: fps, numberOfSharedAudioTags: numberOfSharedAudioTags, initiallyMuted: initiallyMuted, logLevel: logLevel, audioLatencyHint: audioLatencyHint, volumePersistenceKey: volumePersistenceKey, inputProps: actualInputProps, audioEnabled: true, children: jsx_runtime_1.jsx(remotion_1.Internals.SetTimelineContext.Provider, { value: setTimelineContextValue, children: jsx_runtime_1.jsx(EmitterProvider_js_1.PlayerEmitterProvider, { currentPlaybackRate: currentPlaybackRate, children: jsx_runtime_1.jsx(PlayerUI_js_1.default, { ref: rootRef, posterFillMode: posterFillMode, renderLoading: renderLoading, autoPlay: Boolean(autoPlay), loop: Boolean(loop), controls: Boolean(controls), errorFallback: errorFallback, style: style, inputProps: actualInputProps, allowFullscreen: Boolean(allowFullscreen), moveToBeginningWhenEnded: Boolean(moveToBeginningWhenEnded), clickToPlay: typeof clickToPlay === 'boolean'
168
+ return (jsx_runtime_1.jsx(remotion_1.Internals.IsPlayerContextProvider, { children: jsx_runtime_1.jsx(SharedPlayerContext_js_1.SharedPlayerContexts, { timelineContext: timelineContextValue, component: component, compositionHeight: compositionHeight, compositionWidth: compositionWidth, durationInFrames: durationInFrames, fps: fps, numberOfSharedAudioTags: numberOfSharedAudioTags, initiallyMuted: initiallyMuted, logLevel: logLevel, audioLatencyHint: audioLatencyHint, volumePersistenceKey: volumePersistenceKey, initialVolume: initialVolume, inputProps: actualInputProps, audioEnabled: true, children: jsx_runtime_1.jsx(remotion_1.Internals.SetTimelineContext.Provider, { value: setTimelineContextValue, children: jsx_runtime_1.jsx(EmitterProvider_js_1.PlayerEmitterProvider, { currentPlaybackRate: currentPlaybackRate, children: jsx_runtime_1.jsx(PlayerUI_js_1.default, { ref: rootRef, posterFillMode: posterFillMode, renderLoading: renderLoading, autoPlay: Boolean(autoPlay), loop: Boolean(loop), controls: Boolean(controls), errorFallback: errorFallback, style: style, inputProps: actualInputProps, allowFullscreen: Boolean(allowFullscreen), moveToBeginningWhenEnded: Boolean(moveToBeginningWhenEnded), clickToPlay: typeof clickToPlay === 'boolean'
158
169
  ? clickToPlay
159
170
  : Boolean(controls), showVolumeControls: Boolean(showVolumeControls), doubleClickToFullscreen: Boolean(doubleClickToFullscreen), spaceKeyToPlayOrPause: Boolean(spaceKeyToPlayOrPause), playbackRate: currentPlaybackRate, className: className !== null && className !== void 0 ? className : undefined, showPosterWhenUnplayed: Boolean(showPosterWhenUnplayed), showPosterWhenEnded: Boolean(showPosterWhenEnded), showPosterWhenPaused: Boolean(showPosterWhenPaused), showPosterWhenBuffering: Boolean(showPosterWhenBuffering), showPosterWhenBufferingAndPaused: Boolean(showPosterWhenBufferingAndPaused), renderPoster: renderPoster, inFrame: inFrame !== null && inFrame !== void 0 ? inFrame : null, outFrame: outFrame !== null && outFrame !== void 0 ? outFrame : null, initiallyShowControls: initiallyShowControls !== null && initiallyShowControls !== void 0 ? initiallyShowControls : true, renderFullscreen: renderFullscreenButton !== null && renderFullscreenButton !== void 0 ? renderFullscreenButton : null, renderPlayPauseButton: renderPlayPauseButton !== null && renderPlayPauseButton !== void 0 ? renderPlayPauseButton : null, renderMuteButton: renderMuteButton !== null && renderMuteButton !== void 0 ? renderMuteButton : null, renderVolumeSlider: renderVolumeSlider !== null && renderVolumeSlider !== void 0 ? renderVolumeSlider : null, renderCustomControls: renderCustomControls !== null && renderCustomControls !== void 0 ? renderCustomControls : null, alwaysShowControls: alwaysShowControls, showPlaybackRateControl: showPlaybackRateControl, bufferStateDelayInMilliseconds: bufferStateDelayInMilliseconds !== null && bufferStateDelayInMilliseconds !== void 0 ? bufferStateDelayInMilliseconds : 300, hideControlsWhenPointerDoesntMove: hideControlsWhenPointerDoesntMove, overflowVisible: overflowVisible, browserMediaControlsBehavior: browserMediaControlsBehavior, overrideInternalClassName: overrideInternalClassName !== null && overrideInternalClassName !== void 0 ? overrideInternalClassName : undefined, noSuspense: Boolean(noSuspense) }) }) }) }) }));
160
171
  };
@@ -15,6 +15,7 @@ export declare const SharedPlayerContexts: React.FC<{
15
15
  readonly logLevel: LogLevel;
16
16
  readonly audioLatencyHint: AudioContextLatencyCategory;
17
17
  readonly volumePersistenceKey?: string;
18
+ readonly initialVolume?: number;
18
19
  readonly inputProps: Record<string, unknown>;
19
20
  readonly audioEnabled: boolean;
20
21
  }>;
@@ -6,7 +6,8 @@ const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
7
  const volume_persistence_js_1 = require("./volume-persistence.js");
8
8
  exports.PLAYER_COMP_ID = 'player-comp';
9
- const SharedPlayerContexts = ({ children, timelineContext, fps, compositionHeight, compositionWidth, durationInFrames, component, numberOfSharedAudioTags, initiallyMuted, logLevel, audioLatencyHint, volumePersistenceKey, inputProps, audioEnabled, }) => {
9
+ const SharedPlayerContexts = ({ children, timelineContext, fps, compositionHeight, compositionWidth, durationInFrames, component, numberOfSharedAudioTags, initiallyMuted, logLevel, audioLatencyHint, volumePersistenceKey, initialVolume, inputProps, audioEnabled, }) => {
10
+ const persistVolumeToStorage = initialVolume === undefined;
10
11
  const compositionManagerContext = (0, react_1.useMemo)(() => {
11
12
  const context = {
12
13
  compositions: [
@@ -51,7 +52,9 @@ const SharedPlayerContexts = ({ children, timelineContext, fps, compositionHeigh
51
52
  inputProps,
52
53
  ]);
53
54
  const [mediaMuted, setMediaMuted] = (0, react_1.useState)(() => initiallyMuted);
54
- const [mediaVolume, setMediaVolume] = (0, react_1.useState)(() => (0, volume_persistence_js_1.getPreferredVolume)(volumePersistenceKey !== null && volumePersistenceKey !== void 0 ? volumePersistenceKey : null));
55
+ const [mediaVolume, setMediaVolume] = (0, react_1.useState)(() => persistVolumeToStorage
56
+ ? (0, volume_persistence_js_1.getPreferredVolume)(volumePersistenceKey !== null && volumePersistenceKey !== void 0 ? volumePersistenceKey : null)
57
+ : initialVolume);
55
58
  const mediaVolumeContextValue = (0, react_1.useMemo)(() => {
56
59
  return {
57
60
  mediaMuted,
@@ -60,8 +63,10 @@ const SharedPlayerContexts = ({ children, timelineContext, fps, compositionHeigh
60
63
  }, [mediaMuted, mediaVolume]);
61
64
  const setMediaVolumeAndPersist = (0, react_1.useCallback)((vol) => {
62
65
  setMediaVolume(vol);
63
- (0, volume_persistence_js_1.persistVolume)(vol, logLevel, volumePersistenceKey !== null && volumePersistenceKey !== void 0 ? volumePersistenceKey : null);
64
- }, [logLevel, volumePersistenceKey]);
66
+ if (persistVolumeToStorage) {
67
+ (0, volume_persistence_js_1.persistVolume)(vol, logLevel, volumePersistenceKey !== null && volumePersistenceKey !== void 0 ? volumePersistenceKey : null);
68
+ }
69
+ }, [persistVolumeToStorage, logLevel, volumePersistenceKey]);
65
70
  const setMediaVolumeContextValue = (0, react_1.useMemo)(() => {
66
71
  return {
67
72
  setMediaMuted,
@@ -83,6 +88,6 @@ const SharedPlayerContexts = ({ children, timelineContext, fps, compositionHeigh
83
88
  isReadOnlyStudio: false,
84
89
  };
85
90
  }, []);
86
- return (jsx_runtime_1.jsx(remotion_1.Internals.RemotionEnvironmentContext.Provider, { value: env, children: jsx_runtime_1.jsx(remotion_1.Internals.LogLevelContext.Provider, { value: logLevelContext, children: jsx_runtime_1.jsx(remotion_1.Internals.CanUseRemotionHooksProvider, { children: jsx_runtime_1.jsx(remotion_1.Internals.AbsoluteTimeContext.Provider, { value: timelineContext, children: jsx_runtime_1.jsx(remotion_1.Internals.TimelineContext.Provider, { value: timelineContext, children: jsx_runtime_1.jsx(remotion_1.Internals.CompositionManager.Provider, { value: compositionManagerContext, children: jsx_runtime_1.jsx(remotion_1.Internals.PrefetchProvider, { children: jsx_runtime_1.jsx(remotion_1.Internals.DurationsContextProvider, { children: jsx_runtime_1.jsx(remotion_1.Internals.MediaVolumeContext.Provider, { value: mediaVolumeContextValue, children: jsx_runtime_1.jsx(remotion_1.Internals.SetMediaVolumeContext.Provider, { value: setMediaVolumeContextValue, children: jsx_runtime_1.jsx(remotion_1.Internals.SharedAudioContextProvider, { numberOfAudioTags: numberOfSharedAudioTags, audioLatencyHint: audioLatencyHint, audioEnabled: audioEnabled, children: jsx_runtime_1.jsx(remotion_1.Internals.BufferingProvider, { children: children }) }) }) }) }) }) }) }) }) }) }) }));
91
+ return (jsx_runtime_1.jsx(remotion_1.Internals.RemotionEnvironmentContext.Provider, { value: env, children: jsx_runtime_1.jsx(remotion_1.Internals.LogLevelContext.Provider, { value: logLevelContext, children: jsx_runtime_1.jsx(remotion_1.Internals.CanUseRemotionHooksProvider, { children: jsx_runtime_1.jsx(remotion_1.Internals.AbsoluteTimeContext.Provider, { value: timelineContext, children: jsx_runtime_1.jsx(remotion_1.Internals.TimelineContext.Provider, { value: timelineContext, children: jsx_runtime_1.jsx(remotion_1.Internals.CompositionManager.Provider, { value: compositionManagerContext, children: jsx_runtime_1.jsx(remotion_1.Internals.PrefetchProvider, { children: jsx_runtime_1.jsx(remotion_1.Internals.DurationsContextProvider, { children: jsx_runtime_1.jsx(remotion_1.Internals.MediaVolumeContext.Provider, { value: mediaVolumeContextValue, children: jsx_runtime_1.jsx(remotion_1.Internals.SetMediaVolumeContext.Provider, { value: setMediaVolumeContextValue, children: jsx_runtime_1.jsx(remotion_1.Internals.BufferingProvider, { children: jsx_runtime_1.jsx(remotion_1.Internals.SharedAudioContextProvider, { audioLatencyHint: audioLatencyHint, audioEnabled: audioEnabled, children: jsx_runtime_1.jsx(remotion_1.Internals.SharedAudioTagsContextProvider, { numberOfAudioTags: numberOfSharedAudioTags, children: children }) }) }) }) }) }) }) }) }) }) }) }) }));
87
92
  };
88
93
  exports.SharedPlayerContexts = SharedPlayerContexts;
@@ -0,0 +1,10 @@
1
+ export declare const ALLOWED_GLOBAL_TIME_ANCHOR_SHIFT = 0.1;
2
+ export declare const setGlobalTimeAnchor: ({ audioContext, audioSyncAnchor, absoluteTimeInSeconds, globalPlaybackRate, logLevel, }: {
3
+ audioContext: AudioContext;
4
+ audioSyncAnchor: {
5
+ value: number;
6
+ };
7
+ absoluteTimeInSeconds: number;
8
+ globalPlaybackRate: number;
9
+ logLevel: "error" | "info" | "trace" | "verbose" | "warn";
10
+ }) => boolean;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.setGlobalTimeAnchor = exports.ALLOWED_GLOBAL_TIME_ANCHOR_SHIFT = void 0;
4
+ const remotion_1 = require("remotion");
5
+ exports.ALLOWED_GLOBAL_TIME_ANCHOR_SHIFT = 0.1;
6
+ const setGlobalTimeAnchor = ({ audioContext, audioSyncAnchor, absoluteTimeInSeconds, globalPlaybackRate, logLevel, }) => {
7
+ const newAnchor = audioContext.currentTime - absoluteTimeInSeconds / globalPlaybackRate;
8
+ const shift = (newAnchor - audioSyncAnchor.value) * globalPlaybackRate;
9
+ const { outputLatency } = audioContext;
10
+ const safeOutputLatency = outputLatency === 0 ? 0.3 : outputLatency;
11
+ const latency = audioContext.baseLatency + safeOutputLatency;
12
+ // Skip small shifts to avoid audio glitches from frame-quantized re-anchoring
13
+ if (Math.abs(shift) < exports.ALLOWED_GLOBAL_TIME_ANCHOR_SHIFT + latency) {
14
+ return false;
15
+ }
16
+ remotion_1.Internals.Log.verbose({ logLevel, tag: 'audio-scheduling' }, 'Anchor changed from %s to %s with shift %s', audioSyncAnchor.value, newAnchor, shift);
17
+ audioSyncAnchor.value = newAnchor;
18
+ return true;
19
+ };
20
+ exports.setGlobalTimeAnchor = setGlobalTimeAnchor;
@@ -1,24 +1,29 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.usePlayback = void 0;
4
- /* eslint-disable @typescript-eslint/no-use-before-define */
5
4
  const react_1 = require("react");
5
+ /* eslint-disable @typescript-eslint/no-use-before-define */
6
+ const react_2 = require("react");
6
7
  const remotion_1 = require("remotion");
7
8
  const browser_mediasession_js_1 = require("./browser-mediasession.js");
8
9
  const calculate_next_frame_js_1 = require("./calculate-next-frame.js");
9
10
  const is_backgrounded_js_1 = require("./is-backgrounded.js");
11
+ const set_global_time_anchor_js_1 = require("./set-global-time-anchor.js");
10
12
  const use_player_js_1 = require("./use-player.js");
11
13
  const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, outFrame, browserMediaControlsBehavior, getCurrentFrame, }) => {
12
14
  const config = remotion_1.Internals.useUnsafeVideoConfig();
13
15
  const frame = remotion_1.Internals.Timeline.useTimelinePosition();
14
16
  const { playing, pause, emitter, isPlaying } = (0, use_player_js_1.usePlayer)();
15
17
  const setFrame = remotion_1.Internals.Timeline.useTimelineSetFrame();
18
+ const sharedAudioContext = (0, react_2.useContext)(remotion_1.Internals.SharedAudioContext);
19
+ const logLevel = remotion_1.Internals.useLogLevel();
20
+ const timelineContext = remotion_1.Internals.useTimelineContext();
16
21
  // requestAnimationFrame() does not work if the tab is not active.
17
22
  // This means that audio will keep playing even if it has ended.
18
23
  // In that case, we use setTimeout() instead.
19
24
  const isBackgroundedRef = (0, is_backgrounded_js_1.useIsBackgrounded)();
20
- const lastTimeUpdateEvent = (0, react_1.useRef)(null);
21
- const context = (0, react_1.useContext)(remotion_1.Internals.BufferingContextReact);
25
+ const lastTimeUpdateTimestamp = (0, react_2.useRef)(0);
26
+ const context = (0, react_2.useContext)(remotion_1.Internals.BufferingContextReact);
22
27
  if (!context) {
23
28
  throw new Error('Missing the buffering context. Most likely you have a Remotion version mismatch.');
24
29
  }
@@ -27,12 +32,40 @@ const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, ou
27
32
  playbackRate,
28
33
  videoConfig: config,
29
34
  });
30
- // complete code for media session API
31
- (0, react_1.useEffect)(() => {
35
+ (0, react_1.useLayoutEffect)(() => {
36
+ if (!sharedAudioContext) {
37
+ return;
38
+ }
39
+ if (!sharedAudioContext.audioContext) {
40
+ return;
41
+ }
42
+ if (!config) {
43
+ return;
44
+ }
45
+ const changed = (0, set_global_time_anchor_js_1.setGlobalTimeAnchor)({
46
+ audioContext: sharedAudioContext.audioContext,
47
+ audioSyncAnchor: sharedAudioContext.audioSyncAnchor,
48
+ absoluteTimeInSeconds: frame / config.fps,
49
+ globalPlaybackRate: timelineContext.playbackRate,
50
+ logLevel,
51
+ });
52
+ if (changed) {
53
+ sharedAudioContext.audioSyncAnchorEmitter.dispatch('changed');
54
+ }
55
+ }, [
56
+ config,
57
+ frame,
58
+ logLevel,
59
+ sharedAudioContext,
60
+ timelineContext.playbackRate,
61
+ ]);
62
+ (0, react_2.useEffect)(() => {
63
+ var _a;
32
64
  if (!config) {
33
65
  return;
34
66
  }
35
67
  if (!playing) {
68
+ (_a = sharedAudioContext === null || sharedAudioContext === void 0 ? void 0 : sharedAudioContext.suspend) === null || _a === void 0 ? void 0 : _a.call(sharedAudioContext);
36
69
  return;
37
70
  }
38
71
  let hasBeenStopped = false;
@@ -54,12 +87,15 @@ const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, ou
54
87
  cancelQueuedFrame();
55
88
  };
56
89
  const callback = () => {
90
+ var _a, _b;
57
91
  if (hasBeenStopped) {
58
92
  return;
59
93
  }
60
94
  if (!isPlaying()) {
95
+ (_a = sharedAudioContext === null || sharedAudioContext === void 0 ? void 0 : sharedAudioContext.suspend) === null || _a === void 0 ? void 0 : _a.call(sharedAudioContext);
61
96
  return;
62
97
  }
98
+ (_b = sharedAudioContext === null || sharedAudioContext === void 0 ? void 0 : sharedAudioContext.resume) === null || _b === void 0 ? void 0 : _b.call(sharedAudioContext);
63
99
  const time = performance.now() - startedTime;
64
100
  const actualLastFrame = outFrame !== null && outFrame !== void 0 ? outFrame : config.durationInFrames - 1;
65
101
  const actualFirstFrame = inFrame !== null && inFrame !== void 0 ? inFrame : 0;
@@ -88,7 +124,36 @@ const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, ou
88
124
  queueNextFrame();
89
125
  };
90
126
  const queueNextFrame = () => {
127
+ var _a, _b;
128
+ var _c;
129
+ const getIsResumingAudioContext = (_c = (_a = sharedAudioContext === null || sharedAudioContext === void 0 ? void 0 : sharedAudioContext.getIsResumingAudioContext) === null || _a === void 0 ? void 0 : _a.call(sharedAudioContext)) !== null && _c !== void 0 ? _c : null;
130
+ if (getIsResumingAudioContext !== null) {
131
+ getIsResumingAudioContext.then(() => {
132
+ if (!(sharedAudioContext === null || sharedAudioContext === void 0 ? void 0 : sharedAudioContext.audioContext)) {
133
+ return;
134
+ }
135
+ if (!sharedAudioContext.audioSyncAnchor) {
136
+ return;
137
+ }
138
+ // set it here and DON'T propagate an event
139
+ // the useLayoutEffect above is supposed to handle a user seek,
140
+ // this is a natural wait for the audio playback to start.
141
+ // we don't wanna destroy the iterators.
142
+ (0, set_global_time_anchor_js_1.setGlobalTimeAnchor)({
143
+ audioContext: sharedAudioContext.audioContext,
144
+ audioSyncAnchor: sharedAudioContext.audioSyncAnchor,
145
+ absoluteTimeInSeconds: getCurrentFrame() / config.fps,
146
+ globalPlaybackRate: timelineContext.playbackRate,
147
+ logLevel,
148
+ });
149
+ startedTime = performance.now();
150
+ framesAdvanced = 0;
151
+ queueNextFrame();
152
+ });
153
+ return;
154
+ }
91
155
  if (context.buffering.current) {
156
+ (_b = sharedAudioContext === null || sharedAudioContext === void 0 ? void 0 : sharedAudioContext.suspend) === null || _b === void 0 ? void 0 : _b.call(sharedAudioContext);
92
157
  const stopListening = context.listenForResume(() => {
93
158
  stopListening.remove();
94
159
  startedTime = performance.now();
@@ -137,18 +202,25 @@ const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, ou
137
202
  getCurrentFrame,
138
203
  context,
139
204
  isPlaying,
205
+ sharedAudioContext,
206
+ timelineContext.playbackRate,
207
+ logLevel,
140
208
  ]);
141
- (0, react_1.useEffect)(() => {
142
- const interval = setInterval(() => {
143
- if (lastTimeUpdateEvent.current === getCurrentFrame()) {
144
- return;
145
- }
146
- emitter.dispatchTimeUpdate({ frame: getCurrentFrame() });
147
- lastTimeUpdateEvent.current = getCurrentFrame();
148
- }, 250);
149
- return () => clearInterval(interval);
150
- }, [emitter, getCurrentFrame]);
151
- (0, react_1.useEffect)(() => {
209
+ (0, react_2.useEffect)(() => {
210
+ const now = performance.now();
211
+ const timeSinceLastUpdate = now - lastTimeUpdateTimestamp.current;
212
+ if (timeSinceLastUpdate >= 250) {
213
+ emitter.dispatchTimeUpdate({ frame });
214
+ lastTimeUpdateTimestamp.current = now;
215
+ return;
216
+ }
217
+ const timeoutId = setTimeout(() => {
218
+ emitter.dispatchTimeUpdate({ frame });
219
+ lastTimeUpdateTimestamp.current = performance.now();
220
+ }, 250 - timeSinceLastUpdate);
221
+ return () => clearTimeout(timeoutId);
222
+ }, [emitter, frame]);
223
+ (0, react_2.useEffect)(() => {
152
224
  emitter.dispatchFrameUpdate({ frame });
153
225
  }, [emitter, frame]);
154
226
  };
@@ -13,6 +13,7 @@ const usePlayer = () => {
13
13
  const setFrame = remotion_1.Internals.Timeline.useTimelineSetFrame();
14
14
  const setTimelinePosition = remotion_1.Internals.Timeline.useTimelineSetFrame();
15
15
  const audioContext = (0, react_1.useContext)(remotion_1.Internals.SharedAudioContext);
16
+ const audioTagsContext = (0, react_1.useContext)(remotion_1.Internals.SharedAudioTagsContext);
16
17
  const { audioAndVideoTags } = remotion_1.Internals.useTimelineContext();
17
18
  const frameRef = (0, react_1.useRef)(frame);
18
19
  frameRef.current = frame;
@@ -38,7 +39,6 @@ const usePlayer = () => {
38
39
  emitter.dispatchSeek(newFrame);
39
40
  }, [emitter, setTimelinePosition, video === null || video === void 0 ? void 0 : video.id]);
40
41
  const play = (0, react_1.useCallback)((e) => {
41
- var _a;
42
42
  if (imperativePlaying.current) {
43
43
  return;
44
44
  }
@@ -46,12 +46,12 @@ const usePlayer = () => {
46
46
  if (isLastFrame) {
47
47
  seek(0);
48
48
  }
49
- (_a = audioContext === null || audioContext === void 0 ? void 0 : audioContext.audioContext) === null || _a === void 0 ? void 0 : _a.resume();
49
+ audioContext === null || audioContext === void 0 ? void 0 : audioContext.resume();
50
50
  /**
51
51
  * Play silent audio tags to warm them up for autoplay
52
52
  */
53
- if (audioContext && audioContext.numberOfAudioTags > 0 && e) {
54
- audioContext.playAllAudios();
53
+ if (audioTagsContext && audioTagsContext.numberOfAudioTags > 0 && e) {
54
+ audioTagsContext.playAllAudios();
55
55
  }
56
56
  /**
57
57
  * Play audios and videos directly here so they can benefit from
@@ -66,18 +66,18 @@ const usePlayer = () => {
66
66
  imperativePlaying,
67
67
  isLastFrame,
68
68
  audioContext,
69
+ audioTagsContext,
69
70
  setPlaying,
70
71
  emitter,
71
72
  seek,
72
73
  audioAndVideoTags,
73
74
  ]);
74
75
  const pause = (0, react_1.useCallback)(() => {
75
- var _a;
76
76
  if (imperativePlaying.current) {
77
77
  imperativePlaying.current = false;
78
78
  setPlaying(false);
79
79
  emitter.dispatchPause();
80
- (_a = audioContext === null || audioContext === void 0 ? void 0 : audioContext.audioContext) === null || _a === void 0 ? void 0 : _a.suspend();
80
+ audioContext === null || audioContext === void 0 ? void 0 : audioContext.suspend();
81
81
  }
82
82
  }, [emitter, imperativePlaying, setPlaying, audioContext]);
83
83
  const pauseAndReturnToPlayStart = (0, react_1.useCallback)(() => {
@@ -34,21 +34,24 @@ const useElementSize = (ref, options) => {
34
34
  return null;
35
35
  }
36
36
  return new ResizeObserver((entries) => {
37
- // The contentRect returns the width without any `scale()`'s being applied. The height is wrong
37
+ // `contentRect` is the element's pre-transform content box.
38
+ // `getClientRects()` is the post-transform AABB. Dividing each AABB
39
+ // axis by its content-box counterpart cancels the parent CSS transform
40
+ // whether it is uniform or not.
38
41
  const { contentRect, target } = entries[0];
39
- // The clientRect returns the size with `scale()` being applied.
40
42
  const newSize = target.getClientRects();
41
43
  if (!(newSize === null || newSize === void 0 ? void 0 : newSize[0])) {
42
44
  setSize(null);
43
45
  return;
44
46
  }
45
- const probableCssParentScale = contentRect.width === 0 ? 1 : newSize[0].width / contentRect.width;
46
- const width = options.shouldApplyCssTransforms || probableCssParentScale === 0
47
+ const probableCssParentScaleX = contentRect.width === 0 ? 1 : newSize[0].width / contentRect.width;
48
+ const probableCssParentScaleY = contentRect.height === 0 ? 1 : newSize[0].height / contentRect.height;
49
+ const width = options.shouldApplyCssTransforms || probableCssParentScaleX === 0
47
50
  ? newSize[0].width
48
- : newSize[0].width * (1 / probableCssParentScale);
49
- const height = options.shouldApplyCssTransforms || probableCssParentScale === 0
51
+ : newSize[0].width * (1 / probableCssParentScaleX);
52
+ const height = options.shouldApplyCssTransforms || probableCssParentScaleY === 0
50
53
  ? newSize[0].height
51
- : newSize[0].height * (1 / probableCssParentScale);
54
+ : newSize[0].height * (1 / probableCssParentScaleY);
52
55
  setSize((prevState) => {
53
56
  const isSame = prevState &&
54
57
  prevState.width === width &&
@@ -5,11 +5,11 @@ const validatePlaybackRate = (playbackRate) => {
5
5
  if (playbackRate === undefined) {
6
6
  return;
7
7
  }
8
- if (playbackRate > 4) {
9
- throw new Error(`The highest possible playback rate is 4. You passed: ${playbackRate}`);
8
+ if (playbackRate > 10) {
9
+ throw new Error(`The highest possible playback rate is 10. You passed: ${playbackRate}`);
10
10
  }
11
- if (playbackRate < -4) {
12
- throw new Error(`The lowest possible playback rate is -4. You passed: ${playbackRate}`);
11
+ if (playbackRate < -10) {
12
+ throw new Error(`The lowest possible playback rate is -10. You passed: ${playbackRate}`);
13
13
  }
14
14
  if (playbackRate === 0) {
15
15
  throw new Error(`A playback rate of 0 is not supported.`);
@@ -552,8 +552,9 @@ var useHoverState = (ref, hideControlsWhenPointerDoesntMove) => {
552
552
  };
553
553
 
554
554
  // src/use-playback.ts
555
+ import { useLayoutEffect as useLayoutEffect2 } from "react";
555
556
  import { useContext as useContext4, useEffect as useEffect5, useRef as useRef5 } from "react";
556
- import { Internals as Internals6 } from "remotion";
557
+ import { Internals as Internals7 } from "remotion";
557
558
 
558
559
  // src/browser-mediasession.ts
559
560
  import { useEffect as useEffect3, useRef as useRef3 } from "react";
@@ -569,6 +570,7 @@ var usePlayer = () => {
569
570
  const setFrame = Internals5.Timeline.useTimelineSetFrame();
570
571
  const setTimelinePosition = Internals5.Timeline.useTimelineSetFrame();
571
572
  const audioContext = useContext3(Internals5.SharedAudioContext);
573
+ const audioTagsContext = useContext3(Internals5.SharedAudioTagsContext);
572
574
  const { audioAndVideoTags } = Internals5.useTimelineContext();
573
575
  const frameRef = useRef2(frame);
574
576
  frameRef.current = frame;
@@ -601,9 +603,9 @@ var usePlayer = () => {
601
603
  if (isLastFrame) {
602
604
  seek(0);
603
605
  }
604
- audioContext?.audioContext?.resume();
605
- if (audioContext && audioContext.numberOfAudioTags > 0 && e) {
606
- audioContext.playAllAudios();
606
+ audioContext?.resume();
607
+ if (audioTagsContext && audioTagsContext.numberOfAudioTags > 0 && e) {
608
+ audioTagsContext.playAllAudios();
607
609
  }
608
610
  audioAndVideoTags.current.forEach((a) => a.play("player play() was called and playing audio from a click"));
609
611
  imperativePlaying.current = true;
@@ -614,6 +616,7 @@ var usePlayer = () => {
614
616
  imperativePlaying,
615
617
  isLastFrame,
616
618
  audioContext,
619
+ audioTagsContext,
617
620
  setPlaying,
618
621
  emitter,
619
622
  seek,
@@ -624,7 +627,7 @@ var usePlayer = () => {
624
627
  imperativePlaying.current = false;
625
628
  setPlaying(false);
626
629
  emitter.dispatchPause();
627
- audioContext?.audioContext?.suspend();
630
+ audioContext?.suspend();
628
631
  }
629
632
  }, [emitter, imperativePlaying, setPlaying, audioContext]);
630
633
  const pauseAndReturnToPlayStart = useCallback2(() => {
@@ -901,6 +904,29 @@ var useIsBackgrounded = () => {
901
904
  return isBackgrounded;
902
905
  };
903
906
 
907
+ // src/set-global-time-anchor.ts
908
+ import { Internals as Internals6 } from "remotion";
909
+ var ALLOWED_GLOBAL_TIME_ANCHOR_SHIFT = 0.1;
910
+ var setGlobalTimeAnchor = ({
911
+ audioContext,
912
+ audioSyncAnchor,
913
+ absoluteTimeInSeconds,
914
+ globalPlaybackRate,
915
+ logLevel
916
+ }) => {
917
+ const newAnchor = audioContext.currentTime - absoluteTimeInSeconds / globalPlaybackRate;
918
+ const shift = (newAnchor - audioSyncAnchor.value) * globalPlaybackRate;
919
+ const { outputLatency } = audioContext;
920
+ const safeOutputLatency = outputLatency === 0 ? 0.3 : outputLatency;
921
+ const latency = audioContext.baseLatency + safeOutputLatency;
922
+ if (Math.abs(shift) < ALLOWED_GLOBAL_TIME_ANCHOR_SHIFT + latency) {
923
+ return false;
924
+ }
925
+ Internals6.Log.verbose({ logLevel, tag: "audio-scheduling" }, "Anchor changed from %s to %s with shift %s", audioSyncAnchor.value, newAnchor, shift);
926
+ audioSyncAnchor.value = newAnchor;
927
+ return true;
928
+ };
929
+
904
930
  // src/use-playback.ts
905
931
  var usePlayback = ({
906
932
  loop,
@@ -911,13 +937,16 @@ var usePlayback = ({
911
937
  browserMediaControlsBehavior,
912
938
  getCurrentFrame
913
939
  }) => {
914
- const config = Internals6.useUnsafeVideoConfig();
915
- const frame = Internals6.Timeline.useTimelinePosition();
940
+ const config = Internals7.useUnsafeVideoConfig();
941
+ const frame = Internals7.Timeline.useTimelinePosition();
916
942
  const { playing, pause, emitter, isPlaying } = usePlayer();
917
- const setFrame = Internals6.Timeline.useTimelineSetFrame();
943
+ const setFrame = Internals7.Timeline.useTimelineSetFrame();
944
+ const sharedAudioContext = useContext4(Internals7.SharedAudioContext);
945
+ const logLevel = Internals7.useLogLevel();
946
+ const timelineContext = Internals7.useTimelineContext();
918
947
  const isBackgroundedRef = useIsBackgrounded();
919
- const lastTimeUpdateEvent = useRef5(null);
920
- const context = useContext4(Internals6.BufferingContextReact);
948
+ const lastTimeUpdateTimestamp = useRef5(0);
949
+ const context = useContext4(Internals7.BufferingContextReact);
921
950
  if (!context) {
922
951
  throw new Error("Missing the buffering context. Most likely you have a Remotion version mismatch.");
923
952
  }
@@ -926,11 +955,39 @@ var usePlayback = ({
926
955
  playbackRate,
927
956
  videoConfig: config
928
957
  });
958
+ useLayoutEffect2(() => {
959
+ if (!sharedAudioContext) {
960
+ return;
961
+ }
962
+ if (!sharedAudioContext.audioContext) {
963
+ return;
964
+ }
965
+ if (!config) {
966
+ return;
967
+ }
968
+ const changed = setGlobalTimeAnchor({
969
+ audioContext: sharedAudioContext.audioContext,
970
+ audioSyncAnchor: sharedAudioContext.audioSyncAnchor,
971
+ absoluteTimeInSeconds: frame / config.fps,
972
+ globalPlaybackRate: timelineContext.playbackRate,
973
+ logLevel
974
+ });
975
+ if (changed) {
976
+ sharedAudioContext.audioSyncAnchorEmitter.dispatch("changed");
977
+ }
978
+ }, [
979
+ config,
980
+ frame,
981
+ logLevel,
982
+ sharedAudioContext,
983
+ timelineContext.playbackRate
984
+ ]);
929
985
  useEffect5(() => {
930
986
  if (!config) {
931
987
  return;
932
988
  }
933
989
  if (!playing) {
990
+ sharedAudioContext?.suspend?.();
934
991
  return;
935
992
  }
936
993
  let hasBeenStopped = false;
@@ -955,8 +1012,10 @@ var usePlayback = ({
955
1012
  return;
956
1013
  }
957
1014
  if (!isPlaying()) {
1015
+ sharedAudioContext?.suspend?.();
958
1016
  return;
959
1017
  }
1018
+ sharedAudioContext?.resume?.();
960
1019
  const time = performance.now() - startedTime;
961
1020
  const actualLastFrame = outFrame ?? config.durationInFrames - 1;
962
1021
  const actualFirstFrame = inFrame ?? 0;
@@ -984,7 +1043,30 @@ var usePlayback = ({
984
1043
  queueNextFrame();
985
1044
  };
986
1045
  const queueNextFrame = () => {
1046
+ const getIsResumingAudioContext = sharedAudioContext?.getIsResumingAudioContext?.() ?? null;
1047
+ if (getIsResumingAudioContext !== null) {
1048
+ getIsResumingAudioContext.then(() => {
1049
+ if (!sharedAudioContext?.audioContext) {
1050
+ return;
1051
+ }
1052
+ if (!sharedAudioContext.audioSyncAnchor) {
1053
+ return;
1054
+ }
1055
+ setGlobalTimeAnchor({
1056
+ audioContext: sharedAudioContext.audioContext,
1057
+ audioSyncAnchor: sharedAudioContext.audioSyncAnchor,
1058
+ absoluteTimeInSeconds: getCurrentFrame() / config.fps,
1059
+ globalPlaybackRate: timelineContext.playbackRate,
1060
+ logLevel
1061
+ });
1062
+ startedTime = performance.now();
1063
+ framesAdvanced = 0;
1064
+ queueNextFrame();
1065
+ });
1066
+ return;
1067
+ }
987
1068
  if (context.buffering.current) {
1069
+ sharedAudioContext?.suspend?.();
988
1070
  const stopListening = context.listenForResume(() => {
989
1071
  stopListening.remove();
990
1072
  startedTime = performance.now();
@@ -1029,18 +1111,25 @@ var usePlayback = ({
1029
1111
  isBackgroundedRef,
1030
1112
  getCurrentFrame,
1031
1113
  context,
1032
- isPlaying
1114
+ isPlaying,
1115
+ sharedAudioContext,
1116
+ timelineContext.playbackRate,
1117
+ logLevel
1033
1118
  ]);
1034
1119
  useEffect5(() => {
1035
- const interval = setInterval(() => {
1036
- if (lastTimeUpdateEvent.current === getCurrentFrame()) {
1037
- return;
1038
- }
1039
- emitter.dispatchTimeUpdate({ frame: getCurrentFrame() });
1040
- lastTimeUpdateEvent.current = getCurrentFrame();
1041
- }, 250);
1042
- return () => clearInterval(interval);
1043
- }, [emitter, getCurrentFrame]);
1120
+ const now = performance.now();
1121
+ const timeSinceLastUpdate = now - lastTimeUpdateTimestamp.current;
1122
+ if (timeSinceLastUpdate >= 250) {
1123
+ emitter.dispatchTimeUpdate({ frame });
1124
+ lastTimeUpdateTimestamp.current = now;
1125
+ return;
1126
+ }
1127
+ const timeoutId = setTimeout(() => {
1128
+ emitter.dispatchTimeUpdate({ frame });
1129
+ lastTimeUpdateTimestamp.current = performance.now();
1130
+ }, 250 - timeSinceLastUpdate);
1131
+ return () => clearTimeout(timeoutId);
1132
+ }, [emitter, frame]);
1044
1133
  useEffect5(() => {
1045
1134
  emitter.dispatchFrameUpdate({ frame });
1046
1135
  }, [emitter, frame]);
@@ -1085,9 +1174,10 @@ var useElementSize = (ref, options) => {
1085
1174
  setSize(null);
1086
1175
  return;
1087
1176
  }
1088
- const probableCssParentScale = contentRect.width === 0 ? 1 : newSize[0].width / contentRect.width;
1089
- const width = options.shouldApplyCssTransforms || probableCssParentScale === 0 ? newSize[0].width : newSize[0].width * (1 / probableCssParentScale);
1090
- const height = options.shouldApplyCssTransforms || probableCssParentScale === 0 ? newSize[0].height : newSize[0].height * (1 / probableCssParentScale);
1177
+ const probableCssParentScaleX = contentRect.width === 0 ? 1 : newSize[0].width / contentRect.width;
1178
+ const probableCssParentScaleY = contentRect.height === 0 ? 1 : newSize[0].height / contentRect.height;
1179
+ const width = options.shouldApplyCssTransforms || probableCssParentScaleX === 0 ? newSize[0].width : newSize[0].width * (1 / probableCssParentScaleX);
1180
+ const height = options.shouldApplyCssTransforms || probableCssParentScaleY === 0 ? newSize[0].height : newSize[0].height * (1 / probableCssParentScaleY);
1091
1181
  setSize((prevState) => {
1092
1182
  const isSame = prevState && prevState.width === width && prevState.height === height && prevState.left === newSize[0].x && prevState.top === newSize[0].y && prevState.windowSize.height === window.innerHeight && prevState.windowSize.width === window.innerWidth;
1093
1183
  if (isSame) {
@@ -1174,12 +1264,12 @@ import {
1174
1264
  forwardRef as forwardRef2,
1175
1265
  useEffect as useEffect13,
1176
1266
  useImperativeHandle as useImperativeHandle2,
1177
- useLayoutEffect as useLayoutEffect2,
1267
+ useLayoutEffect as useLayoutEffect3,
1178
1268
  useMemo as useMemo14,
1179
1269
  useRef as useRef12,
1180
1270
  useState as useState13
1181
1271
  } from "react";
1182
- import { Composition, Internals as Internals15 } from "remotion";
1272
+ import { Composition, Internals as Internals16 } from "remotion";
1183
1273
 
1184
1274
  // src/player-css-classname.ts
1185
1275
  var playerCssClassname = (override) => {
@@ -1198,7 +1288,7 @@ import React10, {
1198
1288
  useRef as useRef11,
1199
1289
  useState as useState11
1200
1290
  } from "react";
1201
- import { Internals as Internals11 } from "remotion";
1291
+ import { Internals as Internals12 } from "remotion";
1202
1292
 
1203
1293
  // src/error-boundary.tsx
1204
1294
  import React3 from "react";
@@ -1341,7 +1431,7 @@ var DefaultPlayPauseButton = ({ playing, buffering }) => {
1341
1431
 
1342
1432
  // src/MediaVolumeSlider.tsx
1343
1433
  import { useCallback as useCallback5, useMemo as useMemo4, useRef as useRef6, useState as useState6 } from "react";
1344
- import { Internals as Internals7 } from "remotion";
1434
+ import { Internals as Internals8 } from "remotion";
1345
1435
 
1346
1436
  // src/render-volume-slider.tsx
1347
1437
  import React5, { useCallback as useCallback4, useMemo as useMemo3, useState as useState5 } from "react";
@@ -1455,8 +1545,8 @@ var renderDefaultVolumeSlider = (props) => {
1455
1545
  import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
1456
1546
  var VOLUME_SLIDER_WIDTH = 100;
1457
1547
  var MediaVolumeSlider = ({ displayVerticalVolumeSlider, renderMuteButton, renderVolumeSlider }) => {
1458
- const [mediaMuted, setMediaMuted] = Internals7.useMediaMutedState();
1459
- const [mediaVolume, setMediaVolume] = Internals7.useMediaVolumeState();
1548
+ const [mediaMuted, setMediaMuted] = Internals8.useMediaMutedState();
1549
+ const [mediaVolume, setMediaVolume] = Internals8.useMediaVolumeState();
1460
1550
  const [focused, setFocused] = useState6(false);
1461
1551
  const parentDivRef = useRef6(null);
1462
1552
  const inputRef = useRef6(null);
@@ -1517,7 +1607,7 @@ var MediaVolumeSlider = ({ displayVerticalVolumeSlider, renderMuteButton, render
1517
1607
  return renderMuteButton ? renderMuteButton({ muted: mediaMuted, volume: mediaVolume }) : renderDefaultMuteButton({ muted: mediaMuted, volume: mediaVolume });
1518
1608
  }, [mediaMuted, mediaVolume, renderDefaultMuteButton, renderMuteButton]);
1519
1609
  const volumeSlider = useMemo4(() => {
1520
- return (focused || hover) && !mediaMuted && !Internals7.isIosSafari() ? (renderVolumeSlider ?? renderDefaultVolumeSlider)({
1610
+ return (focused || hover) && !mediaMuted && !Internals8.isIosSafari() ? (renderVolumeSlider ?? renderDefaultVolumeSlider)({
1521
1611
  isVertical: displayVerticalVolumeSlider,
1522
1612
  volume: mediaVolume,
1523
1613
  onBlur: () => setFocused(false),
@@ -1545,7 +1635,7 @@ var MediaVolumeSlider = ({ displayVerticalVolumeSlider, renderMuteButton, render
1545
1635
 
1546
1636
  // src/PlaybackrateControl.tsx
1547
1637
  import { useCallback as useCallback6, useEffect as useEffect9, useMemo as useMemo5, useState as useState8 } from "react";
1548
- import { Internals as Internals8 } from "remotion";
1638
+ import { Internals as Internals9 } from "remotion";
1549
1639
 
1550
1640
  // src/utils/use-component-visible.ts
1551
1641
  import { useEffect as useEffect8, useRef as useRef7, useState as useState7 } from "react";
@@ -1637,7 +1727,7 @@ var PlaybackrateOption = ({ rate, onSelect, selectedRate, keyboardSelectedRate }
1637
1727
  }, rate);
1638
1728
  };
1639
1729
  var PlaybackPopup = ({ setIsComponentVisible, playbackRates, canvasSize }) => {
1640
- const { setPlaybackRate, playbackRate } = Internals8.useTimelineContext();
1730
+ const { setPlaybackRate, playbackRate } = Internals9.useTimelineContext();
1641
1731
  const [keyboardSelectedRate, setKeyboardSelectedRate] = useState8(playbackRate);
1642
1732
  useEffect9(() => {
1643
1733
  const listener = (e) => {
@@ -1739,7 +1829,7 @@ var button = {
1739
1829
  };
1740
1830
  var PlaybackrateControl = ({ playbackRates, canvasSize }) => {
1741
1831
  const { ref, isComponentVisible, setIsComponentVisible } = useComponentVisible(false);
1742
- const { playbackRate } = Internals8.useTimelineContext();
1832
+ const { playbackRate } = Internals9.useTimelineContext();
1743
1833
  const onClick = useCallback6((e) => {
1744
1834
  e.stopPropagation();
1745
1835
  e.preventDefault();
@@ -1772,7 +1862,7 @@ var PlaybackrateControl = ({ playbackRates, canvasSize }) => {
1772
1862
 
1773
1863
  // src/PlayerSeekBar.tsx
1774
1864
  import { useCallback as useCallback7, useEffect as useEffect10, useMemo as useMemo6, useRef as useRef8, useState as useState9 } from "react";
1775
- import { Internals as Internals9, interpolate } from "remotion";
1865
+ import { Internals as Internals10, interpolate } from "remotion";
1776
1866
  import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
1777
1867
  var getFrameFromX = (clientX, durationInFrames, width) => {
1778
1868
  const pos = clientX;
@@ -1816,7 +1906,7 @@ var PlayerSeekBar = ({ durationInFrames, onSeekEnd, onSeekStart, inFrame, outFra
1816
1906
  shouldApplyCssTransforms: true
1817
1907
  });
1818
1908
  const { seek, play, pause, playing } = usePlayer();
1819
- const frame = Internals9.Timeline.useTimelinePosition();
1909
+ const frame = Internals10.Timeline.useTimelinePosition();
1820
1910
  const [dragging, setDragging] = useState9({
1821
1911
  dragging: false
1822
1912
  });
@@ -1929,7 +2019,7 @@ var PlayerSeekBar = ({ durationInFrames, onSeekEnd, onSeekStart, inFrame, outFra
1929
2019
 
1930
2020
  // src/PlayerTimeLabel.tsx
1931
2021
  import { useMemo as useMemo7 } from "react";
1932
- import { Internals as Internals10 } from "remotion";
2022
+ import { Internals as Internals11 } from "remotion";
1933
2023
 
1934
2024
  // src/format-time.ts
1935
2025
  var formatTime = (timeInSeconds) => {
@@ -1941,7 +2031,7 @@ var formatTime = (timeInSeconds) => {
1941
2031
  // src/PlayerTimeLabel.tsx
1942
2032
  import { jsxs as jsxs7 } from "react/jsx-runtime";
1943
2033
  var PlayerTimeLabel = ({ durationInFrames, maxTimeLabelWidth, fps }) => {
1944
- const frame = Internals10.Timeline.useTimelinePosition();
2034
+ const frame = Internals11.Timeline.useTimelinePosition();
1945
2035
  const timeLabel = useMemo7(() => {
1946
2036
  return {
1947
2037
  color: "white",
@@ -2429,8 +2519,8 @@ var PlayerUI = ({
2429
2519
  overrideInternalClassName,
2430
2520
  noSuspense
2431
2521
  }, ref) => {
2432
- const config = Internals11.useUnsafeVideoConfig();
2433
- const video = Internals11.useVideo();
2522
+ const config = Internals12.useUnsafeVideoConfig();
2523
+ const video = Internals12.useVideo();
2434
2524
  const container = useRef11(null);
2435
2525
  const canvasSize = useElementSize(container, {
2436
2526
  triggerOnWindowResize: false,
@@ -2550,8 +2640,8 @@ var PlayerUI = ({
2550
2640
  }
2551
2641
  player.emitter.dispatchScaleChange(scale);
2552
2642
  }, [player.emitter, scale]);
2553
- const { setMediaVolume, setMediaMuted } = useContext5(Internals11.SetMediaVolumeContext);
2554
- const { mediaMuted, mediaVolume } = useContext5(Internals11.MediaVolumeContext);
2643
+ const { setMediaVolume, setMediaMuted } = useContext5(Internals12.SetMediaVolumeContext);
2644
+ const { mediaMuted, mediaVolume } = useContext5(Internals12.MediaVolumeContext);
2555
2645
  useEffect12(() => {
2556
2646
  player.emitter.dispatchVolumeChange(mediaVolume);
2557
2647
  }, [player.emitter, mediaVolume]);
@@ -2786,7 +2876,7 @@ var PlayerUI = ({
2786
2876
  VideoComponent ? /* @__PURE__ */ jsx12(ErrorBoundary, {
2787
2877
  onError,
2788
2878
  errorFallback,
2789
- children: /* @__PURE__ */ jsx12(Internals11.CurrentScaleContext.Provider, {
2879
+ children: /* @__PURE__ */ jsx12(Internals12.CurrentScaleContext.Provider, {
2790
2880
  value: currentScale,
2791
2881
  children: /* @__PURE__ */ jsx12(VideoComponent, {
2792
2882
  ...video?.props ?? {},
@@ -2869,10 +2959,10 @@ var PlayerUI_default = forwardRef(PlayerUI);
2869
2959
 
2870
2960
  // src/SharedPlayerContext.tsx
2871
2961
  import { useCallback as useCallback12, useMemo as useMemo13, useState as useState12 } from "react";
2872
- import { Internals as Internals13 } from "remotion";
2962
+ import { Internals as Internals14 } from "remotion";
2873
2963
 
2874
2964
  // src/volume-persistence.ts
2875
- import { Internals as Internals12 } from "remotion";
2965
+ import { Internals as Internals13 } from "remotion";
2876
2966
  var DEFAULT_VOLUME_PERSISTENCE_KEY = "remotion.volumePreference";
2877
2967
  var persistVolume = (volume, logLevel, volumePersistenceKey) => {
2878
2968
  if (typeof window === "undefined") {
@@ -2881,7 +2971,7 @@ var persistVolume = (volume, logLevel, volumePersistenceKey) => {
2881
2971
  try {
2882
2972
  window.localStorage.setItem(volumePersistenceKey ?? DEFAULT_VOLUME_PERSISTENCE_KEY, String(volume));
2883
2973
  } catch (e) {
2884
- Internals12.Log.error({ logLevel, tag: null }, "Could not persist volume", e);
2974
+ Internals13.Log.error({ logLevel, tag: null }, "Could not persist volume", e);
2885
2975
  }
2886
2976
  };
2887
2977
  var getPreferredVolume = (volumePersistenceKey) => {
@@ -2912,9 +3002,11 @@ var SharedPlayerContexts = ({
2912
3002
  logLevel,
2913
3003
  audioLatencyHint,
2914
3004
  volumePersistenceKey,
3005
+ initialVolume,
2915
3006
  inputProps,
2916
3007
  audioEnabled
2917
3008
  }) => {
3009
+ const persistVolumeToStorage = initialVolume === undefined;
2918
3010
  const compositionManagerContext = useMemo13(() => {
2919
3011
  const context = {
2920
3012
  compositions: [
@@ -2959,7 +3051,7 @@ var SharedPlayerContexts = ({
2959
3051
  inputProps
2960
3052
  ]);
2961
3053
  const [mediaMuted, setMediaMuted] = useState12(() => initiallyMuted);
2962
- const [mediaVolume, setMediaVolume] = useState12(() => getPreferredVolume(volumePersistenceKey ?? null));
3054
+ const [mediaVolume, setMediaVolume] = useState12(() => persistVolumeToStorage ? getPreferredVolume(volumePersistenceKey ?? null) : initialVolume);
2963
3055
  const mediaVolumeContextValue = useMemo13(() => {
2964
3056
  return {
2965
3057
  mediaMuted,
@@ -2968,8 +3060,10 @@ var SharedPlayerContexts = ({
2968
3060
  }, [mediaMuted, mediaVolume]);
2969
3061
  const setMediaVolumeAndPersist = useCallback12((vol) => {
2970
3062
  setMediaVolume(vol);
2971
- persistVolume(vol, logLevel, volumePersistenceKey ?? null);
2972
- }, [logLevel, volumePersistenceKey]);
3063
+ if (persistVolumeToStorage) {
3064
+ persistVolume(vol, logLevel, volumePersistenceKey ?? null);
3065
+ }
3066
+ }, [persistVolumeToStorage, logLevel, volumePersistenceKey]);
2973
3067
  const setMediaVolumeContextValue = useMemo13(() => {
2974
3068
  return {
2975
3069
  setMediaMuted,
@@ -2991,29 +3085,31 @@ var SharedPlayerContexts = ({
2991
3085
  isReadOnlyStudio: false
2992
3086
  };
2993
3087
  }, []);
2994
- return /* @__PURE__ */ jsx13(Internals13.RemotionEnvironmentContext.Provider, {
3088
+ return /* @__PURE__ */ jsx13(Internals14.RemotionEnvironmentContext.Provider, {
2995
3089
  value: env,
2996
- children: /* @__PURE__ */ jsx13(Internals13.LogLevelContext.Provider, {
3090
+ children: /* @__PURE__ */ jsx13(Internals14.LogLevelContext.Provider, {
2997
3091
  value: logLevelContext,
2998
- children: /* @__PURE__ */ jsx13(Internals13.CanUseRemotionHooksProvider, {
2999
- children: /* @__PURE__ */ jsx13(Internals13.AbsoluteTimeContext.Provider, {
3092
+ children: /* @__PURE__ */ jsx13(Internals14.CanUseRemotionHooksProvider, {
3093
+ children: /* @__PURE__ */ jsx13(Internals14.AbsoluteTimeContext.Provider, {
3000
3094
  value: timelineContext,
3001
- children: /* @__PURE__ */ jsx13(Internals13.TimelineContext.Provider, {
3095
+ children: /* @__PURE__ */ jsx13(Internals14.TimelineContext.Provider, {
3002
3096
  value: timelineContext,
3003
- children: /* @__PURE__ */ jsx13(Internals13.CompositionManager.Provider, {
3097
+ children: /* @__PURE__ */ jsx13(Internals14.CompositionManager.Provider, {
3004
3098
  value: compositionManagerContext,
3005
- children: /* @__PURE__ */ jsx13(Internals13.PrefetchProvider, {
3006
- children: /* @__PURE__ */ jsx13(Internals13.DurationsContextProvider, {
3007
- children: /* @__PURE__ */ jsx13(Internals13.MediaVolumeContext.Provider, {
3099
+ children: /* @__PURE__ */ jsx13(Internals14.PrefetchProvider, {
3100
+ children: /* @__PURE__ */ jsx13(Internals14.DurationsContextProvider, {
3101
+ children: /* @__PURE__ */ jsx13(Internals14.MediaVolumeContext.Provider, {
3008
3102
  value: mediaVolumeContextValue,
3009
- children: /* @__PURE__ */ jsx13(Internals13.SetMediaVolumeContext.Provider, {
3103
+ children: /* @__PURE__ */ jsx13(Internals14.SetMediaVolumeContext.Provider, {
3010
3104
  value: setMediaVolumeContextValue,
3011
- children: /* @__PURE__ */ jsx13(Internals13.SharedAudioContextProvider, {
3012
- numberOfAudioTags: numberOfSharedAudioTags,
3013
- audioLatencyHint,
3014
- audioEnabled,
3015
- children: /* @__PURE__ */ jsx13(Internals13.BufferingProvider, {
3016
- children
3105
+ children: /* @__PURE__ */ jsx13(Internals14.BufferingProvider, {
3106
+ children: /* @__PURE__ */ jsx13(Internals14.SharedAudioContextProvider, {
3107
+ audioLatencyHint,
3108
+ audioEnabled,
3109
+ children: /* @__PURE__ */ jsx13(Internals14.SharedAudioTagsContextProvider, {
3110
+ numberOfAudioTags: numberOfSharedAudioTags,
3111
+ children
3112
+ })
3017
3113
  })
3018
3114
  })
3019
3115
  })
@@ -3029,7 +3125,7 @@ var SharedPlayerContexts = ({
3029
3125
  };
3030
3126
 
3031
3127
  // src/use-remotion-license-acknowledge.ts
3032
- import { Internals as Internals14 } from "remotion";
3128
+ import { Internals as Internals15 } from "remotion";
3033
3129
  var warningShown = false;
3034
3130
  var acknowledgeRemotionLicenseMessage = (acknowledge, logLevel) => {
3035
3131
  if (acknowledge) {
@@ -3039,7 +3135,7 @@ var acknowledgeRemotionLicenseMessage = (acknowledge, logLevel) => {
3039
3135
  return;
3040
3136
  }
3041
3137
  warningShown = true;
3042
- Internals14.Log.warn({ logLevel, tag: null }, "Note: Some companies are required to obtain a license to use Remotion. See: https://remotion.dev/license\nPass the `acknowledgeRemotionLicense` prop to `<Player />` function to make this message disappear.");
3138
+ Internals15.Log.warn({ logLevel, tag: null }, "Note: Some companies are required to obtain a license to use Remotion. See: https://remotion.dev/license\nPass the `acknowledgeRemotionLicense` prop to `<Player />` function to make this message disappear.");
3043
3139
  };
3044
3140
 
3045
3141
  // src/utils/validate-in-out-frame.ts
@@ -3121,11 +3217,11 @@ var validatePlaybackRate = (playbackRate) => {
3121
3217
  if (playbackRate === undefined) {
3122
3218
  return;
3123
3219
  }
3124
- if (playbackRate > 4) {
3125
- throw new Error(`The highest possible playback rate is 4. You passed: ${playbackRate}`);
3220
+ if (playbackRate > 10) {
3221
+ throw new Error(`The highest possible playback rate is 10. You passed: ${playbackRate}`);
3126
3222
  }
3127
- if (playbackRate < -4) {
3128
- throw new Error(`The lowest possible playback rate is -4. You passed: ${playbackRate}`);
3223
+ if (playbackRate < -10) {
3224
+ throw new Error(`The lowest possible playback rate is -10. You passed: ${playbackRate}`);
3129
3225
  }
3130
3226
  if (playbackRate === 0) {
3131
3227
  throw new Error(`A playback rate of 0 is not supported.`);
@@ -3195,8 +3291,9 @@ var PlayerFn = ({
3195
3291
  logLevel = "info",
3196
3292
  noSuspense,
3197
3293
  acknowledgeRemotionLicense,
3198
- audioLatencyHint = "interactive",
3294
+ audioLatencyHint = "playback",
3199
3295
  volumePersistenceKey,
3296
+ initialVolume,
3200
3297
  ...componentProps
3201
3298
  }, ref) => {
3202
3299
  if (typeof window !== "undefined") {
@@ -3213,7 +3310,7 @@ var PlayerFn = ({
3213
3310
  throw new TypeError(`'component' must not be the 'Composition' component. Pass your own React component directly, and set the duration, fps and dimensions as separate props. See https://www.remotion.dev/docs/player/examples for an example.`);
3214
3311
  }
3215
3312
  useState13(() => acknowledgeRemotionLicenseMessage(Boolean(acknowledgeRemotionLicense), logLevel));
3216
- const component = Internals15.useLazyComponent({
3313
+ const component = Internals16.useLazyComponent({
3217
3314
  compProps: componentProps,
3218
3315
  componentName: "Player",
3219
3316
  noSuspense: Boolean(noSuspense)
@@ -3271,6 +3368,12 @@ var PlayerFn = ({
3271
3368
  if (typeof spaceKeyToPlayOrPause !== "boolean" && typeof spaceKeyToPlayOrPause !== "undefined") {
3272
3369
  throw new TypeError(`'spaceKeyToPlayOrPause' must be a boolean or undefined but got '${typeof spaceKeyToPlayOrPause}' instead`);
3273
3370
  }
3371
+ if (typeof initialVolume !== "undefined" && typeof initialVolume !== "number") {
3372
+ throw new TypeError(`'initialVolume' must be a number or undefined but got '${typeof initialVolume}' instead`);
3373
+ }
3374
+ if (typeof initialVolume === "number" && (!Number.isFinite(initialVolume) || Number.isNaN(initialVolume) || initialVolume < 0 || initialVolume > 1)) {
3375
+ throw new TypeError(`'initialVolume' must be between 0 and 1 but got '${initialVolume}' instead`);
3376
+ }
3274
3377
  if (typeof numberOfSharedAudioTags !== "number" || numberOfSharedAudioTags % 1 !== 0 || !Number.isFinite(numberOfSharedAudioTags) || Number.isNaN(numberOfSharedAudioTags) || numberOfSharedAudioTags < 0) {
3275
3378
  throw new TypeError(`'numberOfSharedAudioTags' must be an integer but got '${numberOfSharedAudioTags}' instead`);
3276
3379
  }
@@ -3280,7 +3383,7 @@ var PlayerFn = ({
3280
3383
  }, [playbackRate]);
3281
3384
  useImperativeHandle2(ref, () => rootRef.current, []);
3282
3385
  useState13(() => {
3283
- Internals15.playbackLogging({
3386
+ Internals16.playbackLogging({
3284
3387
  logLevel,
3285
3388
  message: `[player] Mounting <Player>. User agent = ${typeof navigator === "undefined" ? "server" : navigator.userAgent}`,
3286
3389
  tag: "player",
@@ -3307,8 +3410,8 @@ var PlayerFn = ({
3307
3410
  };
3308
3411
  }, [setFrame]);
3309
3412
  if (typeof window !== "undefined") {
3310
- useLayoutEffect2(() => {
3311
- Internals15.CSSUtils.injectCSS(Internals15.CSSUtils.makeDefaultPreviewCSS(`.${playerCssClassname(overrideInternalClassName)}`, "#fff"));
3413
+ useLayoutEffect3(() => {
3414
+ Internals16.CSSUtils.injectCSS(Internals16.CSSUtils.makeDefaultPreviewCSS(`.${playerCssClassname(overrideInternalClassName)}`, "#fff"));
3312
3415
  }, [overrideInternalClassName]);
3313
3416
  }
3314
3417
  const actualInputProps = useMemo14(() => inputProps ?? {}, [inputProps]);
@@ -3317,7 +3420,7 @@ var PlayerFn = ({
3317
3420
  mode: "prevent-media-session"
3318
3421
  };
3319
3422
  }, [passedBrowserMediaControlsBehavior]);
3320
- return /* @__PURE__ */ jsx14(Internals15.IsPlayerContextProvider, {
3423
+ return /* @__PURE__ */ jsx14(Internals16.IsPlayerContextProvider, {
3321
3424
  children: /* @__PURE__ */ jsx14(SharedPlayerContexts, {
3322
3425
  timelineContext: timelineContextValue,
3323
3426
  component,
@@ -3330,9 +3433,10 @@ var PlayerFn = ({
3330
3433
  logLevel,
3331
3434
  audioLatencyHint,
3332
3435
  volumePersistenceKey,
3436
+ initialVolume,
3333
3437
  inputProps: actualInputProps,
3334
3438
  audioEnabled: true,
3335
- children: /* @__PURE__ */ jsx14(Internals15.SetTimelineContext.Provider, {
3439
+ children: /* @__PURE__ */ jsx14(Internals16.SetTimelineContext.Provider, {
3336
3440
  value: setTimelineContextValue,
3337
3441
  children: /* @__PURE__ */ jsx14(PlayerEmitterProvider, {
3338
3442
  currentPlaybackRate,
@@ -3388,12 +3492,12 @@ var Player = forward(PlayerFn);
3388
3492
  import {
3389
3493
  forwardRef as forwardRef4,
3390
3494
  useImperativeHandle as useImperativeHandle4,
3391
- useLayoutEffect as useLayoutEffect3,
3495
+ useLayoutEffect as useLayoutEffect4,
3392
3496
  useMemo as useMemo17,
3393
3497
  useRef as useRef14,
3394
3498
  useState as useState14
3395
3499
  } from "react";
3396
- import { Internals as Internals17, random as random2 } from "remotion";
3500
+ import { Internals as Internals18, random as random2 } from "remotion";
3397
3501
 
3398
3502
  // src/ThumbnailUI.tsx
3399
3503
  import React13, {
@@ -3404,7 +3508,7 @@ import React13, {
3404
3508
  useMemo as useMemo16,
3405
3509
  useRef as useRef13
3406
3510
  } from "react";
3407
- import { Internals as Internals16 } from "remotion";
3511
+ import { Internals as Internals17 } from "remotion";
3408
3512
 
3409
3513
  // src/use-thumbnail.ts
3410
3514
  import { useContext as useContext6, useMemo as useMemo15 } from "react";
@@ -3438,8 +3542,8 @@ var ThumbnailUI = ({
3438
3542
  noSuspense,
3439
3543
  overrideInternalClassName
3440
3544
  }, ref) => {
3441
- const config = Internals16.useUnsafeVideoConfig();
3442
- const video = Internals16.useVideo();
3545
+ const config = Internals17.useUnsafeVideoConfig();
3546
+ const video = Internals17.useVideo();
3443
3547
  const container = useRef13(null);
3444
3548
  const canvasSize = useElementSize(container, {
3445
3549
  triggerOnWindowResize: false,
@@ -3514,7 +3618,7 @@ var ThumbnailUI = ({
3514
3618
  children: VideoComponent ? /* @__PURE__ */ jsx15(ErrorBoundary, {
3515
3619
  onError,
3516
3620
  errorFallback,
3517
- children: /* @__PURE__ */ jsx15(Internals16.CurrentScaleContext.Provider, {
3621
+ children: /* @__PURE__ */ jsx15(Internals17.CurrentScaleContext.Provider, {
3518
3622
  value: currentScaleContext,
3519
3623
  children: /* @__PURE__ */ jsx15(VideoComponent, {
3520
3624
  ...video?.props ?? {},
@@ -3564,7 +3668,7 @@ var ThumbnailFn = ({
3564
3668
  ...componentProps
3565
3669
  }, ref) => {
3566
3670
  if (typeof window !== "undefined") {
3567
- useLayoutEffect3(() => {
3671
+ useLayoutEffect4(() => {
3568
3672
  window.remotion_isPlayer = true;
3569
3673
  }, []);
3570
3674
  }
@@ -3589,7 +3693,7 @@ var ThumbnailFn = ({
3589
3693
  return value;
3590
3694
  }, [frameToDisplay, thumbnailId]);
3591
3695
  useImperativeHandle4(ref, () => rootRef.current, []);
3592
- const Component = Internals17.useLazyComponent({
3696
+ const Component = Internals18.useLazyComponent({
3593
3697
  compProps: componentProps,
3594
3698
  componentName: "Thumbnail",
3595
3699
  noSuspense: Boolean(noSuspense)
@@ -3598,7 +3702,7 @@ var ThumbnailFn = ({
3598
3702
  const passedInputProps = useMemo17(() => {
3599
3703
  return inputProps ?? {};
3600
3704
  }, [inputProps]);
3601
- return /* @__PURE__ */ jsx16(Internals17.IsPlayerContextProvider, {
3705
+ return /* @__PURE__ */ jsx16(Internals18.IsPlayerContextProvider, {
3602
3706
  children: /* @__PURE__ */ jsx16(SharedPlayerContexts, {
3603
3707
  timelineContext: timelineState,
3604
3708
  component: Component,
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/player"
4
4
  },
5
5
  "name": "@remotion/player",
6
- "version": "4.0.451",
6
+ "version": "4.0.453",
7
7
  "description": "React component for embedding a Remotion preview into your app",
8
8
  "main": "dist/cjs/index.js",
9
9
  "types": "dist/cjs/index.d.ts",
@@ -36,7 +36,7 @@
36
36
  ],
37
37
  "license": "SEE LICENSE IN LICENSE.md",
38
38
  "dependencies": {
39
- "remotion": "4.0.451"
39
+ "remotion": "4.0.453"
40
40
  },
41
41
  "peerDependencies": {
42
42
  "react": ">=16.8.0",
@@ -50,7 +50,7 @@
50
50
  "react-dom": "19.2.3",
51
51
  "webpack": "5.105.0",
52
52
  "zod": "4.3.6",
53
- "@remotion/eslint-config-internal": "4.0.451",
53
+ "@remotion/eslint-config-internal": "4.0.453",
54
54
  "eslint": "9.19.0",
55
55
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
56
56
  },
@@ -1,2 +0,0 @@
1
- export declare const persistVolume: (volume: number, logLevel: "error" | "info" | "trace" | "verbose" | "warn", volumePersistenceKey: string | null) => void;
2
- export declare const getPreferredVolume: (volumePersistenceKey: string | null) => number;
@@ -1,34 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getPreferredVolume = exports.persistVolume = void 0;
4
- const remotion_1 = require("remotion");
5
- const DEFAULT_VOLUME_PERSISTANCE_KEY = 'remotion.volumePreference';
6
- const persistVolume = (volume, logLevel, volumePersistenceKey) => {
7
- if (typeof window === 'undefined') {
8
- return;
9
- }
10
- try {
11
- window.localStorage.setItem(volumePersistenceKey !== null && volumePersistenceKey !== void 0 ? volumePersistenceKey : DEFAULT_VOLUME_PERSISTANCE_KEY, String(volume));
12
- }
13
- catch (e) {
14
- // User can disallow localStorage access
15
- // https://github.com/remotion-dev/remotion/issues/3540
16
- remotion_1.Internals.Log.error({ logLevel, tag: null }, 'Could not persist volume', e);
17
- }
18
- };
19
- exports.persistVolume = persistVolume;
20
- const getPreferredVolume = (volumePersistenceKey) => {
21
- if (typeof window === 'undefined') {
22
- return 1;
23
- }
24
- try {
25
- const val = window.localStorage.getItem(volumePersistenceKey !== null && volumePersistenceKey !== void 0 ? volumePersistenceKey : DEFAULT_VOLUME_PERSISTANCE_KEY);
26
- return val ? Number(val) : 1;
27
- }
28
- catch (_a) {
29
- // User can disallow localStorage access
30
- // https://github.com/remotion-dev/remotion/issues/3540
31
- return 1;
32
- }
33
- };
34
- exports.getPreferredVolume = getPreferredVolume;