@remotion/player 4.0.0-alpha.4 → 4.0.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.
Files changed (216) hide show
  1. package/LICENSE.md +8 -8
  2. package/README.md +1 -1
  3. package/dist/cjs/MediaVolumeSlider.d.ts +5 -0
  4. package/dist/cjs/MediaVolumeSlider.js +142 -0
  5. package/dist/cjs/PlaybackrateControl.d.ts +5 -0
  6. package/dist/cjs/PlaybackrateControl.js +136 -0
  7. package/dist/cjs/Player.d.ts +52 -0
  8. package/dist/{Player.js → cjs/Player.js} +53 -83
  9. package/dist/{PlayerControls.d.ts → cjs/PlayerControls.d.ts} +18 -2
  10. package/dist/cjs/PlayerControls.js +171 -0
  11. package/dist/{PlayerSeekBar.d.ts → cjs/PlayerSeekBar.d.ts} +4 -0
  12. package/dist/{PlayerSeekBar.js → cjs/PlayerSeekBar.js} +41 -17
  13. package/dist/cjs/PlayerUI.d.ts +40 -0
  14. package/dist/{PlayerUI.js → cjs/PlayerUI.js} +115 -88
  15. package/dist/cjs/SharedPlayerContext.d.ts +15 -0
  16. package/dist/cjs/SharedPlayerContext.js +75 -0
  17. package/dist/cjs/Thumbnail.d.ts +24 -0
  18. package/dist/cjs/Thumbnail.js +46 -0
  19. package/dist/cjs/ThumbnailUI.d.ts +11 -0
  20. package/dist/cjs/ThumbnailUI.js +107 -0
  21. package/dist/{calculate-next-frame.d.ts → cjs/calculate-next-frame.d.ts} +0 -0
  22. package/dist/{calculate-next-frame.js → cjs/calculate-next-frame.js} +0 -0
  23. package/dist/cjs/calculate-scale.d.ts +39 -0
  24. package/dist/cjs/calculate-scale.js +85 -0
  25. package/dist/cjs/emitter-context.d.ts +4 -0
  26. package/dist/{emitter-context.js → cjs/emitter-context.js} +2 -1
  27. package/dist/{error-boundary.d.ts → cjs/error-boundary.d.ts} +0 -0
  28. package/dist/{error-boundary.js → cjs/error-boundary.js} +0 -0
  29. package/dist/cjs/event-emitter.d.ts +81 -0
  30. package/dist/cjs/event-emitter.js +103 -0
  31. package/dist/{format-time.d.ts → cjs/format-time.d.ts} +0 -0
  32. package/dist/{format-time.js → cjs/format-time.js} +0 -0
  33. package/dist/{icons.d.ts → cjs/icons.d.ts} +5 -1
  34. package/dist/{icons.js → cjs/icons.js} +11 -7
  35. package/dist/{index.d.ts → cjs/index.d.ts} +22 -12
  36. package/dist/cjs/index.js +25 -0
  37. package/dist/cjs/is-backgrounded.d.ts +2 -0
  38. package/dist/cjs/is-backgrounded.js +24 -0
  39. package/dist/{player-css-classname.d.ts → cjs/player-css-classname.d.ts} +0 -1
  40. package/dist/cjs/player-css-classname.js +4 -0
  41. package/dist/{player-methods.d.ts → cjs/player-methods.d.ts} +8 -4
  42. package/dist/{player-methods.js → cjs/player-methods.js} +0 -0
  43. package/dist/{test → cjs/test}/index.test.d.ts +0 -0
  44. package/dist/cjs/test/index.test.js +9 -0
  45. package/dist/{test → cjs/test}/test-utils.d.ts +0 -0
  46. package/dist/{test → cjs/test}/test-utils.js +0 -0
  47. package/dist/{test/validate-prop.test.d.ts → cjs/test/validate-in-out-frames.test.d.ts} +0 -0
  48. package/dist/cjs/test/validate-in-out-frames.test.js +56 -0
  49. package/dist/cjs/test/validate-prop.test.d.ts +1 -0
  50. package/dist/cjs/test/validate-prop.test.js +131 -0
  51. package/dist/{use-hover-state.d.ts → cjs/use-hover-state.d.ts} +0 -0
  52. package/dist/{use-hover-state.js → cjs/use-hover-state.js} +0 -0
  53. package/dist/{use-playback.d.ts → cjs/use-playback.d.ts} +0 -0
  54. package/dist/{use-playback.js → cjs/use-playback.js} +49 -9
  55. package/dist/{use-player.d.ts → cjs/use-player.d.ts} +3 -1
  56. package/dist/{use-player.js → cjs/use-player.js} +15 -8
  57. package/dist/cjs/use-thumbnail.d.ts +6 -0
  58. package/dist/cjs/use-thumbnail.js +18 -0
  59. package/dist/cjs/use-video-controls-resize.d.ts +11 -0
  60. package/dist/cjs/use-video-controls-resize.js +39 -0
  61. package/dist/{utils → cjs/utils}/calculate-player-size.d.ts +1 -1
  62. package/dist/{utils → cjs/utils}/calculate-player-size.js +9 -10
  63. package/dist/{utils → cjs/utils}/cancellable-promise.d.ts +0 -0
  64. package/dist/{utils → cjs/utils}/cancellable-promise.js +0 -0
  65. package/dist/{utils → cjs/utils}/delay.d.ts +0 -0
  66. package/dist/{utils → cjs/utils}/delay.js +0 -0
  67. package/dist/{utils → cjs/utils}/is-node.d.ts +0 -0
  68. package/dist/{utils → cjs/utils}/is-node.js +0 -0
  69. package/dist/cjs/utils/preview-size.d.ts +8 -0
  70. package/dist/{utils → cjs/utils}/preview-size.js +0 -0
  71. package/dist/cjs/utils/props-if-has-props.d.ts +10 -0
  72. package/dist/cjs/utils/props-if-has-props.js +2 -0
  73. package/dist/{utils → cjs/utils}/use-cancellable-promises.d.ts +1 -1
  74. package/dist/{utils → cjs/utils}/use-cancellable-promises.js +0 -0
  75. package/dist/{utils → cjs/utils}/use-click-prevention-on-double-click.d.ts +0 -0
  76. package/dist/{utils → cjs/utils}/use-click-prevention-on-double-click.js +5 -5
  77. package/dist/cjs/utils/use-component-visible.d.ts +6 -0
  78. package/dist/cjs/utils/use-component-visible.js +21 -0
  79. package/dist/{utils → cjs/utils}/use-element-size.d.ts +1 -0
  80. package/dist/{utils → cjs/utils}/use-element-size.js +24 -12
  81. package/dist/cjs/utils/validate-in-out-frame.d.ts +6 -0
  82. package/dist/cjs/utils/validate-in-out-frame.js +54 -0
  83. package/dist/cjs/utils/validate-initial-frame.d.ts +4 -0
  84. package/dist/cjs/utils/validate-initial-frame.js +27 -0
  85. package/dist/{utils → cjs/utils}/validate-playbackrate.d.ts +0 -0
  86. package/dist/{utils → cjs/utils}/validate-playbackrate.js +0 -0
  87. package/dist/{volume-persistance.d.ts → cjs/volume-persistance.d.ts} +0 -0
  88. package/dist/{volume-persistance.js → cjs/volume-persistance.js} +0 -0
  89. package/dist/esm/MediaVolumeSlider.d.ts +5 -0
  90. package/dist/esm/PlaybackrateControl.d.ts +5 -0
  91. package/dist/esm/Player.d.ts +52 -0
  92. package/dist/esm/PlayerControls.d.ts +41 -0
  93. package/dist/esm/PlayerSeekBar.d.ts +8 -0
  94. package/dist/esm/PlayerUI.d.ts +40 -0
  95. package/dist/esm/SharedPlayerContext.d.ts +15 -0
  96. package/dist/esm/Thumbnail.d.ts +24 -0
  97. package/dist/esm/ThumbnailUI.d.ts +11 -0
  98. package/dist/esm/calculate-next-frame.d.ts +14 -0
  99. package/dist/esm/calculate-scale.d.ts +39 -0
  100. package/dist/esm/emitter-context.d.ts +4 -0
  101. package/dist/esm/error-boundary.d.ts +19 -0
  102. package/dist/esm/event-emitter.d.ts +81 -0
  103. package/dist/esm/format-time.d.ts +1 -0
  104. package/dist/esm/icons.d.ts +13 -0
  105. package/dist/esm/index.d.ts +61 -0
  106. package/dist/esm/index.mjs +2112 -0
  107. package/dist/esm/is-backgrounded.d.ts +2 -0
  108. package/dist/esm/player-css-classname.d.ts +1 -0
  109. package/dist/esm/player-methods.d.ts +24 -0
  110. package/dist/esm/test/index.test.d.ts +1 -0
  111. package/dist/esm/test/test-utils.d.ts +6 -0
  112. package/dist/esm/test/validate-in-out-frames.test.d.ts +1 -0
  113. package/dist/esm/test/validate-prop.test.d.ts +1 -0
  114. package/dist/esm/use-hover-state.d.ts +1 -0
  115. package/dist/esm/use-playback.d.ts +7 -0
  116. package/dist/esm/use-player.d.ts +19 -0
  117. package/dist/esm/use-thumbnail.d.ts +6 -0
  118. package/dist/esm/use-video-controls-resize.d.ts +11 -0
  119. package/dist/esm/utils/calculate-player-size.d.ts +9 -0
  120. package/dist/esm/utils/cancellable-promise.d.ts +5 -0
  121. package/dist/esm/utils/delay.d.ts +1 -0
  122. package/dist/esm/utils/is-node.d.ts +1 -0
  123. package/dist/esm/utils/preview-size.d.ts +8 -0
  124. package/dist/esm/utils/props-if-has-props.d.ts +10 -0
  125. package/dist/esm/utils/use-cancellable-promises.d.ts +7 -0
  126. package/dist/esm/utils/use-click-prevention-on-double-click.d.ts +3 -0
  127. package/dist/esm/utils/use-component-visible.d.ts +5 -0
  128. package/dist/esm/utils/use-element-size.d.ts +16 -0
  129. package/dist/esm/utils/validate-in-out-frame.d.ts +6 -0
  130. package/dist/esm/utils/validate-initial-frame.d.ts +4 -0
  131. package/dist/esm/utils/validate-playbackrate.d.ts +1 -0
  132. package/dist/esm/volume-persistance.d.ts +2 -0
  133. package/dist/tsconfig-esm.tsbuildinfo +1 -0
  134. package/dist/tsconfig.tsbuildinfo +1 -0
  135. package/package.json +80 -66
  136. package/dist/MediaVolumeSlider.d.ts +0 -2
  137. package/dist/MediaVolumeSlider.d.ts.map +0 -1
  138. package/dist/MediaVolumeSlider.js +0 -93
  139. package/dist/MediaVolumeSlider.js.map +0 -1
  140. package/dist/Player.d.ts +0 -41
  141. package/dist/Player.d.ts.map +0 -1
  142. package/dist/Player.js.map +0 -1
  143. package/dist/PlayerControls.d.ts.map +0 -1
  144. package/dist/PlayerControls.js +0 -95
  145. package/dist/PlayerControls.js.map +0 -1
  146. package/dist/PlayerSeekBar.d.ts.map +0 -1
  147. package/dist/PlayerSeekBar.js.map +0 -1
  148. package/dist/PlayerUI.d.ts +0 -31
  149. package/dist/PlayerUI.d.ts.map +0 -1
  150. package/dist/PlayerUI.js.map +0 -1
  151. package/dist/calculate-next-frame.d.ts.map +0 -1
  152. package/dist/calculate-next-frame.js.map +0 -1
  153. package/dist/calculate-scale.d.ts +0 -14
  154. package/dist/calculate-scale.d.ts.map +0 -1
  155. package/dist/calculate-scale.js +0 -24
  156. package/dist/calculate-scale.js.map +0 -1
  157. package/dist/emitter-context.d.ts +0 -3
  158. package/dist/emitter-context.d.ts.map +0 -1
  159. package/dist/emitter-context.js.map +0 -1
  160. package/dist/error-boundary.d.ts.map +0 -1
  161. package/dist/error-boundary.js.map +0 -1
  162. package/dist/event-emitter.d.ts +0 -42
  163. package/dist/event-emitter.d.ts.map +0 -1
  164. package/dist/event-emitter.js +0 -55
  165. package/dist/event-emitter.js.map +0 -1
  166. package/dist/format-time.d.ts.map +0 -1
  167. package/dist/format-time.js.map +0 -1
  168. package/dist/icons.d.ts.map +0 -1
  169. package/dist/icons.js.map +0 -1
  170. package/dist/index.d.ts.map +0 -1
  171. package/dist/index.js +0 -22
  172. package/dist/index.js.map +0 -1
  173. package/dist/player-css-classname.d.ts.map +0 -1
  174. package/dist/player-css-classname.js +0 -5
  175. package/dist/player-css-classname.js.map +0 -1
  176. package/dist/player-methods.d.ts.map +0 -1
  177. package/dist/player-methods.js.map +0 -1
  178. package/dist/test/index.test.d.ts.map +0 -1
  179. package/dist/test/index.test.js +0 -8
  180. package/dist/test/index.test.js.map +0 -1
  181. package/dist/test/test-utils.d.ts.map +0 -1
  182. package/dist/test/test-utils.js.map +0 -1
  183. package/dist/test/validate-prop.test.d.ts.map +0 -1
  184. package/dist/test/validate-prop.test.js +0 -130
  185. package/dist/test/validate-prop.test.js.map +0 -1
  186. package/dist/use-hover-state.d.ts.map +0 -1
  187. package/dist/use-hover-state.js.map +0 -1
  188. package/dist/use-playback.d.ts.map +0 -1
  189. package/dist/use-playback.js.map +0 -1
  190. package/dist/use-player.d.ts.map +0 -1
  191. package/dist/use-player.js.map +0 -1
  192. package/dist/utils/browser-supports-fullscreen.d.ts +0 -12
  193. package/dist/utils/browser-supports-fullscreen.d.ts.map +0 -1
  194. package/dist/utils/browser-supports-fullscreen.js +0 -6
  195. package/dist/utils/browser-supports-fullscreen.js.map +0 -1
  196. package/dist/utils/calculate-player-size.d.ts.map +0 -1
  197. package/dist/utils/calculate-player-size.js.map +0 -1
  198. package/dist/utils/cancellable-promise.d.ts.map +0 -1
  199. package/dist/utils/cancellable-promise.js.map +0 -1
  200. package/dist/utils/delay.d.ts.map +0 -1
  201. package/dist/utils/delay.js.map +0 -1
  202. package/dist/utils/is-node.d.ts.map +0 -1
  203. package/dist/utils/is-node.js.map +0 -1
  204. package/dist/utils/preview-size.d.ts +0 -1
  205. package/dist/utils/preview-size.d.ts.map +0 -1
  206. package/dist/utils/preview-size.js.map +0 -1
  207. package/dist/utils/use-cancellable-promises.d.ts.map +0 -1
  208. package/dist/utils/use-cancellable-promises.js.map +0 -1
  209. package/dist/utils/use-click-prevention-on-double-click.d.ts.map +0 -1
  210. package/dist/utils/use-click-prevention-on-double-click.js.map +0 -1
  211. package/dist/utils/use-element-size.d.ts.map +0 -1
  212. package/dist/utils/use-element-size.js.map +0 -1
  213. package/dist/utils/validate-playbackrate.d.ts.map +0 -1
  214. package/dist/utils/validate-playbackrate.js.map +0 -1
  215. package/dist/volume-persistance.d.ts.map +0 -1
  216. package/dist/volume-persistance.js.map +0 -1
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Controls = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const remotion_1 = require("remotion");
7
+ const format_time_js_1 = require("./format-time.js");
8
+ const icons_js_1 = require("./icons.js");
9
+ const MediaVolumeSlider_js_1 = require("./MediaVolumeSlider.js");
10
+ const PlaybackrateControl_js_1 = require("./PlaybackrateControl.js");
11
+ const PlayerSeekBar_js_1 = require("./PlayerSeekBar.js");
12
+ const use_video_controls_resize_js_1 = require("./use-video-controls-resize.js");
13
+ const gradientSteps = [
14
+ 0, 0.013, 0.049, 0.104, 0.175, 0.259, 0.352, 0.45, 0.55, 0.648, 0.741, 0.825,
15
+ 0.896, 0.951, 0.987,
16
+ ];
17
+ const gradientOpacities = [
18
+ 0, 8.1, 15.5, 22.5, 29, 35.3, 41.2, 47.1, 52.9, 58.8, 64.7, 71, 77.5, 84.5,
19
+ 91.9,
20
+ ];
21
+ const globalGradientOpacity = 1 / 0.7;
22
+ const containerStyle = {
23
+ boxSizing: 'border-box',
24
+ position: 'absolute',
25
+ bottom: 0,
26
+ width: '100%',
27
+ paddingTop: 40,
28
+ paddingBottom: 10,
29
+ backgroundImage: `linear-gradient(to bottom,${gradientSteps
30
+ .map((g, i) => {
31
+ return `hsla(0, 0%, 0%, ${g}) ${gradientOpacities[i] * globalGradientOpacity}%`;
32
+ })
33
+ .join(', ')}, hsl(0, 0%, 0%) 100%)`,
34
+ backgroundSize: 'auto 145px',
35
+ display: 'flex',
36
+ paddingRight: use_video_controls_resize_js_1.X_PADDING,
37
+ paddingLeft: use_video_controls_resize_js_1.X_PADDING,
38
+ flexDirection: 'column',
39
+ transition: 'opacity 0.3s',
40
+ };
41
+ const buttonStyle = {
42
+ appearance: 'none',
43
+ backgroundColor: 'transparent',
44
+ border: 'none',
45
+ cursor: 'pointer',
46
+ paddingLeft: 0,
47
+ paddingRight: 0,
48
+ paddingTop: 6,
49
+ paddingBottom: 6,
50
+ height: 37,
51
+ display: 'inline',
52
+ marginBottom: 0,
53
+ marginTop: 0,
54
+ };
55
+ const controlsRow = {
56
+ display: 'flex',
57
+ flexDirection: 'row',
58
+ width: '100%',
59
+ alignItems: 'center',
60
+ justifyContent: 'center',
61
+ userSelect: 'none',
62
+ };
63
+ const leftPartStyle = {
64
+ display: 'flex',
65
+ flexDirection: 'row',
66
+ userSelect: 'none',
67
+ alignItems: 'center',
68
+ };
69
+ const xSpacer = {
70
+ width: 12,
71
+ };
72
+ const ySpacer = {
73
+ height: 8,
74
+ };
75
+ const flex1 = {
76
+ flex: 1,
77
+ };
78
+ const fullscreen = {};
79
+ const PlayPauseButton = ({ playing }) => playing ? (0, jsx_runtime_1.jsx)(icons_js_1.PauseIcon, {}) : (0, jsx_runtime_1.jsx)(icons_js_1.PlayIcon, {});
80
+ const Controls = ({ durationInFrames, hovered, isFullscreen, fps, player, showVolumeControls, onFullscreenButtonClick, allowFullscreen, onExitFullscreenButtonClick, spaceKeyToPlayOrPause, onSeekEnd, onSeekStart, inFrame, outFrame, initiallyShowControls, playerWidth, renderPlayPauseButton, renderFullscreenButton, alwaysShowControls, showPlaybackRateControl, }) => {
81
+ const playButtonRef = (0, react_1.useRef)(null);
82
+ const frame = remotion_1.Internals.Timeline.useTimelinePosition();
83
+ const [supportsFullscreen, setSupportsFullscreen] = (0, react_1.useState)(false);
84
+ const { maxTimeLabelWidth, displayVerticalVolumeSlider } = (0, use_video_controls_resize_js_1.useVideoControlsResize)({ allowFullscreen, playerWidth });
85
+ const [shouldShowInitially, setInitiallyShowControls] = (0, react_1.useState)(() => {
86
+ if (typeof initiallyShowControls === 'boolean') {
87
+ return initiallyShowControls;
88
+ }
89
+ if (typeof initiallyShowControls === 'number') {
90
+ if (initiallyShowControls % 1 !== 0) {
91
+ throw new Error('initiallyShowControls must be an integer or a boolean');
92
+ }
93
+ if (Number.isNaN(initiallyShowControls)) {
94
+ throw new Error('initiallyShowControls must not be NaN');
95
+ }
96
+ if (!Number.isFinite(initiallyShowControls)) {
97
+ throw new Error('initiallyShowControls must be finite');
98
+ }
99
+ if (initiallyShowControls <= 0) {
100
+ throw new Error('initiallyShowControls must be a positive integer');
101
+ }
102
+ return initiallyShowControls;
103
+ }
104
+ throw new TypeError('initiallyShowControls must be a number or a boolean');
105
+ });
106
+ const containerCss = (0, react_1.useMemo)(() => {
107
+ // Hide if playing and mouse outside
108
+ const shouldShow = hovered || !player.playing || shouldShowInitially || alwaysShowControls;
109
+ return {
110
+ ...containerStyle,
111
+ opacity: Number(shouldShow),
112
+ };
113
+ }, [hovered, shouldShowInitially, player.playing, alwaysShowControls]);
114
+ (0, react_1.useEffect)(() => {
115
+ if (playButtonRef.current && spaceKeyToPlayOrPause) {
116
+ // This switches focus to play button when player.playing flag changes
117
+ playButtonRef.current.focus({
118
+ preventScroll: true,
119
+ });
120
+ }
121
+ }, [player.playing, spaceKeyToPlayOrPause]);
122
+ (0, react_1.useEffect)(() => {
123
+ var _a;
124
+ // Must be handled client-side to avoid SSR hydration mismatch
125
+ setSupportsFullscreen((_a = (typeof document !== 'undefined' &&
126
+ (document.fullscreenEnabled || document.webkitFullscreenEnabled))) !== null && _a !== void 0 ? _a : false);
127
+ }, []);
128
+ (0, react_1.useEffect)(() => {
129
+ if (shouldShowInitially === false) {
130
+ return;
131
+ }
132
+ const time = shouldShowInitially === true ? 2000 : shouldShowInitially;
133
+ const timeout = setTimeout(() => {
134
+ setInitiallyShowControls(false);
135
+ }, time);
136
+ return () => {
137
+ clearInterval(timeout);
138
+ };
139
+ }, [shouldShowInitially]);
140
+ const timeLabel = (0, react_1.useMemo)(() => {
141
+ return {
142
+ color: 'white',
143
+ fontFamily: 'sans-serif',
144
+ fontSize: 14,
145
+ maxWidth: maxTimeLabelWidth === null ? undefined : maxTimeLabelWidth,
146
+ overflow: 'hidden',
147
+ textOverflow: 'ellipsis',
148
+ };
149
+ }, [maxTimeLabelWidth]);
150
+ const playbackRates = (0, react_1.useMemo)(() => {
151
+ if (showPlaybackRateControl === true) {
152
+ return [0.5, 0.8, 1, 1.2, 1.5, 1.8, 2, 2.5, 3];
153
+ }
154
+ if (Array.isArray(showPlaybackRateControl)) {
155
+ for (const rate of showPlaybackRateControl) {
156
+ if (typeof rate !== 'number') {
157
+ throw new Error('Every item in showPlaybackRateControl must be a number');
158
+ }
159
+ if (rate <= 0) {
160
+ throw new Error('Every item in showPlaybackRateControl must be positive');
161
+ }
162
+ }
163
+ return showPlaybackRateControl;
164
+ }
165
+ return null;
166
+ }, [showPlaybackRateControl]);
167
+ 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: renderPlayPauseButton === null ? ((0, jsx_runtime_1.jsx)(PlayPauseButton, { playing: player.playing })) : (renderPlayPauseButton({ playing: player.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, { displayVerticalVolumeSlider: displayVerticalVolumeSlider })] })) : null, (0, jsx_runtime_1.jsx)("div", { style: xSpacer }), (0, jsx_runtime_1.jsxs)("div", { style: timeLabel, children: [(0, format_time_js_1.formatTime)(frame / fps), " / ", (0, format_time_js_1.formatTime)(durationInFrames / fps)] }), (0, jsx_runtime_1.jsx)("div", { style: xSpacer })] }), (0, jsx_runtime_1.jsx)("div", { style: flex1 }), playbackRates && (0, jsx_runtime_1.jsx)(PlaybackrateControl_js_1.PlaybackrateControl, { 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: buttonStyle, onClick: isFullscreen
168
+ ? onExitFullscreenButtonClick
169
+ : 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 })] }));
170
+ };
171
+ exports.Controls = Controls;
@@ -1,4 +1,8 @@
1
1
  /// <reference types="react" />
2
2
  export declare const PlayerSeekBar: React.FC<{
3
3
  durationInFrames: number;
4
+ onSeekStart: () => void;
5
+ onSeekEnd: () => void;
6
+ inFrame: number | null;
7
+ outFrame: number | null;
4
8
  }>;
@@ -4,9 +4,9 @@ exports.PlayerSeekBar = 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
- const use_hover_state_1 = require("./use-hover-state");
8
- const use_player_1 = require("./use-player");
9
- const use_element_size_1 = require("./utils/use-element-size");
7
+ const use_hover_state_js_1 = require("./use-hover-state.js");
8
+ const use_player_js_1 = require("./use-player.js");
9
+ const use_element_size_js_1 = require("./utils/use-element-size.js");
10
10
  const getFrameFromX = (clientX, durationInFrames, width) => {
11
11
  var _a;
12
12
  const pos = clientX;
@@ -30,18 +30,25 @@ const containerStyle = {
30
30
  };
31
31
  const barBackground = {
32
32
  height: BAR_HEIGHT,
33
- backgroundColor: 'rgba(255, 255, 255, 0.5)',
33
+ backgroundColor: 'rgba(255, 255, 255, 0.25)',
34
34
  width: '100%',
35
35
  borderRadius: BAR_HEIGHT / 2,
36
36
  };
37
- const PlayerSeekBar = ({ durationInFrames }) => {
37
+ const findBodyInWhichDivIsLocated = (div) => {
38
+ let current = div;
39
+ while (current.parentElement) {
40
+ current = current.parentElement;
41
+ }
42
+ return current;
43
+ };
44
+ const PlayerSeekBar = ({ durationInFrames, onSeekEnd, onSeekStart, inFrame, outFrame }) => {
38
45
  const containerRef = (0, react_1.useRef)(null);
39
- const barHovered = (0, use_hover_state_1.useHoverState)(containerRef);
40
- const size = (0, use_element_size_1.useElementSize)(containerRef, {
46
+ const barHovered = (0, use_hover_state_js_1.useHoverState)(containerRef);
47
+ const size = (0, use_element_size_js_1.useElementSize)(containerRef, {
41
48
  triggerOnWindowResize: true,
42
49
  shouldApplyCssTransforms: true,
43
50
  });
44
- const { seek, play, pause, playing } = (0, use_player_1.usePlayer)();
51
+ const { seek, play, pause, playing } = (0, use_player_js_1.usePlayer)();
45
52
  const frame = remotion_1.Internals.Timeline.useTimelinePosition();
46
53
  const [dragging, setDragging] = (0, react_1.useState)({
47
54
  dragging: false,
@@ -57,7 +64,8 @@ const PlayerSeekBar = ({ durationInFrames }) => {
57
64
  dragging: true,
58
65
  wasPlaying: playing,
59
66
  });
60
- }, [size, durationInFrames, pause, seek, playing]);
67
+ onSeekStart();
68
+ }, [size, durationInFrames, pause, seek, playing, onSeekStart]);
61
69
  const onPointerMove = (0, react_1.useCallback)((e) => {
62
70
  var _a;
63
71
  if (!size) {
@@ -82,16 +90,18 @@ const PlayerSeekBar = ({ durationInFrames }) => {
82
90
  else {
83
91
  pause();
84
92
  }
85
- }, [dragging, pause, play]);
93
+ onSeekEnd();
94
+ }, [dragging, onSeekEnd, pause, play]);
86
95
  (0, react_1.useEffect)(() => {
87
96
  if (!dragging.dragging) {
88
97
  return;
89
98
  }
90
- window.addEventListener('pointermove', onPointerMove);
91
- window.addEventListener('pointerup', onPointerUp);
99
+ const body = findBodyInWhichDivIsLocated(containerRef.current);
100
+ body.addEventListener('pointermove', onPointerMove);
101
+ body.addEventListener('pointerup', onPointerUp);
92
102
  return () => {
93
- window.removeEventListener('pointermove', onPointerMove);
94
- window.removeEventListener('pointerup', onPointerUp);
103
+ body.removeEventListener('pointermove', onPointerMove);
104
+ body.removeEventListener('pointerup', onPointerUp);
95
105
  };
96
106
  }, [dragging.dragging, onPointerMove, onPointerUp]);
97
107
  const knobStyle = (0, react_1.useMemo)(() => {
@@ -113,10 +123,24 @@ const PlayerSeekBar = ({ durationInFrames }) => {
113
123
  return {
114
124
  height: BAR_HEIGHT,
115
125
  backgroundColor: 'rgba(255, 255, 255, 1)',
116
- width: (frame / (durationInFrames - 1)) * 100 + '%',
126
+ width: ((frame - (inFrame !== null && inFrame !== void 0 ? inFrame : 0)) / (durationInFrames - 1)) * 100 + '%',
127
+ marginLeft: ((inFrame !== null && inFrame !== void 0 ? inFrame : 0) / (durationInFrames - 1)) * 100 + '%',
128
+ borderRadius: BAR_HEIGHT / 2,
129
+ };
130
+ }, [durationInFrames, frame, inFrame]);
131
+ const active = (0, react_1.useMemo)(() => {
132
+ return {
133
+ height: BAR_HEIGHT,
134
+ backgroundColor: 'rgba(255, 255, 255, 0.25)',
135
+ width: (((outFrame !== null && outFrame !== void 0 ? outFrame : durationInFrames - 1) - (inFrame !== null && inFrame !== void 0 ? inFrame : 0)) /
136
+ (durationInFrames - 1)) *
137
+ 100 +
138
+ '%',
139
+ marginLeft: ((inFrame !== null && inFrame !== void 0 ? inFrame : 0) / (durationInFrames - 1)) * 100 + '%',
117
140
  borderRadius: BAR_HEIGHT / 2,
141
+ position: 'absolute',
118
142
  };
119
- }, [durationInFrames, frame]);
120
- return ((0, jsx_runtime_1.jsxs)("div", { ref: containerRef, onPointerDown: onPointerDown, style: containerStyle, children: [(0, jsx_runtime_1.jsx)("div", { style: barBackground, children: (0, jsx_runtime_1.jsx)("div", { style: fillStyle }) }), (0, jsx_runtime_1.jsx)("div", { style: knobStyle })] }));
143
+ }, [durationInFrames, inFrame, outFrame]);
144
+ return ((0, jsx_runtime_1.jsxs)("div", { ref: containerRef, onPointerDown: onPointerDown, style: containerStyle, children: [(0, jsx_runtime_1.jsxs)("div", { style: barBackground, children: [(0, jsx_runtime_1.jsx)("div", { style: active }), (0, jsx_runtime_1.jsx)("div", { style: fillStyle })] }), (0, jsx_runtime_1.jsx)("div", { style: knobStyle })] }));
121
145
  };
122
146
  exports.PlayerSeekBar = PlayerSeekBar;
@@ -0,0 +1,40 @@
1
+ import React from 'react';
2
+ import type { PlayerRef } from './player-methods.js';
3
+ import type { RenderFullscreenButton, RenderPlayPauseButton } from './PlayerControls.js';
4
+ export declare type ErrorFallback = (info: {
5
+ error: Error;
6
+ }) => React.ReactNode;
7
+ export declare type RenderLoading = (canvas: {
8
+ height: number;
9
+ width: number;
10
+ }) => React.ReactNode;
11
+ export declare type RenderPoster = RenderLoading;
12
+ declare const _default: React.ForwardRefExoticComponent<{
13
+ controls: boolean;
14
+ loop: boolean;
15
+ autoPlay: boolean;
16
+ allowFullscreen: boolean;
17
+ inputProps: Record<string, unknown>;
18
+ showVolumeControls: boolean;
19
+ style?: React.CSSProperties | undefined;
20
+ clickToPlay: boolean;
21
+ doubleClickToFullscreen: boolean;
22
+ spaceKeyToPlayOrPause: boolean;
23
+ errorFallback: ErrorFallback;
24
+ playbackRate: number;
25
+ renderLoading: RenderLoading | undefined;
26
+ renderPoster: RenderLoading | undefined;
27
+ className: string | undefined;
28
+ moveToBeginningWhenEnded: boolean;
29
+ showPosterWhenPaused: boolean;
30
+ showPosterWhenEnded: boolean;
31
+ showPosterWhenUnplayed: boolean;
32
+ inFrame: number | null;
33
+ outFrame: number | null;
34
+ initiallyShowControls: number | boolean;
35
+ renderPlayPauseButton: RenderPlayPauseButton | null;
36
+ renderFullscreen: RenderFullscreenButton | null;
37
+ alwaysShowControls: boolean;
38
+ showPlaybackRateControl: boolean | number[];
39
+ } & React.RefAttributes<PlayerRef>>;
40
+ export default _default;
@@ -26,43 +26,43 @@ Object.defineProperty(exports, "__esModule", { value: true });
26
26
  const jsx_runtime_1 = require("react/jsx-runtime");
27
27
  const react_1 = __importStar(require("react"));
28
28
  const remotion_1 = require("remotion");
29
- const calculate_scale_1 = require("./calculate-scale");
30
- const error_boundary_1 = require("./error-boundary");
31
- const player_css_classname_1 = require("./player-css-classname");
32
- const PlayerControls_1 = require("./PlayerControls");
33
- const use_hover_state_1 = require("./use-hover-state");
34
- const use_playback_1 = require("./use-playback");
35
- const use_player_1 = require("./use-player");
36
- const calculate_player_size_1 = require("./utils/calculate-player-size");
37
- const is_node_1 = require("./utils/is-node");
38
- const use_click_prevention_on_double_click_1 = require("./utils/use-click-prevention-on-double-click");
39
- const use_element_size_1 = require("./utils/use-element-size");
29
+ const calculate_scale_js_1 = require("./calculate-scale.js");
30
+ const error_boundary_js_1 = require("./error-boundary.js");
31
+ const player_css_classname_js_1 = require("./player-css-classname.js");
32
+ const PlayerControls_js_1 = require("./PlayerControls.js");
33
+ const use_hover_state_js_1 = require("./use-hover-state.js");
34
+ const use_playback_js_1 = require("./use-playback.js");
35
+ const use_player_js_1 = require("./use-player.js");
36
+ const is_node_js_1 = require("./utils/is-node.js");
37
+ const use_click_prevention_on_double_click_js_1 = require("./utils/use-click-prevention-on-double-click.js");
38
+ const use_element_size_js_1 = require("./utils/use-element-size.js");
40
39
  const reactVersion = react_1.default.version.split('.')[0];
41
40
  if (reactVersion === '0') {
42
41
  throw new Error(`Version ${reactVersion} of "react" is not supported by Remotion`);
43
42
  }
44
43
  const doesReactVersionSupportSuspense = parseInt(reactVersion, 10) >= 18;
45
- const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps, clickToPlay, showVolumeControls, mediaVolume, mediaMuted, doubleClickToFullscreen, setMediaMuted, setMediaVolume, spaceKeyToPlayOrPause, errorFallback, playbackRate, renderLoading, className, moveToBeginningWhenEnded, }, ref) => {
46
- var _a, _b, _c;
44
+ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps, clickToPlay, showVolumeControls, doubleClickToFullscreen, spaceKeyToPlayOrPause, errorFallback, playbackRate, renderLoading, renderPoster, className, moveToBeginningWhenEnded, showPosterWhenUnplayed, showPosterWhenEnded, showPosterWhenPaused, inFrame, outFrame, initiallyShowControls, renderFullscreen: renderFullscreenButton, renderPlayPauseButton, alwaysShowControls, showPlaybackRateControl, }, ref) => {
45
+ var _a, _b, _c, _d;
47
46
  const config = remotion_1.Internals.useUnsafeVideoConfig();
48
47
  const video = remotion_1.Internals.useVideo();
49
48
  const container = (0, react_1.useRef)(null);
50
- const hovered = (0, use_hover_state_1.useHoverState)(container);
51
- const canvasSize = (0, use_element_size_1.useElementSize)(container, {
49
+ const hovered = (0, use_hover_state_js_1.useHoverState)(container);
50
+ const canvasSize = (0, use_element_size_js_1.useElementSize)(container, {
52
51
  triggerOnWindowResize: false,
53
52
  shouldApplyCssTransforms: false,
54
53
  });
55
54
  const [hasPausedToResume, setHasPausedToResume] = (0, react_1.useState)(false);
56
55
  const [shouldAutoplay, setShouldAutoPlay] = (0, react_1.useState)(autoPlay);
57
56
  const [isFullscreen, setIsFullscreen] = (0, react_1.useState)(() => false);
58
- (0, use_playback_1.usePlayback)({
57
+ const [seeking, setSeeking] = (0, react_1.useState)(false);
58
+ (0, use_playback_js_1.usePlayback)({
59
59
  loop,
60
60
  playbackRate,
61
61
  moveToBeginningWhenEnded,
62
- inFrame: null,
63
- outFrame: null,
62
+ inFrame,
63
+ outFrame,
64
64
  });
65
- const player = (0, use_player_1.usePlayer)();
65
+ const player = (0, use_player_js_1.usePlayer)();
66
66
  (0, react_1.useEffect)(() => {
67
67
  if (hasPausedToResume && !player.playing) {
68
68
  setHasPausedToResume(false);
@@ -119,7 +119,64 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
119
119
  document.exitFullscreen();
120
120
  }
121
121
  }, []);
122
+ (0, react_1.useEffect)(() => {
123
+ const { current } = container;
124
+ if (!current) {
125
+ return;
126
+ }
127
+ const fullscreenChange = () => {
128
+ var _a;
129
+ const element = (_a = document.webkitFullscreenElement) !== null && _a !== void 0 ? _a : document.fullscreenElement;
130
+ if (element && element === container.current) {
131
+ player.emitter.dispatchFullscreenChange({
132
+ isFullscreen: true,
133
+ });
134
+ }
135
+ else {
136
+ player.emitter.dispatchFullscreenChange({
137
+ isFullscreen: false,
138
+ });
139
+ }
140
+ };
141
+ current.addEventListener('webkitfullscreenchange', fullscreenChange);
142
+ current.addEventListener('fullscreenchange', fullscreenChange);
143
+ return () => {
144
+ current.removeEventListener('webkitfullscreenchange', fullscreenChange);
145
+ current.removeEventListener('fullscreenchange', fullscreenChange);
146
+ };
147
+ }, [player.emitter]);
122
148
  const durationInFrames = (_a = config === null || config === void 0 ? void 0 : config.durationInFrames) !== null && _a !== void 0 ? _a : 1;
149
+ const layout = (0, react_1.useMemo)(() => {
150
+ if (!config || !canvasSize) {
151
+ return null;
152
+ }
153
+ return (0, calculate_scale_js_1.calculateCanvasTransformation)({
154
+ canvasSize,
155
+ compositionHeight: config.height,
156
+ compositionWidth: config.width,
157
+ previewSize: 'auto',
158
+ });
159
+ }, [canvasSize, config]);
160
+ const scale = (_b = layout === null || layout === void 0 ? void 0 : layout.scale) !== null && _b !== void 0 ? _b : 1;
161
+ const initialScaleIgnored = (0, react_1.useRef)(false);
162
+ (0, react_1.useEffect)(() => {
163
+ if (!initialScaleIgnored.current) {
164
+ initialScaleIgnored.current = true;
165
+ return;
166
+ }
167
+ player.emitter.dispatchScaleChange(scale);
168
+ }, [player.emitter, scale]);
169
+ const { setMediaVolume, setMediaMuted } = (0, react_1.useContext)(remotion_1.Internals.SetMediaVolumeContext);
170
+ const { mediaMuted, mediaVolume } = (0, react_1.useContext)(remotion_1.Internals.MediaVolumeContext);
171
+ (0, react_1.useEffect)(() => {
172
+ player.emitter.dispatchVolumeChange(mediaVolume);
173
+ }, [player.emitter, mediaVolume]);
174
+ const isMuted = mediaMuted || mediaVolume === 0;
175
+ (0, react_1.useEffect)(() => {
176
+ player.emitter.dispatchMuteChange({
177
+ isMuted,
178
+ });
179
+ }, [player.emitter, isMuted]);
123
180
  (0, react_1.useImperativeHandle)(ref, () => {
124
181
  const methods = {
125
182
  play: player.play,
@@ -162,13 +219,14 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
162
219
  }
163
220
  setMediaVolume(vol);
164
221
  },
165
- isMuted: () => mediaMuted || mediaVolume === 0,
222
+ isMuted: () => isMuted,
166
223
  mute: () => {
167
224
  setMediaMuted(true);
168
225
  },
169
226
  unmute: () => {
170
227
  setMediaMuted(false);
171
228
  },
229
+ getScale: () => scale,
172
230
  };
173
231
  return Object.assign(player.emitter, methods);
174
232
  }, [
@@ -177,79 +235,25 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
177
235
  isFullscreen,
178
236
  loop,
179
237
  mediaMuted,
238
+ isMuted,
180
239
  mediaVolume,
181
240
  player,
182
241
  requestFullscreen,
183
242
  setMediaMuted,
184
243
  setMediaVolume,
185
244
  toggle,
245
+ scale,
186
246
  ]);
187
247
  const VideoComponent = video ? video.component : null;
188
248
  const outerStyle = (0, react_1.useMemo)(() => {
189
- if (!config) {
190
- return {};
191
- }
192
- return {
193
- position: 'relative',
194
- overflow: 'hidden',
195
- ...(0, calculate_player_size_1.calculatePlayerSize)({
196
- compositionHeight: config.height,
197
- compositionWidth: config.width,
198
- currentSize: canvasSize,
199
- height: style === null || style === void 0 ? void 0 : style.height,
200
- width: style === null || style === void 0 ? void 0 : style.width,
201
- }),
202
- ...style,
203
- };
249
+ return (0, calculate_scale_js_1.calculateOuterStyle)({ canvasSize, config, style });
204
250
  }, [canvasSize, config, style]);
205
- const layout = (0, react_1.useMemo)(() => {
206
- if (!config || !canvasSize) {
207
- return null;
208
- }
209
- return (0, calculate_scale_1.calculateScale)({
210
- canvasSize,
211
- compositionHeight: config.height,
212
- compositionWidth: config.width,
213
- previewSize: 'auto',
214
- });
215
- }, [canvasSize, config]);
216
251
  const outer = (0, react_1.useMemo)(() => {
217
- if (!layout || !config) {
218
- return {};
219
- }
220
- const { centerX, centerY, scale } = layout;
221
- return {
222
- width: config.width * scale,
223
- height: config.height * scale,
224
- display: 'flex',
225
- flexDirection: 'column',
226
- position: 'absolute',
227
- left: centerX,
228
- top: centerY,
229
- overflow: 'hidden',
230
- };
231
- }, [config, layout]);
252
+ return (0, calculate_scale_js_1.calculateOuter)({ config, layout, scale });
253
+ }, [config, layout, scale]);
232
254
  const containerStyle = (0, react_1.useMemo)(() => {
233
- if (!config || !canvasSize) {
234
- return {};
235
- }
236
- const { scale, xCorrection, yCorrection } = (0, calculate_scale_1.calculateScale)({
237
- canvasSize,
238
- compositionHeight: config.height,
239
- compositionWidth: config.width,
240
- previewSize: 'auto',
241
- });
242
- return {
243
- position: 'absolute',
244
- width: config.width,
245
- height: config.height,
246
- display: 'flex',
247
- transform: `scale(${scale})`,
248
- marginLeft: xCorrection,
249
- marginTop: yCorrection,
250
- overflow: 'hidden',
251
- };
252
- }, [canvasSize, config]);
255
+ return (0, calculate_scale_js_1.calculateContainerStyle)({ canvasSize, config, layout, scale });
256
+ }, [canvasSize, config, layout, scale]);
253
257
  const onError = (0, react_1.useCallback)((error) => {
254
258
  player.pause();
255
259
  // Pay attention to `this context`
@@ -266,6 +270,12 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
266
270
  const onSingleClick = (0, react_1.useCallback)((e) => {
267
271
  toggle(e);
268
272
  }, [toggle]);
273
+ const onSeekStart = (0, react_1.useCallback)(() => {
274
+ setSeeking(true);
275
+ }, []);
276
+ const onSeekEnd = (0, react_1.useCallback)(() => {
277
+ setSeeking(false);
278
+ }, []);
269
279
  const onDoubleClick = (0, react_1.useCallback)(() => {
270
280
  if (isFullscreen) {
271
281
  exitFullscreen();
@@ -274,26 +284,43 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
274
284
  requestFullscreen();
275
285
  }
276
286
  }, [exitFullscreen, isFullscreen, requestFullscreen]);
277
- const [handleClick, handleDoubleClick] = (0, use_click_prevention_on_double_click_1.useClickPreventionOnDoubleClick)(onSingleClick, onDoubleClick, doubleClickToFullscreen);
287
+ const [handleClick, handleDoubleClick] = (0, use_click_prevention_on_double_click_js_1.useClickPreventionOnDoubleClick)(onSingleClick, onDoubleClick, doubleClickToFullscreen);
278
288
  (0, react_1.useEffect)(() => {
279
289
  if (shouldAutoplay) {
280
290
  player.play();
281
291
  setShouldAutoPlay(false);
282
292
  }
283
293
  }, [shouldAutoplay, player]);
294
+ const loadingMarkup = (0, react_1.useMemo)(() => {
295
+ return renderLoading
296
+ ? renderLoading({
297
+ height: outerStyle.height,
298
+ width: outerStyle.width,
299
+ })
300
+ : null;
301
+ }, [outerStyle.height, outerStyle.width, renderLoading]);
284
302
  if (!config) {
285
303
  return null;
286
304
  }
287
- 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, { ...((_b = video === null || video === void 0 ? void 0 : video.defaultProps) !== null && _b !== void 0 ? _b : {}), ...((_c = inputProps) !== null && _c !== void 0 ? _c : {}) }) })) : 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 })) : null] }));
288
- if (is_node_1.IS_NODE && !doesReactVersionSupportSuspense) {
289
- return ((0, jsx_runtime_1.jsx)("div", { ref: container, style: outerStyle, className: className, children: content }));
290
- }
291
- const loadingMarkup = renderLoading
292
- ? renderLoading({
305
+ const poster = renderPoster
306
+ ? renderPoster({
293
307
  height: outerStyle.height,
294
308
  width: outerStyle.width,
295
309
  })
296
310
  : null;
311
+ if (poster === undefined) {
312
+ throw new TypeError('renderPoster() must return a React element, but undefined was returned');
313
+ }
314
+ const shouldShowPoster = poster &&
315
+ [
316
+ showPosterWhenPaused && !player.isPlaying() && !seeking,
317
+ showPosterWhenEnded && player.isLastFrame && !player.isPlaying(),
318
+ showPosterWhenUnplayed && !player.hasPlayed && !player.isPlaying(),
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, playerWidth: (_d = canvasSize === null || canvasSize === void 0 ? void 0 : canvasSize.width) !== null && _d !== void 0 ? _d : 0, renderFullscreenButton: renderFullscreenButton, renderPlayPauseButton: renderPlayPauseButton, alwaysShowControls: alwaysShowControls, showPlaybackRateControl: showPlaybackRateControl })) : null] }));
321
+ if (is_node_js_1.IS_NODE && !doesReactVersionSupportSuspense) {
322
+ return ((0, jsx_runtime_1.jsx)("div", { ref: container, style: outerStyle, className: className, children: content }));
323
+ }
297
324
  return ((0, jsx_runtime_1.jsx)("div", { ref: container, style: outerStyle, className: className, children: (0, jsx_runtime_1.jsx)(react_1.Suspense, { fallback: loadingMarkup, children: content }) }));
298
325
  };
299
326
  exports.default = (0, react_1.forwardRef)(PlayerUI);
@@ -0,0 +1,15 @@
1
+ import type { ComponentType, LazyExoticComponent } from 'react';
2
+ import React from 'react';
3
+ import type { TimelineContextValue } from 'remotion';
4
+ export declare const SharedPlayerContexts: React.FC<{
5
+ children: React.ReactNode;
6
+ timelineContext: TimelineContextValue;
7
+ inputProps?: Record<string, unknown>;
8
+ fps: number;
9
+ compositionWidth: number;
10
+ compositionHeight: number;
11
+ durationInFrames: number;
12
+ component: LazyExoticComponent<ComponentType<unknown>>;
13
+ numberOfSharedAudioTags: number;
14
+ initiallyMuted: boolean;
15
+ }>;