Skip to main content

Playing videos in sequence

If you would like to play multiple videos in sequence, you can:

1
Define a component that renders a <Series> of <OffthreadVideo> components.
2
Create a calculateMetadata() function that fetches the duration of each video.
3
Register a <Composition> that specifies a list of videos.

Basic example

Start off by creating a component that renders a list of videos using the <Series> and <OffthreadVideo> component:

VideosInSequence.tsx
tsx
import React from'react';
import {OffthreadVideo, Series} from'remotion';
typeVideoToEmbed= {
src:string;
durationInFrames:number|null;
};
typeProps= {
videos:VideoToEmbed[];
};
exportconstVideosInSequence:React.FC<Props> = ({videos}) => {
return (
<Series>
{videos.map((vid) => {
if (vid.durationInFrames ===null) {
thrownewError('Could not get video duration');
}
return (
<Series.Sequencekey={vid.src} durationInFrames={vid.durationInFrames}>
<OffthreadVideosrc={vid.src} />
</Series.Sequence>
);
})}
</Series>
);
};

In the same file, create a function that calculates the metadata for the composition:

1
Calls parseMedia() to get the duration of each video.

2
Create a calculateMetadata() function that fetches the duration of each video.

3
Sums up all durations to get the total duration of the composition.
VideosInSequence.tsx
tsx
exportconstcalculateMetadata:CalculateMetadataFunction<Props> =async ({props}) => {
constfps=30;
constvideos=awaitPromise.all([
...props.videos.map(async (video):Promise<VideoToEmbed> => {
const {slowDurationInSeconds} =awaitparseMedia({
src: video.src,
fields: {
slowDurationInSeconds: true,
},
});
return {
durationInFrames: Math.floor(slowDurationInSeconds * fps),
src: video.src,
};
}),
]);
consttotalDurationInFrames= videos.reduce((acc, video) => acc + (video.durationInFrames ??0), 0);
return {
props: {
...props,
videos,
},
fps,
durationInFrames: totalDurationInFrames,
};
};

In your root file, create a <Composition> that uses the VideosInSequence component and the exported calculateMetadata function:

Root.tsx
tsx
import React from'react';
import {Composition, staticFile} from'remotion';
import {VideosInSequence, calculateMetadata} from'./VideosInSequence';
exportconstRoot:React.FC= () => {
return (
<Composition
id="VideosInSequence"
component={VideosInSequence}
width={1920}
height={1080}
defaultProps={{
videos: [
{
durationInFrames: null,
src: 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
},
{
durationInFrames: null,
src: staticFile('localvideo.mp4'),
},
],
}}
calculateMetadata={calculateMetadata}
/>
);
};

Adding premounting

If you only care about the video looking smooth when rendered, you may skip this step.
If you also want smooth preview playback in the Player, consider this:

A video will only load when it is about to be played.
To create a smoother preview playback, we should do two things to all videos:

1
Add a premountFor prop to <Series.Sequence>. This will invisibly mount the video tag before it is played, giving it some time to load.

2
Add the pauseWhenBuffering prop. This will transition the Player into a buffering state, should the video still need to load.
VideosInSequence.tsx
tsx
exportconstVideosInSequence:React.FC<Props> = ({videos}) => {
const {fps} =useVideoConfig();
return (
<Series>
{videos.map((vid) => {
if (vid.durationInFrames ===null) {
thrownewError('Could not get video duration');
}
return (
<Series.Sequencekey={vid.src} premountFor={4* fps} durationInFrames={vid.durationInFrames}>
<OffthreadVideopauseWhenBufferingsrc={vid.src} />
</Series.Sequence>
);
})}
</Series>
);
};

Browser autoplay policies

Mobile browsers are more aggressive in blocking autoplaying videos that enter after the start of the composition.

If you want to ensure a smooth playback experience for all videos, also read the notes about browser autoplay behavior and customize the behavior if needed.

See also

AltStyle によって変換されたページ (->オリジナル) /