@remotion/player 4.0.482 → 4.0.484

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,4 +1,5 @@
1
1
  export declare const DefaultPlayPauseButton: React.FC<{
2
2
  playing: boolean;
3
3
  buffering: boolean;
4
+ focused: boolean;
4
5
  }>;
@@ -4,13 +4,13 @@ exports.DefaultPlayPauseButton = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const BufferingIndicator_js_1 = require("./BufferingIndicator.js");
6
6
  const icons_js_1 = require("./icons.js");
7
- const DefaultPlayPauseButton = ({ playing, buffering }) => {
7
+ const DefaultPlayPauseButton = ({ playing, buffering, focused }) => {
8
8
  if (playing && buffering) {
9
9
  return jsx_runtime_1.jsx(BufferingIndicator_js_1.BufferingIndicator, { type: "player" });
10
10
  }
11
11
  if (playing) {
12
- return jsx_runtime_1.jsx(icons_js_1.PauseIcon, {});
12
+ return jsx_runtime_1.jsx(icons_js_1.PauseIcon, { focused: focused });
13
13
  }
14
- return jsx_runtime_1.jsx(icons_js_1.PlayIcon, {});
14
+ return jsx_runtime_1.jsx(icons_js_1.PlayIcon, { focused: focused });
15
15
  };
16
16
  exports.DefaultPlayPauseButton = DefaultPlayPauseButton;
@@ -68,6 +68,7 @@ const fullscreen = {};
68
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
+ const [playButtonFocused, setPlayButtonFocused] = (0, react_1.useState)(false);
71
72
  const [supportsFullscreen, setSupportsFullscreen] = (0, react_1.useState)(false);
72
73
  const hovered = (0, use_hover_state_js_1.useHoverState)(containerRef, hideControlsWhenPointerDoesntMove);
73
74
  const { maxTimeLabelWidth, displayVerticalVolumeSlider } = (0, use_video_controls_resize_js_1.useVideoControlsResize)({
@@ -103,6 +104,15 @@ const Controls = ({ durationInFrames, isFullscreen, fps, showVolumeControls, onF
103
104
  opacity: Number(shouldShow),
104
105
  };
105
106
  }, [hovered, shouldShowInitially, playing, alwaysShowControls]);
107
+ const playPauseButtonStyle = (0, react_1.useMemo)(() => {
108
+ if (renderPlayPauseButton !== null || (playing && buffering)) {
109
+ return PlaybackrateControl_js_1.playerButtonStyle;
110
+ }
111
+ return {
112
+ ...PlaybackrateControl_js_1.playerButtonStyle,
113
+ outline: 'none',
114
+ };
115
+ }, [buffering, playing, renderPlayPauseButton]);
106
116
  (0, react_1.useEffect)(() => {
107
117
  if (playButtonRef.current && spaceKeyToPlayOrPause) {
108
118
  // This switches focus to play button when player.playing flag changes
@@ -165,13 +175,19 @@ const Controls = ({ durationInFrames, isFullscreen, fps, showVolumeControls, onF
165
175
  onDoubleClick === null || onDoubleClick === void 0 ? void 0 : onDoubleClick(e);
166
176
  }
167
177
  }, [onDoubleClick]);
178
+ const onPlayButtonFocus = (0, react_1.useCallback)(() => {
179
+ setPlayButtonFocused(true);
180
+ }, []);
181
+ const onPlayButtonBlur = (0, react_1.useCallback)(() => {
182
+ setPlayButtonFocused(false);
183
+ }, []);
168
184
  return (jsx_runtime_1.jsxs("div", { ref: ref, style: containerCss, onPointerDown: onPointerDownIfContainer, onDoubleClick: onDoubleClickIfContainer, children: [
169
185
  jsx_runtime_1.jsxs("div", { ref: flexRef, style: controlsRow, children: [
170
186
  jsx_runtime_1.jsxs("div", { style: leftPartStyle, children: [
171
- 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 ? (jsx_runtime_1.jsx(DefaultPlayPauseButton_js_1.DefaultPlayPauseButton, { buffering: buffering, playing: playing })) : (((_b = renderPlayPauseButton({
187
+ jsx_runtime_1.jsx("button", { ref: playButtonRef, type: "button", style: playPauseButtonStyle, onClick: toggle, onFocus: onPlayButtonFocus, onBlur: onPlayButtonBlur, "aria-label": playing ? 'Pause video' : 'Play video', title: playing ? 'Pause video' : 'Play video', children: renderPlayPauseButton === null ? (jsx_runtime_1.jsx(DefaultPlayPauseButton_js_1.DefaultPlayPauseButton, { buffering: buffering, focused: playButtonFocused, playing: playing })) : (((_b = renderPlayPauseButton({
172
188
  playing,
173
189
  isBuffering: buffering,
174
- })) !== null && _b !== void 0 ? _b : (jsx_runtime_1.jsx(DefaultPlayPauseButton_js_1.DefaultPlayPauseButton, { buffering: buffering, playing: playing })))) }), showVolumeControls ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
190
+ })) !== null && _b !== void 0 ? _b : (jsx_runtime_1.jsx(DefaultPlayPauseButton_js_1.DefaultPlayPauseButton, { buffering: buffering, focused: false, playing: playing })))) }), showVolumeControls ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
175
191
  jsx_runtime_1.jsx("div", { style: xSpacer }), jsx_runtime_1.jsx(MediaVolumeSlider_js_1.MediaVolumeSlider, { renderMuteButton: renderMuteButton, renderVolumeSlider: renderVolumeSlider, displayVerticalVolumeSlider: displayVerticalVolumeSlider })
176
192
  ] })) : null, jsx_runtime_1.jsx("div", { style: xSpacer }), jsx_runtime_1.jsx(PlayerTimeLabel_js_1.PlayerTimeLabel, { durationInFrames: durationInFrames, fps: fps, maxTimeLabelWidth: maxTimeLabelWidth }), jsx_runtime_1.jsx("div", { style: xSpacer })
177
193
  ] }), jsx_runtime_1.jsx("div", { style: flex1 }), customControlsElement, customControlsElement && playbackRates && canvasSize ? (jsx_runtime_1.jsx("div", { style: xSpacer })) : null, playbackRates && canvasSize && (jsx_runtime_1.jsx(PlaybackrateControl_js_1.PlaybackrateControl, { canvasSize: canvasSize, playbackRates: playbackRates })), playbackRates && supportsFullscreen && allowFullscreen ? (jsx_runtime_1.jsx("div", { style: xSpacer })) : null, jsx_runtime_1.jsx("div", { style: fullscreen, children: supportsFullscreen && allowFullscreen ? (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
@@ -1,8 +1,12 @@
1
1
  import React from 'react';
2
2
  export declare const ICON_SIZE = 25;
3
3
  export declare const fullscreenIconSize = 16;
4
- export declare const PlayIcon: React.FC;
5
- export declare const PauseIcon: React.FC;
4
+ export declare const PlayIcon: React.FC<{
5
+ readonly focused?: boolean;
6
+ }>;
7
+ export declare const PauseIcon: React.FC<{
8
+ readonly focused?: boolean;
9
+ }>;
6
10
  export declare const FullscreenIcon: React.FC<{
7
11
  readonly isFullscreen: boolean;
8
12
  }>;
package/dist/cjs/icons.js CHANGED
@@ -4,13 +4,62 @@ exports.VolumeOnIcon = exports.VolumeOffIcon = exports.FullscreenIcon = exports.
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  exports.ICON_SIZE = 25;
6
6
  exports.fullscreenIconSize = 16;
7
- const PlayIcon = () => {
8
- return (jsx_runtime_1.jsx("svg", { width: exports.ICON_SIZE, height: exports.ICON_SIZE, viewBox: "0 0 25 25", fill: "none", children: jsx_runtime_1.jsx("path", { d: "M8 6.375C7.40904 8.17576 7.06921 10.2486 7.01438 12.3871C6.95955 14.5255 7.19163 16.6547 7.6875 18.5625C9.95364 18.2995 12.116 17.6164 14.009 16.5655C15.902 15.5147 17.4755 14.124 18.6088 12.5C17.5158 10.8949 15.9949 9.51103 14.1585 8.45082C12.3222 7.3906 10.2174 6.68116 8 6.375Z", fill: "white", stroke: "white", strokeWidth: "6.25", strokeLinejoin: "round" }) }));
7
+ const focusRingFallbackColor = 'Highlight';
8
+ const focusRingColor = '-webkit-focus-ring-color';
9
+ const focusRingStyle = {
10
+ stroke: focusRingColor,
11
+ };
12
+ const playPath = 'M8 6.375C7.40904 8.17576 7.06921 10.2486 7.01438 12.3871C6.95955 14.5255 7.19163 16.6547 7.6875 18.5625C9.95364 18.2995 12.116 17.6164 14.009 16.5655C15.902 15.5147 17.4755 14.124 18.6088 12.5C17.5158 10.8949 15.9949 9.51103 14.1585 8.45082C12.3222 7.3906 10.2174 6.68116 8 6.375Z';
13
+ const playFocusPath = 'M93.4691 0.0367432C84.4873 0.520935 77.2494 1.93634 69.9553 4.69266C66.3176 6.05219 60.3548 9.0134 57.0734 11.062C43.3476 19.6103 32.8846 32.4606 27.428 47.4154C26.3405 50.3766 23.3966 59.8188 21.5027 66.3185C8.88329 109.768 1.7204 157.277 0.182822 207.561C-0.0609408 215.569 -0.0609408 234.639 0.182822 242.517C1.21413 275.854 4.42055 305.949 10.2334 336.641C12.596 349.063 16.3837 365.75 18.5776 373.33C23.059 388.732 32.2095 401.843 45.2227 411.453C53.9419 417.896 63.8425 422.217 74.8118 424.34C80.0996 425.365 87.075 425.83 92.2127 425.495C99.3194 425.029 113.42 423.148 124.877 421.118C176.517 411.974 224.22 395.604 267.478 372.175C294.874 357.332 318.294 341.26 340.888 321.761C363.408 302.355 382.609 281.478 399.504 258.049C403.423 252.63 405.392 249.464 407.361 245.478C412.424 235.198 414.805 224.974 414.786 213.539C414.786 202.886 412.761 193.425 408.392 183.741C406.292 179.066 404.286 175.714 399.785 169.345C383.21 145.898 364.815 125.467 342.389 105.614C307.624 74.8481 266.335 49.613 220.226 30.9334C210.232 26.8921 200.387 23.335 188.537 19.4799C163.448 11.3413 132.396 4.28293 106.126 0.763062C102.001 0.204346 96.3942 -0.112244 93.4691 0.0367432Z';
14
+ const playIconStrokeWidth = 6.25;
15
+ const playFocusStrokeWidth = 1.5;
16
+ const playFocusPadding = 2;
17
+ // Derived with @remotion/paths getBoundingBox() from the paths above.
18
+ const playPathBounds = {
19
+ x1: 7.006500987565134,
20
+ y1: 6.375,
21
+ x2: 18.6088,
22
+ y2: 18.5625,
23
+ };
24
+ const playFocusPathBounds = {
25
+ x1: -9.999999999649709e-8,
26
+ y1: 0.000013203698169792638,
27
+ x2: 414.7861127950162,
28
+ y2: 425.60252460486765,
29
+ };
30
+ const expandBounds = (bounds, padding) => {
31
+ return {
32
+ x1: bounds.x1 - padding,
33
+ y1: bounds.y1 - padding,
34
+ x2: bounds.x2 + padding,
35
+ y2: bounds.y2 + padding,
36
+ };
37
+ };
38
+ const getBoundsWidth = (bounds) => bounds.x2 - bounds.x1;
39
+ const getBoundsHeight = (bounds) => bounds.y2 - bounds.y1;
40
+ const fitBoundsTransform = ({ source, target, }) => {
41
+ const scale = Math.min(getBoundsWidth(target) / getBoundsWidth(source), getBoundsHeight(target) / getBoundsHeight(source));
42
+ const x = target.x1 +
43
+ (getBoundsWidth(target) - getBoundsWidth(source) * scale) / 2 -
44
+ source.x1 * scale;
45
+ const y = target.y1 +
46
+ (getBoundsHeight(target) - getBoundsHeight(source) * scale) / 2 -
47
+ source.y1 * scale;
48
+ return `translate(${x.toFixed(4)} ${y.toFixed(4)}) scale(${scale.toFixed(5)})`;
49
+ };
50
+ const playFocusTransform = fitBoundsTransform({
51
+ source: playFocusPathBounds,
52
+ target: expandBounds(expandBounds(playPathBounds, playIconStrokeWidth / 2), playFocusPadding),
53
+ });
54
+ const PlayIcon = ({ focused }) => {
55
+ return (jsx_runtime_1.jsxs("svg", { width: exports.ICON_SIZE, height: exports.ICON_SIZE, viewBox: "0 0 25 25", fill: "none", children: [focused ? (jsx_runtime_1.jsx("path", { d: playFocusPath, fill: "none", stroke: focusRingFallbackColor, strokeWidth: playFocusStrokeWidth, style: focusRingStyle, transform: playFocusTransform, vectorEffect: "non-scaling-stroke" })) : null, jsx_runtime_1.jsx("path", { d: playPath, fill: "white", stroke: "white", strokeWidth: playIconStrokeWidth, strokeLinejoin: "round" })
56
+ ] }));
9
57
  };
10
58
  exports.PlayIcon = PlayIcon;
11
- const PauseIcon = () => {
12
- return (jsx_runtime_1.jsxs("svg", { viewBox: "0 0 100 100", width: exports.ICON_SIZE, height: exports.ICON_SIZE, children: [
13
- jsx_runtime_1.jsx("rect", { x: "25", y: "20", width: "20", height: "60", fill: "#fff", ry: "5", rx: "5" }), jsx_runtime_1.jsx("rect", { x: "55", y: "20", width: "20", height: "60", fill: "#fff", ry: "5", rx: "5" })
59
+ const PauseIcon = ({ focused, }) => {
60
+ return (jsx_runtime_1.jsxs("svg", { viewBox: "0 0 100 100", width: exports.ICON_SIZE, height: exports.ICON_SIZE, children: [focused ? (jsx_runtime_1.jsxs(jsx_runtime_1.Fragment, { children: [
61
+ jsx_runtime_1.jsx("rect", { x: "21", y: "16", width: "28", height: "68", fill: "none", stroke: focusRingFallbackColor, strokeWidth: "4", ry: "9", rx: "9", style: focusRingStyle }), jsx_runtime_1.jsx("rect", { x: "51", y: "16", width: "28", height: "68", fill: "none", stroke: focusRingFallbackColor, strokeWidth: "4", ry: "9", rx: "9", style: focusRingStyle })
62
+ ] })) : null, jsx_runtime_1.jsx("rect", { x: "25", y: "20", width: "20", height: "60", fill: "#fff", ry: "5", rx: "5" }), jsx_runtime_1.jsx("rect", { x: "55", y: "20", width: "20", height: "60", fill: "#fff", ry: "5", rx: "5" })
14
63
  ] }));
15
64
  };
16
65
  exports.PauseIcon = PauseIcon;
@@ -18,30 +18,116 @@ if (typeof createContext !== "function") {
18
18
  }
19
19
 
20
20
  // src/icons.tsx
21
- import { jsx, jsxs } from "react/jsx-runtime";
21
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
22
22
  var ICON_SIZE = 25;
23
23
  var fullscreenIconSize = 16;
24
- var PlayIcon = () => {
25
- return /* @__PURE__ */ jsx("svg", {
24
+ var focusRingFallbackColor = "Highlight";
25
+ var focusRingColor = "-webkit-focus-ring-color";
26
+ var focusRingStyle = {
27
+ stroke: focusRingColor
28
+ };
29
+ var playPath = "M8 6.375C7.40904 8.17576 7.06921 10.2486 7.01438 12.3871C6.95955 14.5255 7.19163 16.6547 7.6875 18.5625C9.95364 18.2995 12.116 17.6164 14.009 16.5655C15.902 15.5147 17.4755 14.124 18.6088 12.5C17.5158 10.8949 15.9949 9.51103 14.1585 8.45082C12.3222 7.3906 10.2174 6.68116 8 6.375Z";
30
+ var playFocusPath = "M93.4691 0.0367432C84.4873 0.520935 77.2494 1.93634 69.9553 4.69266C66.3176 6.05219 60.3548 9.0134 57.0734 11.062C43.3476 19.6103 32.8846 32.4606 27.428 47.4154C26.3405 50.3766 23.3966 59.8188 21.5027 66.3185C8.88329 109.768 1.7204 157.277 0.182822 207.561C-0.0609408 215.569 -0.0609408 234.639 0.182822 242.517C1.21413 275.854 4.42055 305.949 10.2334 336.641C12.596 349.063 16.3837 365.75 18.5776 373.33C23.059 388.732 32.2095 401.843 45.2227 411.453C53.9419 417.896 63.8425 422.217 74.8118 424.34C80.0996 425.365 87.075 425.83 92.2127 425.495C99.3194 425.029 113.42 423.148 124.877 421.118C176.517 411.974 224.22 395.604 267.478 372.175C294.874 357.332 318.294 341.26 340.888 321.761C363.408 302.355 382.609 281.478 399.504 258.049C403.423 252.63 405.392 249.464 407.361 245.478C412.424 235.198 414.805 224.974 414.786 213.539C414.786 202.886 412.761 193.425 408.392 183.741C406.292 179.066 404.286 175.714 399.785 169.345C383.21 145.898 364.815 125.467 342.389 105.614C307.624 74.8481 266.335 49.613 220.226 30.9334C210.232 26.8921 200.387 23.335 188.537 19.4799C163.448 11.3413 132.396 4.28293 106.126 0.763062C102.001 0.204346 96.3942 -0.112244 93.4691 0.0367432Z";
31
+ var playIconStrokeWidth = 6.25;
32
+ var playFocusStrokeWidth = 1.5;
33
+ var playFocusPadding = 2;
34
+ var playPathBounds = {
35
+ x1: 7.006500987565134,
36
+ y1: 6.375,
37
+ x2: 18.6088,
38
+ y2: 18.5625
39
+ };
40
+ var playFocusPathBounds = {
41
+ x1: -0.00000009999999999649709,
42
+ y1: 0.000013203698169792638,
43
+ x2: 414.7861127950162,
44
+ y2: 425.60252460486765
45
+ };
46
+ var expandBounds = (bounds, padding) => {
47
+ return {
48
+ x1: bounds.x1 - padding,
49
+ y1: bounds.y1 - padding,
50
+ x2: bounds.x2 + padding,
51
+ y2: bounds.y2 + padding
52
+ };
53
+ };
54
+ var getBoundsWidth = (bounds) => bounds.x2 - bounds.x1;
55
+ var getBoundsHeight = (bounds) => bounds.y2 - bounds.y1;
56
+ var fitBoundsTransform = ({
57
+ source,
58
+ target
59
+ }) => {
60
+ const scale = Math.min(getBoundsWidth(target) / getBoundsWidth(source), getBoundsHeight(target) / getBoundsHeight(source));
61
+ const x = target.x1 + (getBoundsWidth(target) - getBoundsWidth(source) * scale) / 2 - source.x1 * scale;
62
+ const y = target.y1 + (getBoundsHeight(target) - getBoundsHeight(source) * scale) / 2 - source.y1 * scale;
63
+ return `translate(${x.toFixed(4)} ${y.toFixed(4)}) scale(${scale.toFixed(5)})`;
64
+ };
65
+ var playFocusTransform = fitBoundsTransform({
66
+ source: playFocusPathBounds,
67
+ target: expandBounds(expandBounds(playPathBounds, playIconStrokeWidth / 2), playFocusPadding)
68
+ });
69
+ var PlayIcon = ({ focused }) => {
70
+ return /* @__PURE__ */ jsxs("svg", {
26
71
  width: ICON_SIZE,
27
72
  height: ICON_SIZE,
28
73
  viewBox: "0 0 25 25",
29
74
  fill: "none",
30
- children: /* @__PURE__ */ jsx("path", {
31
- d: "M8 6.375C7.40904 8.17576 7.06921 10.2486 7.01438 12.3871C6.95955 14.5255 7.19163 16.6547 7.6875 18.5625C9.95364 18.2995 12.116 17.6164 14.009 16.5655C15.902 15.5147 17.4755 14.124 18.6088 12.5C17.5158 10.8949 15.9949 9.51103 14.1585 8.45082C12.3222 7.3906 10.2174 6.68116 8 6.375Z",
32
- fill: "white",
33
- stroke: "white",
34
- strokeWidth: "6.25",
35
- strokeLinejoin: "round"
36
- })
75
+ children: [
76
+ focused ? /* @__PURE__ */ jsx("path", {
77
+ d: playFocusPath,
78
+ fill: "none",
79
+ stroke: focusRingFallbackColor,
80
+ strokeWidth: playFocusStrokeWidth,
81
+ style: focusRingStyle,
82
+ transform: playFocusTransform,
83
+ vectorEffect: "non-scaling-stroke"
84
+ }) : null,
85
+ /* @__PURE__ */ jsx("path", {
86
+ d: playPath,
87
+ fill: "white",
88
+ stroke: "white",
89
+ strokeWidth: playIconStrokeWidth,
90
+ strokeLinejoin: "round"
91
+ })
92
+ ]
37
93
  });
38
94
  };
39
- var PauseIcon = () => {
95
+ var PauseIcon = ({
96
+ focused
97
+ }) => {
40
98
  return /* @__PURE__ */ jsxs("svg", {
41
99
  viewBox: "0 0 100 100",
42
100
  width: ICON_SIZE,
43
101
  height: ICON_SIZE,
44
102
  children: [
103
+ focused ? /* @__PURE__ */ jsxs(Fragment, {
104
+ children: [
105
+ /* @__PURE__ */ jsx("rect", {
106
+ x: "21",
107
+ y: "16",
108
+ width: "28",
109
+ height: "68",
110
+ fill: "none",
111
+ stroke: focusRingFallbackColor,
112
+ strokeWidth: "4",
113
+ ry: "9",
114
+ rx: "9",
115
+ style: focusRingStyle
116
+ }),
117
+ /* @__PURE__ */ jsx("rect", {
118
+ x: "51",
119
+ y: "16",
120
+ width: "28",
121
+ height: "68",
122
+ fill: "none",
123
+ stroke: focusRingFallbackColor,
124
+ strokeWidth: "4",
125
+ ry: "9",
126
+ rx: "9",
127
+ style: focusRingStyle
128
+ })
129
+ ]
130
+ }) : null,
45
131
  /* @__PURE__ */ jsx("rect", {
46
132
  x: "25",
47
133
  y: "20",
@@ -143,7 +229,7 @@ var VolumeOnIcon = () => {
143
229
  };
144
230
 
145
231
  // src/BufferingIndicator.tsx
146
- import { jsx as jsx2, jsxs as jsxs2, Fragment } from "react/jsx-runtime";
232
+ import { jsx as jsx2, jsxs as jsxs2, Fragment as Fragment2 } from "react/jsx-runtime";
147
233
  var className = "__remotion_buffering_indicator";
148
234
  var remotionBufferingAnimation = "__remotion_buffering_animation";
149
235
  var playerStyle = {
@@ -162,7 +248,7 @@ var studioStyle = {
162
248
  };
163
249
  var BufferingIndicator = ({ type }) => {
164
250
  const style = type === "player" ? playerStyle : studioStyle;
165
- return /* @__PURE__ */ jsxs2(Fragment, {
251
+ return /* @__PURE__ */ jsxs2(Fragment2, {
166
252
  children: [
167
253
  /* @__PURE__ */ jsx2("style", {
168
254
  type: "text/css",
@@ -1475,16 +1561,20 @@ import { useCallback as useCallback7, useEffect as useEffect11, useMemo as useMe
1475
1561
 
1476
1562
  // src/DefaultPlayPauseButton.tsx
1477
1563
  import { jsx as jsx6 } from "react/jsx-runtime";
1478
- var DefaultPlayPauseButton = ({ playing, buffering }) => {
1564
+ var DefaultPlayPauseButton = ({ playing, buffering, focused }) => {
1479
1565
  if (playing && buffering) {
1480
1566
  return /* @__PURE__ */ jsx6(BufferingIndicator, {
1481
1567
  type: "player"
1482
1568
  });
1483
1569
  }
1484
1570
  if (playing) {
1485
- return /* @__PURE__ */ jsx6(PauseIcon, {});
1571
+ return /* @__PURE__ */ jsx6(PauseIcon, {
1572
+ focused
1573
+ });
1486
1574
  }
1487
- return /* @__PURE__ */ jsx6(PlayIcon, {});
1575
+ return /* @__PURE__ */ jsx6(PlayIcon, {
1576
+ focused
1577
+ });
1488
1578
  };
1489
1579
 
1490
1580
  // src/MediaVolumeSlider.tsx
@@ -2140,7 +2230,7 @@ var useVideoControlsResize = ({
2140
2230
  };
2141
2231
 
2142
2232
  // src/PlayerControls.tsx
2143
- import { jsx as jsx11, jsxs as jsxs8, Fragment as Fragment2 } from "react/jsx-runtime";
2233
+ import { jsx as jsx11, jsxs as jsxs8, Fragment as Fragment3 } from "react/jsx-runtime";
2144
2234
  var gradientSteps = [
2145
2235
  0,
2146
2236
  0.013,
@@ -2250,6 +2340,7 @@ var Controls = ({
2250
2340
  renderCustomControls
2251
2341
  }) => {
2252
2342
  const playButtonRef = useRef8(null);
2343
+ const [playButtonFocused, setPlayButtonFocused] = useState10(false);
2253
2344
  const [supportsFullscreen, setSupportsFullscreen] = useState10(false);
2254
2345
  const hovered = useHoverState(containerRef, hideControlsWhenPointerDoesntMove);
2255
2346
  const { maxTimeLabelWidth, displayVerticalVolumeSlider } = useVideoControlsResize({
@@ -2284,6 +2375,15 @@ var Controls = ({
2284
2375
  opacity: Number(shouldShow)
2285
2376
  };
2286
2377
  }, [hovered, shouldShowInitially, playing, alwaysShowControls]);
2378
+ const playPauseButtonStyle = useMemo9(() => {
2379
+ if (renderPlayPauseButton !== null || playing && buffering) {
2380
+ return playerButtonStyle;
2381
+ }
2382
+ return {
2383
+ ...playerButtonStyle,
2384
+ outline: "none"
2385
+ };
2386
+ }, [buffering, playing, renderPlayPauseButton]);
2287
2387
  useEffect11(() => {
2288
2388
  if (playButtonRef.current && spaceKeyToPlayOrPause) {
2289
2389
  playButtonRef.current.focus({
@@ -2336,6 +2436,12 @@ var Controls = ({
2336
2436
  onDoubleClick?.(e);
2337
2437
  }
2338
2438
  }, [onDoubleClick]);
2439
+ const onPlayButtonFocus = useCallback7(() => {
2440
+ setPlayButtonFocused(true);
2441
+ }, []);
2442
+ const onPlayButtonBlur = useCallback7(() => {
2443
+ setPlayButtonFocused(false);
2444
+ }, []);
2339
2445
  return /* @__PURE__ */ jsxs8("div", {
2340
2446
  ref,
2341
2447
  style: containerCss,
@@ -2352,22 +2458,26 @@ var Controls = ({
2352
2458
  /* @__PURE__ */ jsx11("button", {
2353
2459
  ref: playButtonRef,
2354
2460
  type: "button",
2355
- style: playerButtonStyle,
2461
+ style: playPauseButtonStyle,
2356
2462
  onClick: toggle,
2463
+ onFocus: onPlayButtonFocus,
2464
+ onBlur: onPlayButtonBlur,
2357
2465
  "aria-label": playing ? "Pause video" : "Play video",
2358
2466
  title: playing ? "Pause video" : "Play video",
2359
2467
  children: renderPlayPauseButton === null ? /* @__PURE__ */ jsx11(DefaultPlayPauseButton, {
2360
2468
  buffering,
2469
+ focused: playButtonFocused,
2361
2470
  playing
2362
2471
  }) : renderPlayPauseButton({
2363
2472
  playing,
2364
2473
  isBuffering: buffering
2365
2474
  }) ?? /* @__PURE__ */ jsx11(DefaultPlayPauseButton, {
2366
2475
  buffering,
2476
+ focused: false,
2367
2477
  playing
2368
2478
  })
2369
2479
  }),
2370
- showVolumeControls ? /* @__PURE__ */ jsxs8(Fragment2, {
2480
+ showVolumeControls ? /* @__PURE__ */ jsxs8(Fragment3, {
2371
2481
  children: [
2372
2482
  /* @__PURE__ */ jsx11("div", {
2373
2483
  style: xSpacer
@@ -2531,7 +2641,7 @@ var useClickPreventionOnDoubleClick = (onClick, onDoubleClick, doubleClickToFull
2531
2641
  };
2532
2642
 
2533
2643
  // src/PlayerUI.tsx
2534
- import { jsx as jsx12, jsxs as jsxs9, Fragment as Fragment3 } from "react/jsx-runtime";
2644
+ import { jsx as jsx12, jsxs as jsxs9, Fragment as Fragment4 } from "react/jsx-runtime";
2535
2645
  var reactVersion = React10.version.split(".")[0];
2536
2646
  if (reactVersion === "0") {
2537
2647
  throw new Error(`Version ${reactVersion} of "react" is not supported by Remotion`);
@@ -2921,7 +3031,7 @@ var PlayerUI = ({
2921
3031
  showPosterWhenBufferingAndPaused && showBufferIndicator && !player.isPlaying()
2922
3032
  ].some(Boolean);
2923
3033
  const { left, top, width, height, ...outerWithoutScale } = outer;
2924
- const content = /* @__PURE__ */ jsxs9(Fragment3, {
3034
+ const content = /* @__PURE__ */ jsxs9(Fragment4, {
2925
3035
  children: [
2926
3036
  /* @__PURE__ */ jsxs9("div", {
2927
3037
  style: outer,
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.482",
6
+ "version": "4.0.484",
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.482"
38
+ "remotion": "4.0.484"
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.105.0",
51
51
  "zod": "4.3.6",
52
- "@remotion/eslint-config-internal": "4.0.482",
52
+ "@remotion/eslint-config-internal": "4.0.484",
53
53
  "eslint": "9.19.0",
54
54
  "@typescript/native-preview": "7.0.0-dev.20260217.1"
55
55
  },