UNPKG

@remotion/player

Version:

React component for embedding a Remotion preview into your app

193 lines (192 loc) • 7.19 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 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 } = remotion_1.Internals.useTimelineContext(); 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) => { var _a; if (imperativePlaying.current) { return; } setHasPlayed(true); if (isLastFrame) { seek(0); } (_a = audioContext === null || audioContext === void 0 ? void 0 : audioContext.audioContext) === null || _a === void 0 ? void 0 : _a.resume(); /** * 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)(() => { var _a; if (imperativePlaying.current) { imperativePlaying.current = false; setPlaying(false); emitter.dispatchPause(); (_a = audioContext === null || audioContext === void 0 ? void 0 : audioContext.audioContext) === null || _a === void 0 ? void 0 : _a.suspend(); } }, [emitter, imperativePlaying, setPlaying, audioContext]); 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 toggle = (0, react_1.useCallback)((e) => { if (imperativePlaying.current) { pause(); } else { play(e); } }, [imperativePlaying, pause, play]); const isPlaying = (0, react_1.useCallback)(() => { return imperativePlaying.current; }, [imperativePlaying]); const getCurrentFrame = (0, react_1.useCallback)(() => { return frameRef.current; }, [frameRef]); const isBuffering = (0, react_1.useCallback)(() => { return buffering.current; }, [buffering]); const returnValue = (0, react_1.useMemo)(() => { return { frameBack, frameForward, isLastFrame, emitter, playing, play, pause, seek, isFirstFrame, getCurrentFrame, isPlaying, isBuffering, pauseAndReturnToPlayStart, hasPlayed, toggle, }; }, [ emitter, frameBack, frameForward, hasPlayed, isFirstFrame, isLastFrame, getCurrentFrame, pause, pauseAndReturnToPlayStart, play, playing, seek, toggle, isPlaying, isBuffering, ]); return returnValue; }; exports.usePlayer = usePlayer;