Add Custom Video Transitions with React

Jason Lengstorf

For added cohesion and professionalism in videos, adding transitions goes a long way. In this tutorial, we’ll first look at how Cloudinary allows us to concatenate two videos together with a custom transition between them. Then, we'll learn how to display it all together in a React component.

Upload your assets to Cloudinary

To start, we'll upload the videos to Cloudinary. The fastest way to do this is using the Cloudinary console.

For this tutorial, we’ll use three videos:

  1. The first video we want to show
  2. The second video that should play after the first one
  3. A video to use as a transition, often referred to as a “luma matte”

For our first video, we’ll use this one:

1https://res.cloudinary.com/jlengstorf/video/upload/mediajams/disappointed-coffee.mp4

For the second video, we’ll use this:

1https://res.cloudinary.com/jlengstorf/video/upload/mediajams/deploy-to-netlify.mp4

And finally, let’s use this as our luma matte:

1https://res.cloudinary.com/jlengstorf/video/upload/mediajams/transition.mp4

Now that we have the pieces, we can assemble them into a single, seamless video!

Create a Video Component in React

Before we add the logo, let’s create a React component that displays our Cloudinary video.

1function Video({ cloudName, videoOneId, videoTwoId, transitionId }) {
2 // set up a Cloudinary URL to use your cloud name and display video
3 let videoSource = `https://res.cloudinary.com/${cloudName}/video/upload`;
4
5 // automatically adjust the quality, and set the video to 600px wide
6 videoSource += "/q_auto,w_600";
7
8 // set the public ID to display the video as an MP4
9 videoSource += `/${videoOneId}.mp4`;
10
11 // add the full URL to a standard HTML5 video element
12 return (
13 <video controls>
14 <source src={videoSource} type="video/mp4" />
15 </video>
16 );
17}

The component, which we’ve named Video, accepts three values as props: cloudName, videoOneId, videoTwoId, and transitionId.

The cloudName should contain our Cloudinary cloud name, which is displayed at the top-right of the console.

videoOneId will contain the public ID of the first video asset, which is the name of the file on Cloudinary, including any folders. Using our example video from above, the public ID is mediajams/disappointed-coffee.

videoTwoId contains the public ID of the second video, which is mediajams/deploy-to-netlify.

Finally, the transitionId will contain the public ID of the luma matte: mediajams/transition.

To set up our video, we build a Cloudinary URL that contains:

  1. The public Cloudinary URL, https://res.cloudinary.com/
  2. Our cloud name
  3. The asset type, /video/upload/
  4. Transformations to adjust the quality automatically and resize to 600px wide: q_auto,w_600
  5. The public ID of our video
  6. A file type of MP4 using a file extension

Once we have the URL, we can add that as the src value in a video element, and return that from our component.

Add a video overlay with a transition effect

Combining the videos with a transition requires two discrete steps to be added:

  1. The second video needs to be added as a video overlay, which requires replacing any slashes in the public ID with the colon (:) to avoid URL issues. Using the fill crop transformation, we set the video to be the same size as the first video.
  2. Next, we add an additional video overlay with the transition video, but we apply the transition effect to let Cloudinary know that it’s a luma matte. We also crop and resize this appropriately. Finally, we apply the layer to let Cloudinary know that it needs to apply the transition to the two videos.
1function Video({ cloudName, videoOneId, videoTwoId, transitionId }) {
2 // set up a Cloudinary URL to use your cloud name and display video
3 let videoSource = `https://res.cloudinary.com/${cloudName}/video/upload`;
4
5 // automatically adjust the quality and set the video to 600px wide
6 videoSource += "/q_auto,w_600";
7
8+ // replace folder slashes with colons so the URL works
9+ const videoTwo = videoTwoId.replace("/", ":");
10+
11+ // splice in the bumper video at the beginning
12+ // set it to the same width and make sure it fills the space
13+ videoSource += `/l_video:${videoTwo},c_fill,w_600`;
14+
15+ // replace folder slashes with colons so the URL works
16+ const transition = transitionId.replace("/", ":");
17+
18+ // add in the transition and apply it
19+ videoSource += `/l_video:${transition},c_fill,w_600,e_transition/fl_layer_apply`;
20
21 // set the public ID to display the video as an MP4
22 videoSource += `/${videoOneId}.mp4`;
23
24 // add the full URL to a standard HTML5 video element
25 return (
26 <video controls>
27 <source src={videoSource} type="video/mp4" />
28 </video>
29 );
30 }

Adding these two pieces to the URL gives us a generated video from Cloudinary that shows the first video, and then transitions to the second video.

Display the combined video in a React component on screen

With our Video component configured to combine videos with a custom transition, we’re ready to display it on screen!

We can add the React component to our app like this:

1function App() {
2 return (
3 <main>
4 <h1>Video Transitions with React & Cloudinary</h1>
5 <Video
6 cloudName="jlengstorf"
7 videoOneId="mediajams/disappointed-coffee"
8 videoTwoId="mediajams/deploy-to-netlify"
9 transitionId="mediajams/transition"
10 />
11 </main>
12 );
13}

Our app will now display a video that shows our first video, and then transitions into the second!

Jason Lengstorf

VP of Developer Experience at Netlify

Jason Lengstorf the VP of Developer Experience at Netlify, where he works to improve the experience of building and deploying to the modern web. He also hosts Learn With Jason, a live-streamed video show where he pair programs to learn something new in 90 minutes. He spends a lot of time telling people that the formula for success and happiness is to lift each other up and share what we learn. He is trying his very best to follow his own advice. He lives in Portland, Oregon.