Dynamic Metadata & Calculations
The calculateMetadata function allows you to dynamically determine a composition's properties—such as duration, dimensions, and props—before rendering begins. This is essential when creating videos based on dynamic assets (like a user-uploaded video) or external data (like an API response).
Overview
You provide calculateMetadata as a prop to your <Composition>. It is an asynchronous function that runs once before the composition is initialized. Any values returned by this function will override the hardcoded props on the <Composition> component.
import { Composition } from "remotion";
import { MyVideo, calculateMetadata } from "./MyVideo";
export const RemotionRoot = () => {
return (
<Composition
id="DynamicVideo"
component={MyVideo}
durationInFrames={1} // Placeholder
fps={30}
width={1920}
height={1080}
calculateMetadata={calculateMetadata}
/>
);
};
Common Patterns
Matching Metadata to a Source Video
If your composition acts as an overlay or wrapper for an existing video, use calculateMetadata to ensure the composition matches the source's duration and resolution exactly.
import { CalculateMetadataFunction } from "remotion";
import { getMediaMetadata } from "./utils/get-media-metadata";
type Props = {
videoSrc: string;
};
export const calculateMetadata: CalculateMetadataFunction<Props> = async ({ props }) => {
const metadata = await getMediaMetadata(props.videoSrc);
return {
durationInFrames: Math.ceil(metadata.durationInSeconds * 30),
width: metadata.dimensions?.width ?? 1920,
height: metadata.dimensions?.height ?? 1080,
};
};
Fetching External Data
You can fetch data from an API and pass it into your component as transformed props. Use the provided abortSignal to cancel requests if the user changes props in the Remotion Studio before the previous fetch completes.
export const calculateMetadata: CalculateMetadataFunction<Props> = async ({
props,
abortSignal
}) => {
const response = await fetch(`https://api.example.com/stats/${props.userId}`, {
signal: abortSignal,
});
const data = await response.json();
return {
props: {
...props,
stats: data, // Injected into the component's props
},
};
};
Dynamic Output Filenames
You can define the default filename for the rendered video based on the input props.
export const calculateMetadata: CalculateMetadataFunction<Props> = async ({ props }) => {
return {
defaultOutName: `render-${props.username}-${Date.now()}.mp4`,
};
};
API Reference
The calculateMetadata function receives an object containing:
props: The current props passed to the composition.abortSignal: A signal to handle request cancellation.
Return Values
The function should return an object (all fields are optional):
| Field | Type | Description |
| :--- | :--- | :--- |
| durationInFrames | number | Overrides the composition duration. |
| width | number | Overrides the composition width. |
| height | number | Overrides the composition height. |
| fps | number | Overrides the frames per second. |
| props | T | Transforms or adds data to the props passed to the component. |
| defaultOutName | string | Sets the default name for the output file. |
| defaultCodec | Codec | Sets the preferred codec (e.g., h264, vp9). |
Implementation Notes
- JSON Serialization: When passing props through
calculateMetadata, ensure they are JSON-serializable. Functions and complex classes cannot be passed, thoughDate,Map,Set, andstaticFile()are supported. - Type Safety: Use the
CalculateMetadataFunction<Props>type to ensure that the returnedpropsobject matches your component's expected interface. - Performance: Since this function is awaited before the Studio or the render starts, avoid performing excessively heavy computations. Use it primarily for metadata extraction and data fetching.