UNPKG

@remotion/gif

Version:

Embed GIFs in a Remotion video

108 lines (107 loc) 4.48 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GifForRendering = void 0; const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const remotion_1 = require("remotion"); const canvas_1 = require("./canvas"); const gif_cache_1 = require("./gif-cache"); const is_cors_error_1 = require("./is-cors-error"); const react_tools_1 = require("./react-tools"); const resolve_gif_source_1 = require("./resolve-gif-source"); const useCurrentGifIndex_1 = require("./useCurrentGifIndex"); exports.GifForRendering = (0, react_1.forwardRef)(({ src, width, height, onLoad, onError, loopBehavior = 'loop', playbackRate = 1, fit = 'fill', delayRenderTimeoutInMilliseconds, ...props }, ref) => { const resolvedSrc = (0, resolve_gif_source_1.resolveGifSource)(src); const { delayRender, continueRender } = (0, remotion_1.useDelayRender)(); const [state, update] = (0, react_1.useState)(() => { const parsedGif = gif_cache_1.volatileGifCache.get(resolvedSrc); if (parsedGif === undefined) { return { delays: [], frames: [], width: 0, height: 0, }; } return parsedGif; }); const [error, setError] = (0, react_1.useState)(null); const [renderHandle] = (0, react_1.useState)(() => delayRender(`Rendering <Gif/> with src="${resolvedSrc}"`, { timeoutInMilliseconds: delayRenderTimeoutInMilliseconds, })); const logLevel = remotion_1.Internals.useLogLevel(); (0, react_1.useEffect)(() => { return () => { continueRender(renderHandle); }; }, [renderHandle, continueRender]); const index = (0, useCurrentGifIndex_1.useCurrentGifIndex)({ delays: state.delays, loopBehavior, playbackRate, }); const currentOnLoad = (0, react_1.useRef)(onLoad); const currentOnError = (0, react_1.useRef)(onError); currentOnLoad.current = onLoad; currentOnError.current = onError; (0, react_1.useEffect)(() => { const controller = new AbortController(); let done = false; let aborted = false; const newHandle = delayRender('Loading <Gif /> with src=' + resolvedSrc, { timeoutInMilliseconds: delayRenderTimeoutInMilliseconds, }); remotion_1.Internals.Log.verbose({ logLevel, tag: null }, 'Loading GIF with source', resolvedSrc); const time = Date.now(); (0, react_tools_1.parseGif)({ controller, src: resolvedSrc }) .then((parsed) => { var _a; remotion_1.Internals.Log.verbose({ logLevel, tag: null }, 'Parsed GIF in', Date.now() - time, 'ms'); (_a = currentOnLoad.current) === null || _a === void 0 ? void 0 : _a.call(currentOnLoad, parsed); update(parsed); gif_cache_1.volatileGifCache.set(resolvedSrc, parsed); done = true; continueRender(newHandle); continueRender(renderHandle); }) .catch((err) => { if (aborted) { continueRender(newHandle); return; } remotion_1.Internals.Log.error({ logLevel, tag: null }, 'Failed to load GIF', err); if (currentOnError.current) { currentOnError.current(err); } else { setError(err); } }); return () => { if (!done) { aborted = true; controller.abort(); } continueRender(newHandle); continueRender(renderHandle); }; }, [ renderHandle, logLevel, resolvedSrc, delayRender, continueRender, delayRenderTimeoutInMilliseconds, ]); if (error) { remotion_1.Internals.Log.error({ logLevel, tag: null }, error.stack); if ((0, is_cors_error_1.isCorsError)(error)) { throw new Error(`Failed to render GIF with source ${src}: "${error.message}". You must enable CORS for this URL.`); } throw new Error(`Failed to render GIF with source ${src}: "${error.message}". Render with --log=verbose to see the full stack.`); } if (index === -1) { return null; } return (jsx_runtime_1.jsx(canvas_1.Canvas, { fit: fit, index: index, frames: state.frames, width: width, height: height, ...props, ref: ref })); });