@remotion/player 3.2.24 → 3.2.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,5 @@
1
1
  import React from 'react';
2
- export declare const MediaVolumeSlider: React.FC;
2
+ export declare const VOLUME_SLIDER_WIDTH = 100;
3
+ export declare const MediaVolumeSlider: React.FC<{
4
+ displayVerticalVolumeSlider: Boolean;
5
+ }>;
@@ -1,72 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MediaVolumeSlider = void 0;
3
+ exports.MediaVolumeSlider = exports.VOLUME_SLIDER_WIDTH = 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 icons_1 = require("./icons");
8
- const player_css_classname_1 = require("./player-css-classname");
9
8
  const use_hover_state_1 = require("./use-hover-state");
10
9
  const BAR_HEIGHT = 5;
11
10
  const KNOB_SIZE = 12;
12
- const VOLUME_SLIDER_WIDTH = 100;
13
- const scope = `.${player_css_classname_1.VOLUME_SLIDER_INPUT_CSS_CLASSNAME}`;
14
- const sliderStyle = `
15
- ${scope} {
16
- -webkit-appearance: none;
17
- background-color: rgba(255, 255, 255, 0.5);
18
- border-radius: ${BAR_HEIGHT / 2}px;
19
- cursor: pointer;
20
- height: ${BAR_HEIGHT}px;
21
- margin-left: 5px;
22
- width: ${VOLUME_SLIDER_WIDTH}px;
23
- }
24
-
25
- ${scope}::-webkit-slider-thumb {
26
- -webkit-appearance: none;
27
- background-color: white;
28
- border-radius: ${KNOB_SIZE / 2}px;
29
- box-shadow: 0 0 2px black;
30
- height: ${KNOB_SIZE}px;
31
- width: ${KNOB_SIZE}px;
32
- }
33
-
34
- ${scope}::-moz-range-thumb {
35
- -webkit-appearance: none;
36
- background-color: white;
37
- border-radius: ${KNOB_SIZE / 2}px;
38
- box-shadow: 0 0 2px black;
39
- height: ${KNOB_SIZE}px;
40
- width: ${KNOB_SIZE}px;
41
- }
42
- `;
43
- remotion_1.Internals.CSSUtils.injectCSS(sliderStyle);
44
- const parentDivStyle = {
45
- display: 'inline-flex',
46
- background: 'none',
47
- border: 'none',
48
- padding: '6px',
49
- justifyContent: 'center',
50
- alignItems: 'center',
51
- touchAction: 'none',
52
- };
53
- const volumeContainer = {
54
- display: 'inline',
55
- width: icons_1.ICON_SIZE,
56
- height: icons_1.ICON_SIZE,
57
- cursor: 'pointer',
58
- appearance: 'none',
59
- background: 'none',
60
- border: 'none',
61
- padding: 0,
62
- };
63
- const MediaVolumeSlider = () => {
11
+ exports.VOLUME_SLIDER_WIDTH = 100;
12
+ const MediaVolumeSlider = ({ displayVerticalVolumeSlider }) => {
64
13
  const [mediaMuted, setMediaMuted] = remotion_1.Internals.useMediaMutedState();
65
14
  const [mediaVolume, setMediaVolume] = remotion_1.Internals.useMediaVolumeState();
66
15
  const [focused, setFocused] = (0, react_1.useState)(false);
67
16
  const parentDivRef = (0, react_1.useRef)(null);
68
17
  const inputRef = (0, react_1.useRef)(null);
69
18
  const hover = (0, use_hover_state_1.useHoverState)(parentDivRef);
19
+ const [randomClass] = (0, react_1.useState)(() => `slider-${(0, remotion_1.random)(null)}`.replace('.', ''));
70
20
  const isMutedOrZero = mediaMuted || mediaVolume === 0;
71
21
  const onVolumeChange = (e) => {
72
22
  setMediaVolume(parseFloat(e.target.value));
@@ -88,6 +38,81 @@ const MediaVolumeSlider = () => {
88
38
  }
89
39
  setMediaMuted((mute) => !mute);
90
40
  }, [mediaVolume, setMediaMuted, setMediaVolume]);
91
- return ((0, jsx_runtime_1.jsxs)("div", { ref: parentDivRef, style: parentDivStyle, children: [(0, jsx_runtime_1.jsx)("button", { "aria-label": isMutedOrZero ? 'Unmute sound' : 'Mute sound', title: isMutedOrZero ? 'Unmute sound' : 'Mute sound', onClick: onClick, onBlur: onBlur, onFocus: () => setFocused(true), style: volumeContainer, type: "button", children: isMutedOrZero ? (0, jsx_runtime_1.jsx)(icons_1.VolumeOffIcon, {}) : (0, jsx_runtime_1.jsx)(icons_1.VolumeOnIcon, {}) }), (focused || hover) && !mediaMuted ? ((0, jsx_runtime_1.jsx)("input", { ref: inputRef, "aria-label": "Change volume", className: player_css_classname_1.VOLUME_SLIDER_INPUT_CSS_CLASSNAME, max: 1, min: 0, onBlur: () => setFocused(false), onChange: onVolumeChange, step: 0.01, type: "range", value: mediaVolume })) : null] }));
41
+ const parentDivStyle = (0, react_1.useMemo)(() => {
42
+ return {
43
+ display: 'inline-flex',
44
+ background: 'none',
45
+ border: 'none',
46
+ padding: '6px',
47
+ justifyContent: 'center',
48
+ alignItems: 'center',
49
+ touchAction: 'none',
50
+ ...(displayVerticalVolumeSlider && { position: 'relative' }),
51
+ };
52
+ }, [displayVerticalVolumeSlider]);
53
+ const volumeContainer = (0, react_1.useMemo)(() => {
54
+ return {
55
+ display: 'inline',
56
+ width: icons_1.ICON_SIZE,
57
+ height: icons_1.ICON_SIZE,
58
+ cursor: 'pointer',
59
+ appearance: 'none',
60
+ background: 'none',
61
+ border: 'none',
62
+ padding: 0,
63
+ };
64
+ }, []);
65
+ const inputStyle = (0, react_1.useMemo)(() => {
66
+ const commonStyle = {
67
+ WebkitAppearance: 'none',
68
+ backgroundColor: 'rgba(255, 255, 255, 0.5)',
69
+ borderRadius: BAR_HEIGHT / 2,
70
+ cursor: 'pointer',
71
+ height: BAR_HEIGHT,
72
+ width: exports.VOLUME_SLIDER_WIDTH,
73
+ };
74
+ if (displayVerticalVolumeSlider) {
75
+ return {
76
+ ...commonStyle,
77
+ transform: `rotate(-90deg)`,
78
+ position: 'absolute',
79
+ bottom: icons_1.ICON_SIZE + exports.VOLUME_SLIDER_WIDTH / 2 + 5,
80
+ };
81
+ }
82
+ return {
83
+ ...commonStyle,
84
+ marginLeft: 5,
85
+ };
86
+ }, [displayVerticalVolumeSlider]);
87
+ const sliderStyle = `
88
+ .${randomClass}::-webkit-slider-thumb {
89
+ -webkit-appearance: none;
90
+ background-color: white;
91
+ border-radius: ${KNOB_SIZE / 2}px;
92
+ box-shadow: 0 0 2px black;
93
+ height: ${KNOB_SIZE}px;
94
+ width: ${KNOB_SIZE}px;
95
+ }
96
+ .${randomClass} {
97
+ background-image: linear-gradient(
98
+ to right,
99
+ white ${mediaVolume * 100}%, rgba(255, 255, 255, 0) ${mediaVolume * 100}%
100
+ );
101
+ }
102
+
103
+ .${randomClass}::-moz-range-thumb {
104
+ -webkit-appearance: none;
105
+ background-color: white;
106
+ border-radius: ${KNOB_SIZE / 2}px;
107
+ box-shadow: 0 0 2px black;
108
+ height: ${KNOB_SIZE}px;
109
+ width: ${KNOB_SIZE}px;
110
+ }
111
+ `;
112
+ return ((0, jsx_runtime_1.jsxs)("div", { ref: parentDivRef, style: parentDivStyle, children: [(0, jsx_runtime_1.jsx)("style", {
113
+ // eslint-disable-next-line react/no-danger
114
+ dangerouslySetInnerHTML: {
115
+ __html: sliderStyle,
116
+ } }), (0, jsx_runtime_1.jsx)("button", { "aria-label": isMutedOrZero ? 'Unmute sound' : 'Mute sound', title: isMutedOrZero ? 'Unmute sound' : 'Mute sound', onClick: onClick, onBlur: onBlur, onFocus: () => setFocused(true), style: volumeContainer, type: "button", children: isMutedOrZero ? (0, jsx_runtime_1.jsx)(icons_1.VolumeOffIcon, {}) : (0, jsx_runtime_1.jsx)(icons_1.VolumeOnIcon, {}) }), (focused || hover) && !mediaMuted ? ((0, jsx_runtime_1.jsx)("input", { ref: inputRef, "aria-label": "Change volume", className: randomClass, max: 1, min: 0, onBlur: () => setFocused(false), onChange: onVolumeChange, step: 0.01, type: "range", value: mediaVolume, style: inputStyle })) : null] }));
92
117
  };
93
118
  exports.MediaVolumeSlider = MediaVolumeSlider;
@@ -1,6 +1,8 @@
1
1
  import type { MouseEventHandler } from 'react';
2
2
  import React from 'react';
3
3
  import type { usePlayer } from './use-player';
4
+ export declare const X_SPACER = 10;
5
+ export declare const X_PADDING = 12;
4
6
  declare global {
5
7
  interface Document {
6
8
  webkitFullscreenEnabled?: boolean;
@@ -27,4 +29,5 @@ export declare const Controls: React.FC<{
27
29
  inFrame: number | null;
28
30
  outFrame: number | null;
29
31
  initiallyShowControls: number | boolean;
32
+ playerWidth: number;
30
33
  }>;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Controls = void 0;
3
+ exports.Controls = exports.X_PADDING = exports.X_SPACER = 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");
@@ -8,6 +8,9 @@ const format_time_1 = require("./format-time");
8
8
  const icons_1 = require("./icons");
9
9
  const MediaVolumeSlider_1 = require("./MediaVolumeSlider");
10
10
  const PlayerSeekBar_1 = require("./PlayerSeekBar");
11
+ const use_video_controls_resize_1 = require("./use-video-controls-resize");
12
+ exports.X_SPACER = 10;
13
+ exports.X_PADDING = 12;
11
14
  const containerStyle = {
12
15
  boxSizing: 'border-box',
13
16
  position: 'absolute',
@@ -17,8 +20,8 @@ const containerStyle = {
17
20
  paddingBottom: 10,
18
21
  background: 'linear-gradient(transparent, rgba(0, 0, 0, 0.4))',
19
22
  display: 'flex',
20
- paddingRight: 12,
21
- paddingLeft: 12,
23
+ paddingRight: exports.X_PADDING,
24
+ paddingLeft: exports.X_PADDING,
22
25
  flexDirection: 'column',
23
26
  transition: 'opacity 0.3s',
24
27
  };
@@ -57,15 +60,11 @@ const flex1 = {
57
60
  flex: 1,
58
61
  };
59
62
  const fullscreen = {};
60
- const timeLabel = {
61
- color: 'white',
62
- fontFamily: 'sans-serif',
63
- fontSize: 14,
64
- };
65
- const Controls = ({ durationInFrames, hovered, isFullscreen, fps, player, showVolumeControls, onFullscreenButtonClick, allowFullscreen, onExitFullscreenButtonClick, spaceKeyToPlayOrPause, onSeekEnd, onSeekStart, inFrame, outFrame, initiallyShowControls, }) => {
63
+ const Controls = ({ durationInFrames, hovered, isFullscreen, fps, player, showVolumeControls, onFullscreenButtonClick, allowFullscreen, onExitFullscreenButtonClick, spaceKeyToPlayOrPause, onSeekEnd, onSeekStart, inFrame, outFrame, initiallyShowControls, playerWidth, }) => {
66
64
  const playButtonRef = (0, react_1.useRef)(null);
67
65
  const frame = remotion_1.Internals.Timeline.useTimelinePosition();
68
66
  const [supportsFullscreen, setSupportsFullscreen] = (0, react_1.useState)(false);
67
+ const { maxTimeLabelWidth, displayVerticalVolumeSlider } = (0, use_video_controls_resize_1.useVideoControlsResize)({ allowFullscreen, playerWidth });
69
68
  const [shouldShowInitially, setInitiallyShowControls] = (0, react_1.useState)(() => {
70
69
  if (typeof initiallyShowControls === 'boolean') {
71
70
  return initiallyShowControls;
@@ -121,7 +120,17 @@ const Controls = ({ durationInFrames, hovered, isFullscreen, fps, player, showVo
121
120
  clearInterval(timeout);
122
121
  };
123
122
  }, [shouldShowInitially]);
124
- return ((0, jsx_runtime_1.jsxs)("div", { style: containerCss, children: [(0, jsx_runtime_1.jsxs)("div", { style: controlsRow, children: [(0, jsx_runtime_1.jsxs)("div", { style: leftPartStyle, children: [(0, jsx_runtime_1.jsx)("button", { ref: playButtonRef, type: "button", style: buttonStyle, onClick: player.playing ? player.pause : player.play, "aria-label": player.playing ? 'Pause video' : 'Play video', title: player.playing ? 'Pause video' : 'Play video', children: player.playing ? (0, jsx_runtime_1.jsx)(icons_1.PauseIcon, {}) : (0, jsx_runtime_1.jsx)(icons_1.PlayIcon, {}) }), 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_1.MediaVolumeSlider, {})] })) : null, (0, jsx_runtime_1.jsx)("div", { style: xSpacer }), (0, jsx_runtime_1.jsxs)("div", { style: timeLabel, children: [(0, format_time_1.formatTime)(frame / fps), " / ", (0, format_time_1.formatTime)(durationInFrames / fps)] }), (0, jsx_runtime_1.jsx)("div", { style: xSpacer })] }), (0, jsx_runtime_1.jsx)("div", { style: flex1 }), (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: buttonStyle, onClick: isFullscreen
123
+ const timeLabel = (0, react_1.useMemo)(() => {
124
+ return {
125
+ color: 'white',
126
+ fontFamily: 'sans-serif',
127
+ fontSize: 14,
128
+ maxWidth: maxTimeLabelWidth,
129
+ overflow: 'hidden',
130
+ textOverflow: 'ellipsis',
131
+ };
132
+ }, [maxTimeLabelWidth]);
133
+ return ((0, jsx_runtime_1.jsxs)("div", { style: containerCss, children: [(0, jsx_runtime_1.jsxs)("div", { style: controlsRow, children: [(0, jsx_runtime_1.jsxs)("div", { style: leftPartStyle, children: [(0, jsx_runtime_1.jsx)("button", { ref: playButtonRef, type: "button", style: buttonStyle, onClick: player.playing ? player.pause : player.play, "aria-label": player.playing ? 'Pause video' : 'Play video', title: player.playing ? 'Pause video' : 'Play video', children: player.playing ? (0, jsx_runtime_1.jsx)(icons_1.PauseIcon, {}) : (0, jsx_runtime_1.jsx)(icons_1.PlayIcon, {}) }), 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_1.MediaVolumeSlider, { displayVerticalVolumeSlider: displayVerticalVolumeSlider })] })) : null, (0, jsx_runtime_1.jsx)("div", { style: xSpacer }), (0, jsx_runtime_1.jsxs)("div", { style: timeLabel, children: [(0, format_time_1.formatTime)(frame / fps), " / ", (0, format_time_1.formatTime)(durationInFrames / fps)] }), (0, jsx_runtime_1.jsx)("div", { style: xSpacer })] }), (0, jsx_runtime_1.jsx)("div", { style: flex1 }), (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: buttonStyle, onClick: isFullscreen
125
134
  ? onExitFullscreenButtonClick
126
135
  : onFullscreenButtonClick, children: (0, jsx_runtime_1.jsx)(icons_1.FullscreenIcon, { minimized: !isFullscreen }) })) : null })] }), (0, jsx_runtime_1.jsx)("div", { style: ySpacer }), (0, jsx_runtime_1.jsx)(PlayerSeekBar_1.PlayerSeekBar, { onSeekEnd: onSeekEnd, onSeekStart: onSeekStart, durationInFrames: durationInFrames, inFrame: inFrame, outFrame: outFrame })] }));
127
136
  };
package/dist/PlayerUI.js CHANGED
@@ -43,7 +43,7 @@ if (reactVersion === '0') {
43
43
  }
44
44
  const doesReactVersionSupportSuspense = parseInt(reactVersion, 10) >= 18;
45
45
  const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps, clickToPlay, showVolumeControls, mediaVolume, mediaMuted, doubleClickToFullscreen, setMediaMuted, setMediaVolume, spaceKeyToPlayOrPause, errorFallback, playbackRate, renderLoading, renderPoster, className, moveToBeginningWhenEnded, showPosterWhenUnplayed, showPosterWhenEnded, showPosterWhenPaused, inFrame, outFrame, initiallyShowControls, }, ref) => {
46
- var _a, _b, _c, _d;
46
+ var _a, _b, _c, _d, _e;
47
47
  const config = remotion_1.Internals.useUnsafeVideoConfig();
48
48
  const video = remotion_1.Internals.useVideo();
49
49
  const container = (0, react_1.useRef)(null);
@@ -329,7 +329,7 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
329
329
  showPosterWhenEnded && player.isLastFrame && !player.isPlaying(),
330
330
  showPosterWhenUnplayed && !player.hasPlayed && !player.isPlaying(),
331
331
  ].some(Boolean);
332
- 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_1.PLAYER_CSS_CLASSNAME, children: VideoComponent ? ((0, jsx_runtime_1.jsx)(error_boundary_1.ErrorBoundary, { onError: onError, errorFallback: errorFallback, children: (0, jsx_runtime_1.jsx)(VideoComponent, { ...((_c = video === null || video === void 0 ? void 0 : video.defaultProps) !== null && _c !== void 0 ? _c : {}), ...((_d = inputProps) !== null && _d !== void 0 ? _d : {}) }) })) : null }) }), shouldShowPoster ? ((0, jsx_runtime_1.jsx)("div", { style: outer, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null, controls ? ((0, jsx_runtime_1.jsx)(PlayerControls_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 })) : null] }));
332
+ 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_1.PLAYER_CSS_CLASSNAME, children: VideoComponent ? ((0, jsx_runtime_1.jsx)(error_boundary_1.ErrorBoundary, { onError: onError, errorFallback: errorFallback, children: (0, jsx_runtime_1.jsx)(VideoComponent, { ...((_c = video === null || video === void 0 ? void 0 : video.defaultProps) !== null && _c !== void 0 ? _c : {}), ...((_d = inputProps) !== null && _d !== void 0 ? _d : {}) }) })) : null }) }), shouldShowPoster ? ((0, jsx_runtime_1.jsx)("div", { style: outer, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null, controls ? ((0, jsx_runtime_1.jsx)(PlayerControls_1.Controls, { fps: config.fps, durationInFrames: config.durationInFrames, hovered: hovered, player: player, onFullscreenButtonClick: onFullscreenButtonClick, isFullscreen: isFullscreen, allowFullscreen: allowFullscreen, showVolumeControls: showVolumeControls, onExitFullscreenButtonClick: onExitFullscreenButtonClick, spaceKeyToPlayOrPause: spaceKeyToPlayOrPause, onSeekEnd: onSeekEnd, onSeekStart: onSeekStart, inFrame: inFrame, outFrame: outFrame, initiallyShowControls: initiallyShowControls, playerWidth: (_e = canvasSize === null || canvasSize === void 0 ? void 0 : canvasSize.width) !== null && _e !== void 0 ? _e : 0 })) : null] }));
333
333
  if (is_node_1.IS_NODE && !doesReactVersionSupportSuspense) {
334
334
  return ((0, jsx_runtime_1.jsx)("div", { ref: container, style: outerStyle, className: className, children: content }));
335
335
  }
@@ -7,6 +7,9 @@ declare type ErrorPayload = {
7
7
  declare type TimeUpdateEventPayload = {
8
8
  frame: number;
9
9
  };
10
+ declare type FrameUpdateEventPayload = {
11
+ frame: number;
12
+ };
10
13
  declare type RateChangeEventPayload = {
11
14
  playbackRate: number;
12
15
  };
@@ -21,6 +24,7 @@ declare type StateEventMap = {
21
24
  ended: undefined;
22
25
  error: ErrorPayload;
23
26
  timeupdate: TimeUpdateEventPayload;
27
+ frameupdate: FrameUpdateEventPayload;
24
28
  fullscreenchange: FullscreenChangeEventPayload;
25
29
  };
26
30
  export declare type EventTypes = keyof StateEventMap;
@@ -42,6 +46,7 @@ export declare class PlayerEmitter {
42
46
  dispatchRatechange(playbackRate: number): void;
43
47
  dispatchError(error: Error): void;
44
48
  dispatchTimeUpdate(event: TimeUpdateEventPayload): void;
49
+ dispatchFrameUpdate(event: FrameUpdateEventPayload): void;
45
50
  dispatchFullscreenChangeUpdate(event: FullscreenChangeEventPayload): void;
46
51
  }
47
52
  export {};
@@ -11,6 +11,7 @@ class PlayerEmitter {
11
11
  ratechange: [],
12
12
  seeked: [],
13
13
  timeupdate: [],
14
+ frameupdate: [],
14
15
  fullscreenchange: [],
15
16
  };
16
17
  }
@@ -52,6 +53,9 @@ class PlayerEmitter {
52
53
  dispatchTimeUpdate(event) {
53
54
  this.dispatchEvent('timeupdate', event);
54
55
  }
56
+ dispatchFrameUpdate(event) {
57
+ this.dispatchEvent('frameupdate', event);
58
+ }
55
59
  dispatchFullscreenChangeUpdate(event) {
56
60
  this.dispatchEvent('fullscreenchange', event);
57
61
  }
package/dist/icons.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  export declare const ICON_SIZE = 25;
3
+ export declare const fullscreenIconSize = 16;
3
4
  export declare const PlayIcon: React.FC;
4
5
  export declare const PauseIcon: React.FC;
5
6
  export declare const FullscreenIcon: React.FC<{
package/dist/icons.js CHANGED
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.VolumeOnIcon = exports.VolumeOffIcon = exports.FullscreenIcon = exports.PauseIcon = exports.PlayIcon = exports.ICON_SIZE = void 0;
3
+ exports.VolumeOnIcon = exports.VolumeOffIcon = exports.FullscreenIcon = exports.PauseIcon = exports.PlayIcon = exports.fullscreenIconSize = exports.ICON_SIZE = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  exports.ICON_SIZE = 25;
6
- const fullscreenIconSize = 16;
6
+ exports.fullscreenIconSize = 16;
7
7
  const rotate = {
8
8
  transform: `rotate(90deg)`,
9
9
  };
@@ -21,7 +21,7 @@ const FullscreenIcon = ({ minimized }) => {
21
21
  const out = minimized ? strokeWidth / 2 : 0;
22
22
  const middleInset = minimized ? strokeWidth / 2 : strokeWidth * 1.6;
23
23
  const inset = minimized ? strokeWidth * 2 : strokeWidth * 1.6;
24
- return ((0, jsx_runtime_1.jsxs)("svg", { viewBox: `0 0 ${viewSize} ${viewSize}`, height: fullscreenIconSize, width: fullscreenIconSize, children: [(0, jsx_runtime_1.jsx)("path", { d: `
24
+ return ((0, jsx_runtime_1.jsxs)("svg", { viewBox: `0 0 ${viewSize} ${viewSize}`, height: exports.fullscreenIconSize, width: exports.fullscreenIconSize, children: [(0, jsx_runtime_1.jsx)("path", { d: `
25
25
  M ${out} ${inset}
26
26
  L ${middleInset} ${middleInset}
27
27
  L ${inset} ${out}
@@ -1,2 +1 @@
1
1
  export declare const PLAYER_CSS_CLASSNAME = "__remotion-player";
2
- export declare const VOLUME_SLIDER_INPUT_CSS_CLASSNAME: string;
@@ -1,5 +1,4 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.VOLUME_SLIDER_INPUT_CSS_CLASSNAME = exports.PLAYER_CSS_CLASSNAME = void 0;
3
+ exports.PLAYER_CSS_CLASSNAME = void 0;
4
4
  exports.PLAYER_CSS_CLASSNAME = '__remotion-player';
5
- exports.VOLUME_SLIDER_INPUT_CSS_CLASSNAME = exports.PLAYER_CSS_CLASSNAME.concat('_volume-slider-input');
@@ -85,5 +85,8 @@ const usePlayback = ({ loop, playbackRate, moveToBeginningWhenEnded, inFrame, ou
85
85
  }, 250);
86
86
  return () => clearInterval(interval);
87
87
  }, [emitter]);
88
+ (0, react_1.useEffect)(() => {
89
+ emitter.dispatchFrameUpdate({ frame });
90
+ }, [emitter, frame]);
88
91
  };
89
92
  exports.usePlayback = usePlayback;
@@ -0,0 +1,7 @@
1
+ export declare const useVideoControlsResize: ({ allowFullscreen: allowFullScreen, playerWidth, }: {
2
+ allowFullscreen: boolean;
3
+ playerWidth: number;
4
+ }) => {
5
+ maxTimeLabelWidth: number;
6
+ displayVerticalVolumeSlider: boolean;
7
+ };
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useVideoControlsResize = void 0;
4
+ const react_1 = require("react");
5
+ const icons_1 = require("./icons");
6
+ const MediaVolumeSlider_1 = require("./MediaVolumeSlider");
7
+ const PlayerControls_1 = require("./PlayerControls");
8
+ const useVideoControlsResize = ({ allowFullscreen: allowFullScreen, playerWidth, }) => {
9
+ const resizeInfo = (0, react_1.useMemo)(() => {
10
+ const playPauseIconSize = icons_1.ICON_SIZE;
11
+ const volumeIconSize = icons_1.ICON_SIZE;
12
+ const _fullscreenIconSize = allowFullScreen ? icons_1.fullscreenIconSize : 0;
13
+ const elementsSize = volumeIconSize +
14
+ playPauseIconSize +
15
+ _fullscreenIconSize +
16
+ PlayerControls_1.X_PADDING * 2 +
17
+ PlayerControls_1.X_SPACER * 2;
18
+ const maxTimeLabelWidth = playerWidth - elementsSize;
19
+ const maxTimeLabelWidthWithoutNegativeValue = Math.max(maxTimeLabelWidth, 0);
20
+ const availableTimeLabelWidthIfVolumeOpen = maxTimeLabelWidthWithoutNegativeValue - MediaVolumeSlider_1.VOLUME_SLIDER_WIDTH;
21
+ // If max label width is lower than the volume width
22
+ // then it means we need to take it's width as the max label width
23
+ // otherwise we took the available width when volume open
24
+ const computedLabelWidth = availableTimeLabelWidthIfVolumeOpen < MediaVolumeSlider_1.VOLUME_SLIDER_WIDTH
25
+ ? maxTimeLabelWidthWithoutNegativeValue
26
+ : availableTimeLabelWidthIfVolumeOpen;
27
+ const minWidthForHorizontalDisplay = computedLabelWidth + elementsSize + MediaVolumeSlider_1.VOLUME_SLIDER_WIDTH;
28
+ const displayVerticalVolumeSlider = playerWidth < minWidthForHorizontalDisplay;
29
+ return {
30
+ maxTimeLabelWidth: maxTimeLabelWidthWithoutNegativeValue,
31
+ displayVerticalVolumeSlider,
32
+ };
33
+ }, [allowFullScreen, playerWidth]);
34
+ return resizeInfo;
35
+ };
36
+ exports.useVideoControlsResize = useVideoControlsResize;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remotion/player",
3
- "version": "3.2.24",
3
+ "version": "3.2.27",
4
4
  "description": "Remotion Player",
5
5
  "main": "dist/index.js",
6
6
  "sideEffects": false,
@@ -28,7 +28,7 @@
28
28
  ],
29
29
  "license": "SEE LICENSE IN LICENSE.md",
30
30
  "dependencies": {
31
- "remotion": "3.2.24"
31
+ "remotion": "3.2.27"
32
32
  },
33
33
  "peerDependencies": {
34
34
  "react": ">=16.8.0",
@@ -63,5 +63,5 @@
63
63
  "publishConfig": {
64
64
  "access": "public"
65
65
  },
66
- "gitHead": "1f11ef8d122eadb6d6f6aa0570ffc4936d43a886"
66
+ "gitHead": "662c69bcb2fee4d51553b2f8e61635fb4d6688b1"
67
67
  }