@remotion/player 4.0.0-alpha10 → 4.0.0-alpha12
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.
- package/dist/cjs/MediaVolumeSlider.js +0 -1
- package/dist/cjs/PlaybackrateControl.d.ts +5 -0
- package/dist/cjs/PlaybackrateControl.js +136 -0
- package/dist/cjs/Player.d.ts +1 -0
- package/dist/cjs/Player.js +13 -9
- package/dist/cjs/PlayerControls.d.ts +1 -0
- package/dist/cjs/PlayerControls.js +21 -3
- package/dist/cjs/PlayerUI.d.ts +1 -0
- package/dist/cjs/PlayerUI.js +2 -2
- package/dist/cjs/icons.d.ts +3 -0
- package/dist/cjs/icons.js +5 -1
- package/dist/cjs/index.d.ts +0 -1
- package/dist/cjs/utils/use-component-visible.d.ts +5 -0
- package/dist/cjs/utils/use-component-visible.js +21 -0
- package/dist/cjs/utils/use-element-size.js +6 -1
- package/dist/esm/PlaybackrateControl.d.ts +5 -0
- package/dist/esm/Player.d.ts +1 -0
- package/dist/esm/PlayerControls.d.ts +1 -0
- package/dist/esm/PlayerUI.d.ts +1 -0
- package/dist/esm/error-boundary.d.ts +1 -1
- package/dist/esm/icons.d.ts +3 -0
- package/dist/esm/index.d.ts +0 -1
- package/dist/esm/index.mjs +186 -16
- package/dist/esm/utils/use-component-visible.d.ts +5 -0
- package/dist/tsconfig-esm.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
package/dist/esm/index.mjs
CHANGED
|
@@ -624,7 +624,12 @@ const useElementSize = (ref, options) => {
|
|
|
624
624
|
elementSizeHooks = elementSizeHooks.filter((e) => e !== updateSize);
|
|
625
625
|
};
|
|
626
626
|
}, [updateSize]);
|
|
627
|
-
return
|
|
627
|
+
return useMemo(() => {
|
|
628
|
+
if (!size) {
|
|
629
|
+
return null;
|
|
630
|
+
}
|
|
631
|
+
return { ...size, refresh: updateSize };
|
|
632
|
+
}, [size, updateSize]);
|
|
628
633
|
};
|
|
629
634
|
|
|
630
635
|
const PLAYER_CSS_CLASSNAME = '__remotion-player';
|
|
@@ -707,6 +712,9 @@ const VolumeOffIcon = () => {
|
|
|
707
712
|
const VolumeOnIcon = () => {
|
|
708
713
|
return (jsx("svg", { width: ICON_SIZE, height: ICON_SIZE, viewBox: "0 0 24 24", children: jsx("path", { d: "M3 10v4c0 .55.45 1 1 1h3l3.29 3.29c.63.63 1.71.18 1.71-.71V6.41c0-.89-1.08-1.34-1.71-.71L7 9H4c-.55 0-1 .45-1 1zm13.5 2A4.5 4.5 0 0014 7.97v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 4.45v.2c0 .38.25.71.6.85C17.18 6.53 19 9.06 19 12s-1.82 5.47-4.4 6.5c-.36.14-.6.47-.6.85v.2c0 .63.63 1.07 1.21.85C18.6 19.11 21 15.84 21 12s-2.4-7.11-5.79-8.4c-.58-.23-1.21.22-1.21.85z", fill: "#fff" }) }));
|
|
709
714
|
};
|
|
715
|
+
const SettingsIcon = ({ iconSize }) => {
|
|
716
|
+
return (jsx("svg", { xmlns: "http://www.w3.org/2000/svg", height: iconSize !== null && iconSize !== void 0 ? iconSize : ICON_SIZE, viewBox: "0 0 512 512", style: { fill: '#fff' }, children: jsx("path", { d: "M495.9 166.6c3.2 8.7 .5 18.4-6.4 24.6l-43.3 39.4c1.1 8.3 1.7 16.8 1.7 25.4s-.6 17.1-1.7 25.4l43.3 39.4c6.9 6.2 9.6 15.9 6.4 24.6c-4.4 11.9-9.7 23.3-15.8 34.3l-4.7 8.1c-6.6 11-14 21.4-22.1 31.2c-5.9 7.2-15.7 9.6-24.5 6.8l-55.7-17.7c-13.4 10.3-28.2 18.9-44 25.4l-12.5 57.1c-2 9.1-9 16.3-18.2 17.8c-13.8 2.3-28 3.5-42.5 3.5s-28.7-1.2-42.5-3.5c-9.2-1.5-16.2-8.7-18.2-17.8l-12.5-57.1c-15.8-6.5-30.6-15.1-44-25.4L83.1 425.9c-8.8 2.8-18.6 .3-24.5-6.8c-8.1-9.8-15.5-20.2-22.1-31.2l-4.7-8.1c-6.1-11-11.4-22.4-15.8-34.3c-3.2-8.7-.5-18.4 6.4-24.6l43.3-39.4C64.6 273.1 64 264.6 64 256s.6-17.1 1.7-25.4L22.4 191.2c-6.9-6.2-9.6-15.9-6.4-24.6c4.4-11.9 9.7-23.3 15.8-34.3l4.7-8.1c6.6-11 14-21.4 22.1-31.2c5.9-7.2 15.7-9.6 24.5-6.8l55.7 17.7c13.4-10.3 28.2-18.9 44-25.4l12.5-57.1c2-9.1 9-16.3 18.2-17.8C227.3 1.2 241.5 0 256 0s28.7 1.2 42.5 3.5c9.2 1.5 16.2 8.7 18.2 17.8l12.5 57.1c15.8 6.5 30.6 15.1 44 25.4l55.7-17.7c8.8-2.8 18.6-.3 24.5 6.8c8.1 9.8 15.5 20.2 22.1 31.2l4.7 8.1c6.1 11 11.4 22.4 15.8 34.3zM256 336a80 80 0 1 0 0-160 80 80 0 1 0 0 160z" }) }));
|
|
717
|
+
};
|
|
710
718
|
|
|
711
719
|
const BAR_HEIGHT$1 = 5;
|
|
712
720
|
const KNOB_SIZE$1 = 12;
|
|
@@ -749,7 +757,6 @@ const MediaVolumeSlider = ({ displayVerticalVolumeSlider }) => {
|
|
|
749
757
|
display: 'inline-flex',
|
|
750
758
|
background: 'none',
|
|
751
759
|
border: 'none',
|
|
752
|
-
padding: 6,
|
|
753
760
|
justifyContent: 'center',
|
|
754
761
|
alignItems: 'center',
|
|
755
762
|
touchAction: 'none',
|
|
@@ -820,6 +827,148 @@ const MediaVolumeSlider = ({ displayVerticalVolumeSlider }) => {
|
|
|
820
827
|
} }), 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 ? jsx(VolumeOffIcon, {}) : jsx(VolumeOnIcon, {}) }), (focused || hover) && !mediaMuted ? (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] }));
|
|
821
828
|
};
|
|
822
829
|
|
|
830
|
+
// hook to hide a popup/modal when clicked outside
|
|
831
|
+
function useComponentVisible(initialIsVisible) {
|
|
832
|
+
const [isComponentVisible, setIsComponentVisible] = useState(initialIsVisible);
|
|
833
|
+
const ref = useRef(null);
|
|
834
|
+
useEffect(() => {
|
|
835
|
+
const handleClickOutside = (event) => {
|
|
836
|
+
if (ref.current && !ref.current.contains(event.target)) {
|
|
837
|
+
setIsComponentVisible(false);
|
|
838
|
+
}
|
|
839
|
+
};
|
|
840
|
+
document.addEventListener('pointerup', handleClickOutside, true);
|
|
841
|
+
return () => {
|
|
842
|
+
document.removeEventListener('pointerup', handleClickOutside, true);
|
|
843
|
+
};
|
|
844
|
+
}, []);
|
|
845
|
+
return { ref, isComponentVisible, setIsComponentVisible };
|
|
846
|
+
}
|
|
847
|
+
|
|
848
|
+
const playbackPopup = {
|
|
849
|
+
position: 'absolute',
|
|
850
|
+
right: 0,
|
|
851
|
+
width: 125,
|
|
852
|
+
bottom: 35,
|
|
853
|
+
background: '#fff',
|
|
854
|
+
borderRadius: 4,
|
|
855
|
+
overflow: 'hidden',
|
|
856
|
+
color: 'black',
|
|
857
|
+
textAlign: 'left',
|
|
858
|
+
};
|
|
859
|
+
const rateDiv = {
|
|
860
|
+
height: 30,
|
|
861
|
+
paddingRight: 15,
|
|
862
|
+
paddingLeft: 12,
|
|
863
|
+
display: 'flex',
|
|
864
|
+
flexDirection: 'row',
|
|
865
|
+
alignItems: 'center',
|
|
866
|
+
};
|
|
867
|
+
const checkmarkContainer = {
|
|
868
|
+
width: 22,
|
|
869
|
+
display: 'flex',
|
|
870
|
+
alignItems: 'center',
|
|
871
|
+
};
|
|
872
|
+
const checkmarkStyle = {
|
|
873
|
+
width: 14,
|
|
874
|
+
height: 14,
|
|
875
|
+
color: 'black',
|
|
876
|
+
};
|
|
877
|
+
const Checkmark = () => (jsx("svg", { viewBox: "0 0 512 512", style: checkmarkStyle, children: jsx("path", { fill: "currentColor", d: "M435.848 83.466L172.804 346.51l-96.652-96.652c-4.686-4.686-12.284-4.686-16.971 0l-28.284 28.284c-4.686 4.686-4.686 12.284 0 16.971l133.421 133.421c4.686 4.686 12.284 4.686 16.971 0l299.813-299.813c4.686-4.686 4.686-12.284 0-16.971l-28.284-28.284c-4.686-4.686-12.284-4.686-16.97 0z" }) }));
|
|
878
|
+
const PlaybackPopup = ({ setIsComponentVisible, playbackRates }) => {
|
|
879
|
+
const { setPlaybackRate, playbackRate } = useContext(Internals.Timeline.TimelineContext);
|
|
880
|
+
const [keyboardSelectedRate, setKeyboardSelectedRate] = useState(playbackRate);
|
|
881
|
+
useEffect(() => {
|
|
882
|
+
const listener = (e) => {
|
|
883
|
+
e.preventDefault();
|
|
884
|
+
if (e.key === 'ArrowUp') {
|
|
885
|
+
const currentIndex = playbackRates.findIndex((rate) => rate === keyboardSelectedRate);
|
|
886
|
+
if (currentIndex === 0) {
|
|
887
|
+
return;
|
|
888
|
+
}
|
|
889
|
+
if (currentIndex === -1) {
|
|
890
|
+
setKeyboardSelectedRate(playbackRates[0]);
|
|
891
|
+
}
|
|
892
|
+
else {
|
|
893
|
+
setKeyboardSelectedRate(playbackRates[currentIndex - 1]);
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
else if (e.key === 'ArrowDown') {
|
|
897
|
+
const currentIndex = playbackRates.findIndex((rate) => rate === keyboardSelectedRate);
|
|
898
|
+
if (currentIndex === playbackRates.length - 1) {
|
|
899
|
+
return;
|
|
900
|
+
}
|
|
901
|
+
if (currentIndex === -1) {
|
|
902
|
+
setKeyboardSelectedRate(playbackRates[playbackRates.length - 1]);
|
|
903
|
+
}
|
|
904
|
+
else {
|
|
905
|
+
setKeyboardSelectedRate(playbackRates[currentIndex + 1]);
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
else if (e.key === 'Enter') {
|
|
909
|
+
setPlaybackRate(keyboardSelectedRate);
|
|
910
|
+
setIsComponentVisible(false);
|
|
911
|
+
}
|
|
912
|
+
};
|
|
913
|
+
window.addEventListener('keydown', listener);
|
|
914
|
+
return () => {
|
|
915
|
+
window.removeEventListener('keydown', listener);
|
|
916
|
+
};
|
|
917
|
+
}, [
|
|
918
|
+
playbackRates,
|
|
919
|
+
keyboardSelectedRate,
|
|
920
|
+
setPlaybackRate,
|
|
921
|
+
setIsComponentVisible,
|
|
922
|
+
]);
|
|
923
|
+
const onSelect = useCallback((rate) => {
|
|
924
|
+
setPlaybackRate(rate);
|
|
925
|
+
setIsComponentVisible(false);
|
|
926
|
+
}, [setIsComponentVisible, setPlaybackRate]);
|
|
927
|
+
return (jsx("div", { style: playbackPopup, children: playbackRates.map((rate) => {
|
|
928
|
+
return (jsx(PlaybackrateOption, { selectedRate: playbackRate, onSelect: onSelect, rate: rate, keyboardSelectedRate: keyboardSelectedRate }, rate));
|
|
929
|
+
}) }));
|
|
930
|
+
};
|
|
931
|
+
const PlaybackrateOption = ({ rate, onSelect, selectedRate, keyboardSelectedRate }) => {
|
|
932
|
+
const onClick = useCallback((e) => {
|
|
933
|
+
e.stopPropagation();
|
|
934
|
+
e.preventDefault();
|
|
935
|
+
onSelect(rate);
|
|
936
|
+
}, [onSelect, rate]);
|
|
937
|
+
const [hovered, setHovered] = useState(false);
|
|
938
|
+
const onMouseEnter = useCallback(() => {
|
|
939
|
+
setHovered(true);
|
|
940
|
+
}, []);
|
|
941
|
+
const onMouseLeave = useCallback(() => {
|
|
942
|
+
setHovered(false);
|
|
943
|
+
}, []);
|
|
944
|
+
const actualStyle = useMemo(() => {
|
|
945
|
+
return {
|
|
946
|
+
...rateDiv,
|
|
947
|
+
backgroundColor: hovered || keyboardSelectedRate === rate ? '#eee' : 'transparent',
|
|
948
|
+
};
|
|
949
|
+
}, [hovered, keyboardSelectedRate, rate]);
|
|
950
|
+
return (jsxs("div", { onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, tabIndex: 0, style: actualStyle, onClick: onClick, children: [jsx("div", { style: checkmarkContainer, children: rate === selectedRate ? jsx(Checkmark, {}) : null }), rate.toFixed(1), "x"] }, rate));
|
|
951
|
+
};
|
|
952
|
+
const playbackButton = {
|
|
953
|
+
position: 'relative',
|
|
954
|
+
display: 'inline-flex',
|
|
955
|
+
alignItems: 'center',
|
|
956
|
+
padding: '6px 0 6px 0',
|
|
957
|
+
border: 'none',
|
|
958
|
+
background: 'none',
|
|
959
|
+
height: 36,
|
|
960
|
+
cursor: 'pointer',
|
|
961
|
+
};
|
|
962
|
+
const PlaybackrateControl = ({ playbackRates }) => {
|
|
963
|
+
const { ref, isComponentVisible, setIsComponentVisible } = useComponentVisible(false);
|
|
964
|
+
const onClick = useCallback((e) => {
|
|
965
|
+
e.stopPropagation();
|
|
966
|
+
e.preventDefault();
|
|
967
|
+
setIsComponentVisible(!isComponentVisible);
|
|
968
|
+
}, [isComponentVisible, setIsComponentVisible]);
|
|
969
|
+
return (jsx("div", { ref: ref, children: jsxs("button", { type: "button", "aria-label": "Change playback rate", style: playbackButton, onClick: onClick, children: [jsx(SettingsIcon, { iconSize: 22 }), isComponentVisible && (jsx(PlaybackPopup, { playbackRates: playbackRates, setIsComponentVisible: setIsComponentVisible }))] }) }));
|
|
970
|
+
};
|
|
971
|
+
|
|
823
972
|
const getFrameFromX = (clientX, durationInFrames, width) => {
|
|
824
973
|
var _a;
|
|
825
974
|
const pos = clientX;
|
|
@@ -1047,7 +1196,7 @@ const leftPartStyle = {
|
|
|
1047
1196
|
alignItems: 'center',
|
|
1048
1197
|
};
|
|
1049
1198
|
const xSpacer = {
|
|
1050
|
-
width:
|
|
1199
|
+
width: 12,
|
|
1051
1200
|
};
|
|
1052
1201
|
const ySpacer = {
|
|
1053
1202
|
height: 8,
|
|
@@ -1057,7 +1206,7 @@ const flex1 = {
|
|
|
1057
1206
|
};
|
|
1058
1207
|
const fullscreen = {};
|
|
1059
1208
|
const PlayPauseButton = ({ playing }) => playing ? jsx(PauseIcon, {}) : jsx(PlayIcon, {});
|
|
1060
|
-
const Controls = ({ durationInFrames, hovered, isFullscreen, fps, player, showVolumeControls, onFullscreenButtonClick, allowFullscreen, onExitFullscreenButtonClick, spaceKeyToPlayOrPause, onSeekEnd, onSeekStart, inFrame, outFrame, initiallyShowControls, playerWidth, renderPlayPauseButton, renderFullscreenButton, alwaysShowControls, }) => {
|
|
1209
|
+
const Controls = ({ durationInFrames, hovered, isFullscreen, fps, player, showVolumeControls, onFullscreenButtonClick, allowFullscreen, onExitFullscreenButtonClick, spaceKeyToPlayOrPause, onSeekEnd, onSeekStart, inFrame, outFrame, initiallyShowControls, playerWidth, renderPlayPauseButton, renderFullscreenButton, alwaysShowControls, showPlaybackRateControl, }) => {
|
|
1061
1210
|
const playButtonRef = useRef(null);
|
|
1062
1211
|
const frame = Internals.Timeline.useTimelinePosition();
|
|
1063
1212
|
const [supportsFullscreen, setSupportsFullscreen] = useState(false);
|
|
@@ -1127,7 +1276,24 @@ const Controls = ({ durationInFrames, hovered, isFullscreen, fps, player, showVo
|
|
|
1127
1276
|
textOverflow: 'ellipsis',
|
|
1128
1277
|
};
|
|
1129
1278
|
}, [maxTimeLabelWidth]);
|
|
1130
|
-
|
|
1279
|
+
const playbackRates = useMemo(() => {
|
|
1280
|
+
if (showPlaybackRateControl === true) {
|
|
1281
|
+
return [0.5, 0.8, 1, 1.2, 1.5, 1.8, 2, 2.5, 3];
|
|
1282
|
+
}
|
|
1283
|
+
if (Array.isArray(showPlaybackRateControl)) {
|
|
1284
|
+
for (const rate of showPlaybackRateControl) {
|
|
1285
|
+
if (typeof rate !== 'number') {
|
|
1286
|
+
throw new Error('Every item in showPlaybackRateControl must be a number');
|
|
1287
|
+
}
|
|
1288
|
+
if (rate <= 0) {
|
|
1289
|
+
throw new Error('Every item in showPlaybackRateControl must be positive');
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
return showPlaybackRateControl;
|
|
1293
|
+
}
|
|
1294
|
+
return null;
|
|
1295
|
+
}, [showPlaybackRateControl]);
|
|
1296
|
+
return (jsxs("div", { style: containerCss, children: [jsxs("div", { style: controlsRow, children: [jsxs("div", { style: leftPartStyle, children: [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 ? (jsx(PlayPauseButton, { playing: player.playing })) : (renderPlayPauseButton({ playing: player.playing })) }), showVolumeControls ? (jsxs(Fragment, { children: [jsx("div", { style: xSpacer }), jsx(MediaVolumeSlider, { displayVerticalVolumeSlider: displayVerticalVolumeSlider })] })) : null, jsx("div", { style: xSpacer }), jsxs("div", { style: timeLabel, children: [formatTime(frame / fps), " / ", formatTime(durationInFrames / fps)] }), jsx("div", { style: xSpacer })] }), jsx("div", { style: flex1 }), playbackRates && jsx(PlaybackrateControl, { playbackRates: playbackRates }), playbackRates && supportsFullscreen && allowFullscreen ? (jsx("div", { style: xSpacer })) : null, jsx("div", { style: fullscreen, children: supportsFullscreen && allowFullscreen ? (jsx("button", { type: "button", "aria-label": isFullscreen ? 'Exit fullscreen' : 'Enter Fullscreen', title: isFullscreen ? 'Exit fullscreen' : 'Enter Fullscreen', style: buttonStyle, onClick: isFullscreen
|
|
1131
1297
|
? onExitFullscreenButtonClick
|
|
1132
1298
|
: onFullscreenButtonClick, children: renderFullscreenButton === null ? (jsx(FullscreenIcon, { isFullscreen: isFullscreen })) : (renderFullscreenButton({ isFullscreen })) })) : null })] }), jsx("div", { style: ySpacer }), jsx(PlayerSeekBar, { onSeekEnd: onSeekEnd, onSeekStart: onSeekStart, durationInFrames: durationInFrames, inFrame: inFrame, outFrame: outFrame })] }));
|
|
1133
1299
|
};
|
|
@@ -1220,7 +1386,7 @@ if (reactVersion$1 === '0') {
|
|
|
1220
1386
|
throw new Error(`Version ${reactVersion$1} of "react" is not supported by Remotion`);
|
|
1221
1387
|
}
|
|
1222
1388
|
const doesReactVersionSupportSuspense$1 = parseInt(reactVersion$1, 10) >= 18;
|
|
1223
|
-
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, }, ref) => {
|
|
1389
|
+
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) => {
|
|
1224
1390
|
var _a, _b, _c, _d;
|
|
1225
1391
|
const config = Internals.useUnsafeVideoConfig();
|
|
1226
1392
|
const video = Internals.useVideo();
|
|
@@ -1496,7 +1662,7 @@ const PlayerUI = ({ controls, style, loop, autoPlay, allowFullscreen, inputProps
|
|
|
1496
1662
|
showPosterWhenEnded && player.isLastFrame && !player.isPlaying(),
|
|
1497
1663
|
showPosterWhenUnplayed && !player.hasPlayed && !player.isPlaying(),
|
|
1498
1664
|
].some(Boolean);
|
|
1499
|
-
const content = (jsxs(Fragment, { children: [jsx("div", { style: outer, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: jsx("div", { style: containerStyle, className: PLAYER_CSS_CLASSNAME, children: VideoComponent ? (jsx(ErrorBoundary, { onError: onError, errorFallback: errorFallback, children: 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 ? (jsx("div", { style: outer, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null, controls ? (jsx(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 })) : null] }));
|
|
1665
|
+
const content = (jsxs(Fragment, { children: [jsx("div", { style: outer, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: jsx("div", { style: containerStyle, className: PLAYER_CSS_CLASSNAME, children: VideoComponent ? (jsx(ErrorBoundary, { onError: onError, errorFallback: errorFallback, children: 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 ? (jsx("div", { style: outer, onClick: clickToPlay ? handleClick : undefined, onDoubleClick: doubleClickToFullscreen ? handleDoubleClick : undefined, children: poster })) : null, controls ? (jsx(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] }));
|
|
1500
1666
|
if (IS_NODE && !doesReactVersionSupportSuspense$1) {
|
|
1501
1667
|
return (jsx("div", { ref: container, style: outerStyle, className: className, children: content }));
|
|
1502
1668
|
}
|
|
@@ -1682,7 +1848,7 @@ const componentOrNullIfLazy = (props) => {
|
|
|
1682
1848
|
}
|
|
1683
1849
|
return null;
|
|
1684
1850
|
};
|
|
1685
|
-
const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps, inputProps, style, controls = false, loop = false, autoPlay = false, showVolumeControls = true, allowFullscreen = true, clickToPlay, doubleClickToFullscreen = false, spaceKeyToPlayOrPause = true, moveToBeginningWhenEnded = true, numberOfSharedAudioTags = 5, errorFallback = () => '⚠️', playbackRate = 1, renderLoading, className, showPosterWhenUnplayed, showPosterWhenEnded, showPosterWhenPaused, initialFrame, renderPoster, inFrame, outFrame, initiallyShowControls, renderFullscreenButton, renderPlayPauseButton, alwaysShowControls = false, initiallyMuted = false, ...componentProps }, ref) => {
|
|
1851
|
+
const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps, inputProps, style, controls = false, loop = false, autoPlay = false, showVolumeControls = true, allowFullscreen = true, clickToPlay, doubleClickToFullscreen = false, spaceKeyToPlayOrPause = true, moveToBeginningWhenEnded = true, numberOfSharedAudioTags = 5, errorFallback = () => '⚠️', playbackRate = 1, renderLoading, className, showPosterWhenUnplayed, showPosterWhenEnded, showPosterWhenPaused, initialFrame, renderPoster, inFrame, outFrame, initiallyShowControls, renderFullscreenButton, renderPlayPauseButton, alwaysShowControls = false, initiallyMuted = false, showPlaybackRateControl = false, ...componentProps }, ref) => {
|
|
1686
1852
|
if (typeof window !== 'undefined') {
|
|
1687
1853
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
1688
1854
|
useLayoutEffect(() => {
|
|
@@ -1710,6 +1876,7 @@ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps,
|
|
|
1710
1876
|
const rootRef = useRef(null);
|
|
1711
1877
|
const audioAndVideoTags = useRef([]);
|
|
1712
1878
|
const imperativePlaying = useRef(false);
|
|
1879
|
+
const [currentPlaybackRate, setCurrentPlaybackRate] = useState(playbackRate);
|
|
1713
1880
|
if (typeof compositionHeight !== 'number') {
|
|
1714
1881
|
throw new TypeError(`'compositionHeight' must be a number but got '${typeof compositionHeight}' instead`);
|
|
1715
1882
|
}
|
|
@@ -1765,10 +1932,13 @@ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps,
|
|
|
1765
1932
|
numberOfSharedAudioTags < 0) {
|
|
1766
1933
|
throw new TypeError(`'numberOfSharedAudioTags' must be an integer but got '${numberOfSharedAudioTags}' instead`);
|
|
1767
1934
|
}
|
|
1768
|
-
validatePlaybackRate(
|
|
1935
|
+
validatePlaybackRate(currentPlaybackRate);
|
|
1769
1936
|
useEffect(() => {
|
|
1770
|
-
emitter.dispatchRateChange(
|
|
1771
|
-
}, [emitter,
|
|
1937
|
+
emitter.dispatchRateChange(currentPlaybackRate);
|
|
1938
|
+
}, [emitter, currentPlaybackRate]);
|
|
1939
|
+
useEffect(() => {
|
|
1940
|
+
setCurrentPlaybackRate(playbackRate);
|
|
1941
|
+
}, [playbackRate]);
|
|
1772
1942
|
useImperativeHandle(ref, () => rootRef.current, []);
|
|
1773
1943
|
const timelineContextValue = useMemo(() => {
|
|
1774
1944
|
return {
|
|
@@ -1776,14 +1946,14 @@ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps,
|
|
|
1776
1946
|
playing,
|
|
1777
1947
|
rootId,
|
|
1778
1948
|
shouldRegisterSequences: false,
|
|
1779
|
-
playbackRate,
|
|
1949
|
+
playbackRate: currentPlaybackRate,
|
|
1780
1950
|
imperativePlaying,
|
|
1781
|
-
setPlaybackRate: () => {
|
|
1782
|
-
|
|
1951
|
+
setPlaybackRate: (rate) => {
|
|
1952
|
+
setCurrentPlaybackRate(rate);
|
|
1783
1953
|
},
|
|
1784
1954
|
audioAndVideoTags,
|
|
1785
1955
|
};
|
|
1786
|
-
}, [frame,
|
|
1956
|
+
}, [frame, currentPlaybackRate, playing, rootId]);
|
|
1787
1957
|
const setTimelineContextValue = useMemo(() => {
|
|
1788
1958
|
return {
|
|
1789
1959
|
setFrame,
|
|
@@ -1803,7 +1973,7 @@ const PlayerFn = ({ durationInFrames, compositionHeight, compositionWidth, fps,
|
|
|
1803
1973
|
const actualInputProps = useMemo(() => inputProps !== null && inputProps !== void 0 ? inputProps : {}, [inputProps]);
|
|
1804
1974
|
return (jsx(Internals.IsPlayerContextProvider, { children: jsx(SharedPlayerContexts, { timelineContext: timelineContextValue, component: component, compositionHeight: compositionHeight, compositionWidth: compositionWidth, durationInFrames: durationInFrames, fps: fps, inputProps: actualInputProps, numberOfSharedAudioTags: numberOfSharedAudioTags, initiallyMuted: initiallyMuted, children: jsx(Internals.Timeline.SetTimelineContext.Provider, { value: setTimelineContextValue, children: jsx(PlayerEventEmitterContext.Provider, { value: emitter, children: jsx(PlayerUI$1, { ref: rootRef, renderLoading: renderLoading, autoPlay: Boolean(autoPlay), loop: Boolean(loop), controls: Boolean(controls), errorFallback: errorFallback, style: style, inputProps: passedInputProps, allowFullscreen: Boolean(allowFullscreen), moveToBeginningWhenEnded: Boolean(moveToBeginningWhenEnded), clickToPlay: typeof clickToPlay === 'boolean'
|
|
1805
1975
|
? clickToPlay
|
|
1806
|
-
: Boolean(controls), showVolumeControls: Boolean(showVolumeControls), doubleClickToFullscreen: Boolean(doubleClickToFullscreen), spaceKeyToPlayOrPause: Boolean(spaceKeyToPlayOrPause), playbackRate:
|
|
1976
|
+
: Boolean(controls), showVolumeControls: Boolean(showVolumeControls), doubleClickToFullscreen: Boolean(doubleClickToFullscreen), spaceKeyToPlayOrPause: Boolean(spaceKeyToPlayOrPause), playbackRate: currentPlaybackRate, className: className !== null && className !== void 0 ? className : undefined, showPosterWhenUnplayed: Boolean(showPosterWhenUnplayed), showPosterWhenEnded: Boolean(showPosterWhenEnded), showPosterWhenPaused: Boolean(showPosterWhenPaused), renderPoster: renderPoster, inFrame: inFrame !== null && inFrame !== void 0 ? inFrame : null, outFrame: outFrame !== null && outFrame !== void 0 ? outFrame : null, initiallyShowControls: initiallyShowControls !== null && initiallyShowControls !== void 0 ? initiallyShowControls : true, renderFullscreen: renderFullscreenButton !== null && renderFullscreenButton !== void 0 ? renderFullscreenButton : null, renderPlayPauseButton: renderPlayPauseButton !== null && renderPlayPauseButton !== void 0 ? renderPlayPauseButton : null, alwaysShowControls: alwaysShowControls, showPlaybackRateControl: showPlaybackRateControl }) }) }) }) }));
|
|
1807
1977
|
};
|
|
1808
1978
|
const forward$1 = forwardRef;
|
|
1809
1979
|
/**
|