@remotion/player 4.1.0-alpha1 → 4.1.0-alpha11

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.
@@ -43,7 +43,9 @@ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps,
43
43
  }
44
44
  const component = remotion_1.Internals.useLazyComponent(componentProps);
45
45
  (0, validate_initial_frame_js_1.validateInitialFrame)({ initialFrame, durationInFrames });
46
- const [frame, setFrame] = (0, react_1.useState)(() => initialFrame !== null && initialFrame !== void 0 ? initialFrame : 0);
46
+ const [frame, setFrame] = (0, react_1.useState)(() => ({
47
+ [SharedPlayerContext_js_1.PLAYER_COMP_ID]: initialFrame !== null && initialFrame !== void 0 ? initialFrame : 0,
48
+ }));
47
49
  const [playing, setPlaying] = (0, react_1.useState)(false);
48
50
  const [rootId] = (0, react_1.useState)('player-comp');
49
51
  const [emitter] = (0, react_1.useState)(() => new event_emitter_js_1.PlayerEmitter());
@@ -59,8 +61,7 @@ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps,
59
61
  }
60
62
  remotion_1.Internals.validateDimension(compositionHeight, 'compositionHeight', 'of the <Player /> component');
61
63
  remotion_1.Internals.validateDimension(compositionWidth, 'compositionWidth', 'of the <Player /> component');
62
- remotion_1.Internals.validateDurationInFrames({
63
- durationInFrames,
64
+ remotion_1.Internals.validateDurationInFrames(durationInFrames, {
64
65
  component: 'of the <Player/> component',
65
66
  allowFloats: false,
66
67
  });
@@ -317,7 +317,7 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
317
317
  showPosterWhenEnded && player.isLastFrame && !player.isPlaying(),
318
318
  showPosterWhenUnplayed && !player.hasPlayed && !player.isPlaying(),
319
319
  ].some(Boolean);
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, canvasSize: canvasSize, renderFullscreenButton: renderFullscreenButton, renderPlayPauseButton: renderPlayPauseButton, alwaysShowControls: alwaysShowControls, showPlaybackRateControl: showPlaybackRateControl })) : 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)(remotion_1.Internals.ClipComposition, { children: (0, jsx_runtime_1.jsx)(VideoComponent, { ...((_c = video === null || video === void 0 ? void 0 : video.props) !== 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, canvasSize: canvasSize, renderFullscreenButton: renderFullscreenButton, renderPlayPauseButton: renderPlayPauseButton, alwaysShowControls: alwaysShowControls, showPlaybackRateControl: showPlaybackRateControl })) : null] }));
321
321
  if (is_node_js_1.IS_NODE && !doesReactVersionSupportSuspense) {
322
322
  return ((0, jsx_runtime_1.jsx)("div", { ref: container, style: outerStyle, className: className, children: content }));
323
323
  }
@@ -1,6 +1,7 @@
1
1
  import type { ComponentType, LazyExoticComponent } from 'react';
2
2
  import React from 'react';
3
3
  import type { TimelineContextValue } from 'remotion';
4
+ export declare const PLAYER_COMP_ID = "player-comp";
4
5
  export declare const SharedPlayerContexts: React.FC<{
5
6
  children: React.ReactNode;
6
7
  timelineContext: TimelineContextValue;
@@ -1,10 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SharedPlayerContexts = void 0;
3
+ exports.SharedPlayerContexts = exports.PLAYER_COMP_ID = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const remotion_1 = require("remotion");
7
7
  const volume_persistance_js_1 = require("./volume-persistance.js");
8
+ exports.PLAYER_COMP_ID = 'player-comp';
8
9
  const SharedPlayerContexts = ({ children, timelineContext, inputProps, fps, compositionHeight, compositionWidth, durationInFrames, component, numberOfSharedAudioTags, initiallyMuted, }) => {
9
10
  const compositionManagerContext = (0, react_1.useMemo)(() => {
10
11
  return {
@@ -15,7 +16,7 @@ const SharedPlayerContexts = ({ children, timelineContext, inputProps, fps, comp
15
16
  height: compositionHeight,
16
17
  width: compositionWidth,
17
18
  fps,
18
- id: 'player-comp',
19
+ id: exports.PLAYER_COMP_ID,
19
20
  props: inputProps,
20
21
  nonce: 777,
21
22
  scale: 1,
@@ -70,6 +71,6 @@ const SharedPlayerContexts = ({ children, timelineContext, inputProps, fps, comp
70
71
  setMediaVolume: setMediaVolumeAndPersist,
71
72
  };
72
73
  }, [setMediaVolumeAndPersist]);
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 }) }) }) }) }) }) }) }) }));
74
+ 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.NativeLayersProvider, { 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 }) }) }) }) }) }) }) }) }) }));
74
75
  };
75
76
  exports.SharedPlayerContexts = SharedPlayerContexts;
@@ -4,7 +4,7 @@ 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
- type ThumbnailProps<Schema extends AnyZodObject, Props> = PropsIfHasProps<Schema, Props> & CompProps<Schema> & {
7
+ type ThumbnailProps<Schema extends AnyZodObject, Props extends Record<string, unknown>> = PropsIfHasProps<Schema, Props> & CompProps<Props> & {
8
8
  frameToDisplay: number;
9
9
  style?: CSSProperties;
10
10
  durationInFrames: number;
@@ -15,10 +15,10 @@ type ThumbnailProps<Schema extends AnyZodObject, Props> = PropsIfHasProps<Schema
15
15
  renderLoading?: RenderLoading;
16
16
  className?: string;
17
17
  };
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;
18
+ export declare const ThumbnailFn: <Schema extends AnyZodObject, Props extends Record<string, unknown>>({ 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 AnyZodObject, Props>(props: ThumbnailProps<Schema, Props> & import("react").RefAttributes<ThumbnailMethods>) => React.ReactElement | null;
23
+ export declare const Thumbnail: <Schema extends AnyZodObject, Props extends Record<string, unknown>>(props: ThumbnailProps<Schema, Props> & import("react").RefAttributes<ThumbnailMethods>) => React.ReactElement | null;
24
24
  export {};
@@ -17,7 +17,9 @@ const ThumbnailFn = ({ frameToDisplay, style, inputProps, compositionHeight, com
17
17
  const timelineState = (0, react_1.useMemo)(() => {
18
18
  return {
19
19
  playing: false,
20
- frame: frameToDisplay,
20
+ frame: {
21
+ [SharedPlayerContext_js_1.PLAYER_COMP_ID]: frameToDisplay,
22
+ },
21
23
  rootId: thumbnailId,
22
24
  imperativePlaying: {
23
25
  current: false,
@@ -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 : {}), ...(inputProps !== null && inputProps !== void 0 ? inputProps : {}) }) })) : 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.props) !== 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
  }
package/dist/cjs/icons.js CHANGED
@@ -4,11 +4,8 @@ exports.VolumeOnIcon = exports.VolumeOffIcon = exports.FullscreenIcon = exports.
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  exports.ICON_SIZE = 25;
6
6
  exports.fullscreenIconSize = 16;
7
- const rotate = {
8
- transform: `rotate(90deg)`,
9
- };
10
7
  const PlayIcon = () => {
11
- return ((0, jsx_runtime_1.jsx)("svg", { width: exports.ICON_SIZE, height: exports.ICON_SIZE, viewBox: "-100 -100 400 400", style: rotate, children: (0, jsx_runtime_1.jsx)("path", { fill: "#fff", stroke: "#fff", strokeWidth: "100", strokeLinejoin: "round", d: "M 2 172 a 196 100 0 0 0 195 5 A 196 240 0 0 0 100 2.259 A 196 240 0 0 0 2 172 z" }) }));
8
+ return ((0, jsx_runtime_1.jsx)("svg", { width: exports.ICON_SIZE, height: exports.ICON_SIZE, viewBox: "0 0 25 25", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: (0, jsx_runtime_1.jsx)("path", { d: "M8 6.375C7.40904 8.17576 7.06921 10.2486 7.01438 12.3871C6.95955 14.5255 7.19163 16.6547 7.6875 18.5625C9.95364 18.2995 12.116 17.6164 14.009 16.5655C15.902 15.5147 17.4755 14.124 18.6088 12.5C17.5158 10.8949 15.9949 9.51103 14.1585 8.45082C12.3222 7.3906 10.2174 6.68116 8 6.375Z", fill: "white", stroke: "white", strokeWidth: "6.25", strokeLinejoin: "round" }) }));
12
9
  };
13
10
  exports.PlayIcon = PlayIcon;
14
11
  const PauseIcon = () => {
@@ -7,8 +7,8 @@ const calculate_next_frame_js_1 = require("./calculate-next-frame.js");
7
7
  const is_backgrounded_js_1 = require("./is-backgrounded.js");
8
8
  const use_player_js_1 = require("./use-player.js");
9
9
  const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, outFrame, }) => {
10
- const frame = remotion_1.Internals.Timeline.useTimelinePosition();
11
10
  const config = remotion_1.Internals.useUnsafeVideoConfig();
11
+ const frame = remotion_1.Internals.Timeline.useTimelinePosition();
12
12
  const { playing, pause, emitter } = (0, use_player_js_1.usePlayer)();
13
13
  const setFrame = remotion_1.Internals.Timeline.useTimelineSetFrame();
14
14
  // requestAnimationFrame() does not work if the tab is not active.
@@ -60,7 +60,7 @@ const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, ou
60
60
  framesAdvanced += framesToAdvance;
61
61
  if (nextFrame !== frameRef.current &&
62
62
  (!hasEnded || moveToBeginningWhenEnded)) {
63
- setFrame(nextFrame);
63
+ setFrame((c) => ({ ...c, [config.id]: nextFrame }));
64
64
  }
65
65
  if (hasEnded) {
66
66
  stop();
@@ -26,9 +26,11 @@ const usePlayer = () => {
26
26
  throw new TypeError('Expected Player event emitter context');
27
27
  }
28
28
  const seek = (0, react_1.useCallback)((newFrame) => {
29
- setTimelinePosition(newFrame);
29
+ if (video === null || video === void 0 ? void 0 : video.id) {
30
+ setTimelinePosition((c) => ({ ...c, [video.id]: newFrame }));
31
+ }
30
32
  emitter.dispatchSeek(newFrame);
31
- }, [emitter, setTimelinePosition]);
33
+ }, [emitter, setTimelinePosition, video === null || video === void 0 ? void 0 : video.id]);
32
34
  const play = (0, react_1.useCallback)((e) => {
33
35
  if (imperativePlaying.current) {
34
36
  return;
@@ -71,32 +73,49 @@ const usePlayer = () => {
71
73
  const pauseAndReturnToPlayStart = (0, react_1.useCallback)(() => {
72
74
  if (imperativePlaying.current) {
73
75
  imperativePlaying.current = false;
74
- setTimelinePosition(playStart.current);
75
- setPlaying(false);
76
- emitter.dispatchPause();
76
+ if (config) {
77
+ setTimelinePosition((c) => ({
78
+ ...c,
79
+ [config.id]: playStart.current,
80
+ }));
81
+ setPlaying(false);
82
+ emitter.dispatchPause();
83
+ }
77
84
  }
78
- }, [emitter, imperativePlaying, setPlaying, setTimelinePosition]);
79
- const hasVideo = Boolean(video);
85
+ }, [config, emitter, imperativePlaying, setPlaying, setTimelinePosition]);
86
+ const videoId = video === null || video === void 0 ? void 0 : video.id;
80
87
  const frameBack = (0, react_1.useCallback)((frames) => {
81
- if (!hasVideo) {
88
+ if (!videoId) {
82
89
  return null;
83
90
  }
84
91
  if (imperativePlaying.current) {
85
92
  return;
86
93
  }
87
- setFrame((f) => {
88
- return Math.max(0, f - frames);
94
+ setFrame((c) => {
95
+ var _a, _b;
96
+ const prev = (_b = (_a = c[videoId]) !== null && _a !== void 0 ? _a : window.remotion_initialFrame) !== null && _b !== void 0 ? _b : 0;
97
+ return {
98
+ ...c,
99
+ [videoId]: Math.max(0, prev - frames),
100
+ };
89
101
  });
90
- }, [hasVideo, imperativePlaying, setFrame]);
102
+ }, [imperativePlaying, setFrame, videoId]);
91
103
  const frameForward = (0, react_1.useCallback)((frames) => {
92
- if (!hasVideo) {
104
+ if (!videoId) {
93
105
  return null;
94
106
  }
95
107
  if (imperativePlaying.current) {
96
108
  return;
97
109
  }
98
- setFrame((f) => Math.min(lastFrame, f + frames));
99
- }, [hasVideo, imperativePlaying, lastFrame, setFrame]);
110
+ setFrame((c) => {
111
+ var _a, _b;
112
+ const prev = (_b = (_a = c[videoId]) !== null && _a !== void 0 ? _a : window.remotion_initialFrame) !== null && _b !== void 0 ? _b : 0;
113
+ return {
114
+ ...c,
115
+ [videoId]: Math.min(lastFrame, prev + frames),
116
+ };
117
+ });
118
+ }, [videoId, imperativePlaying, lastFrame, setFrame]);
100
119
  const returnValue = (0, react_1.useMemo)(() => {
101
120
  return {
102
121
  frameBack,
@@ -1,6 +1,7 @@
1
1
  import type { ComponentType, LazyExoticComponent } from 'react';
2
2
  import React from 'react';
3
3
  import type { TimelineContextValue } from 'remotion';
4
+ export declare const PLAYER_COMP_ID = "player-comp";
4
5
  export declare const SharedPlayerContexts: React.FC<{
5
6
  children: React.ReactNode;
6
7
  timelineContext: TimelineContextValue;
@@ -4,7 +4,7 @@ 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
- type ThumbnailProps<Schema extends AnyZodObject, Props> = PropsIfHasProps<Schema, Props> & CompProps<Schema> & {
7
+ type ThumbnailProps<Schema extends AnyZodObject, Props extends Record<string, unknown>> = PropsIfHasProps<Schema, Props> & CompProps<Props> & {
8
8
  frameToDisplay: number;
9
9
  style?: CSSProperties;
10
10
  durationInFrames: number;
@@ -15,10 +15,10 @@ type ThumbnailProps<Schema extends AnyZodObject, Props> = PropsIfHasProps<Schema
15
15
  renderLoading?: RenderLoading;
16
16
  className?: string;
17
17
  };
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;
18
+ export declare const ThumbnailFn: <Schema extends AnyZodObject, Props extends Record<string, unknown>>({ 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 AnyZodObject, Props>(props: ThumbnailProps<Schema, Props> & import("react").RefAttributes<ThumbnailMethods>) => React.ReactElement | null;
23
+ export declare const Thumbnail: <Schema extends AnyZodObject, Props extends Record<string, unknown>>(props: ThumbnailProps<Schema, Props> & import("react").RefAttributes<ThumbnailMethods>) => React.ReactElement | null;
24
24
  export {};
@@ -297,9 +297,11 @@ const usePlayer = () => {
297
297
  throw new TypeError('Expected Player event emitter context');
298
298
  }
299
299
  const seek = useCallback((newFrame) => {
300
- setTimelinePosition(newFrame);
300
+ if (video === null || video === void 0 ? void 0 : video.id) {
301
+ setTimelinePosition((c) => ({ ...c, [video.id]: newFrame }));
302
+ }
301
303
  emitter.dispatchSeek(newFrame);
302
- }, [emitter, setTimelinePosition]);
304
+ }, [emitter, setTimelinePosition, video === null || video === void 0 ? void 0 : video.id]);
303
305
  const play = useCallback((e) => {
304
306
  if (imperativePlaying.current) {
305
307
  return;
@@ -342,32 +344,49 @@ const usePlayer = () => {
342
344
  const pauseAndReturnToPlayStart = useCallback(() => {
343
345
  if (imperativePlaying.current) {
344
346
  imperativePlaying.current = false;
345
- setTimelinePosition(playStart.current);
346
- setPlaying(false);
347
- emitter.dispatchPause();
347
+ if (config) {
348
+ setTimelinePosition((c) => ({
349
+ ...c,
350
+ [config.id]: playStart.current,
351
+ }));
352
+ setPlaying(false);
353
+ emitter.dispatchPause();
354
+ }
348
355
  }
349
- }, [emitter, imperativePlaying, setPlaying, setTimelinePosition]);
350
- const hasVideo = Boolean(video);
356
+ }, [config, emitter, imperativePlaying, setPlaying, setTimelinePosition]);
357
+ const videoId = video === null || video === void 0 ? void 0 : video.id;
351
358
  const frameBack = useCallback((frames) => {
352
- if (!hasVideo) {
359
+ if (!videoId) {
353
360
  return null;
354
361
  }
355
362
  if (imperativePlaying.current) {
356
363
  return;
357
364
  }
358
- setFrame((f) => {
359
- return Math.max(0, f - frames);
365
+ setFrame((c) => {
366
+ var _a, _b;
367
+ const prev = (_b = (_a = c[videoId]) !== null && _a !== void 0 ? _a : window.remotion_initialFrame) !== null && _b !== void 0 ? _b : 0;
368
+ return {
369
+ ...c,
370
+ [videoId]: Math.max(0, prev - frames),
371
+ };
360
372
  });
361
- }, [hasVideo, imperativePlaying, setFrame]);
373
+ }, [imperativePlaying, setFrame, videoId]);
362
374
  const frameForward = useCallback((frames) => {
363
- if (!hasVideo) {
375
+ if (!videoId) {
364
376
  return null;
365
377
  }
366
378
  if (imperativePlaying.current) {
367
379
  return;
368
380
  }
369
- setFrame((f) => Math.min(lastFrame, f + frames));
370
- }, [hasVideo, imperativePlaying, lastFrame, setFrame]);
381
+ setFrame((c) => {
382
+ var _a, _b;
383
+ const prev = (_b = (_a = c[videoId]) !== null && _a !== void 0 ? _a : window.remotion_initialFrame) !== null && _b !== void 0 ? _b : 0;
384
+ return {
385
+ ...c,
386
+ [videoId]: Math.min(lastFrame, prev + frames),
387
+ };
388
+ });
389
+ }, [videoId, imperativePlaying, lastFrame, setFrame]);
371
390
  const returnValue = useMemo(() => {
372
391
  return {
373
392
  frameBack,
@@ -402,8 +421,8 @@ const usePlayer = () => {
402
421
  };
403
422
 
404
423
  const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, outFrame, }) => {
405
- const frame = Internals.Timeline.useTimelinePosition();
406
424
  const config = Internals.useUnsafeVideoConfig();
425
+ const frame = Internals.Timeline.useTimelinePosition();
407
426
  const { playing, pause, emitter } = usePlayer();
408
427
  const setFrame = Internals.Timeline.useTimelineSetFrame();
409
428
  // requestAnimationFrame() does not work if the tab is not active.
@@ -455,7 +474,7 @@ const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, ou
455
474
  framesAdvanced += framesToAdvance;
456
475
  if (nextFrame !== frameRef.current &&
457
476
  (!hasEnded || moveToBeginningWhenEnded)) {
458
- setFrame(nextFrame);
477
+ setFrame((c) => ({ ...c, [config.id]: nextFrame }));
459
478
  }
460
479
  if (hasEnded) {
461
480
  stop();
@@ -673,11 +692,8 @@ const formatTime = (timeInSeconds) => {
673
692
 
674
693
  const ICON_SIZE = 25;
675
694
  const fullscreenIconSize = 16;
676
- const rotate = {
677
- transform: `rotate(90deg)`,
678
- };
679
695
  const PlayIcon = () => {
680
- return (jsx("svg", { width: ICON_SIZE, height: ICON_SIZE, viewBox: "-100 -100 400 400", style: rotate, children: jsx("path", { fill: "#fff", stroke: "#fff", strokeWidth: "100", strokeLinejoin: "round", d: "M 2 172 a 196 100 0 0 0 195 5 A 196 240 0 0 0 100 2.259 A 196 240 0 0 0 2 172 z" }) }));
696
+ return (jsx("svg", { width: ICON_SIZE, height: ICON_SIZE, viewBox: "0 0 25 25", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: jsx("path", { d: "M8 6.375C7.40904 8.17576 7.06921 10.2486 7.01438 12.3871C6.95955 14.5255 7.19163 16.6547 7.6875 18.5625C9.95364 18.2995 12.116 17.6164 14.009 16.5655C15.902 15.5147 17.4755 14.124 18.6088 12.5C17.5158 10.8949 15.9949 9.51103 14.1585 8.45082C12.3222 7.3906 10.2174 6.68116 8 6.375Z", fill: "white", stroke: "white", strokeWidth: "6.25", strokeLinejoin: "round" }) }));
681
697
  };
682
698
  const PauseIcon = () => {
683
699
  return (jsxs("svg", { viewBox: "0 0 100 100", width: ICON_SIZE, height: ICON_SIZE, children: [jsx("rect", { x: "25", y: "20", width: "20", height: "60", fill: "#fff", ry: "5", rx: "5" }), jsx("rect", { x: "55", y: "20", width: "20", height: "60", fill: "#fff", ry: "5", rx: "5" })] }));
@@ -1677,7 +1693,7 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
1677
1693
  showPosterWhenEnded && player.isLastFrame && !player.isPlaying(),
1678
1694
  showPosterWhenUnplayed && !player.hasPlayed && !player.isPlaying(),
1679
1695
  ].some(Boolean);
1680
- const content = (jsxs(Fragment, { children: [jsx("div", { style: outer, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: jsx("div", { style: containerStyle, className: PLAYER_CSS_CLASSNAME, children: VideoComponent ? (jsx(ErrorBoundary, { onError: onError, errorFallback: errorFallback, children: 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 ? (jsx("div", { style: outer, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null, controls ? (jsx(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, canvasSize: canvasSize, renderFullscreenButton: renderFullscreenButton, renderPlayPauseButton: renderPlayPauseButton, alwaysShowControls: alwaysShowControls, showPlaybackRateControl: showPlaybackRateControl })) : null] }));
1696
+ const content = (jsxs(Fragment, { children: [jsx("div", { style: outer, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: jsx("div", { style: containerStyle, className: PLAYER_CSS_CLASSNAME, children: VideoComponent ? (jsx(ErrorBoundary, { onError: onError, errorFallback: errorFallback, children: jsx(Internals.ClipComposition, { children: jsx(VideoComponent, { ...((_c = video === null || video === void 0 ? void 0 : video.props) !== null && _c !== void 0 ? _c : {}), ...(inputProps !== null && inputProps !== void 0 ? inputProps : {}) }) }) })) : null }) }), shouldShowPoster ? (jsx("div", { style: outer, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null, controls ? (jsx(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, canvasSize: canvasSize, renderFullscreenButton: renderFullscreenButton, renderPlayPauseButton: renderPlayPauseButton, alwaysShowControls: alwaysShowControls, showPlaybackRateControl: showPlaybackRateControl })) : null] }));
1681
1697
  if (IS_NODE && !doesReactVersionSupportSuspense$1) {
1682
1698
  return (jsx("div", { ref: container, style: outerStyle, className: className, children: content }));
1683
1699
  }
@@ -1700,6 +1716,7 @@ const getPreferredVolume = () => {
1700
1716
  return val ? Number(val) : 1;
1701
1717
  };
1702
1718
 
1719
+ const PLAYER_COMP_ID = 'player-comp';
1703
1720
  const SharedPlayerContexts = ({ children, timelineContext, inputProps, fps, compositionHeight, compositionWidth, durationInFrames, component, numberOfSharedAudioTags, initiallyMuted, }) => {
1704
1721
  const compositionManagerContext = useMemo(() => {
1705
1722
  return {
@@ -1710,7 +1727,7 @@ const SharedPlayerContexts = ({ children, timelineContext, inputProps, fps, comp
1710
1727
  height: compositionHeight,
1711
1728
  width: compositionWidth,
1712
1729
  fps,
1713
- id: 'player-comp',
1730
+ id: PLAYER_COMP_ID,
1714
1731
  props: inputProps,
1715
1732
  nonce: 777,
1716
1733
  scale: 1,
@@ -1765,7 +1782,7 @@ const SharedPlayerContexts = ({ children, timelineContext, inputProps, fps, comp
1765
1782
  setMediaVolume: setMediaVolumeAndPersist,
1766
1783
  };
1767
1784
  }, [setMediaVolumeAndPersist]);
1768
- return (jsx(Internals.CanUseRemotionHooksProvider, { children: jsx(Internals.Timeline.TimelineContext.Provider, { value: timelineContext, children: jsx(Internals.CompositionManager.Provider, { value: compositionManagerContext, children: jsx(Internals.ResolveCompositionConfig, { children: jsx(Internals.PrefetchProvider, { children: jsx(Internals.DurationsContextProvider, { children: jsx(Internals.MediaVolumeContext.Provider, { value: mediaVolumeContextValue, children: jsx(Internals.SetMediaVolumeContext.Provider, { value: setMediaVolumeContextValue, children: jsx(Internals.SharedAudioContextProvider, { numberOfAudioTags: numberOfSharedAudioTags, component: component, children: children }) }) }) }) }) }) }) }) }));
1785
+ return (jsx(Internals.CanUseRemotionHooksProvider, { children: jsx(Internals.Timeline.TimelineContext.Provider, { value: timelineContext, children: jsx(Internals.CompositionManager.Provider, { value: compositionManagerContext, children: jsx(Internals.ResolveCompositionConfig, { children: jsx(Internals.PrefetchProvider, { children: jsx(Internals.DurationsContextProvider, { children: jsx(Internals.MediaVolumeContext.Provider, { value: mediaVolumeContextValue, children: jsx(Internals.NativeLayersProvider, { children: jsx(Internals.SetMediaVolumeContext.Provider, { value: setMediaVolumeContextValue, children: jsx(Internals.SharedAudioContextProvider, { numberOfAudioTags: numberOfSharedAudioTags, component: component, children: children }) }) }) }) }) }) }) }) }) }));
1769
1786
  };
1770
1787
 
1771
1788
  const validateSingleFrame = (frame, variableName) => {
@@ -1884,7 +1901,9 @@ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps,
1884
1901
  }
1885
1902
  const component = Internals.useLazyComponent(componentProps);
1886
1903
  validateInitialFrame({ initialFrame, durationInFrames });
1887
- const [frame, setFrame] = useState(() => initialFrame !== null && initialFrame !== void 0 ? initialFrame : 0);
1904
+ const [frame, setFrame] = useState(() => ({
1905
+ [PLAYER_COMP_ID]: initialFrame !== null && initialFrame !== void 0 ? initialFrame : 0,
1906
+ }));
1888
1907
  const [playing, setPlaying] = useState(false);
1889
1908
  const [rootId] = useState('player-comp');
1890
1909
  const [emitter] = useState(() => new PlayerEmitter());
@@ -1900,8 +1919,7 @@ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps,
1900
1919
  }
1901
1920
  Internals.validateDimension(compositionHeight, 'compositionHeight', 'of the <Player /> component');
1902
1921
  Internals.validateDimension(compositionWidth, 'compositionWidth', 'of the <Player /> component');
1903
- Internals.validateDurationInFrames({
1904
- durationInFrames,
1922
+ Internals.validateDurationInFrames(durationInFrames, {
1905
1923
  component: 'of the <Player/> component',
1906
1924
  allowFloats: false,
1907
1925
  });
@@ -2076,7 +2094,7 @@ const ThumbnailUI = ({ style, inputProps, errorFallback, renderLoading, classNam
2076
2094
  if (!config) {
2077
2095
  return null;
2078
2096
  }
2079
- const content = (jsx("div", { style: outer, children: jsx("div", { style: containerStyle, className: PLAYER_CSS_CLASSNAME, children: VideoComponent ? (jsx(ErrorBoundary, { onError: onError, errorFallback: errorFallback, children: jsx(VideoComponent, { ...((_b = video === null || video === void 0 ? void 0 : video.defaultProps) !== null && _b !== void 0 ? _b : {}), ...(inputProps !== null && inputProps !== void 0 ? inputProps : {}) }) })) : null }) }));
2097
+ const content = (jsx("div", { style: outer, children: jsx("div", { style: containerStyle, className: PLAYER_CSS_CLASSNAME, children: VideoComponent ? (jsx(ErrorBoundary, { onError: onError, errorFallback: errorFallback, children: jsx(VideoComponent, { ...((_b = video === null || video === void 0 ? void 0 : video.props) !== null && _b !== void 0 ? _b : {}), ...(inputProps !== null && inputProps !== void 0 ? inputProps : {}) }) })) : null }) }));
2080
2098
  if (IS_NODE && !doesReactVersionSupportSuspense) {
2081
2099
  return (jsx("div", { ref: container, style: outerStyle, className: className, children: content }));
2082
2100
  }
@@ -2090,7 +2108,9 @@ const ThumbnailFn = ({ frameToDisplay, style, inputProps, compositionHeight, com
2090
2108
  const timelineState = useMemo(() => {
2091
2109
  return {
2092
2110
  playing: false,
2093
- frame: frameToDisplay,
2111
+ frame: {
2112
+ [PLAYER_COMP_ID]: frameToDisplay,
2113
+ },
2094
2114
  rootId: thumbnailId,
2095
2115
  imperativePlaying: {
2096
2116
  current: false,