Skip to main content

How do I make the composition the same duration as my video?

If you have a component rendering a video:

MyComp.tsx
tsx
import React from "react";
import { OffthreadVideo, staticFile } from "remotion";
 
export const MyComp: React.FC = () => {
return <OffthreadVideo src={staticFile("video.mp4")} />;
};
MyComp.tsx
tsx
import React from "react";
import { OffthreadVideo, staticFile } from "remotion";
 
export const MyComp: React.FC = () => {
return <OffthreadVideo src={staticFile("video.mp4")} />;
};

and you want to make the composition the same duration as the video, first make the video source a React prop:

MyComp.tsx
tsx
import React from "react";
import { OffthreadVideo, staticFile } from "remotion";
 
type MyCompProps = {
src: string;
};
 
export const MyComp: React.FC<MyCompProps> = ({ src }) => {
return <OffthreadVideo src={src} />;
};
MyComp.tsx
tsx
import React from "react";
import { OffthreadVideo, staticFile } from "remotion";
 
type MyCompProps = {
src: string;
};
 
export const MyComp: React.FC<MyCompProps> = ({ src }) => {
return <OffthreadVideo src={src} />;
};

Then, define a calculateMetadata() function that calculates the duration of the composition based on the video.
Install @remotion/media-utils if necessary.

MyComp.tsx
tsx
import { CalculateMetadataFunction } from "remotion";
import { getVideoMetadata } from "@remotion/media-utils";
 
export const calculateMetadata: CalculateMetadataFunction<
MyCompProps
> = async ({ props }) => {
const data = await getVideoMetadata(props.src);
const fps = 30;
 
return {
durationInFrames: Math.floor(data.durationInSeconds * fps),
fps,
};
};
MyComp.tsx
tsx
import { CalculateMetadataFunction } from "remotion";
import { getVideoMetadata } from "@remotion/media-utils";
 
export const calculateMetadata: CalculateMetadataFunction<
MyCompProps
> = async ({ props }) => {
const data = await getVideoMetadata(props.src);
const fps = 30;
 
return {
durationInFrames: Math.floor(data.durationInSeconds * fps),
fps,
};
};

Finally, pass the calculateMetadata function to the Composition component and define the previously hardcoded src as a default prop:

Root.tsx
tsx
import React from "react";
import { Composition } from "remotion";
import { MyComp, calculateMetadata } from "./MyComp";
 
export const Root: React.FC = () => {
return (
<Composition
id="MyComp"
component={MyComp}
durationInFrames={300}
fps={30}
width={1920}
height={1080}
defaultProps={{
src: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
}}
calculateMetadata={calculateMetadata}
/>
);
};
Root.tsx
tsx
import React from "react";
import { Composition } from "remotion";
import { MyComp, calculateMetadata } from "./MyComp";
 
export const Root: React.FC = () => {
return (
<Composition
id="MyComp"
component={MyComp}
durationInFrames={300}
fps={30}
width={1920}
height={1080}
defaultProps={{
src: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
}}
calculateMetadata={calculateMetadata}
/>
);
};

How do I make the composition the same duration as my audio?

Follow the same steps, but instead if getVideoMetadata(), use getAudioDurationInSeconds() from @remotion/media-utils to calculate the duration of the composition based on the audio file.

See Also