UNPKG

remotion

Version:

Make videos programmatically

166 lines (165 loc) • 6.94 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.AnimatedImage = void 0; const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const cancel_render_js_1 = require("../cancel-render.js"); const use_memoized_effects_js_1 = require("../effects/use-memoized-effects.js"); const enable_sequence_stack_traces_js_1 = require("../enable-sequence-stack-traces.js"); const sequence_field_schema_js_1 = require("../sequence-field-schema.js"); const Sequence_js_1 = require("../Sequence.js"); const use_current_frame_js_1 = require("../use-current-frame.js"); const use_delay_render_js_1 = require("../use-delay-render.js"); const use_video_config_js_1 = require("../use-video-config.js"); const wrap_in_schema_js_1 = require("../wrap-in-schema.js"); const canvas_1 = require("./canvas"); const decode_image_js_1 = require("./decode-image.js"); const resolve_image_source_1 = require("./resolve-image-source"); const animatedImageSchema = { playbackRate: { type: 'number', min: 0, max: 10, step: 0.1, default: 1, description: 'Playback Rate', }, ...sequence_field_schema_js_1.sequenceVisualStyleSchema, hidden: sequence_field_schema_js_1.hiddenField, }; const AnimatedImageContent = (0, react_1.forwardRef)(({ src, width, height, onError, loopBehavior = 'loop', playbackRate = 1, fit = 'fill', effects, controls, ...props }, canvasRef) => { var _a; const resolvedSrc = (0, resolve_image_source_1.resolveAnimatedImageSource)(src); const [imageDecoder, setImageDecoder] = (0, react_1.useState)(null); const { delayRender, continueRender } = (0, use_delay_render_js_1.useDelayRender)(); const [decodeHandle] = (0, react_1.useState)(() => delayRender(`Rendering <AnimatedImage/> with src="${resolvedSrc}"`)); const frame = (0, use_current_frame_js_1.useCurrentFrame)(); const { fps } = (0, use_video_config_js_1.useVideoConfig)(); const currentTime = frame / playbackRate / fps; const currentTimeRef = (0, react_1.useRef)(currentTime); currentTimeRef.current = currentTime; const ref = (0, react_1.useRef)(null); const memoizedEffects = (0, use_memoized_effects_js_1.useMemoizedEffects)({ effects, overrideId: (_a = controls === null || controls === void 0 ? void 0 : controls.overrideId) !== null && _a !== void 0 ? _a : null, }); (0, react_1.useImperativeHandle)(canvasRef, () => { var _a; const c = (_a = ref.current) === null || _a === void 0 ? void 0 : _a.getCanvas(); if (!c) { throw new Error('Canvas ref is not set'); } return c; }, []); const [initialLoopBehavior] = (0, react_1.useState)(() => loopBehavior); (0, react_1.useEffect)(() => { const controller = new AbortController(); (0, decode_image_js_1.decodeImage)({ resolvedSrc, signal: controller.signal, currentTime: currentTimeRef.current, initialLoopBehavior, }) .then((d) => { setImageDecoder(d); continueRender(decodeHandle); }) .catch((err) => { if (err.name === 'AbortError') { continueRender(decodeHandle); return; } if (onError) { onError === null || onError === void 0 ? void 0 : onError(err); continueRender(decodeHandle); } else { (0, cancel_render_js_1.cancelRender)(err); } }); return () => { controller.abort(); }; }, [ resolvedSrc, decodeHandle, onError, initialLoopBehavior, continueRender, ]); (0, react_1.useLayoutEffect)(() => { if (!imageDecoder) { return; } const delay = delayRender(`Rendering frame at ${currentTime} of <AnimatedImage src="${src}"/>`); let cancelled = false; imageDecoder .getFrame(currentTime, loopBehavior) .then(async (videoFrame) => { var _a, _b; if (cancelled) { return; } if (videoFrame === null) { (_a = ref.current) === null || _a === void 0 ? void 0 : _a.clear(); continueRender(delay); return; } const completed = await ((_b = ref.current) === null || _b === void 0 ? void 0 : _b.draw(videoFrame.frame)); if (completed && !cancelled) { continueRender(delay); } }) .catch((err) => { if (cancelled) { return; } if (onError) { onError(err); continueRender(delay); } else { (0, cancel_render_js_1.cancelRender)(err); } }); return () => { cancelled = true; continueRender(delay); }; }, [ currentTime, imageDecoder, loopBehavior, onError, src, continueRender, delayRender, memoizedEffects, fit, width, height, ]); return ((0, jsx_runtime_1.jsx)(canvas_1.Canvas, { ref: ref, width: width, height: height, fit: fit, effects: memoizedEffects, ...props })); }); AnimatedImageContent.displayName = 'AnimatedImageContent'; const AnimatedImageInner = ({ src, width, height, onError, fit, playbackRate, loopBehavior, id, className, style, durationInFrames, effects = [], _experimentalControls: controls, ref, ...sequenceProps }) => { const { durationInFrames: videoDuration } = (0, use_video_config_js_1.useVideoConfig)(); const resolvedDuration = durationInFrames !== null && durationInFrames !== void 0 ? durationInFrames : videoDuration; const memoizedEffectDefinitions = (0, use_memoized_effects_js_1.useMemoizedEffectDefinitions)(effects); const animatedImageProps = { src, width, height, onError, fit, playbackRate, loopBehavior, id, className, style, }; return ((0, jsx_runtime_1.jsx)(Sequence_js_1.Sequence, { layout: "none", durationInFrames: resolvedDuration, name: "<AnimatedImage>", _remotionInternalDocumentationLink: "https://www.remotion.dev/docs/animatedimage", _experimentalControls: controls, _remotionInternalEffects: memoizedEffectDefinitions, ...sequenceProps, children: (0, jsx_runtime_1.jsx)(AnimatedImageContent, { ...animatedImageProps, ref: ref, effects: effects, controls: controls }) })); }; exports.AnimatedImage = (0, wrap_in_schema_js_1.wrapInSchema)(AnimatedImageInner, animatedImageSchema); exports.AnimatedImage.displayName = 'AnimatedImage'; (0, enable_sequence_stack_traces_js_1.addSequenceStackTraces)(exports.AnimatedImage);