@remotion/player 4.0.417 → 4.0.418

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.
@@ -6,7 +6,7 @@ import type { RenderMuteButton } from './MediaVolumeSlider.js';
6
6
  import type { RenderFullscreenButton, RenderPlayPauseButton } from './PlayerControls.js';
7
7
  import type { PosterFillMode, RenderLoading, RenderPoster } from './PlayerUI.js';
8
8
  import type { BrowserMediaControlsBehavior } from './browser-mediasession.js';
9
- import type { PlayerRef } from './player-methods.js';
9
+ import type { PlayerRef, RenderCustomControls } from './player-methods.js';
10
10
  import type { RenderVolumeSlider } from './render-volume-slider.js';
11
11
  import type { PropsIfHasProps } from './utils/props-if-has-props.js';
12
12
  export type ErrorFallback = (info: {
@@ -46,6 +46,7 @@ export type PlayerProps<Schema extends AnyZodObject, Props extends Record<string
46
46
  readonly renderFullscreenButton?: RenderFullscreenButton;
47
47
  readonly renderMuteButton?: RenderMuteButton;
48
48
  readonly renderVolumeSlider?: RenderVolumeSlider;
49
+ readonly renderCustomControls?: RenderCustomControls;
49
50
  readonly alwaysShowControls?: boolean;
50
51
  readonly schema?: Schema;
51
52
  readonly initiallyMuted?: boolean;
@@ -23,7 +23,7 @@ const componentOrNullIfLazy = (props) => {
23
23
  return null;
24
24
  };
25
25
  exports.componentOrNullIfLazy = componentOrNullIfLazy;
26
- const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps, inputProps, style, controls = false, loop = false, autoPlay = false, showVolumeControls = true, allowFullscreen = true, clickToPlay, doubleClickToFullscreen = false, spaceKeyToPlayOrPause = true, moveToBeginningWhenEnded = true, numberOfSharedAudioTags = 5, errorFallback = () => '⚠️', playbackRate = 1, renderLoading, className, showPosterWhenUnplayed, showPosterWhenEnded, showPosterWhenPaused, showPosterWhenBuffering, showPosterWhenBufferingAndPaused, initialFrame, renderPoster, inFrame, outFrame, initiallyShowControls, renderFullscreenButton, renderPlayPauseButton, renderVolumeSlider, alwaysShowControls = false, initiallyMuted = false, showPlaybackRateControl = false, posterFillMode = 'player-size', bufferStateDelayInMilliseconds, hideControlsWhenPointerDoesntMove = true, overflowVisible = false, renderMuteButton, browserMediaControlsBehavior: passedBrowserMediaControlsBehavior, overrideInternalClassName, logLevel = 'info', noSuspense, acknowledgeRemotionLicense, audioLatencyHint = 'interactive', volumePersistenceKey, ...componentProps }, ref) => {
26
+ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps, inputProps, style, controls = false, loop = false, autoPlay = false, showVolumeControls = true, allowFullscreen = true, clickToPlay, doubleClickToFullscreen = false, spaceKeyToPlayOrPause = true, moveToBeginningWhenEnded = true, numberOfSharedAudioTags = 5, errorFallback = () => '⚠️', playbackRate = 1, renderLoading, className, showPosterWhenUnplayed, showPosterWhenEnded, showPosterWhenPaused, showPosterWhenBuffering, showPosterWhenBufferingAndPaused, initialFrame, renderPoster, inFrame, outFrame, initiallyShowControls, renderFullscreenButton, renderPlayPauseButton, renderVolumeSlider, renderCustomControls, alwaysShowControls = false, initiallyMuted = false, showPlaybackRateControl = false, posterFillMode = 'player-size', bufferStateDelayInMilliseconds, hideControlsWhenPointerDoesntMove = true, overflowVisible = false, renderMuteButton, browserMediaControlsBehavior: passedBrowserMediaControlsBehavior, overrideInternalClassName, logLevel = 'info', noSuspense, acknowledgeRemotionLicense, audioLatencyHint = 'interactive', volumePersistenceKey, ...componentProps }, ref) => {
27
27
  if (typeof window !== 'undefined') {
28
28
  window.remotion_isPlayer = true;
29
29
  }
@@ -156,7 +156,7 @@ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps,
156
156
  }, [passedBrowserMediaControlsBehavior]);
157
157
  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, numberOfSharedAudioTags: numberOfSharedAudioTags, initiallyMuted: initiallyMuted, logLevel: logLevel, audioLatencyHint: audioLatencyHint, volumePersistenceKey: volumePersistenceKey, inputProps: actualInputProps, audioEnabled: true, children: (0, jsx_runtime_1.jsx)(remotion_1.Internals.SetTimelineContext.Provider, { value: setTimelineContextValue, children: (0, jsx_runtime_1.jsx)(EmitterProvider_js_1.PlayerEmitterProvider, { currentPlaybackRate: currentPlaybackRate, children: (0, jsx_runtime_1.jsx)(PlayerUI_js_1.default, { ref: rootRef, posterFillMode: posterFillMode, renderLoading: renderLoading, autoPlay: Boolean(autoPlay), loop: Boolean(loop), controls: Boolean(controls), errorFallback: errorFallback, style: style, inputProps: actualInputProps, allowFullscreen: Boolean(allowFullscreen), moveToBeginningWhenEnded: Boolean(moveToBeginningWhenEnded), clickToPlay: typeof clickToPlay === 'boolean'
158
158
  ? clickToPlay
159
- : Boolean(controls), showVolumeControls: Boolean(showVolumeControls), doubleClickToFullscreen: Boolean(doubleClickToFullscreen), spaceKeyToPlayOrPause: Boolean(spaceKeyToPlayOrPause), playbackRate: currentPlaybackRate, className: className !== null && className !== void 0 ? className : undefined, showPosterWhenUnplayed: Boolean(showPosterWhenUnplayed), showPosterWhenEnded: Boolean(showPosterWhenEnded), showPosterWhenPaused: Boolean(showPosterWhenPaused), showPosterWhenBuffering: Boolean(showPosterWhenBuffering), showPosterWhenBufferingAndPaused: Boolean(showPosterWhenBufferingAndPaused), renderPoster: renderPoster, inFrame: inFrame !== null && inFrame !== void 0 ? inFrame : null, outFrame: outFrame !== null && outFrame !== void 0 ? outFrame : null, initiallyShowControls: initiallyShowControls !== null && initiallyShowControls !== void 0 ? initiallyShowControls : true, renderFullscreen: renderFullscreenButton !== null && renderFullscreenButton !== void 0 ? renderFullscreenButton : null, renderPlayPauseButton: renderPlayPauseButton !== null && renderPlayPauseButton !== void 0 ? renderPlayPauseButton : null, renderMuteButton: renderMuteButton !== null && renderMuteButton !== void 0 ? renderMuteButton : null, renderVolumeSlider: renderVolumeSlider !== null && renderVolumeSlider !== void 0 ? renderVolumeSlider : null, alwaysShowControls: alwaysShowControls, showPlaybackRateControl: showPlaybackRateControl, bufferStateDelayInMilliseconds: bufferStateDelayInMilliseconds !== null && bufferStateDelayInMilliseconds !== void 0 ? bufferStateDelayInMilliseconds : 300, hideControlsWhenPointerDoesntMove: hideControlsWhenPointerDoesntMove, overflowVisible: overflowVisible, browserMediaControlsBehavior: browserMediaControlsBehavior, overrideInternalClassName: overrideInternalClassName !== null && overrideInternalClassName !== void 0 ? overrideInternalClassName : undefined, noSuspense: Boolean(noSuspense) }) }) }) }) }));
159
+ : Boolean(controls), showVolumeControls: Boolean(showVolumeControls), doubleClickToFullscreen: Boolean(doubleClickToFullscreen), spaceKeyToPlayOrPause: Boolean(spaceKeyToPlayOrPause), playbackRate: currentPlaybackRate, className: className !== null && className !== void 0 ? className : undefined, showPosterWhenUnplayed: Boolean(showPosterWhenUnplayed), showPosterWhenEnded: Boolean(showPosterWhenEnded), showPosterWhenPaused: Boolean(showPosterWhenPaused), showPosterWhenBuffering: Boolean(showPosterWhenBuffering), showPosterWhenBufferingAndPaused: Boolean(showPosterWhenBufferingAndPaused), renderPoster: renderPoster, inFrame: inFrame !== null && inFrame !== void 0 ? inFrame : null, outFrame: outFrame !== null && outFrame !== void 0 ? outFrame : null, initiallyShowControls: initiallyShowControls !== null && initiallyShowControls !== void 0 ? initiallyShowControls : true, renderFullscreen: renderFullscreenButton !== null && renderFullscreenButton !== void 0 ? renderFullscreenButton : null, renderPlayPauseButton: renderPlayPauseButton !== null && renderPlayPauseButton !== void 0 ? renderPlayPauseButton : null, renderMuteButton: renderMuteButton !== null && renderMuteButton !== void 0 ? renderMuteButton : null, renderVolumeSlider: renderVolumeSlider !== null && renderVolumeSlider !== void 0 ? renderVolumeSlider : null, renderCustomControls: renderCustomControls !== null && renderCustomControls !== void 0 ? renderCustomControls : null, alwaysShowControls: alwaysShowControls, showPlaybackRateControl: showPlaybackRateControl, bufferStateDelayInMilliseconds: bufferStateDelayInMilliseconds !== null && bufferStateDelayInMilliseconds !== void 0 ? bufferStateDelayInMilliseconds : 300, hideControlsWhenPointerDoesntMove: hideControlsWhenPointerDoesntMove, overflowVisible: overflowVisible, browserMediaControlsBehavior: browserMediaControlsBehavior, overrideInternalClassName: overrideInternalClassName !== null && overrideInternalClassName !== void 0 ? overrideInternalClassName : undefined, noSuspense: Boolean(noSuspense) }) }) }) }) }));
160
160
  };
161
161
  const forward = react_1.forwardRef;
162
162
  /*
@@ -1,6 +1,7 @@
1
1
  import type { MouseEventHandler, ReactNode, SyntheticEvent } from 'react';
2
2
  import React from 'react';
3
3
  import type { RenderMuteButton } from './MediaVolumeSlider.js';
4
+ import type { RenderCustomControls } from './player-methods.js';
4
5
  import type { RenderVolumeSlider } from './render-volume-slider.js';
5
6
  import type { Size } from './utils/use-element-size.js';
6
7
  export type RenderPlayPauseButton = (props: {
@@ -38,4 +39,5 @@ export declare const Controls: React.FC<{
38
39
  readonly renderVolumeSlider: RenderVolumeSlider | null;
39
40
  readonly playing: boolean;
40
41
  readonly toggle: (e?: SyntheticEvent | PointerEvent) => void;
42
+ readonly renderCustomControls: RenderCustomControls | null;
41
43
  }>;
@@ -65,7 +65,7 @@ const flex1 = {
65
65
  flex: 1,
66
66
  };
67
67
  const fullscreen = {};
68
- const Controls = ({ durationInFrames, isFullscreen, fps, showVolumeControls, onFullscreenButtonClick, allowFullscreen, onExitFullscreenButtonClick, spaceKeyToPlayOrPause, onSeekEnd, onSeekStart, inFrame, outFrame, initiallyShowControls, canvasSize, renderPlayPauseButton, renderFullscreenButton, alwaysShowControls, showPlaybackRateControl, containerRef, buffering, hideControlsWhenPointerDoesntMove, onPointerDown, onDoubleClick, renderMuteButton, renderVolumeSlider, playing, toggle, }) => {
68
+ const Controls = ({ durationInFrames, isFullscreen, fps, showVolumeControls, onFullscreenButtonClick, allowFullscreen, onExitFullscreenButtonClick, spaceKeyToPlayOrPause, onSeekEnd, onSeekStart, inFrame, outFrame, initiallyShowControls, canvasSize, renderPlayPauseButton, renderFullscreenButton, alwaysShowControls, showPlaybackRateControl, containerRef, buffering, hideControlsWhenPointerDoesntMove, onPointerDown, onDoubleClick, renderMuteButton, renderVolumeSlider, playing, toggle, renderCustomControls, }) => {
69
69
  var _a, _b;
70
70
  const playButtonRef = (0, react_1.useRef)(null);
71
71
  const [supportsFullscreen, setSupportsFullscreen] = (0, react_1.useState)(false);
@@ -148,6 +148,9 @@ const Controls = ({ durationInFrames, isFullscreen, fps, showVolumeControls, onF
148
148
  }
149
149
  return null;
150
150
  }, [showPlaybackRateControl]);
151
+ const customControlsElement = renderCustomControls
152
+ ? renderCustomControls()
153
+ : null;
151
154
  const ref = (0, react_1.useRef)(null);
152
155
  const flexRef = (0, react_1.useRef)(null);
153
156
  const onPointerDownIfContainer = (0, react_1.useCallback)((e) => {
@@ -165,7 +168,7 @@ const Controls = ({ durationInFrames, isFullscreen, fps, showVolumeControls, onF
165
168
  return ((0, jsx_runtime_1.jsxs)("div", { ref: ref, style: containerCss, onPointerDown: onPointerDownIfContainer, onDoubleClick: onDoubleClickIfContainer, children: [(0, jsx_runtime_1.jsxs)("div", { ref: flexRef, style: controlsRow, children: [(0, jsx_runtime_1.jsxs)("div", { style: leftPartStyle, children: [(0, jsx_runtime_1.jsx)("button", { ref: playButtonRef, type: "button", style: PlaybackrateControl_js_1.playerButtonStyle, onClick: toggle, "aria-label": playing ? 'Pause video' : 'Play video', title: playing ? 'Pause video' : 'Play video', children: renderPlayPauseButton === null ? ((0, jsx_runtime_1.jsx)(DefaultPlayPauseButton_js_1.DefaultPlayPauseButton, { buffering: buffering, playing: playing })) : (((_b = renderPlayPauseButton({
166
169
  playing,
167
170
  isBuffering: buffering,
168
- })) !== null && _b !== void 0 ? _b : ((0, jsx_runtime_1.jsx)(DefaultPlayPauseButton_js_1.DefaultPlayPauseButton, { buffering: buffering, playing: playing })))) }), showVolumeControls ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { style: xSpacer }), (0, jsx_runtime_1.jsx)(MediaVolumeSlider_js_1.MediaVolumeSlider, { renderMuteButton: renderMuteButton, renderVolumeSlider: renderVolumeSlider, displayVerticalVolumeSlider: displayVerticalVolumeSlider })] })) : null, (0, jsx_runtime_1.jsx)("div", { style: xSpacer }), (0, jsx_runtime_1.jsx)(PlayerTimeLabel_js_1.PlayerTimeLabel, { durationInFrames: durationInFrames, fps: fps, maxTimeLabelWidth: maxTimeLabelWidth }), (0, jsx_runtime_1.jsx)("div", { style: xSpacer })] }), (0, jsx_runtime_1.jsx)("div", { style: flex1 }), playbackRates && canvasSize && ((0, jsx_runtime_1.jsx)(PlaybackrateControl_js_1.PlaybackrateControl, { canvasSize: canvasSize, playbackRates: playbackRates })), playbackRates && supportsFullscreen && allowFullscreen ? ((0, jsx_runtime_1.jsx)("div", { style: xSpacer })) : null, (0, jsx_runtime_1.jsx)("div", { style: fullscreen, children: supportsFullscreen && allowFullscreen ? ((0, jsx_runtime_1.jsx)("button", { type: "button", "aria-label": isFullscreen ? 'Exit fullscreen' : 'Enter Fullscreen', title: isFullscreen ? 'Exit fullscreen' : 'Enter Fullscreen', style: PlaybackrateControl_js_1.playerButtonStyle, onClick: isFullscreen
171
+ })) !== null && _b !== void 0 ? _b : ((0, jsx_runtime_1.jsx)(DefaultPlayPauseButton_js_1.DefaultPlayPauseButton, { buffering: buffering, playing: playing })))) }), showVolumeControls ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { style: xSpacer }), (0, jsx_runtime_1.jsx)(MediaVolumeSlider_js_1.MediaVolumeSlider, { renderMuteButton: renderMuteButton, renderVolumeSlider: renderVolumeSlider, displayVerticalVolumeSlider: displayVerticalVolumeSlider })] })) : null, (0, jsx_runtime_1.jsx)("div", { style: xSpacer }), (0, jsx_runtime_1.jsx)(PlayerTimeLabel_js_1.PlayerTimeLabel, { durationInFrames: durationInFrames, fps: fps, maxTimeLabelWidth: maxTimeLabelWidth }), (0, jsx_runtime_1.jsx)("div", { style: xSpacer })] }), (0, jsx_runtime_1.jsx)("div", { style: flex1 }), customControlsElement, customControlsElement && playbackRates && canvasSize ? ((0, jsx_runtime_1.jsx)("div", { style: xSpacer })) : null, playbackRates && canvasSize && ((0, jsx_runtime_1.jsx)(PlaybackrateControl_js_1.PlaybackrateControl, { canvasSize: canvasSize, playbackRates: playbackRates })), playbackRates && supportsFullscreen && allowFullscreen ? ((0, jsx_runtime_1.jsx)("div", { style: xSpacer })) : null, (0, jsx_runtime_1.jsx)("div", { style: fullscreen, children: supportsFullscreen && allowFullscreen ? ((0, jsx_runtime_1.jsx)("button", { type: "button", "aria-label": isFullscreen ? 'Exit fullscreen' : 'Enter Fullscreen', title: isFullscreen ? 'Exit fullscreen' : 'Enter Fullscreen', style: PlaybackrateControl_js_1.playerButtonStyle, onClick: isFullscreen
169
172
  ? onExitFullscreenButtonClick
170
173
  : onFullscreenButtonClick, children: renderFullscreenButton === null ? ((0, jsx_runtime_1.jsx)(icons_js_1.FullscreenIcon, { isFullscreen: isFullscreen })) : (renderFullscreenButton({ isFullscreen })) })) : null })] }), (0, jsx_runtime_1.jsx)("div", { style: ySpacer }), (0, jsx_runtime_1.jsx)(PlayerSeekBar_js_1.PlayerSeekBar, { onSeekEnd: onSeekEnd, onSeekStart: onSeekStart, durationInFrames: durationInFrames, inFrame: inFrame, outFrame: outFrame })] }));
171
174
  };
@@ -2,7 +2,7 @@ import React from 'react';
2
2
  import type { RenderMuteButton } from './MediaVolumeSlider.js';
3
3
  import type { RenderFullscreenButton, RenderPlayPauseButton } from './PlayerControls.js';
4
4
  import type { BrowserMediaControlsBehavior } from './browser-mediasession.js';
5
- import type { PlayerRef } from './player-methods.js';
5
+ import type { PlayerRef, RenderCustomControls } from './player-methods.js';
6
6
  import type { RenderVolumeSlider } from './render-volume-slider.js';
7
7
  export type ErrorFallback = (info: {
8
8
  error: Error;
@@ -43,6 +43,7 @@ declare const _default: React.ForwardRefExoticComponent<{
43
43
  readonly renderFullscreen: RenderFullscreenButton | null;
44
44
  readonly renderMuteButton: RenderMuteButton | null;
45
45
  readonly renderVolumeSlider: RenderVolumeSlider | null;
46
+ readonly renderCustomControls: RenderCustomControls | null;
46
47
  readonly alwaysShowControls: boolean;
47
48
  readonly showPlaybackRateControl: boolean | number[];
48
49
  readonly posterFillMode: PosterFillMode;
@@ -51,7 +51,7 @@ if (reactVersion === '0') {
51
51
  throw new Error(`Version ${reactVersion} of "react" is not supported by Remotion`);
52
52
  }
53
53
  const doesReactVersionSupportSuspense = parseInt(reactVersion, 10) >= 18;
54
- const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps, clickToPlay, showVolumeControls, doubleClickToFullscreen, spaceKeyToPlayOrPause, errorFallback, playbackRate, renderLoading, renderPoster, className, moveToBeginningWhenEnded, showPosterWhenUnplayed, showPosterWhenEnded, showPosterWhenPaused, showPosterWhenBuffering, showPosterWhenBufferingAndPaused, inFrame, outFrame, initiallyShowControls, renderFullscreen: renderFullscreenButton, renderPlayPauseButton, renderMuteButton, renderVolumeSlider, alwaysShowControls, showPlaybackRateControl, posterFillMode, bufferStateDelayInMilliseconds, hideControlsWhenPointerDoesntMove, overflowVisible, browserMediaControlsBehavior, overrideInternalClassName, noSuspense, }, ref) => {
54
+ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps, clickToPlay, showVolumeControls, doubleClickToFullscreen, spaceKeyToPlayOrPause, errorFallback, playbackRate, renderLoading, renderPoster, className, moveToBeginningWhenEnded, showPosterWhenUnplayed, showPosterWhenEnded, showPosterWhenPaused, showPosterWhenBuffering, showPosterWhenBufferingAndPaused, inFrame, outFrame, initiallyShowControls, renderFullscreen: renderFullscreenButton, renderPlayPauseButton, renderMuteButton, renderVolumeSlider, renderCustomControls, alwaysShowControls, showPlaybackRateControl, posterFillMode, bufferStateDelayInMilliseconds, hideControlsWhenPointerDoesntMove, overflowVisible, browserMediaControlsBehavior, overrideInternalClassName, noSuspense, }, ref) => {
55
55
  var _a, _b, _c;
56
56
  const config = remotion_1.Internals.useUnsafeVideoConfig();
57
57
  const video = remotion_1.Internals.useVideo();
@@ -436,7 +436,7 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
436
436
  height: config.height,
437
437
  }, onPointerDown: clickToPlay ? handlePointerDown : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null] }), (0, jsx_runtime_1.jsx)(license_blacklist_js_1.RenderWarningIfBlacklist, {})] }), shouldShowPoster && posterFillMode === 'player-size' ? ((0, jsx_runtime_1.jsx)("div", { style: outer, onPointerDown: clickToPlay ? handlePointerDown : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null, controls ? ((0, jsx_runtime_1.jsx)(PlayerControls_js_1.Controls, { fps: config.fps, playing: player.playing, toggle: player.toggle, durationInFrames: config.durationInFrames, 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, onPointerDown: clickToPlay
438
438
  ? handlePointerDown
439
- : undefined, renderMuteButton: renderMuteButton, renderVolumeSlider: renderVolumeSlider })) : null] }));
439
+ : undefined, renderMuteButton: renderMuteButton, renderVolumeSlider: renderVolumeSlider, renderCustomControls: renderCustomControls })) : null] }));
440
440
  if (noSuspense || (is_node_js_1.IS_NODE && !doesReactVersionSupportSuspense)) {
441
441
  return ((0, jsx_runtime_1.jsx)("div", { ref: container, style: outerStyle, className: className, children: content }));
442
442
  }
@@ -2,7 +2,7 @@ import './_check-rsc.js';
2
2
  import type { CallbackListener, PlayerEventTypes } from './event-emitter.js';
3
3
  import { PlayerEmitter } from './event-emitter.js';
4
4
  export type { RenderMuteButton } from './MediaVolumeSlider.js';
5
- export type { PlayerMethods, PlayerRef, ThumbnailMethods, ThumbnailRef, } from './player-methods.js';
5
+ export type { PlayerMethods, PlayerRef, RenderCustomControls, ThumbnailMethods, ThumbnailRef, } from './player-methods.js';
6
6
  export { Player } from './Player.js';
7
7
  export type { PlayerProps, PlayerPropsWithoutZod } from './Player.js';
8
8
  export type { RenderFullscreenButton, RenderPlayPauseButton, } from './PlayerControls.js';
@@ -1,4 +1,4 @@
1
- import type { SyntheticEvent } from 'react';
1
+ import type { ReactElement, SyntheticEvent } from 'react';
2
2
  import type { PlayerEmitter, ThumbnailEmitter } from './event-emitter.js';
3
3
  export type ThumbnailMethods = {
4
4
  getContainerNode: () => HTMLDivElement | null;
@@ -23,3 +23,4 @@ export type PlayerMethods = ThumbnailMethods & {
23
23
  };
24
24
  export type ThumbnailRef = ThumbnailEmitter & ThumbnailMethods;
25
25
  export type PlayerRef = PlayerEmitter & PlayerMethods;
26
+ export type RenderCustomControls = () => ReactElement | null;
@@ -1971,7 +1971,8 @@ var Controls = ({
1971
1971
  renderMuteButton,
1972
1972
  renderVolumeSlider,
1973
1973
  playing,
1974
- toggle
1974
+ toggle,
1975
+ renderCustomControls
1975
1976
  }) => {
1976
1977
  const playButtonRef = useRef8(null);
1977
1978
  const [supportsFullscreen, setSupportsFullscreen] = useState10(false);
@@ -2047,6 +2048,7 @@ var Controls = ({
2047
2048
  }
2048
2049
  return null;
2049
2050
  }, [showPlaybackRateControl]);
2051
+ const customControlsElement = renderCustomControls ? renderCustomControls() : null;
2050
2052
  const ref = useRef8(null);
2051
2053
  const flexRef = useRef8(null);
2052
2054
  const onPointerDownIfContainer = useCallback8((e) => {
@@ -2118,6 +2120,10 @@ var Controls = ({
2118
2120
  /* @__PURE__ */ jsx9("div", {
2119
2121
  style: flex1
2120
2122
  }),
2123
+ customControlsElement,
2124
+ customControlsElement && playbackRates && canvasSize ? /* @__PURE__ */ jsx9("div", {
2125
+ style: xSpacer
2126
+ }) : null,
2121
2127
  playbackRates && canvasSize && /* @__PURE__ */ jsx9(PlaybackrateControl, {
2122
2128
  canvasSize,
2123
2129
  playbackRates
@@ -2412,6 +2418,7 @@ var PlayerUI = ({
2412
2418
  renderPlayPauseButton,
2413
2419
  renderMuteButton,
2414
2420
  renderVolumeSlider,
2421
+ renderCustomControls,
2415
2422
  alwaysShowControls,
2416
2423
  showPlaybackRateControl,
2417
2424
  posterFillMode,
@@ -2835,7 +2842,8 @@ var PlayerUI = ({
2835
2842
  onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined,
2836
2843
  onPointerDown: clickToPlay ? handlePointerDown : undefined,
2837
2844
  renderMuteButton,
2838
- renderVolumeSlider
2845
+ renderVolumeSlider,
2846
+ renderCustomControls
2839
2847
  }) : null
2840
2848
  ]
2841
2849
  });
@@ -3168,6 +3176,7 @@ var PlayerFn = ({
3168
3176
  renderFullscreenButton,
3169
3177
  renderPlayPauseButton,
3170
3178
  renderVolumeSlider,
3179
+ renderCustomControls,
3171
3180
  alwaysShowControls = false,
3172
3181
  initiallyMuted = false,
3173
3182
  showPlaybackRateControl = false,
@@ -3353,6 +3362,7 @@ var PlayerFn = ({
3353
3362
  renderPlayPauseButton: renderPlayPauseButton ?? null,
3354
3363
  renderMuteButton: renderMuteButton ?? null,
3355
3364
  renderVolumeSlider: renderVolumeSlider ?? null,
3365
+ renderCustomControls: renderCustomControls ?? null,
3356
3366
  alwaysShowControls,
3357
3367
  showPlaybackRateControl,
3358
3368
  bufferStateDelayInMilliseconds: bufferStateDelayInMilliseconds ?? 300,
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/player"
4
4
  },
5
5
  "name": "@remotion/player",
6
- "version": "4.0.417",
6
+ "version": "4.0.418",
7
7
  "description": "React component for embedding a Remotion preview into your app",
8
8
  "main": "dist/cjs/index.js",
9
9
  "types": "dist/cjs/index.d.ts",
@@ -35,7 +35,7 @@
35
35
  ],
36
36
  "license": "SEE LICENSE IN LICENSE.md",
37
37
  "dependencies": {
38
- "remotion": "4.0.417"
38
+ "remotion": "4.0.418"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "react": ">=16.8.0",
@@ -49,7 +49,7 @@
49
49
  "react-dom": "19.2.3",
50
50
  "webpack": "5.96.1",
51
51
  "zod": "3.22.3",
52
- "@remotion/eslint-config-internal": "4.0.417",
52
+ "@remotion/eslint-config-internal": "4.0.418",
53
53
  "eslint": "9.19.0"
54
54
  },
55
55
  "keywords": [