Create Videos With React

Create Videos With React blog banner image

You may have created the videos and animation with adobe after effects, or any other similar tool. Remotion provides you a programmatic solution to do the same. And if you are familiar with react then it will be a super fun 😇. It enables you to create videos with the skills you already have.

Requirements

You only need to install FFMPEG, which remotion uses under the hood to stitch the screenshots together. Basically, remotion provides you a current frame, its your responsibility to render something. And then to render the video, it uses the puppeteer to make ton of screenshots and stich it together. Of course concurrency and optimization is done to make the process fast. Now lets get started.

Concepts

Idea behind the remotion is it provides you frame, render anything that you want in that frame using react.

useCurrentFrame

This is the hook that you can use in any of the component to get the current frame. We will dive deep on how to use this frame number to animate something.

useVideoConfig

This hook provides you video configuration like width, height, durationInFrames, fps. This helps you to reuse components with different configuration. So, you don't have to hardcode anything derive it from the width and height of your video.

Composition

Composition is the component where you will be specifying all the above mentioned meta data and once you start up development process, all compositions will show up in left sidebar. Here is how you can define it.

1export const MyFirstVideo: React.FC = () => {
2 return (
3 <>
4 <Composition
5 id="MyVideo"
6 component={Video}
7 durationInFrames={150} // 5 seconds
8 fps={30}
9 width={1920}
10 height={1080}
11 />
12 </>
13 );
14};

Component={Video} defined the entry point of your video.

Now lets see what utility it exposes to animate something

interpolate

As the name suggest it interpolates the input value. It takes 4 arguments.

1const frame = useCurrentFrame();
2
3const coverScale = interpolate(frame, [0, 20], [0, 1], {});

First argument is the input value, second is the range which input can assume, third is range you want to map input to and fourth is some optional settings like extrapolateRight, extrapolateLeft, etc. extrapolateRight clamps all the value greater then your output range to max value. In our case it will clamp the output so that it is always less then 1.

You might have already guessed how you can use this for animation. Lets say you want to animate image such that it fades in. We will be using scale transform to do the same.

1const IMAGE_SIZE = 400;
2
3export const AnimateImage = () => {
4 const frame = useCurrentFrame();
5 const { width } = useVideoConfig();
6 const coverScale = interpolate(frame, [0, 30], [0, 1], {
7 extrapolateRight: 'clamp',
8 });
9
10 return (
11 <img
12 src="https://pbs.twimg.com/profile_images/1328161728924774401/Eh_AIWRa_400x400.jpg"
13 style={{
14 left: width / 2 - IMAGE_SIZE / 2,
15 height: IMAGE_SIZE,
16 transform: `scale(${coverScale})`,
17 }}
18 />
19 );
20};

This example will help you to understand how we are using width from the hook so that we can use same component with different Composition. Using the interpolate function to animate the scale of image. On line 6 to 8, We are saying that take the current frame as input, it may vary between 0-30(1 second) and give me output which is clamped between 0 and 1. Then we will use coverScale value to transform the scale of image on line 16. You can check in devtool to observe how coverScale is changing. This code will scale the given image over first second.

spring

Remotion also provides spring animation to put things into motion and make them natural. Lets see the same example with spring

1const IMAGE_SIZE = 400;
2
3export const SpringAnimation = () => {
4 const frame = useCurrentFrame();
5 const { width, fps } = useVideoConfig();
6 const coverScale = spring({
7 frame,
8 fps,
9 config: {
10 damping: 100,
11 stiffness: 200,
12 mass: 10,
13 },
14 });
15
16 return (
17 <img
18 src="https://pbs.twimg.com/profile_images/1328161728924774401/Eh_AIWRa_400x400.jpg"
19 style={{
20 left: width / 2 - IMAGE_SIZE / 2,
21 height: IMAGE_SIZE,
22 transform: `scale(${coverScale})`,
23 }}
24 />
25 );
26};

By default spring animation slightly bounces, thats why we used config to increase the mass and stiffness of spring. You can also delay the animation. For example if you want the above mentioned animation to run after 1 second, you can do that by passing frame - 30 to the frame in spring as shown below.

1const IMAGE_SIZE = 400;
2
3export const SpringAnimation = () => {
4 const frame = useCurrentFrame();
5 const { width, fps } = useVideoConfig();
6 const coverScale = spring({
7 frame: frame - 30,
8 fps,
9 config: {
10 damping: 100,
11 stiffness: 200,
12 mass: 10,
13 },
14 });
15
16 return (
17 <img
18 src="https://pbs.twimg.com/profile_images/1328161728924774401/Eh_AIWRa_400x400.jpg"
19 style={{
20 left: width / 2 - IMAGE_SIZE / 2,
21 height: IMAGE_SIZE,
22 transform: `scale(${coverScale})`,
23 }}
24 />
25 );
26};

Sequence

With the Sequence component, you can sequence the animations to play one after the other. It accepts prop from, this will be the number of frame after which it should appear in the screen and durationInFrames. For example lets say you have two images and you want to animate both in same manner as we saw in the above code but it should be one after the other.

1export const SequenceExample = () => {
2 return (
3 <div
4 style={{
5 flex: 1,
6 justifyContent: 'center',
7 alignItems: 'center',
8 backgroundColor: 'white',
9 }}
10 >
11 <Sequence from={0} durationInFrames={30}>
12 <SpringAnimation />
13 </Sequence>
14 <Sequence from={30} durationInFrames={Infinity}>
15 <SpringAnimation />
16 </Sequence>
17 </div>
18 );
19};

With this, first image will animate for the first second. After that as we have specified durationInFrames as 30, it will disappear. And the second which where we specified from as 30 will appear and animate. You can style the SpringAnimation component and make it to accept the prop, such that two images appear side by side and specify durationInFrames as Infinity for the first image too.

Img

This works pretty much like img tag from html, the difference is remotion will ensure that the image is loaded before rendering the frame. So, in the above example instead of using native img tag use Img tag so that image is already loaded when it animates to avoid any kind of flickering.

There are lots of other interesting thing remotion offers, but this is sufficient to get started and create your first video with React 🎉. You can read more about delayRender which can be used if you want to wait for the API response before rendering the frame, AbsoluteFill, etc... on the documentation site.

Resources

I have also created an example repo remotion-instagram, which creates the video of your instagram profile. All the above mentioned concepts are used in the example, you may like to look at the code and create something super cool with it.

Remotion 2.0 is also released just 2 days before with lots of improvements and interesting stuff. Here is the detail thread on twitter by Jonny. And we will go through that too in future posts.

Conclusion

It gives you lots of confident to create the videos and animations with the technology you are expert in. Let me know on twitter what you create with the remotion.

Subscribe for the newsletter