Playing videos in sequence
If you would like to play multiple videos in sequence, you can:
Define a component that renders a<Series> of <OffthreadVideo> components.
calculateMetadata() function that fetches the duration of each video.
<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.tsximportReact from 'react'; import {OffthreadVideo ,Series } from 'remotion'; typeVideoToEmbed = {src : string;durationInFrames : number | null; }; typeProps = {videos :VideoToEmbed []; }; export constVideosInSequence :React .FC <Props > = ({videos }) => { return ( <Series > {videos .map ((vid ) => { if (vid .durationInFrames === null) { throw newError ('Could not get video duration'); } return ( <Series .Sequence key ={vid .src }durationInFrames ={vid .durationInFrames }> <OffthreadVideo src ={vid .src } /> </Series .Sequence > ); })} </Series > ); };
In the same file, create a function that calculates the metadata for the composition:
CallsparseMedia() to get the duration of each video.
Create a calculateMetadata() function that fetches the duration of each video.
Sums up all durations to get the total duration of the composition.
VideosInSequence.tsxexport constcalculateMetadata :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.tsximportReact from 'react'; import {Composition ,staticFile } from 'remotion'; import {VideosInSequence ,calculateMetadata } from './VideosInSequence'; export constRoot :React .FC = () => { return ( <Composition id ="VideosInSequence"component ={VideosInSequence }width ={1920}height ={1080}defaultProps ={{videos : [ {durationInFrames : null,src : 'https://remotion.media/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:
premountFor prop to <Series.Sequence>. This will
invisibly mount the video tag before it is played, giving it some time to load.
Add the pauseWhenBuffering prop. This will transition the Player into a buffering state, should the video still need to load.
VideosInSequence.tsxexport constVideosInSequence :React .FC <Props > = ({videos }) => { const {fps } =useVideoConfig (); return ( <Series > {videos .map ((vid ) => { if (vid .durationInFrames === null) { throw newError ('Could not get video duration'); } return ( <Series .Sequence key ={vid .src }premountFor ={4 *fps }durationInFrames ={vid .durationInFrames }> <OffthreadVideo pauseWhenBuffering src ={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.