UNPKG

@remotion/player

Version:

React component for embedding a Remotion preview into your app

183 lines (182 loc) • 6.79 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.usePlayer = void 0; const react_1 = require("react"); const remotion_1 = require("remotion"); const emitter_context_js_1 = require("./emitter-context.js"); const use_frame_imperative_js_1 = require("./use-frame-imperative.js"); const usePlayer = () => { var _a; const [playing, setPlaying, imperativePlaying] = remotion_1.Internals.Timeline.usePlayingState(); const [hasPlayed, setHasPlayed] = (0, react_1.useState)(false); const frame = remotion_1.Internals.Timeline.useTimelinePosition(); const playStart = (0, react_1.useRef)(frame); const setFrame = remotion_1.Internals.Timeline.useTimelineSetFrame(); const setTimelinePosition = remotion_1.Internals.Timeline.useTimelineSetFrame(); const audioContext = (0, react_1.useContext)(remotion_1.Internals.SharedAudioContext); const { audioAndVideoTags } = (0, react_1.useContext)(remotion_1.Internals.Timeline.TimelineContext); const frameRef = (0, react_1.useRef)(frame); frameRef.current = frame; const video = remotion_1.Internals.useVideo(); const config = remotion_1.Internals.useUnsafeVideoConfig(); const emitter = (0, react_1.useContext)(emitter_context_js_1.PlayerEventEmitterContext); const lastFrame = ((_a = config === null || config === void 0 ? void 0 : config.durationInFrames) !== null && _a !== void 0 ? _a : 1) - 1; const isLastFrame = frame === lastFrame; const isFirstFrame = frame === 0; if (!emitter) { throw new TypeError('Expected Player event emitter context'); } const bufferingContext = (0, react_1.useContext)(remotion_1.Internals.BufferingContextReact); if (!bufferingContext) { throw new Error('Missing the buffering context. Most likely you have a Remotion version mismatch.'); } const { buffering } = bufferingContext; const seek = (0, react_1.useCallback)((newFrame) => { if (video === null || video === void 0 ? void 0 : video.id) { setTimelinePosition((c) => ({ ...c, [video.id]: newFrame })); } frameRef.current = newFrame; emitter.dispatchSeek(newFrame); }, [emitter, setTimelinePosition, video === null || video === void 0 ? void 0 : video.id]); const play = (0, react_1.useCallback)((e) => { if (imperativePlaying.current) { return; } setHasPlayed(true); if (isLastFrame) { seek(0); } /** * Play silent audio tags to warm them up for autoplay */ if (audioContext && audioContext.numberOfAudioTags > 0 && e) { audioContext.playAllAudios(); } /** * Play audios and videos directly here so they can benefit from * being triggered by a click */ audioAndVideoTags.current.forEach((a) => a.play('player play() was called and playing audio from a click')); imperativePlaying.current = true; setPlaying(true); playStart.current = frameRef.current; emitter.dispatchPlay(); }, [ imperativePlaying, isLastFrame, audioContext, setPlaying, emitter, seek, audioAndVideoTags, ]); const pause = (0, react_1.useCallback)(() => { if (imperativePlaying.current) { imperativePlaying.current = false; setPlaying(false); emitter.dispatchPause(); } }, [emitter, imperativePlaying, setPlaying]); const pauseAndReturnToPlayStart = (0, react_1.useCallback)(() => { if (imperativePlaying.current) { imperativePlaying.current = false; frameRef.current = playStart.current; if (config) { setTimelinePosition((c) => ({ ...c, [config.id]: playStart.current, })); setPlaying(false); emitter.dispatchPause(); } } }, [config, emitter, imperativePlaying, setPlaying, setTimelinePosition]); const videoId = video === null || video === void 0 ? void 0 : video.id; const frameBack = (0, react_1.useCallback)((frames) => { if (!videoId) { return null; } if (imperativePlaying.current) { return; } setFrame((c) => { var _a, _b; const prevFrame = (_b = (_a = c[videoId]) !== null && _a !== void 0 ? _a : window.remotion_initialFrame) !== null && _b !== void 0 ? _b : 0; const newFrame = Math.max(0, prevFrame - frames); if (prevFrame === newFrame) { return c; } return { ...c, [videoId]: newFrame, }; }); }, [imperativePlaying, setFrame, videoId]); const frameForward = (0, react_1.useCallback)((frames) => { if (!videoId) { return null; } if (imperativePlaying.current) { return; } setFrame((c) => { var _a, _b; const prevFrame = (_b = (_a = c[videoId]) !== null && _a !== void 0 ? _a : window.remotion_initialFrame) !== null && _b !== void 0 ? _b : 0; const newFrame = Math.min(lastFrame, prevFrame + frames); if (prevFrame === newFrame) { return c; } return { ...c, [videoId]: newFrame, }; }); }, [videoId, imperativePlaying, lastFrame, setFrame]); const getCurrentFrame = (0, use_frame_imperative_js_1.useFrameImperative)(); const toggle = (0, react_1.useCallback)((e) => { if (imperativePlaying.current) { pause(); } else { play(e); } }, [imperativePlaying, pause, play]); const returnValue = (0, react_1.useMemo)(() => { return { frameBack, frameForward, isLastFrame, emitter, playing, play, pause, seek, isFirstFrame, getCurrentFrame, isPlaying: () => imperativePlaying.current, isBuffering: () => buffering.current, pauseAndReturnToPlayStart, hasPlayed, remotionInternal_currentFrameRef: frameRef, toggle, }; }, [ buffering, emitter, frameBack, frameForward, getCurrentFrame, hasPlayed, imperativePlaying, isFirstFrame, isLastFrame, pause, pauseAndReturnToPlayStart, play, playing, seek, toggle, ]); return returnValue; }; exports.usePlayer = usePlayer;