@remotion/gif
Version:
Embed GIFs in a Remotion video
108 lines (107 loc) • 4.48 kB
JavaScript
;
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 }));
});