246 lines
10 KiB
JavaScript
246 lines
10 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.PlayPause = void 0;
|
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
const player_1 = require("@remotion/player");
|
|
const react_1 = require("react");
|
|
const remotion_1 = require("remotion");
|
|
const is_current_selected_still_1 = require("../helpers/is-current-selected-still");
|
|
const use_keybinding_1 = require("../helpers/use-keybinding");
|
|
const jump_to_start_1 = require("../icons/jump-to-start");
|
|
const pause_1 = require("../icons/pause");
|
|
const play_1 = require("../icons/play");
|
|
const step_back_1 = require("../icons/step-back");
|
|
const step_forward_1 = require("../icons/step-forward");
|
|
const in_out_1 = require("../state/in-out");
|
|
const ControlButton_1 = require("./ControlButton");
|
|
const imperative_state_1 = require("./Timeline/imperative-state");
|
|
const timeline_scroll_logic_1 = require("./Timeline/timeline-scroll-logic");
|
|
const backStyle = {
|
|
height: 18,
|
|
color: 'white',
|
|
};
|
|
const forwardBackStyle = {
|
|
height: 16,
|
|
color: 'white',
|
|
};
|
|
const iconButton = {
|
|
height: 14,
|
|
width: 14,
|
|
color: 'white',
|
|
};
|
|
const PlayPause = ({ playbackRate, loop, bufferStateDelayInMilliseconds }) => {
|
|
const { inFrame, outFrame } = (0, in_out_1.useTimelineInOutFramePosition)();
|
|
const videoConfig = remotion_1.Internals.useUnsafeVideoConfig();
|
|
const [showBufferIndicator, setShowBufferState] = (0, react_1.useState)(false);
|
|
const { playing, play, pause, pauseAndReturnToPlayStart, frameBack, seek, frameForward, isLastFrame, isFirstFrame, emitter, getCurrentFrame, } = player_1.PlayerInternals.usePlayer();
|
|
player_1.PlayerInternals.usePlayback({
|
|
loop,
|
|
playbackRate,
|
|
moveToBeginningWhenEnded: true,
|
|
inFrame,
|
|
outFrame,
|
|
getCurrentFrame,
|
|
browserMediaControlsBehavior: {
|
|
mode: 'register-media-session',
|
|
},
|
|
});
|
|
const isStill = (0, is_current_selected_still_1.useIsStill)();
|
|
(0, react_1.useEffect)(() => {
|
|
if (isStill) {
|
|
pause();
|
|
}
|
|
}, [isStill, pause]);
|
|
const onSpace = (0, react_1.useCallback)((e) => {
|
|
if (playing) {
|
|
pause();
|
|
}
|
|
else {
|
|
play();
|
|
}
|
|
e.preventDefault();
|
|
}, [pause, play, playing]);
|
|
const onEnter = (0, react_1.useCallback)((e) => {
|
|
if (playing) {
|
|
// Don't prevent keyboard navigation
|
|
e.preventDefault();
|
|
pauseAndReturnToPlayStart();
|
|
}
|
|
}, [pauseAndReturnToPlayStart, playing]);
|
|
const onArrowLeft = (0, react_1.useCallback)((e) => {
|
|
e.preventDefault();
|
|
if (e.altKey) {
|
|
seek(0);
|
|
(0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
|
|
direction: 'fit-left',
|
|
durationInFrames: (0, imperative_state_1.getCurrentDuration)(),
|
|
frame: 0,
|
|
});
|
|
}
|
|
else if (e.shiftKey) {
|
|
frameBack((0, imperative_state_1.getCurrentFps)());
|
|
(0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
|
|
direction: 'fit-left',
|
|
durationInFrames: (0, imperative_state_1.getCurrentDuration)(),
|
|
frame: Math.max(0, getCurrentFrame() - (0, imperative_state_1.getCurrentFps)()),
|
|
});
|
|
}
|
|
else {
|
|
frameBack(1);
|
|
(0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
|
|
direction: 'fit-left',
|
|
durationInFrames: (0, imperative_state_1.getCurrentDuration)(),
|
|
frame: Math.max(0, getCurrentFrame() - 1),
|
|
});
|
|
}
|
|
}, [frameBack, seek, getCurrentFrame]);
|
|
const onArrowRight = (0, react_1.useCallback)((e) => {
|
|
if (e.altKey) {
|
|
seek((0, imperative_state_1.getCurrentDuration)() - 1);
|
|
(0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
|
|
direction: 'fit-right',
|
|
durationInFrames: (0, imperative_state_1.getCurrentDuration)() - 1,
|
|
frame: (0, imperative_state_1.getCurrentDuration)() - 1,
|
|
});
|
|
}
|
|
else if (e.shiftKey) {
|
|
frameForward((0, imperative_state_1.getCurrentFps)());
|
|
(0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
|
|
direction: 'fit-right',
|
|
durationInFrames: (0, imperative_state_1.getCurrentDuration)(),
|
|
frame: Math.min((0, imperative_state_1.getCurrentDuration)() - 1, getCurrentFrame() + (0, imperative_state_1.getCurrentFps)()),
|
|
});
|
|
}
|
|
else {
|
|
frameForward(1);
|
|
(0, timeline_scroll_logic_1.ensureFrameIsInViewport)({
|
|
direction: 'fit-right',
|
|
durationInFrames: (0, imperative_state_1.getCurrentDuration)(),
|
|
frame: Math.min((0, imperative_state_1.getCurrentDuration)() - 1, getCurrentFrame() + 1),
|
|
});
|
|
}
|
|
e.preventDefault();
|
|
}, [frameForward, seek, getCurrentFrame]);
|
|
const oneFrameBack = (0, react_1.useCallback)(() => {
|
|
frameBack(1);
|
|
}, [frameBack]);
|
|
const oneFrameForward = (0, react_1.useCallback)(() => {
|
|
frameForward(1);
|
|
}, [frameForward]);
|
|
const jumpToStart = (0, react_1.useCallback)(() => {
|
|
seek(inFrame !== null && inFrame !== void 0 ? inFrame : 0);
|
|
}, [seek, inFrame]);
|
|
const jumpToEnd = (0, react_1.useCallback)(() => {
|
|
seek(outFrame !== null && outFrame !== void 0 ? outFrame : (0, imperative_state_1.getCurrentDuration)() - 1);
|
|
}, [seek, outFrame]);
|
|
const keybindings = (0, use_keybinding_1.useKeybinding)();
|
|
(0, react_1.useEffect)(() => {
|
|
const arrowLeft = keybindings.registerKeybinding({
|
|
event: 'keydown',
|
|
key: 'ArrowLeft',
|
|
callback: onArrowLeft,
|
|
commandCtrlKey: false,
|
|
preventDefault: true,
|
|
triggerIfInputFieldFocused: false,
|
|
keepRegisteredWhenNotHighestContext: false,
|
|
});
|
|
const arrowRight = keybindings.registerKeybinding({
|
|
event: 'keydown',
|
|
key: 'ArrowRight',
|
|
callback: onArrowRight,
|
|
commandCtrlKey: false,
|
|
preventDefault: true,
|
|
triggerIfInputFieldFocused: false,
|
|
keepRegisteredWhenNotHighestContext: false,
|
|
});
|
|
const space = keybindings.registerKeybinding({
|
|
event: 'keydown',
|
|
key: ' ',
|
|
callback: onSpace,
|
|
commandCtrlKey: false,
|
|
preventDefault: true,
|
|
triggerIfInputFieldFocused: false,
|
|
keepRegisteredWhenNotHighestContext: false,
|
|
});
|
|
const enter = keybindings.registerKeybinding({
|
|
event: 'keydown',
|
|
key: 'enter',
|
|
callback: onEnter,
|
|
commandCtrlKey: false,
|
|
preventDefault: false,
|
|
triggerIfInputFieldFocused: false,
|
|
keepRegisteredWhenNotHighestContext: false,
|
|
});
|
|
const a = keybindings.registerKeybinding({
|
|
event: 'keydown',
|
|
key: 'a',
|
|
callback: jumpToStart,
|
|
commandCtrlKey: false,
|
|
preventDefault: true,
|
|
triggerIfInputFieldFocused: false,
|
|
keepRegisteredWhenNotHighestContext: false,
|
|
});
|
|
const e = keybindings.registerKeybinding({
|
|
event: 'keydown',
|
|
key: 'e',
|
|
callback: jumpToEnd,
|
|
commandCtrlKey: false,
|
|
preventDefault: true,
|
|
triggerIfInputFieldFocused: false,
|
|
keepRegisteredWhenNotHighestContext: false,
|
|
});
|
|
return () => {
|
|
arrowLeft.unregister();
|
|
arrowRight.unregister();
|
|
space.unregister();
|
|
enter.unregister();
|
|
a.unregister();
|
|
e.unregister();
|
|
};
|
|
}, [
|
|
jumpToEnd,
|
|
jumpToStart,
|
|
keybindings,
|
|
onArrowLeft,
|
|
onArrowRight,
|
|
onEnter,
|
|
onSpace,
|
|
]);
|
|
(0, react_1.useEffect)(() => {
|
|
let timeout = null;
|
|
let stopped = false;
|
|
const onBuffer = () => {
|
|
requestAnimationFrame(() => {
|
|
stopped = false;
|
|
timeout = setTimeout(() => {
|
|
if (!stopped) {
|
|
setShowBufferState(true);
|
|
}
|
|
}, bufferStateDelayInMilliseconds);
|
|
});
|
|
};
|
|
const onResume = () => {
|
|
requestAnimationFrame(() => {
|
|
setShowBufferState(false);
|
|
stopped = true;
|
|
if (timeout) {
|
|
clearTimeout(timeout);
|
|
}
|
|
});
|
|
};
|
|
emitter.addEventListener('waiting', onBuffer);
|
|
emitter.addEventListener('resume', onResume);
|
|
return () => {
|
|
emitter.removeEventListener('waiting', onBuffer);
|
|
emitter.removeEventListener('resume', onResume);
|
|
setShowBufferState(false);
|
|
if (timeout) {
|
|
clearTimeout(timeout);
|
|
}
|
|
stopped = true;
|
|
};
|
|
}, [bufferStateDelayInMilliseconds, emitter]);
|
|
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ControlButton_1.ControlButton, { "aria-label": "Jump to beginning", title: "Jump to beginning", disabled: !videoConfig || isFirstFrame, onClick: jumpToStart, children: (0, jsx_runtime_1.jsx)(jump_to_start_1.JumpToStart, { style: backStyle }) }), (0, jsx_runtime_1.jsx)(ControlButton_1.ControlButton, { "aria-label": "Step back one frame", title: "Step back one frame", disabled: !videoConfig || isFirstFrame, onClick: oneFrameBack, children: (0, jsx_runtime_1.jsx)(step_back_1.StepBack, { style: forwardBackStyle }) }), (0, jsx_runtime_1.jsx)(ControlButton_1.ControlButton, { "aria-label": playing ? 'Pause' : 'Play', title: playing ? 'Pause' : 'Play', onClick: playing ? pause : play, disabled: !videoConfig, children: playing ? (showBufferIndicator ? ((0, jsx_runtime_1.jsx)(player_1.PlayerInternals.BufferingIndicator, { type: "studio" })) : ((0, jsx_runtime_1.jsx)(pause_1.Pause, { style: iconButton }))) : ((0, jsx_runtime_1.jsx)(play_1.Play, { style: iconButton })) }), (0, jsx_runtime_1.jsx)(ControlButton_1.ControlButton, { "aria-label": "Step forward one frame", title: "Step forward one frame", disabled: !videoConfig || isLastFrame, onClick: oneFrameForward, children: (0, jsx_runtime_1.jsx)(step_forward_1.StepForward, { style: forwardBackStyle }) })] }));
|
|
};
|
|
exports.PlayPause = PlayPause;
|