@remotion/player 4.0.122 → 4.0.124

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.
Files changed (48) hide show
  1. package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/MediaVolumeSlider.js +1 -1
  2. package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/Player.d.ts +1 -0
  3. package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/Player.js +2 -2
  4. package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/PlayerControls.d.ts +3 -0
  5. package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/PlayerControls.js +18 -4
  6. package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/PlayerSeekBar.js +1 -1
  7. package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/PlayerUI.d.ts +1 -0
  8. package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/PlayerUI.js +11 -6
  9. package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/Thumbnail.d.ts +1 -2
  10. package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/Thumbnail.js +1 -1
  11. package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/ThumbnailUI.js +0 -2
  12. package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/error-boundary.d.ts +1 -1
  13. package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/index.d.ts +1 -2
  14. package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/is-backgrounded.d.ts +0 -1
  15. package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/use-hover-state.d.ts +1 -1
  16. package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/use-hover-state.js +26 -6
  17. package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/utils/use-click-prevention-on-double-click.js +7 -8
  18. package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/esm/utils/use-component-visible.d.ts +0 -1
  19. package/.rollup.cache/Users/jonathanburger/remotion/packages/player/dist/tsconfig-esm.tsbuildinfo +1 -1
  20. package/dist/cjs/MediaVolumeSlider.js +1 -1
  21. package/dist/cjs/Player.d.ts +1 -0
  22. package/dist/cjs/Player.js +2 -2
  23. package/dist/cjs/PlayerControls.d.ts +3 -0
  24. package/dist/cjs/PlayerControls.js +17 -3
  25. package/dist/cjs/PlayerSeekBar.js +1 -1
  26. package/dist/cjs/PlayerUI.d.ts +1 -0
  27. package/dist/cjs/PlayerUI.js +11 -6
  28. package/dist/cjs/Thumbnail.d.ts +1 -2
  29. package/dist/cjs/Thumbnail.js +2 -3
  30. package/dist/cjs/ThumbnailUI.js +0 -2
  31. package/dist/cjs/error-boundary.d.ts +1 -1
  32. package/dist/cjs/index.d.ts +1 -2
  33. package/dist/cjs/is-backgrounded.d.ts +0 -1
  34. package/dist/cjs/use-hover-state.d.ts +1 -1
  35. package/dist/cjs/use-hover-state.js +26 -6
  36. package/dist/cjs/utils/use-click-prevention-on-double-click.js +7 -8
  37. package/dist/cjs/utils/use-component-visible.d.ts +0 -1
  38. package/dist/esm/Player.d.ts +1 -0
  39. package/dist/esm/PlayerControls.d.ts +3 -0
  40. package/dist/esm/PlayerUI.d.ts +1 -0
  41. package/dist/esm/Thumbnail.d.ts +1 -2
  42. package/dist/esm/error-boundary.d.ts +1 -1
  43. package/dist/esm/index.d.ts +1 -2
  44. package/dist/esm/index.mjs +65 -29
  45. package/dist/esm/is-backgrounded.d.ts +0 -1
  46. package/dist/esm/use-hover-state.d.ts +1 -1
  47. package/dist/esm/utils/use-component-visible.d.ts +0 -1
  48. package/package.json +2 -2
@@ -12,7 +12,7 @@ export const MediaVolumeSlider = ({ displayVerticalVolumeSlider }) => {
12
12
  const [focused, setFocused] = useState(false);
13
13
  const parentDivRef = useRef(null);
14
14
  const inputRef = useRef(null);
15
- const hover = useHoverState(parentDivRef);
15
+ const hover = useHoverState(parentDivRef, false);
16
16
  // Need to import it from React to fix React 17 ESM support.
17
17
  const randomId =
18
18
  // eslint-disable-next-line react-hooks/rules-of-hooks
@@ -46,6 +46,7 @@ export type PlayerProps<Schema extends AnyZodObject, Props> = {
46
46
  showPlaybackRateControl?: boolean | number[];
47
47
  posterFillMode?: PosterFillMode;
48
48
  bufferStateDelayInMilliseconds?: number;
49
+ hideControlsWhenPointerDoesntMove?: boolean | number;
49
50
  } & CompProps<Props> & PropsIfHasProps<Schema, Props>;
50
51
  export declare const componentOrNullIfLazy: <Props>(props: CompProps<Props>) => ComponentType<Props> | null;
51
52
  /**
@@ -15,7 +15,7 @@ export const componentOrNullIfLazy = (props) => {
15
15
  }
16
16
  return null;
17
17
  };
18
- 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, initialFrame, renderPoster, inFrame, outFrame, initiallyShowControls, renderFullscreenButton, renderPlayPauseButton, alwaysShowControls = false, initiallyMuted = false, showPlaybackRateControl = false, posterFillMode = 'player-size', bufferStateDelayInMilliseconds, ...componentProps }, ref) => {
18
+ 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, initialFrame, renderPoster, inFrame, outFrame, initiallyShowControls, renderFullscreenButton, renderPlayPauseButton, alwaysShowControls = false, initiallyMuted = false, showPlaybackRateControl = false, posterFillMode = 'player-size', bufferStateDelayInMilliseconds, hideControlsWhenPointerDoesntMove = true, ...componentProps }, ref) => {
19
19
  if (typeof window !== 'undefined') {
20
20
  // eslint-disable-next-line react-hooks/rules-of-hooks
21
21
  useLayoutEffect(() => {
@@ -133,7 +133,7 @@ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps,
133
133
  const actualInputProps = useMemo(() => inputProps !== null && inputProps !== void 0 ? inputProps : {}, [inputProps]);
134
134
  return (_jsx(Internals.IsPlayerContextProvider, { children: _jsx(SharedPlayerContexts, { timelineContext: timelineContextValue, component: component, compositionHeight: compositionHeight, compositionWidth: compositionWidth, durationInFrames: durationInFrames, fps: fps, numberOfSharedAudioTags: numberOfSharedAudioTags, initiallyMuted: initiallyMuted, children: _jsx(Internals.Timeline.SetTimelineContext.Provider, { value: setTimelineContextValue, children: _jsx(PlayerEmitterProvider, { currentPlaybackRate: currentPlaybackRate, children: _jsx(PlayerUI, { 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'
135
135
  ? clickToPlay
136
- : 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), 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, showPlaybackRateControl: showPlaybackRateControl, bufferStateDelayInMilliseconds: bufferStateDelayInMilliseconds !== null && bufferStateDelayInMilliseconds !== void 0 ? bufferStateDelayInMilliseconds : 300 }) }) }) }) }));
136
+ : 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), 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, showPlaybackRateControl: showPlaybackRateControl, bufferStateDelayInMilliseconds: bufferStateDelayInMilliseconds !== null && bufferStateDelayInMilliseconds !== void 0 ? bufferStateDelayInMilliseconds : 300, hideControlsWhenPointerDoesntMove: hideControlsWhenPointerDoesntMove }) }) }) }) }));
137
137
  };
138
138
  const forward = forwardRef;
139
139
  /**
@@ -41,4 +41,7 @@ export declare const Controls: React.FC<{
41
41
  showPlaybackRateControl: boolean | number[];
42
42
  containerRef: React.RefObject<HTMLDivElement>;
43
43
  buffering: boolean;
44
+ hideControlsWhenPointerDoesntMove: boolean | number;
45
+ onPointerUp: React.PointerEventHandler<HTMLDivElement> | undefined;
46
+ onDoubleClick: MouseEventHandler<HTMLDivElement> | undefined;
44
47
  }>;
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useMemo, useRef, useState } from 'react';
2
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
3
  import { Internals } from 'remotion';
4
4
  import { DefaultPlayPauseButton } from './DefaultPlayPauseButton.js';
5
5
  import { formatTime } from './format-time.js';
@@ -61,12 +61,12 @@ const flex1 = {
61
61
  flex: 1,
62
62
  };
63
63
  const fullscreen = {};
64
- export const Controls = ({ durationInFrames, isFullscreen, fps, player, showVolumeControls, onFullscreenButtonClick, allowFullscreen, onExitFullscreenButtonClick, spaceKeyToPlayOrPause, onSeekEnd, onSeekStart, inFrame, outFrame, initiallyShowControls, canvasSize, renderPlayPauseButton, renderFullscreenButton, alwaysShowControls, showPlaybackRateControl, containerRef, buffering, }) => {
64
+ export const Controls = ({ durationInFrames, isFullscreen, fps, player, showVolumeControls, onFullscreenButtonClick, allowFullscreen, onExitFullscreenButtonClick, spaceKeyToPlayOrPause, onSeekEnd, onSeekStart, inFrame, outFrame, initiallyShowControls, canvasSize, renderPlayPauseButton, renderFullscreenButton, alwaysShowControls, showPlaybackRateControl, containerRef, buffering, hideControlsWhenPointerDoesntMove, onPointerUp, onDoubleClick, }) => {
65
65
  var _a, _b;
66
66
  const playButtonRef = useRef(null);
67
67
  const frame = Internals.Timeline.useTimelinePosition();
68
68
  const [supportsFullscreen, setSupportsFullscreen] = useState(false);
69
- const hovered = useHoverState(containerRef);
69
+ const hovered = useHoverState(containerRef, hideControlsWhenPointerDoesntMove);
70
70
  const { maxTimeLabelWidth, displayVerticalVolumeSlider } = useVideoControlsResize({
71
71
  allowFullscreen,
72
72
  playerWidth: (_a = canvasSize === null || canvasSize === void 0 ? void 0 : canvasSize.width) !== null && _a !== void 0 ? _a : 0,
@@ -153,7 +153,21 @@ export const Controls = ({ durationInFrames, isFullscreen, fps, player, showVolu
153
153
  }
154
154
  return null;
155
155
  }, [showPlaybackRateControl]);
156
- return (_jsxs("div", { style: containerCss, children: [_jsxs("div", { style: controlsRow, children: [_jsxs("div", { style: leftPartStyle, children: [_jsx("button", { ref: playButtonRef, type: "button", style: playerButtonStyle, onClick: player.playing ? player.pause : player.play, "aria-label": player.playing ? 'Pause video' : 'Play video', title: player.playing ? 'Pause video' : 'Play video', children: renderPlayPauseButton === null ? (_jsx(DefaultPlayPauseButton, { buffering: buffering, playing: player.playing })) : ((_b = renderPlayPauseButton({
156
+ const ref = useRef(null);
157
+ const flexRef = useRef(null);
158
+ const onPointerUpIfContainer = useCallback((e) => {
159
+ // Only if pressing the container
160
+ if (e.target === ref.current || e.target === flexRef.current) {
161
+ onPointerUp === null || onPointerUp === void 0 ? void 0 : onPointerUp(e);
162
+ }
163
+ }, [onPointerUp]);
164
+ const onDoubleClickIfContainer = useCallback((e) => {
165
+ // Only if pressing the container
166
+ if (e.target === ref.current || e.target === flexRef.current) {
167
+ onDoubleClick === null || onDoubleClick === void 0 ? void 0 : onDoubleClick(e);
168
+ }
169
+ }, [onDoubleClick]);
170
+ return (_jsxs("div", { ref: ref, style: containerCss, onPointerUp: onPointerUpIfContainer, onDoubleClick: onDoubleClickIfContainer, children: [_jsxs("div", { ref: flexRef, style: controlsRow, children: [_jsxs("div", { style: leftPartStyle, children: [_jsx("button", { ref: playButtonRef, type: "button", style: playerButtonStyle, onClick: player.playing ? player.pause : player.play, "aria-label": player.playing ? 'Pause video' : 'Play video', title: player.playing ? 'Pause video' : 'Play video', children: renderPlayPauseButton === null ? (_jsx(DefaultPlayPauseButton, { buffering: buffering, playing: player.playing })) : ((_b = renderPlayPauseButton({
157
171
  playing: player.playing,
158
172
  isBuffering: buffering,
159
173
  })) !== null && _b !== void 0 ? _b : (_jsx(DefaultPlayPauseButton, { buffering: buffering, playing: player.playing }))) }), showVolumeControls ? (_jsxs(_Fragment, { children: [_jsx("div", { style: xSpacer }), _jsx(MediaVolumeSlider, { displayVerticalVolumeSlider: displayVerticalVolumeSlider })] })) : null, _jsx("div", { style: xSpacer }), _jsxs("div", { style: timeLabel, children: [formatTime(frame / fps), " / ", formatTime(durationInFrames / fps)] }), _jsx("div", { style: xSpacer })] }), _jsx("div", { style: flex1 }), playbackRates && canvasSize && (_jsx(PlaybackrateControl, { canvasSize: canvasSize, playbackRates: playbackRates })), playbackRates && supportsFullscreen && allowFullscreen ? (_jsx("div", { style: xSpacer })) : null, _jsx("div", { style: fullscreen, children: supportsFullscreen && allowFullscreen ? (_jsx("button", { type: "button", "aria-label": isFullscreen ? 'Exit fullscreen' : 'Enter Fullscreen', title: isFullscreen ? 'Exit fullscreen' : 'Enter Fullscreen', style: playerButtonStyle, onClick: isFullscreen
@@ -41,7 +41,7 @@ const findBodyInWhichDivIsLocated = (div) => {
41
41
  export const PlayerSeekBar = ({ durationInFrames, onSeekEnd, onSeekStart, inFrame, outFrame }) => {
42
42
  var _a;
43
43
  const containerRef = useRef(null);
44
- const barHovered = useHoverState(containerRef);
44
+ const barHovered = useHoverState(containerRef, false);
45
45
  const size = useElementSize(containerRef, {
46
46
  triggerOnWindowResize: true,
47
47
  shouldApplyCssTransforms: true,
@@ -41,5 +41,6 @@ declare const _default: React.ForwardRefExoticComponent<{
41
41
  showPlaybackRateControl: boolean | number[];
42
42
  posterFillMode: PosterFillMode;
43
43
  bufferStateDelayInMilliseconds: number;
44
+ hideControlsWhenPointerDoesntMove: number | boolean;
44
45
  } & React.RefAttributes<PlayerRef>>;
45
46
  export default _default;
@@ -15,7 +15,7 @@ if (reactVersion === '0') {
15
15
  throw new Error(`Version ${reactVersion} of "react" is not supported by Remotion`);
16
16
  }
17
17
  const doesReactVersionSupportSuspense = parseInt(reactVersion, 10) >= 18;
18
- const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps, clickToPlay, showVolumeControls, doubleClickToFullscreen, spaceKeyToPlayOrPause, errorFallback, playbackRate, renderLoading, renderPoster, className, moveToBeginningWhenEnded, showPosterWhenUnplayed, showPosterWhenEnded, showPosterWhenPaused, showPosterWhenBuffering, inFrame, outFrame, initiallyShowControls, renderFullscreen: renderFullscreenButton, renderPlayPauseButton, alwaysShowControls, showPlaybackRateControl, posterFillMode, bufferStateDelayInMilliseconds, }, ref) => {
18
+ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps, clickToPlay, showVolumeControls, doubleClickToFullscreen, spaceKeyToPlayOrPause, errorFallback, playbackRate, renderLoading, renderPoster, className, moveToBeginningWhenEnded, showPosterWhenUnplayed, showPosterWhenEnded, showPosterWhenPaused, showPosterWhenBuffering, inFrame, outFrame, initiallyShowControls, renderFullscreen: renderFullscreenButton, renderPlayPauseButton, alwaysShowControls, showPlaybackRateControl, posterFillMode, bufferStateDelayInMilliseconds, hideControlsWhenPointerDoesntMove, }, ref) => {
19
19
  var _a, _b, _c;
20
20
  const config = Internals.useUnsafeVideoConfig();
21
21
  const video = Internals.useVideo();
@@ -28,6 +28,12 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
28
28
  const [shouldAutoplay, setShouldAutoPlay] = useState(autoPlay);
29
29
  const [isFullscreen, setIsFullscreen] = useState(() => false);
30
30
  const [seeking, setSeeking] = useState(false);
31
+ const supportsFullScreen = useMemo(() => {
32
+ if (typeof document === 'undefined') {
33
+ return false;
34
+ }
35
+ return Boolean(document.fullscreenEnabled || document.webkitFullscreenEnabled);
36
+ }, []);
31
37
  const player = usePlayer();
32
38
  usePlayback({
33
39
  loop,
@@ -71,7 +77,6 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
71
77
  if (!allowFullscreen) {
72
78
  throw new Error('allowFullscreen is false');
73
79
  }
74
- const supportsFullScreen = document.fullscreenEnabled || document.webkitFullscreenEnabled;
75
80
  if (!supportsFullScreen) {
76
81
  throw new Error('Browser doesnt support fullscreen');
77
82
  }
@@ -84,7 +89,7 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
84
89
  else {
85
90
  container.current.requestFullscreen();
86
91
  }
87
- }, [allowFullscreen]);
92
+ }, [allowFullscreen, supportsFullScreen]);
88
93
  const exitFullscreen = useCallback(() => {
89
94
  if (document.webkitExitFullscreen) {
90
95
  document.webkitExitFullscreen();
@@ -304,7 +309,7 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
304
309
  requestFullscreen();
305
310
  }
306
311
  }, [exitFullscreen, isFullscreen, requestFullscreen]);
307
- const [handleClick, handleDoubleClick] = useClickPreventionOnDoubleClick(onSingleClick, onDoubleClick, doubleClickToFullscreen);
312
+ const [handleClick, handleDoubleClick] = useClickPreventionOnDoubleClick(onSingleClick, onDoubleClick, doubleClickToFullscreen && allowFullscreen && supportsFullScreen);
308
313
  useEffect(() => {
309
314
  if (shouldAutoplay) {
310
315
  player.play();
@@ -351,11 +356,11 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
351
356
  showPosterWhenBuffering && showBufferIndicator && player.isPlaying(),
352
357
  ].some(Boolean);
353
358
  const { left, top, width, height, ...outerWithoutScale } = outer;
354
- const content = (_jsxs(_Fragment, { children: [_jsx("div", { style: outer, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: _jsxs("div", { style: containerStyle, className: PLAYER_CSS_CLASSNAME, children: [VideoComponent ? (_jsx(ErrorBoundary, { onError: onError, errorFallback: errorFallback, children: _jsx(Internals.ClipComposition, { children: _jsx(Internals.CurrentScaleContext.Provider, { value: currentScale, 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 && posterFillMode === 'composition-size' ? (_jsx("div", { style: {
359
+ const content = (_jsxs(_Fragment, { children: [_jsx("div", { style: outer, onPointerUp: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: _jsxs("div", { style: containerStyle, className: PLAYER_CSS_CLASSNAME, children: [VideoComponent ? (_jsx(ErrorBoundary, { onError: onError, errorFallback: errorFallback, children: _jsx(Internals.ClipComposition, { children: _jsx(Internals.CurrentScaleContext.Provider, { value: currentScale, 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 && posterFillMode === 'composition-size' ? (_jsx("div", { style: {
355
360
  ...outerWithoutScale,
356
361
  width: config.width,
357
362
  height: config.height,
358
- }, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null] }) }), shouldShowPoster && posterFillMode === 'player-size' ? (_jsx("div", { style: outer, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null, controls ? (_jsx(Controls, { fps: config.fps, durationInFrames: config.durationInFrames, player: player, containerRef: container, 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, buffering: showBufferIndicator })) : null] }));
363
+ }, onPointerUp: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null] }) }), shouldShowPoster && posterFillMode === 'player-size' ? (_jsx("div", { style: outer, onPointerUp: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null, controls ? (_jsx(Controls, { fps: config.fps, durationInFrames: config.durationInFrames, player: player, containerRef: container, 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, buffering: showBufferIndicator, hideControlsWhenPointerDoesntMove: hideControlsWhenPointerDoesntMove, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, onPointerUp: clickToPlay ? handleClick : undefined })) : null] }));
359
364
  if (IS_NODE && !doesReactVersionSupportSuspense) {
360
365
  return (_jsx("div", { ref: container, style: outerStyle, className: className, children: content }));
361
366
  }
@@ -1,4 +1,4 @@
1
- import type { CSSProperties, MutableRefObject } from 'react';
1
+ import type { CSSProperties } from 'react';
2
2
  import type { CompProps } from 'remotion';
3
3
  import type { AnyZodObject } from 'zod';
4
4
  import type { ThumbnailMethods } from './player-methods.js';
@@ -15,7 +15,6 @@ type ThumbnailProps<Schema extends AnyZodObject, Props extends Record<string, un
15
15
  renderLoading?: RenderLoading;
16
16
  className?: string;
17
17
  };
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>) => import("react/jsx-runtime.js").JSX.Element;
19
18
  /**
20
19
  * @description A component which can be rendered in a regular React App (for example: Next.js, Vite) to display a single frame of a video.
21
20
  * @see [Documentation](https://www.remotion.dev/docs/player/thumbnail)
@@ -5,7 +5,7 @@ import { ThumbnailEmitterContext } from './emitter-context.js';
5
5
  import { ThumbnailEmitter } from './event-emitter.js';
6
6
  import { PLAYER_COMP_ID, SharedPlayerContexts } from './SharedPlayerContext.js';
7
7
  import ThumbnailUI from './ThumbnailUI.js';
8
- export const ThumbnailFn = ({ frameToDisplay, style, inputProps, compositionHeight, compositionWidth, durationInFrames, fps, className, errorFallback = () => '⚠️', renderLoading, ...componentProps }, ref) => {
8
+ const ThumbnailFn = ({ frameToDisplay, style, inputProps, compositionHeight, compositionWidth, durationInFrames, fps, className, errorFallback = () => '⚠️', renderLoading, ...componentProps }, ref) => {
9
9
  if (typeof window !== 'undefined') {
10
10
  // eslint-disable-next-line react-hooks/rules-of-hooks
11
11
  useLayoutEffect(() => {
@@ -60,8 +60,6 @@ const ThumbnailUI = ({ style, inputProps, errorFallback, renderLoading, classNam
60
60
  // Pay attention to `this context`
61
61
  thumbnail.emitter.dispatchError(error);
62
62
  }, [thumbnail.emitter]);
63
- const rootRef = useRef(null);
64
- useImperativeHandle(ref, () => rootRef.current, []);
65
63
  const loadingMarkup = useMemo(() => {
66
64
  return renderLoading
67
65
  ? renderLoading({
@@ -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 | import("react/jsx-runtime").JSX.Element | Iterable<React.ReactNode> | null | undefined;
18
+ render(): string | number | boolean | Iterable<React.ReactNode> | import("react/jsx-runtime").JSX.Element | null | undefined;
19
19
  }
@@ -1,4 +1,3 @@
1
- /// <reference types="react" />
2
1
  import type { CallbackListener, PlayerEventTypes } from './event-emitter.js';
3
2
  import { PlayerEmitter } from './event-emitter.js';
4
3
  export { PlayerMethods, PlayerRef, ThumbnailMethods, ThumbnailRef, } from './player-methods.js';
@@ -52,7 +51,7 @@ export declare const PlayerInternals: {
52
51
  yCorrection: number;
53
52
  scale: number;
54
53
  };
55
- useHoverState: (ref: import("react").RefObject<HTMLDivElement>) => boolean;
54
+ useHoverState: (ref: import("react").RefObject<HTMLDivElement>, hideControlsWhenPointerDoesntMove: number | boolean) => boolean;
56
55
  updateAllElementsSizes: () => void;
57
56
  PlayerEmitterProvider: import("react").FC<{
58
57
  children: import("react").ReactNode;
@@ -1,2 +1 @@
1
- /// <reference types="react" />
2
1
  export declare const useIsBackgrounded: () => import("react").MutableRefObject<boolean>;
@@ -1 +1 @@
1
- export declare const useHoverState: (ref: React.RefObject<HTMLDivElement>) => boolean;
1
+ export declare const useHoverState: (ref: React.RefObject<HTMLDivElement>, hideControlsWhenPointerDoesntMove: boolean | number) => boolean;
@@ -1,23 +1,43 @@
1
1
  import { useEffect, useState } from 'react';
2
- export const useHoverState = (ref) => {
3
- const [hovered, stetHovered] = useState(false);
2
+ export const useHoverState = (ref, hideControlsWhenPointerDoesntMove) => {
3
+ const [hovered, setHovered] = useState(false);
4
4
  useEffect(() => {
5
5
  const { current } = ref;
6
6
  if (!current) {
7
7
  return;
8
8
  }
9
+ let hoverTimeout;
10
+ const addHoverTimeout = () => {
11
+ if (hideControlsWhenPointerDoesntMove) {
12
+ clearTimeout(hoverTimeout);
13
+ hoverTimeout = setTimeout(() => {
14
+ setHovered(false);
15
+ }, hideControlsWhenPointerDoesntMove === true
16
+ ? 3000
17
+ : hideControlsWhenPointerDoesntMove);
18
+ }
19
+ };
9
20
  const onHover = () => {
10
- stetHovered(true);
21
+ setHovered(true);
22
+ addHoverTimeout();
11
23
  };
12
24
  const onLeave = () => {
13
- stetHovered(false);
25
+ setHovered(false);
26
+ clearTimeout(hoverTimeout);
27
+ };
28
+ const onMove = () => {
29
+ setHovered(true);
30
+ addHoverTimeout();
14
31
  };
15
32
  current.addEventListener('mouseenter', onHover);
16
33
  current.addEventListener('mouseleave', onLeave);
34
+ current.addEventListener('mousemove', onMove);
17
35
  return () => {
18
36
  current.removeEventListener('mouseenter', onHover);
19
- current.removeEventListener('mouseenter', onLeave);
37
+ current.removeEventListener('mouseleave', onLeave);
38
+ current.removeEventListener('mousemove', onMove);
39
+ clearTimeout(hoverTimeout);
20
40
  };
21
- }, [ref]);
41
+ }, [hideControlsWhenPointerDoesntMove, ref]);
22
42
  return hovered;
23
43
  };
@@ -5,6 +5,11 @@ import { useCancellablePromises } from './use-cancellable-promises.js';
5
5
  const useClickPreventionOnDoubleClick = (onClick, onDoubleClick, doubleClickToFullscreen) => {
6
6
  const api = useCancellablePromises();
7
7
  const handleClick = useCallback(async (e) => {
8
+ // UnSupported double click on touch.(mobile)
9
+ if (e.nativeEvent.pointerType === 'touch') {
10
+ onClick(e);
11
+ return;
12
+ }
8
13
  api.clearPendingPromises();
9
14
  const waitForClick = cancellablePromise(delay(200));
10
15
  api.appendPendingPromise(waitForClick);
@@ -27,16 +32,10 @@ const useClickPreventionOnDoubleClick = (onClick, onDoubleClick, doubleClickToFu
27
32
  }, [api, onDoubleClick]);
28
33
  const returnValue = useMemo(() => {
29
34
  if (!doubleClickToFullscreen) {
30
- return [onClick, onDoubleClick];
35
+ return [onClick, () => undefined];
31
36
  }
32
37
  return [handleClick, handleDoubleClick];
33
- }, [
34
- doubleClickToFullscreen,
35
- handleClick,
36
- handleDoubleClick,
37
- onClick,
38
- onDoubleClick,
39
- ]);
38
+ }, [doubleClickToFullscreen, handleClick, handleDoubleClick, onClick]);
40
39
  return returnValue;
41
40
  };
42
41
  export { useClickPreventionOnDoubleClick };
@@ -1,4 +1,3 @@
1
- /// <reference types="react" />
2
1
  export default function useComponentVisible(initialIsVisible: boolean): {
3
2
  ref: import("react").RefObject<HTMLDivElement>;
4
3
  isComponentVisible: boolean;