@remotion/player 4.0.0-alpha.217 → 4.0.0-alpha10

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.
@@ -1,7 +1,7 @@
1
1
  import type { ComponentType } from 'react';
2
2
  import React from 'react';
3
3
  import type { CompProps } from 'remotion';
4
- import type { z } from 'zod';
4
+ import type { AnyZodObject } from 'zod';
5
5
  import type { PlayerRef } from './player-methods.js';
6
6
  import type { RenderFullscreenButton, RenderPlayPauseButton } from './PlayerControls.js';
7
7
  import type { RenderLoading, RenderPoster } from './PlayerUI.js';
@@ -9,7 +9,7 @@ import type { PropsIfHasProps } from './utils/props-if-has-props.js';
9
9
  export declare type ErrorFallback = (info: {
10
10
  error: Error;
11
11
  }) => React.ReactNode;
12
- export declare type PlayerProps<Schema extends z.ZodTypeAny, Props> = {
12
+ export declare type PlayerProps<Schema extends AnyZodObject, Props> = {
13
13
  durationInFrames: number;
14
14
  compositionWidth: number;
15
15
  compositionHeight: number;
@@ -48,4 +48,4 @@ export declare const componentOrNullIfLazy: <Props>(props: CompProps<Props>) =>
48
48
  * @description A component which can be rendered in a regular React App (for example: Create React App, Next.js) to display a Remotion video.
49
49
  * @see [Documentation](https://www.remotion.dev/docs/player/player)
50
50
  */
51
- export declare const Player: <Schema extends z.ZodTypeAny, Props>(props: PlayerProps<Schema, Props> & React.RefAttributes<PlayerRef>) => React.ReactElement | null;
51
+ export declare const Player: <Schema extends AnyZodObject, Props>(props: PlayerProps<Schema, Props> & React.RefAttributes<PlayerRef>) => React.ReactElement | null;
@@ -64,6 +64,7 @@ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps,
64
64
  allowFloats: false,
65
65
  });
66
66
  remotion_1.Internals.validateFps(fps, 'as a prop of the <Player/> component', false);
67
+ remotion_1.Internals.validateDefaultAndInputProps(inputProps, 'inputProps', null);
67
68
  (0, validate_in_out_frame_js_1.validateInOutFrames)({
68
69
  durationInFrames,
69
70
  inFrame,
@@ -106,7 +107,7 @@ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps,
106
107
  }
107
108
  (0, validate_playbackrate_js_1.validatePlaybackRate)(playbackRate);
108
109
  (0, react_1.useEffect)(() => {
109
- emitter.dispatchRatechange(playbackRate);
110
+ emitter.dispatchRateChange(playbackRate);
110
111
  }, [emitter, playbackRate]);
111
112
  (0, react_1.useImperativeHandle)(ref, () => rootRef.current, []);
112
113
  const timelineContextValue = (0, react_1.useMemo)(() => {
@@ -139,7 +140,8 @@ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps,
139
140
  remotion_1.Internals.CSSUtils.injectCSS(remotion_1.Internals.CSSUtils.makeDefaultCSS(`.${player_css_classname_js_1.PLAYER_CSS_CLASSNAME}`, '#fff'));
140
141
  }, []);
141
142
  }
142
- return ((0, jsx_runtime_1.jsx)(remotion_1.Internals.IsPlayerContextProvider, { children: (0, jsx_runtime_1.jsx)(SharedPlayerContext_js_1.SharedPlayerContexts, { timelineContext: timelineContextValue, component: component, compositionHeight: compositionHeight, compositionWidth: compositionWidth, durationInFrames: durationInFrames, fps: fps, inputProps: inputProps, numberOfSharedAudioTags: numberOfSharedAudioTags, initiallyMuted: initiallyMuted, children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.Timeline.SetTimelineContext.Provider, { value: setTimelineContextValue, children: (0, jsx_runtime_1.jsx)(emitter_context_js_1.PlayerEventEmitterContext.Provider, { value: emitter, children: (0, jsx_runtime_1.jsx)(PlayerUI_js_1.default, { ref: rootRef, renderLoading: renderLoading, autoPlay: Boolean(autoPlay), loop: Boolean(loop), controls: Boolean(controls), errorFallback: errorFallback, style: style, inputProps: passedInputProps, allowFullscreen: Boolean(allowFullscreen), moveToBeginningWhenEnded: Boolean(moveToBeginningWhenEnded), clickToPlay: typeof clickToPlay === 'boolean'
143
+ const actualInputProps = (0, react_1.useMemo)(() => inputProps !== null && inputProps !== void 0 ? inputProps : {}, [inputProps]);
144
+ return ((0, jsx_runtime_1.jsx)(remotion_1.Internals.IsPlayerContextProvider, { children: (0, jsx_runtime_1.jsx)(SharedPlayerContext_js_1.SharedPlayerContexts, { timelineContext: timelineContextValue, component: component, compositionHeight: compositionHeight, compositionWidth: compositionWidth, durationInFrames: durationInFrames, fps: fps, inputProps: actualInputProps, numberOfSharedAudioTags: numberOfSharedAudioTags, initiallyMuted: initiallyMuted, children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.Timeline.SetTimelineContext.Provider, { value: setTimelineContextValue, children: (0, jsx_runtime_1.jsx)(emitter_context_js_1.PlayerEventEmitterContext.Provider, { value: emitter, children: (0, jsx_runtime_1.jsx)(PlayerUI_js_1.default, { ref: rootRef, renderLoading: renderLoading, autoPlay: Boolean(autoPlay), loop: Boolean(loop), controls: Boolean(controls), errorFallback: errorFallback, style: style, inputProps: passedInputProps, allowFullscreen: Boolean(allowFullscreen), moveToBeginningWhenEnded: Boolean(moveToBeginningWhenEnded), clickToPlay: typeof clickToPlay === 'boolean'
143
145
  ? clickToPlay
144
146
  : Boolean(controls), showVolumeControls: Boolean(showVolumeControls), doubleClickToFullscreen: Boolean(doubleClickToFullscreen), spaceKeyToPlayOrPause: Boolean(spaceKeyToPlayOrPause), playbackRate: playbackRate, className: className !== null && className !== void 0 ? className : undefined, showPosterWhenUnplayed: Boolean(showPosterWhenUnplayed), showPosterWhenEnded: Boolean(showPosterWhenEnded), showPosterWhenPaused: Boolean(showPosterWhenPaused), 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, alwaysShowControls: alwaysShowControls }) }) }) }) }));
145
147
  };
@@ -14,7 +14,7 @@ declare const _default: React.ForwardRefExoticComponent<{
14
14
  loop: boolean;
15
15
  autoPlay: boolean;
16
16
  allowFullscreen: boolean;
17
- inputProps: unknown;
17
+ inputProps: Record<string, unknown>;
18
18
  showVolumeControls: boolean;
19
19
  style?: React.CSSProperties | undefined;
20
20
  clickToPlay: boolean;
@@ -42,7 +42,7 @@ if (reactVersion === '0') {
42
42
  }
43
43
  const doesReactVersionSupportSuspense = parseInt(reactVersion, 10) >= 18;
44
44
  const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps, clickToPlay, showVolumeControls, doubleClickToFullscreen, spaceKeyToPlayOrPause, errorFallback, playbackRate, renderLoading, renderPoster, className, moveToBeginningWhenEnded, showPosterWhenUnplayed, showPosterWhenEnded, showPosterWhenPaused, inFrame, outFrame, initiallyShowControls, renderFullscreen: renderFullscreenButton, renderPlayPauseButton, alwaysShowControls, }, ref) => {
45
- var _a, _b, _c, _d, _e;
45
+ var _a, _b, _c, _d;
46
46
  const config = remotion_1.Internals.useUnsafeVideoConfig();
47
47
  const video = remotion_1.Internals.useVideo();
48
48
  const container = (0, react_1.useRef)(null);
@@ -128,12 +128,12 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
128
128
  var _a;
129
129
  const element = (_a = document.webkitFullscreenElement) !== null && _a !== void 0 ? _a : document.fullscreenElement;
130
130
  if (element && element === container.current) {
131
- player.emitter.dispatchFullscreenChangeUpdate({
131
+ player.emitter.dispatchFullscreenChange({
132
132
  isFullscreen: true,
133
133
  });
134
134
  }
135
135
  else {
136
- player.emitter.dispatchFullscreenChangeUpdate({
136
+ player.emitter.dispatchFullscreenChange({
137
137
  isFullscreen: false,
138
138
  });
139
139
  }
@@ -158,8 +158,25 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
158
158
  });
159
159
  }, [canvasSize, config]);
160
160
  const scale = (_b = layout === null || layout === void 0 ? void 0 : layout.scale) !== null && _b !== void 0 ? _b : 1;
161
+ const initialScaleIgnored = (0, react_1.useRef)(false);
162
+ (0, react_1.useEffect)(() => {
163
+ if (!initialScaleIgnored.current) {
164
+ initialScaleIgnored.current = true;
165
+ return;
166
+ }
167
+ player.emitter.dispatchScaleChange(scale);
168
+ }, [player.emitter, scale]);
161
169
  const { setMediaVolume, setMediaMuted } = (0, react_1.useContext)(remotion_1.Internals.SetMediaVolumeContext);
162
170
  const { mediaMuted, mediaVolume } = (0, react_1.useContext)(remotion_1.Internals.MediaVolumeContext);
171
+ (0, react_1.useEffect)(() => {
172
+ player.emitter.dispatchVolumeChange(mediaVolume);
173
+ }, [player.emitter, mediaVolume]);
174
+ const isMuted = mediaMuted || mediaVolume === 0;
175
+ (0, react_1.useEffect)(() => {
176
+ player.emitter.dispatchMuteChange({
177
+ isMuted,
178
+ });
179
+ }, [player.emitter, isMuted]);
163
180
  (0, react_1.useImperativeHandle)(ref, () => {
164
181
  const methods = {
165
182
  play: player.play,
@@ -202,7 +219,7 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
202
219
  }
203
220
  setMediaVolume(vol);
204
221
  },
205
- isMuted: () => mediaMuted || mediaVolume === 0,
222
+ isMuted: () => isMuted,
206
223
  mute: () => {
207
224
  setMediaMuted(true);
208
225
  },
@@ -218,6 +235,7 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
218
235
  isFullscreen,
219
236
  loop,
220
237
  mediaMuted,
238
+ isMuted,
221
239
  mediaVolume,
222
240
  player,
223
241
  requestFullscreen,
@@ -299,7 +317,7 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
299
317
  showPosterWhenEnded && player.isLastFrame && !player.isPlaying(),
300
318
  showPosterWhenUnplayed && !player.hasPlayed && !player.isPlaying(),
301
319
  ].some(Boolean);
302
- const content = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { style: outer, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: (0, jsx_runtime_1.jsx)("div", { style: containerStyle, className: player_css_classname_js_1.PLAYER_CSS_CLASSNAME, children: VideoComponent ? ((0, jsx_runtime_1.jsx)(error_boundary_js_1.ErrorBoundary, { onError: onError, errorFallback: errorFallback, children: (0, jsx_runtime_1.jsx)(VideoComponent, { ...((_c = video === null || video === void 0 ? void 0 : video.defaultProps) !== null && _c !== void 0 ? _c : {}), ...((_d = inputProps) !== null && _d !== void 0 ? _d : {}) }) })) : null }) }), shouldShowPoster ? ((0, jsx_runtime_1.jsx)("div", { style: outer, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null, controls ? ((0, jsx_runtime_1.jsx)(PlayerControls_js_1.Controls, { fps: config.fps, durationInFrames: config.durationInFrames, hovered: hovered, player: player, onFullscreenButtonClick: onFullscreenButtonClick, isFullscreen: isFullscreen, allowFullscreen: allowFullscreen, showVolumeControls: showVolumeControls, onExitFullscreenButtonClick: onExitFullscreenButtonClick, spaceKeyToPlayOrPause: spaceKeyToPlayOrPause, onSeekEnd: onSeekEnd, onSeekStart: onSeekStart, inFrame: inFrame, outFrame: outFrame, initiallyShowControls: initiallyShowControls, playerWidth: (_e = canvasSize === null || canvasSize === void 0 ? void 0 : canvasSize.width) !== null && _e !== void 0 ? _e : 0, renderFullscreenButton: renderFullscreenButton, renderPlayPauseButton: renderPlayPauseButton, alwaysShowControls: alwaysShowControls })) : null] }));
320
+ const content = ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { style: outer, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: (0, jsx_runtime_1.jsx)("div", { style: containerStyle, className: player_css_classname_js_1.PLAYER_CSS_CLASSNAME, children: VideoComponent ? ((0, jsx_runtime_1.jsx)(error_boundary_js_1.ErrorBoundary, { onError: onError, errorFallback: errorFallback, children: (0, jsx_runtime_1.jsx)(VideoComponent, { ...((_c = video === null || video === void 0 ? void 0 : video.defaultProps) !== null && _c !== void 0 ? _c : {}), ...(inputProps !== null && inputProps !== void 0 ? inputProps : {}) }) })) : null }) }), shouldShowPoster ? ((0, jsx_runtime_1.jsx)("div", { style: outer, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null, controls ? ((0, jsx_runtime_1.jsx)(PlayerControls_js_1.Controls, { fps: config.fps, durationInFrames: config.durationInFrames, hovered: hovered, player: player, onFullscreenButtonClick: onFullscreenButtonClick, isFullscreen: isFullscreen, allowFullscreen: allowFullscreen, showVolumeControls: showVolumeControls, onExitFullscreenButtonClick: onExitFullscreenButtonClick, spaceKeyToPlayOrPause: spaceKeyToPlayOrPause, onSeekEnd: onSeekEnd, onSeekStart: onSeekStart, inFrame: inFrame, outFrame: outFrame, initiallyShowControls: initiallyShowControls, playerWidth: (_d = canvasSize === null || canvasSize === void 0 ? void 0 : canvasSize.width) !== null && _d !== void 0 ? _d : 0, renderFullscreenButton: renderFullscreenButton, renderPlayPauseButton: renderPlayPauseButton, alwaysShowControls: alwaysShowControls })) : null] }));
303
321
  if (is_node_js_1.IS_NODE && !doesReactVersionSupportSuspense) {
304
322
  return ((0, jsx_runtime_1.jsx)("div", { ref: container, style: outerStyle, className: className, children: content }));
305
323
  }
@@ -4,7 +4,7 @@ import type { TimelineContextValue } from 'remotion';
4
4
  export declare const SharedPlayerContexts: React.FC<{
5
5
  children: React.ReactNode;
6
6
  timelineContext: TimelineContextValue;
7
- inputProps?: unknown;
7
+ inputProps?: Record<string, unknown>;
8
8
  fps: number;
9
9
  compositionWidth: number;
10
10
  compositionHeight: number;
@@ -23,6 +23,7 @@ const SharedPlayerContexts = ({ children, timelineContext, inputProps, fps, comp
23
23
  defaultProps: undefined,
24
24
  parentFolderName: null,
25
25
  schema: null,
26
+ calculateMetadata: null,
26
27
  },
27
28
  ],
28
29
  folders: [],
@@ -41,6 +42,7 @@ const SharedPlayerContexts = ({ children, timelineContext, inputProps, fps, comp
41
42
  setCurrentCompositionMetadata: () => undefined,
42
43
  assets: [],
43
44
  setClipRegion: () => undefined,
45
+ resolved: null,
44
46
  };
45
47
  }, [
46
48
  component,
@@ -68,6 +70,6 @@ const SharedPlayerContexts = ({ children, timelineContext, inputProps, fps, comp
68
70
  setMediaVolume: setMediaVolumeAndPersist,
69
71
  };
70
72
  }, [setMediaVolumeAndPersist]);
71
- return ((0, jsx_runtime_1.jsx)(remotion_1.Internals.CanUseRemotionHooksProvider, { children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.Timeline.TimelineContext.Provider, { value: timelineContext, children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.CompositionManager.Provider, { value: compositionManagerContext, children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.PrefetchProvider, { children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.DurationsContextProvider, { children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.MediaVolumeContext.Provider, { value: mediaVolumeContextValue, children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.SetMediaVolumeContext.Provider, { value: setMediaVolumeContextValue, children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.SharedAudioContextProvider, { numberOfAudioTags: numberOfSharedAudioTags, component: component, children: children }) }) }) }) }) }) }) }));
73
+ return ((0, jsx_runtime_1.jsx)(remotion_1.Internals.CanUseRemotionHooksProvider, { children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.Timeline.TimelineContext.Provider, { value: timelineContext, children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.CompositionManager.Provider, { value: compositionManagerContext, children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.ResolveCompositionConfig, { children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.PrefetchProvider, { children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.DurationsContextProvider, { children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.MediaVolumeContext.Provider, { value: mediaVolumeContextValue, children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.SetMediaVolumeContext.Provider, { value: setMediaVolumeContextValue, children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.SharedAudioContextProvider, { numberOfAudioTags: numberOfSharedAudioTags, component: component, children: children }) }) }) }) }) }) }) }) }));
72
74
  };
73
75
  exports.SharedPlayerContexts = SharedPlayerContexts;
@@ -1,10 +1,10 @@
1
1
  import type { CSSProperties, MutableRefObject } from 'react';
2
2
  import type { CompProps } from 'remotion';
3
- import type { z } from 'zod';
3
+ import type { AnyZodObject } from 'zod';
4
4
  import type { ThumbnailMethods } from './player-methods.js';
5
5
  import type { ErrorFallback, RenderLoading } from './PlayerUI.js';
6
6
  import type { PropsIfHasProps } from './utils/props-if-has-props.js';
7
- declare type ThumbnailProps<Schema extends z.ZodTypeAny, Props> = PropsIfHasProps<Schema, Props> & CompProps<Schema> & {
7
+ declare type ThumbnailProps<Schema extends AnyZodObject, Props> = PropsIfHasProps<Schema, Props> & CompProps<Schema> & {
8
8
  frameToDisplay: number;
9
9
  style?: CSSProperties;
10
10
  durationInFrames: number;
@@ -15,10 +15,10 @@ declare type ThumbnailProps<Schema extends z.ZodTypeAny, Props> = PropsIfHasProp
15
15
  renderLoading?: RenderLoading;
16
16
  className?: string;
17
17
  };
18
- export declare const ThumbnailFn: <Schema extends z.ZodTypeAny, Props>({ frameToDisplay, style, inputProps, compositionHeight, compositionWidth, durationInFrames, fps, className, errorFallback, renderLoading, ...componentProps }: ThumbnailProps<Schema, Props>, ref: MutableRefObject<ThumbnailMethods>) => JSX.Element;
18
+ export declare const ThumbnailFn: <Schema extends AnyZodObject, Props>({ frameToDisplay, style, inputProps, compositionHeight, compositionWidth, durationInFrames, fps, className, errorFallback, renderLoading, ...componentProps }: ThumbnailProps<Schema, Props>, ref: MutableRefObject<ThumbnailMethods>) => JSX.Element;
19
19
  /**
20
20
  * @description A component which can be rendered in a regular React App (for example: Create React App, Next.js) to display a single frame of a video.
21
21
  * @see [Documentation](https://www.remotion.dev/docs/player/thumbnail)
22
22
  */
23
- export declare const Thumbnail: <Schema extends z.ZodTypeAny, Props>(props: ThumbnailProps<Schema, Props> & import("react").RefAttributes<ThumbnailMethods>) => React.ReactElement | null;
23
+ export declare const Thumbnail: <Schema extends AnyZodObject, Props>(props: ThumbnailProps<Schema, Props> & import("react").RefAttributes<ThumbnailMethods>) => React.ReactElement | null;
24
24
  export {};
@@ -35,7 +35,7 @@ const ThumbnailFn = ({ frameToDisplay, style, inputProps, compositionHeight, com
35
35
  const passedInputProps = (0, react_1.useMemo)(() => {
36
36
  return inputProps !== null && inputProps !== void 0 ? inputProps : {};
37
37
  }, [inputProps]);
38
- return ((0, jsx_runtime_1.jsx)(remotion_1.Internals.IsPlayerContextProvider, { children: (0, jsx_runtime_1.jsx)(SharedPlayerContext_js_1.SharedPlayerContexts, { timelineContext: timelineState, component: Component, compositionHeight: compositionHeight, compositionWidth: compositionWidth, durationInFrames: durationInFrames, fps: fps, inputProps: inputProps, numberOfSharedAudioTags: 0, initiallyMuted: true, children: (0, jsx_runtime_1.jsx)(emitter_context_js_1.ThumbnailEmitterContext.Provider, { value: emitter, children: (0, jsx_runtime_1.jsx)(ThumbnailUI_js_1.default, { className: className, errorFallback: errorFallback, inputProps: passedInputProps, renderLoading: renderLoading, style: style }) }) }) }));
38
+ return ((0, jsx_runtime_1.jsx)(remotion_1.Internals.IsPlayerContextProvider, { children: (0, jsx_runtime_1.jsx)(SharedPlayerContext_js_1.SharedPlayerContexts, { timelineContext: timelineState, component: Component, compositionHeight: compositionHeight, compositionWidth: compositionWidth, durationInFrames: durationInFrames, fps: fps, inputProps: passedInputProps, numberOfSharedAudioTags: 0, initiallyMuted: true, children: (0, jsx_runtime_1.jsx)(emitter_context_js_1.ThumbnailEmitterContext.Provider, { value: emitter, children: (0, jsx_runtime_1.jsx)(ThumbnailUI_js_1.default, { className: className, errorFallback: errorFallback, inputProps: passedInputProps, renderLoading: renderLoading, style: style }) }) }) }));
39
39
  };
40
40
  exports.ThumbnailFn = ThumbnailFn;
41
41
  const forward = react_1.forwardRef;
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import type { ThumbnailMethods } from './player-methods.js';
3
3
  import type { ErrorFallback, RenderLoading } from './PlayerUI.js';
4
4
  declare const _default: React.ForwardRefExoticComponent<{
5
- inputProps: unknown;
5
+ inputProps: Record<string, unknown>;
6
6
  style?: React.CSSProperties | undefined;
7
7
  errorFallback: ErrorFallback;
8
8
  renderLoading: RenderLoading | undefined;
@@ -38,7 +38,7 @@ if (reactVersion === '0') {
38
38
  }
39
39
  const doesReactVersionSupportSuspense = parseInt(reactVersion, 10) >= 18;
40
40
  const ThumbnailUI = ({ style, inputProps, errorFallback, renderLoading, className }, ref) => {
41
- var _a, _b, _c;
41
+ var _a, _b;
42
42
  const config = remotion_1.Internals.useUnsafeVideoConfig();
43
43
  const video = remotion_1.Internals.useVideo();
44
44
  const container = (0, react_1.useRef)(null);
@@ -98,7 +98,7 @@ const ThumbnailUI = ({ style, inputProps, errorFallback, renderLoading, classNam
98
98
  if (!config) {
99
99
  return null;
100
100
  }
101
- const content = ((0, jsx_runtime_1.jsx)("div", { style: outer, children: (0, jsx_runtime_1.jsx)("div", { style: containerStyle, className: player_css_classname_js_1.PLAYER_CSS_CLASSNAME, children: VideoComponent ? ((0, jsx_runtime_1.jsx)(error_boundary_js_1.ErrorBoundary, { onError: onError, errorFallback: errorFallback, children: (0, jsx_runtime_1.jsx)(VideoComponent, { ...((_b = video === null || video === void 0 ? void 0 : video.defaultProps) !== null && _b !== void 0 ? _b : {}), ...((_c = inputProps) !== null && _c !== void 0 ? _c : {}) }) })) : null }) }));
101
+ const content = ((0, jsx_runtime_1.jsx)("div", { style: outer, children: (0, jsx_runtime_1.jsx)("div", { style: containerStyle, className: player_css_classname_js_1.PLAYER_CSS_CLASSNAME, children: VideoComponent ? ((0, jsx_runtime_1.jsx)(error_boundary_js_1.ErrorBoundary, { onError: onError, errorFallback: errorFallback, children: (0, jsx_runtime_1.jsx)(VideoComponent, { ...((_b = video === null || video === void 0 ? void 0 : video.defaultProps) !== null && _b !== void 0 ? _b : {}), ...(inputProps !== null && inputProps !== void 0 ? inputProps : {}) }) })) : null }) }));
102
102
  if (is_node_js_1.IS_NODE && !doesReactVersionSupportSuspense) {
103
103
  return ((0, jsx_runtime_1.jsx)("div", { ref: container, style: outerStyle, className: className, children: content }));
104
104
  }
@@ -13,19 +13,31 @@ declare type FrameUpdateEventPayload = {
13
13
  declare type RateChangeEventPayload = {
14
14
  playbackRate: number;
15
15
  };
16
+ declare type ScaleChangeEventPayload = {
17
+ scale: number;
18
+ };
19
+ declare type VolumeChangeEventPayload = {
20
+ volume: number;
21
+ };
16
22
  declare type FullscreenChangeEventPayload = {
17
23
  isFullscreen: boolean;
18
24
  };
25
+ declare type MuteChangeEventPayload = {
26
+ isMuted: boolean;
27
+ };
19
28
  declare type PlayerStateEventMap = {
20
29
  seeked: SeekPayload;
21
30
  pause: undefined;
22
31
  play: undefined;
23
32
  ratechange: RateChangeEventPayload;
33
+ scalechange: ScaleChangeEventPayload;
34
+ volumechange: VolumeChangeEventPayload;
24
35
  ended: undefined;
25
36
  error: ErrorPayload;
26
37
  timeupdate: TimeUpdateEventPayload;
27
38
  frameupdate: FrameUpdateEventPayload;
28
39
  fullscreenchange: FullscreenChangeEventPayload;
40
+ mutechange: MuteChangeEventPayload;
29
41
  };
30
42
  declare type ThumbnailStateEventMap = {
31
43
  error: ErrorPayload;
@@ -47,14 +59,17 @@ export declare class PlayerEmitter {
47
59
  removeEventListener<Q extends PlayerEventTypes>(name: Q, callback: CallbackListener<Q>): void;
48
60
  private dispatchEvent;
49
61
  dispatchSeek(frame: number): void;
62
+ dispatchVolumeChange(volume: number): void;
50
63
  dispatchPause(): void;
51
64
  dispatchPlay(): void;
52
65
  dispatchEnded(): void;
53
- dispatchRatechange(playbackRate: number): void;
66
+ dispatchRateChange(playbackRate: number): void;
67
+ dispatchScaleChange(scale: number): void;
54
68
  dispatchError(error: Error): void;
55
69
  dispatchTimeUpdate(event: TimeUpdateEventPayload): void;
56
70
  dispatchFrameUpdate(event: FrameUpdateEventPayload): void;
57
- dispatchFullscreenChangeUpdate(event: FullscreenChangeEventPayload): void;
71
+ dispatchFullscreenChange(event: FullscreenChangeEventPayload): void;
72
+ dispatchMuteChange(event: MuteChangeEventPayload): void;
58
73
  }
59
74
  export declare class ThumbnailEmitter {
60
75
  listeners: ThumbnailListeners;
@@ -9,10 +9,13 @@ class PlayerEmitter {
9
9
  pause: [],
10
10
  play: [],
11
11
  ratechange: [],
12
+ scalechange: [],
12
13
  seeked: [],
13
14
  timeupdate: [],
14
15
  frameupdate: [],
15
16
  fullscreenchange: [],
17
+ volumechange: [],
18
+ mutechange: [],
16
19
  };
17
20
  }
18
21
  addEventListener(name, callback) {
@@ -31,6 +34,11 @@ class PlayerEmitter {
31
34
  frame,
32
35
  });
33
36
  }
37
+ dispatchVolumeChange(volume) {
38
+ this.dispatchEvent('volumechange', {
39
+ volume,
40
+ });
41
+ }
34
42
  dispatchPause() {
35
43
  this.dispatchEvent('pause', undefined);
36
44
  }
@@ -40,11 +48,16 @@ class PlayerEmitter {
40
48
  dispatchEnded() {
41
49
  this.dispatchEvent('ended', undefined);
42
50
  }
43
- dispatchRatechange(playbackRate) {
51
+ dispatchRateChange(playbackRate) {
44
52
  this.dispatchEvent('ratechange', {
45
53
  playbackRate,
46
54
  });
47
55
  }
56
+ dispatchScaleChange(scale) {
57
+ this.dispatchEvent('scalechange', {
58
+ scale,
59
+ });
60
+ }
48
61
  dispatchError(error) {
49
62
  this.dispatchEvent('error', {
50
63
  error,
@@ -56,9 +69,12 @@ class PlayerEmitter {
56
69
  dispatchFrameUpdate(event) {
57
70
  this.dispatchEvent('frameupdate', event);
58
71
  }
59
- dispatchFullscreenChangeUpdate(event) {
72
+ dispatchFullscreenChange(event) {
60
73
  this.dispatchEvent('fullscreenchange', event);
61
74
  }
75
+ dispatchMuteChange(event) {
76
+ this.dispatchEvent('mutechange', event);
77
+ }
62
78
  }
63
79
  exports.PlayerEmitter = PlayerEmitter;
64
80
  class ThumbnailEmitter {
@@ -1,8 +1,8 @@
1
1
  /// <reference types="react" />
2
2
  import type { CallbackListener, PlayerEventTypes } from './event-emitter.js';
3
3
  import { PlayerEmitter } from './event-emitter.js';
4
- export { Player, PlayerProps } from './Player.js';
5
4
  export { PlayerMethods, PlayerRef, ThumbnailMethods, ThumbnailRef, } from './player-methods.js';
5
+ export { Player, PlayerProps } from './Player.js';
6
6
  export type { RenderFullscreenButton, RenderPlayPauseButton, } from './PlayerControls.js';
7
7
  export type { ErrorFallback, RenderLoading, RenderPoster } from './PlayerUI.js';
8
8
  export { Thumbnail } from './Thumbnail.js';
@@ -0,0 +1,2 @@
1
+ /// <reference types="react" />
2
+ export declare const useIsBackgrounded: () => import("react").MutableRefObject<boolean>;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useIsBackgrounded = void 0;
4
+ const react_1 = require("react");
5
+ const getIsBackgrounded = () => {
6
+ if (typeof document === 'undefined') {
7
+ return false;
8
+ }
9
+ return document.visibilityState === 'hidden';
10
+ };
11
+ const useIsBackgrounded = () => {
12
+ const isBackgrounded = (0, react_1.useRef)(getIsBackgrounded());
13
+ (0, react_1.useEffect)(() => {
14
+ const onVisibilityChange = () => {
15
+ isBackgrounded.current = getIsBackgrounded();
16
+ };
17
+ document.addEventListener('visibilitychange', onVisibilityChange);
18
+ return () => {
19
+ document.removeEventListener('visibilitychange', onVisibilityChange);
20
+ };
21
+ }, []);
22
+ return isBackgrounded;
23
+ };
24
+ exports.useIsBackgrounded = useIsBackgrounded;
@@ -12,7 +12,7 @@ export declare type PlayerMethods = ThumbnailMethods & {
12
12
  getCurrentFrame: () => number;
13
13
  requestFullscreen: () => void;
14
14
  exitFullscreen: () => void;
15
- isFullscreen: () => void;
15
+ isFullscreen: () => boolean;
16
16
  setVolume: (num: number) => void;
17
17
  getVolume: () => number;
18
18
  isMuted: () => boolean;
@@ -4,12 +4,17 @@ exports.usePlayback = void 0;
4
4
  const react_1 = require("react");
5
5
  const remotion_1 = require("remotion");
6
6
  const calculate_next_frame_js_1 = require("./calculate-next-frame.js");
7
+ const is_backgrounded_js_1 = require("./is-backgrounded.js");
7
8
  const use_player_js_1 = require("./use-player.js");
8
9
  const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, outFrame, }) => {
9
10
  const frame = remotion_1.Internals.Timeline.useTimelinePosition();
10
11
  const config = remotion_1.Internals.useUnsafeVideoConfig();
11
12
  const { playing, pause, emitter } = (0, use_player_js_1.usePlayer)();
12
13
  const setFrame = remotion_1.Internals.Timeline.useTimelineSetFrame();
14
+ // requestAnimationFrame() does not work if the tab is not active.
15
+ // This means that audio will keep playing even if it has ended.
16
+ // In that case, we use setTimeout() instead.
17
+ const isBackgroundedRef = (0, is_backgrounded_js_1.useIsBackgrounded)();
13
18
  const frameRef = (0, react_1.useRef)(frame);
14
19
  frameRef.current = frame;
15
20
  const lastTimeUpdateEvent = (0, react_1.useRef)(null);
@@ -24,12 +29,20 @@ const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, ou
24
29
  let reqAnimFrameCall = null;
25
30
  const startedTime = performance.now();
26
31
  let framesAdvanced = 0;
27
- const stop = () => {
28
- hasBeenStopped = true;
32
+ const cancelQueuedFrame = () => {
29
33
  if (reqAnimFrameCall !== null) {
30
- cancelAnimationFrame(reqAnimFrameCall);
34
+ if (reqAnimFrameCall.type === 'raf') {
35
+ cancelAnimationFrame(reqAnimFrameCall.id);
36
+ }
37
+ else {
38
+ clearTimeout(reqAnimFrameCall.id);
39
+ }
31
40
  }
32
41
  };
42
+ const stop = () => {
43
+ hasBeenStopped = true;
44
+ cancelQueuedFrame();
45
+ };
33
46
  const callback = () => {
34
47
  const time = performance.now() - startedTime;
35
48
  const actualLastFrame = outFrame !== null && outFrame !== void 0 ? outFrame : config.durationInFrames - 1;
@@ -56,11 +69,34 @@ const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, ou
56
69
  return;
57
70
  }
58
71
  if (!hasBeenStopped) {
59
- reqAnimFrameCall = requestAnimationFrame(callback);
72
+ queueNextFrame();
73
+ }
74
+ };
75
+ const queueNextFrame = () => {
76
+ if (isBackgroundedRef.current) {
77
+ reqAnimFrameCall = {
78
+ type: 'timeout',
79
+ // Note: Most likely, this will not be 1000 / fps, but the browser will throttle it to ~1/sec.
80
+ id: setTimeout(callback, 1000 / config.fps),
81
+ };
82
+ }
83
+ else {
84
+ reqAnimFrameCall = { type: 'raf', id: requestAnimationFrame(callback) };
85
+ }
86
+ };
87
+ queueNextFrame();
88
+ const onVisibilityChange = () => {
89
+ if (document.visibilityState === 'visible') {
90
+ return;
60
91
  }
92
+ // If tab goes into the background, cancel requestAnimationFrame() and update immediately.
93
+ // , so the transition to setTimeout() can be fulfilled.
94
+ cancelQueuedFrame();
95
+ callback();
61
96
  };
62
- reqAnimFrameCall = requestAnimationFrame(callback);
97
+ window.addEventListener('visibilitychange', onVisibilityChange);
63
98
  return () => {
99
+ window.removeEventListener('visibilitychange', onVisibilityChange);
64
100
  stop();
65
101
  };
66
102
  }, [
@@ -74,6 +110,7 @@ const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, ou
74
110
  inFrame,
75
111
  outFrame,
76
112
  moveToBeginningWhenEnded,
113
+ isBackgroundedRef,
77
114
  ]);
78
115
  (0, react_1.useEffect)(() => {
79
116
  const interval = setInterval(() => {
@@ -1,5 +1,5 @@
1
- import type { z } from 'zod';
2
- export declare type PropsIfHasProps<Schema extends z.ZodTypeAny, Props> = z.ZodTypeAny extends Schema ? {} extends Props ? {
1
+ import type { AnyZodObject, z } from 'zod';
2
+ export declare type PropsIfHasProps<Schema extends AnyZodObject, Props> = AnyZodObject extends Schema ? {} extends Props ? {
3
3
  inputProps?: z.infer<Schema> & Props;
4
4
  } : {
5
5
  inputProps: Props;
@@ -1,7 +1,7 @@
1
1
  import type { ComponentType } from 'react';
2
2
  import React from 'react';
3
3
  import type { CompProps } from 'remotion';
4
- import type { z } from 'zod';
4
+ import type { AnyZodObject } from 'zod';
5
5
  import type { PlayerRef } from './player-methods.js';
6
6
  import type { RenderFullscreenButton, RenderPlayPauseButton } from './PlayerControls.js';
7
7
  import type { RenderLoading, RenderPoster } from './PlayerUI.js';
@@ -9,7 +9,7 @@ import type { PropsIfHasProps } from './utils/props-if-has-props.js';
9
9
  export declare type ErrorFallback = (info: {
10
10
  error: Error;
11
11
  }) => React.ReactNode;
12
- export declare type PlayerProps<Schema extends z.ZodTypeAny, Props> = {
12
+ export declare type PlayerProps<Schema extends AnyZodObject, Props> = {
13
13
  durationInFrames: number;
14
14
  compositionWidth: number;
15
15
  compositionHeight: number;
@@ -48,4 +48,4 @@ export declare const componentOrNullIfLazy: <Props>(props: CompProps<Props>) =>
48
48
  * @description A component which can be rendered in a regular React App (for example: Create React App, Next.js) to display a Remotion video.
49
49
  * @see [Documentation](https://www.remotion.dev/docs/player/player)
50
50
  */
51
- export declare const Player: <Schema extends z.ZodTypeAny, Props>(props: PlayerProps<Schema, Props> & React.RefAttributes<PlayerRef>) => React.ReactElement | null;
51
+ export declare const Player: <Schema extends AnyZodObject, Props>(props: PlayerProps<Schema, Props> & React.RefAttributes<PlayerRef>) => React.ReactElement | null;
@@ -14,7 +14,7 @@ declare const _default: React.ForwardRefExoticComponent<{
14
14
  loop: boolean;
15
15
  autoPlay: boolean;
16
16
  allowFullscreen: boolean;
17
- inputProps: unknown;
17
+ inputProps: Record<string, unknown>;
18
18
  showVolumeControls: boolean;
19
19
  style?: React.CSSProperties | undefined;
20
20
  clickToPlay: boolean;
@@ -4,7 +4,7 @@ import type { TimelineContextValue } from 'remotion';
4
4
  export declare const SharedPlayerContexts: React.FC<{
5
5
  children: React.ReactNode;
6
6
  timelineContext: TimelineContextValue;
7
- inputProps?: unknown;
7
+ inputProps?: Record<string, unknown>;
8
8
  fps: number;
9
9
  compositionWidth: number;
10
10
  compositionHeight: number;
@@ -1,10 +1,10 @@
1
1
  import type { CSSProperties, MutableRefObject } from 'react';
2
2
  import type { CompProps } from 'remotion';
3
- import type { z } from 'zod';
3
+ import type { AnyZodObject } from 'zod';
4
4
  import type { ThumbnailMethods } from './player-methods.js';
5
5
  import type { ErrorFallback, RenderLoading } from './PlayerUI.js';
6
6
  import type { PropsIfHasProps } from './utils/props-if-has-props.js';
7
- declare type ThumbnailProps<Schema extends z.ZodTypeAny, Props> = PropsIfHasProps<Schema, Props> & CompProps<Schema> & {
7
+ declare type ThumbnailProps<Schema extends AnyZodObject, Props> = PropsIfHasProps<Schema, Props> & CompProps<Schema> & {
8
8
  frameToDisplay: number;
9
9
  style?: CSSProperties;
10
10
  durationInFrames: number;
@@ -15,10 +15,10 @@ declare type ThumbnailProps<Schema extends z.ZodTypeAny, Props> = PropsIfHasProp
15
15
  renderLoading?: RenderLoading;
16
16
  className?: string;
17
17
  };
18
- export declare const ThumbnailFn: <Schema extends z.ZodTypeAny, Props>({ frameToDisplay, style, inputProps, compositionHeight, compositionWidth, durationInFrames, fps, className, errorFallback, renderLoading, ...componentProps }: ThumbnailProps<Schema, Props>, ref: MutableRefObject<ThumbnailMethods>) => JSX.Element;
18
+ export declare const ThumbnailFn: <Schema extends AnyZodObject, Props>({ frameToDisplay, style, inputProps, compositionHeight, compositionWidth, durationInFrames, fps, className, errorFallback, renderLoading, ...componentProps }: ThumbnailProps<Schema, Props>, ref: MutableRefObject<ThumbnailMethods>) => JSX.Element;
19
19
  /**
20
20
  * @description A component which can be rendered in a regular React App (for example: Create React App, Next.js) to display a single frame of a video.
21
21
  * @see [Documentation](https://www.remotion.dev/docs/player/thumbnail)
22
22
  */
23
- export declare const Thumbnail: <Schema extends z.ZodTypeAny, Props>(props: ThumbnailProps<Schema, Props> & import("react").RefAttributes<ThumbnailMethods>) => React.ReactElement | null;
23
+ export declare const Thumbnail: <Schema extends AnyZodObject, Props>(props: ThumbnailProps<Schema, Props> & import("react").RefAttributes<ThumbnailMethods>) => React.ReactElement | null;
24
24
  export {};
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import type { ThumbnailMethods } from './player-methods.js';
3
3
  import type { ErrorFallback, RenderLoading } from './PlayerUI.js';
4
4
  declare const _default: React.ForwardRefExoticComponent<{
5
- inputProps: unknown;
5
+ inputProps: Record<string, unknown>;
6
6
  style?: React.CSSProperties | undefined;
7
7
  errorFallback: ErrorFallback;
8
8
  renderLoading: RenderLoading | undefined;
@@ -15,5 +15,5 @@ export declare class ErrorBoundary extends React.Component<{
15
15
  hasError: Error;
16
16
  };
17
17
  componentDidCatch(error: Error): void;
18
- render(): string | number | boolean | JSX.Element | React.ReactFragment | null | undefined;
18
+ render(): string | number | boolean | React.ReactFragment | JSX.Element | null | undefined;
19
19
  }