remotion
Version:
Make videos programmatically
354 lines (353 loc) • 17.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.useResolvedVideoConfig = exports.ResolveCompositionConfig = exports.PROPS_UPDATED_EXTERNALLY = exports.needsResolution = exports.resolveCompositionsRef = exports.ResolveCompositionContext = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const CompositionManagerContext_js_1 = require("./CompositionManagerContext.js");
const EditorProps_js_1 = require("./EditorProps.js");
const input_props_js_1 = require("./config/input-props.js");
const get_remotion_environment_js_1 = require("./get-remotion-environment.js");
const nonce_js_1 = require("./nonce.js");
const resolve_video_config_js_1 = require("./resolve-video-config.js");
const validate_dimensions_js_1 = require("./validation/validate-dimensions.js");
const validate_duration_in_frames_js_1 = require("./validation/validate-duration-in-frames.js");
const validate_fps_js_1 = require("./validation/validate-fps.js");
exports.ResolveCompositionContext = (0, react_1.createContext)(null);
exports.resolveCompositionsRef = (0, react_1.createRef)();
const needsResolution = (composition) => {
return Boolean(composition.calculateMetadata);
};
exports.needsResolution = needsResolution;
exports.PROPS_UPDATED_EXTERNALLY = 'remotion.propsUpdatedExternally';
const ResolveCompositionConfig = ({ children }) => {
const [currentRenderModalComposition, setCurrentRenderModalComposition] = (0, react_1.useState)(null);
const { compositions, canvasContent, currentCompositionMetadata } = (0, react_1.useContext)(CompositionManagerContext_js_1.CompositionManager);
const { fastRefreshes, manualRefreshes } = (0, react_1.useContext)(nonce_js_1.NonceContext);
// don't do anything, this component should should re-render if the value changes
if (manualRefreshes) {
/** */
}
const selectedComposition = (0, react_1.useMemo)(() => {
return compositions.find((c) => canvasContent &&
canvasContent.type === 'composition' &&
canvasContent.compositionId === c.id);
}, [canvasContent, compositions]);
const renderModalComposition = compositions.find((c) => c.id === currentRenderModalComposition);
const { props: allEditorProps } = (0, react_1.useContext)(EditorProps_js_1.EditorPropsContext);
const inputProps = (0, react_1.useMemo)(() => {
var _a;
return typeof window === 'undefined' || (0, get_remotion_environment_js_1.getRemotionEnvironment)().isPlayer
? {}
: ((_a = (0, input_props_js_1.getInputProps)()) !== null && _a !== void 0 ? _a : {});
}, []);
const [resolvedConfigs, setResolvedConfigs] = (0, react_1.useState)({});
const selectedEditorProps = (0, react_1.useMemo)(() => {
var _a;
return selectedComposition
? ((_a = allEditorProps[selectedComposition.id]) !== null && _a !== void 0 ? _a : {})
: {};
}, [allEditorProps, selectedComposition]);
const renderModalProps = (0, react_1.useMemo)(() => {
var _a;
return renderModalComposition
? ((_a = allEditorProps[renderModalComposition.id]) !== null && _a !== void 0 ? _a : {})
: {};
}, [allEditorProps, renderModalComposition]);
const hasResolution = Boolean(currentCompositionMetadata);
const doResolution = (0, react_1.useCallback)(({ calculateMetadata, combinedProps, compositionDurationInFrames, compositionFps, compositionHeight, compositionId, compositionWidth, defaultProps, }) => {
const controller = new AbortController();
if (hasResolution) {
return controller;
}
const { signal } = controller;
const result = (0, resolve_video_config_js_1.resolveVideoConfigOrCatch)({
compositionId,
calculateMetadata,
originalProps: combinedProps,
signal,
defaultProps,
compositionDurationInFrames,
compositionFps,
compositionHeight,
compositionWidth,
});
if (result.type === 'error') {
setResolvedConfigs((r) => ({
...r,
[compositionId]: {
type: 'error',
error: result.error,
},
}));
return controller;
}
const promOrNot = result.result;
if (typeof promOrNot === 'object' && 'then' in promOrNot) {
setResolvedConfigs((r) => {
const prev = r[compositionId];
if ((prev === null || prev === void 0 ? void 0 : prev.type) === 'success' ||
(prev === null || prev === void 0 ? void 0 : prev.type) === 'success-and-refreshing') {
return {
...r,
[compositionId]: {
type: 'success-and-refreshing',
result: prev.result,
},
};
}
return {
...r,
[compositionId]: {
type: 'loading',
},
};
});
promOrNot
.then((c) => {
if (controller.signal.aborted) {
return;
}
setResolvedConfigs((r) => ({
...r,
[compositionId]: {
type: 'success',
result: c,
},
}));
})
.catch((err) => {
if (controller.signal.aborted) {
return;
}
setResolvedConfigs((r) => ({
...r,
[compositionId]: {
type: 'error',
error: err,
},
}));
});
}
else {
setResolvedConfigs((r) => ({
...r,
[compositionId]: {
type: 'success',
result: promOrNot,
},
}));
}
return controller;
}, [hasResolution]);
const currentComposition = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition' ? canvasContent.compositionId : null;
(0, react_1.useImperativeHandle)(exports.resolveCompositionsRef, () => {
return {
setCurrentRenderModalComposition: (id) => {
setCurrentRenderModalComposition(id);
},
reloadCurrentlySelectedComposition: () => {
var _a, _b, _c, _d, _e, _f;
if (!currentComposition) {
return;
}
const composition = compositions.find((c) => c.id === currentComposition);
if (!composition) {
throw new Error(`Could not find composition with id ${currentComposition}`);
}
const editorProps = (_a = allEditorProps[currentComposition]) !== null && _a !== void 0 ? _a : {};
const defaultProps = {
...((_b = composition.defaultProps) !== null && _b !== void 0 ? _b : {}),
...(editorProps !== null && editorProps !== void 0 ? editorProps : {}),
};
const props = {
...defaultProps,
...(inputProps !== null && inputProps !== void 0 ? inputProps : {}),
};
doResolution({
defaultProps,
calculateMetadata: composition.calculateMetadata,
combinedProps: props,
compositionDurationInFrames: (_c = composition.durationInFrames) !== null && _c !== void 0 ? _c : null,
compositionFps: (_d = composition.fps) !== null && _d !== void 0 ? _d : null,
compositionHeight: (_e = composition.height) !== null && _e !== void 0 ? _e : null,
compositionWidth: (_f = composition.width) !== null && _f !== void 0 ? _f : null,
compositionId: composition.id,
});
},
};
}, [
allEditorProps,
compositions,
currentComposition,
doResolution,
inputProps,
]);
const isTheSame = (selectedComposition === null || selectedComposition === void 0 ? void 0 : selectedComposition.id) === (renderModalComposition === null || renderModalComposition === void 0 ? void 0 : renderModalComposition.id);
const currentDefaultProps = (0, react_1.useMemo)(() => {
var _a;
return {
...((_a = selectedComposition === null || selectedComposition === void 0 ? void 0 : selectedComposition.defaultProps) !== null && _a !== void 0 ? _a : {}),
...(selectedEditorProps !== null && selectedEditorProps !== void 0 ? selectedEditorProps : {}),
};
}, [selectedComposition === null || selectedComposition === void 0 ? void 0 : selectedComposition.defaultProps, selectedEditorProps]);
const originalProps = (0, react_1.useMemo)(() => {
return {
...currentDefaultProps,
...(inputProps !== null && inputProps !== void 0 ? inputProps : {}),
};
}, [currentDefaultProps, inputProps]);
const canResolve = selectedComposition && (0, exports.needsResolution)(selectedComposition);
const shouldIgnoreUpdate = typeof window !== 'undefined' &&
window.remotion_ignoreFastRefreshUpdate &&
fastRefreshes <= window.remotion_ignoreFastRefreshUpdate;
(0, react_1.useEffect)(() => {
var _a, _b, _c, _d;
if (shouldIgnoreUpdate) {
// We already have the current state, we just saved it back
// to the file
return;
}
if (canResolve) {
const controller = doResolution({
calculateMetadata: selectedComposition.calculateMetadata,
combinedProps: originalProps,
compositionDurationInFrames: (_a = selectedComposition.durationInFrames) !== null && _a !== void 0 ? _a : null,
compositionFps: (_b = selectedComposition.fps) !== null && _b !== void 0 ? _b : null,
compositionHeight: (_c = selectedComposition.height) !== null && _c !== void 0 ? _c : null,
compositionWidth: (_d = selectedComposition.width) !== null && _d !== void 0 ? _d : null,
defaultProps: currentDefaultProps,
compositionId: selectedComposition.id,
});
return () => {
controller.abort();
};
}
}, [
canResolve,
currentDefaultProps,
doResolution,
originalProps,
selectedComposition === null || selectedComposition === void 0 ? void 0 : selectedComposition.calculateMetadata,
selectedComposition === null || selectedComposition === void 0 ? void 0 : selectedComposition.durationInFrames,
selectedComposition === null || selectedComposition === void 0 ? void 0 : selectedComposition.fps,
selectedComposition === null || selectedComposition === void 0 ? void 0 : selectedComposition.height,
selectedComposition === null || selectedComposition === void 0 ? void 0 : selectedComposition.id,
selectedComposition === null || selectedComposition === void 0 ? void 0 : selectedComposition.width,
shouldIgnoreUpdate,
]);
(0, react_1.useEffect)(() => {
var _a, _b, _c, _d, _e;
if (renderModalComposition && !isTheSame) {
const combinedProps = {
...((_a = renderModalComposition.defaultProps) !== null && _a !== void 0 ? _a : {}),
...(renderModalProps !== null && renderModalProps !== void 0 ? renderModalProps : {}),
...(inputProps !== null && inputProps !== void 0 ? inputProps : {}),
};
const controller = doResolution({
calculateMetadata: renderModalComposition.calculateMetadata,
compositionDurationInFrames: (_b = renderModalComposition.durationInFrames) !== null && _b !== void 0 ? _b : null,
compositionFps: (_c = renderModalComposition.fps) !== null && _c !== void 0 ? _c : null,
compositionHeight: (_d = renderModalComposition.height) !== null && _d !== void 0 ? _d : null,
compositionId: renderModalComposition.id,
compositionWidth: (_e = renderModalComposition.width) !== null && _e !== void 0 ? _e : null,
defaultProps: currentDefaultProps,
combinedProps,
});
return () => {
controller.abort();
};
}
}, [
currentDefaultProps,
doResolution,
inputProps,
isTheSame,
renderModalComposition,
renderModalProps,
]);
const resolvedConfigsIncludingStaticOnes = (0, react_1.useMemo)(() => {
const staticComps = compositions.filter((c) => {
return c.calculateMetadata === null;
});
return {
...resolvedConfigs,
...staticComps.reduce((acc, curr) => {
var _a;
return {
...acc,
[curr.id]: {
type: 'success',
result: { ...curr, defaultProps: (_a = curr.defaultProps) !== null && _a !== void 0 ? _a : {} },
},
};
}, {}),
};
}, [compositions, resolvedConfigs]);
return ((0, jsx_runtime_1.jsx)(exports.ResolveCompositionContext.Provider, { value: resolvedConfigsIncludingStaticOnes, children: children }));
};
exports.ResolveCompositionConfig = ResolveCompositionConfig;
const useResolvedVideoConfig = (preferredCompositionId) => {
const context = (0, react_1.useContext)(exports.ResolveCompositionContext);
const { props: allEditorProps } = (0, react_1.useContext)(EditorProps_js_1.EditorPropsContext);
const { compositions, canvasContent, currentCompositionMetadata } = (0, react_1.useContext)(CompositionManagerContext_js_1.CompositionManager);
const currentComposition = (canvasContent === null || canvasContent === void 0 ? void 0 : canvasContent.type) === 'composition' ? canvasContent.compositionId : null;
const compositionId = preferredCompositionId !== null && preferredCompositionId !== void 0 ? preferredCompositionId : currentComposition;
const composition = compositions.find((c) => c.id === compositionId);
const selectedEditorProps = (0, react_1.useMemo)(() => {
var _a;
return composition ? ((_a = allEditorProps[composition.id]) !== null && _a !== void 0 ? _a : {}) : {};
}, [allEditorProps, composition]);
return (0, react_1.useMemo)(() => {
var _a, _b, _c, _d;
if (!composition) {
return null;
}
if (currentCompositionMetadata) {
return {
type: 'success',
result: {
...currentCompositionMetadata,
id: composition.id,
defaultProps: (_a = composition.defaultProps) !== null && _a !== void 0 ? _a : {},
},
};
}
if (!(0, exports.needsResolution)(composition)) {
(0, validate_duration_in_frames_js_1.validateDurationInFrames)(composition.durationInFrames, {
allowFloats: false,
component: `in <Composition id="${composition.id}">`,
});
(0, validate_fps_js_1.validateFps)(composition.fps, `in <Composition id="${composition.id}">`, false);
(0, validate_dimensions_js_1.validateDimension)(composition.width, 'width', `in <Composition id="${composition.id}">`);
(0, validate_dimensions_js_1.validateDimension)(composition.height, 'height', `in <Composition id="${composition.id}">`);
return {
type: 'success',
result: {
width: composition.width,
height: composition.height,
fps: composition.fps,
id: composition.id,
durationInFrames: composition.durationInFrames,
defaultProps: (_b = composition.defaultProps) !== null && _b !== void 0 ? _b : {},
props: {
...((_c = composition.defaultProps) !== null && _c !== void 0 ? _c : {}),
...(selectedEditorProps !== null && selectedEditorProps !== void 0 ? selectedEditorProps : {}),
...(typeof window === 'undefined' ||
(0, get_remotion_environment_js_1.getRemotionEnvironment)().isPlayer
? {}
: ((_d = (0, input_props_js_1.getInputProps)()) !== null && _d !== void 0 ? _d : {})),
},
defaultCodec: null,
defaultOutName: null,
defaultVideoImageFormat: null,
defaultPixelFormat: null,
},
};
}
if (!context[composition.id]) {
return null;
}
return context[composition.id];
}, [composition, context, currentCompositionMetadata, selectedEditorProps]);
};
exports.useResolvedVideoConfig = useResolvedVideoConfig;