Build Customized Video Players with React

Ifeoma Imoh

Do you need to add a video player to your website? Cloudinary offers various solutions that make it easy to build and personalize video galleries or video playlists with as many videos as you like.

In this post, we will go through how to add two types of video players to your site using Cloudinary's JavaScript-based HTML5 video player. The first is an interactive video player, and the second is a video player with playlist functionality.

Here is a link to the demo on CodeSandbox.

Cloudinary Setup

If you don't have a Cloudinary account, you can create one for free. You should see all your credentials on your dashboard page (cloud name, etc.), but we'll need just the cloud name for this app.

Upload some videos to your account or see this short video on how to upload assets to Cloudinary. We need to add resource tags to the videos we want to use to create our playlist. See here for how to add tags to your assets.

We also need to disable the Resource list option because it is restricted by default. To enable it, click on the Security setting icon on your Cloudinary console. Click the Settings link on the security page and uncheck the Resource list option under Restricted media types.

Project Setup

Open your terminal and run the following command:

1npx create-react-app video-players

The command creates a React application inside a folder called video-players.

The next step is to install the dependencies we will need in this project. Run the following command to install them.

1npm install cloudinary-core cloudinary-video-player

The command above installs the Cloudinary Video Player and the Cloudinary JavaScript SDK package.

Video Player Component

Let's create the component where both our video players will be rendered. Inside your src directory, create a folder called components. Create a file called videoPlayer.js inside the components folder and add the following to it:

1import React, { useEffect } from "react";
2 import { Cloudinary } from "cloudinary-core";
3
4 const cld = new Cloudinary({ cloud_name: "ifeomaimoh", secure: true });
5
6 const VideoPlayers = () => {
7 return (
8 <div className="container">
9 <div>
10 <h1>Interactive Video Player</h1>
11 <p>Click on the video player to see the UI interactions.</p>
12 </div>
13 </div>
14 );
15 };
16 export default VideoPlayers;

We're importing Cloudinary and instantiating a new Cloudinary class configured with our cloud name in the code above. For now, our component called VideoPlayers returns a simple UI where we will embed our video players.

Interactive Video Player

Let's go ahead and create our interactive video player. In the components folder, create another file named interactive-player.js and add the following to it:

1function interactivePlayer(cld) {
2
3 var player = cld.videoPlayer("player", {
4 bigPlayButton: true,
5 interactionDisplay: {
6 theme: {
7 template: "shadowed",
8 },
9 layout: {
10 enable: true,
11 showAgain: true,
12 },
13 },
14 controls: true,
15 // showJumpControls: true,
16 });
17 const sources = {
18 top: "https://res.cloudinary.com/ifeomaimoh/video/upload/v1637162706/flower_left_zoom.mp4",
19 middle:
20 "https://res.cloudinary.com/ifeomaimoh/video/upload/v1637162660/flower_middle_zoom.mp4",
21 bottom:
22 "https://res.cloudinary.com/ifeomaimoh/video/upload/v1637162736/flower_right_zoom.mp4",
23 };
24
25 player.source("flower", {
26 interactionAreas: {
27 enable: true,
28 template: "landscape",
29 onClick: function (event) {
30 var src = sources[event.item.id];
31 event.zoom(src);
32 },
33 },
34 });
35 return;
36 }
37 export default interactivePlayer;

In the code above, our function interactivePlayer accepts cld as props — the instance of Cloudinary we defined in videoPlayer. We instantiate the video player using the videoPlayer method, which returns a player object. The method accepts an ID — that will be the ID of the video element, which tells Cloudinary where to embed the video player. It also accepts some configurations as constructor parameters.

Next, we call the source method, which takes a string as its first argument. The string is the public id of the video. We're adding interactivity (zoom functionality) to our source video by defining a set of interaction areas with the interactionAreas object, passed as a second argument.

We're calling the zoom method inside the onClick event handler. The zoom method receives a source ID which we are then using to select a video from the sources object. This will help us achieve more advanced zooming. See here for more on interactive videos.

Embed the Video Player

Now, let’s bring in our interactivePlayer component into our VideoPlayer.js file. Update the VideoPlayers component with the following:

1import React, { useEffect } from "react";
2 import { Cloudinary } from "cloudinary-core";
3 import interactivePlayer from "./interactive-player";
4
5 const cld = new Cloudinary({ cloud_name: "ifeomaimoh", secure: true });
6
7 const VideoPlayers = () => {
8
9 useEffect(() => {
10 interactivePlayer(cld);
11 }, []);
12
13 return (
14 <div className="container">
15 //...
16 <div style={{ width: "600px", height: "400", margin: "20px" }}>
17 <video
18 id="player"
19 controls
20 muted
21 className="cld-video-player cld-fluid cld-video-player-skin-dark"
22 ></video>
23 </div>
24 </div>
25 </div>
26 );
27 };
28
29 export default VideoPlayers;

In the code above, we imported our interactivePlayer function and called it inside a useEffect() hook, and it receives cld as an argument. We then embed the video player by adding a video tag and passing the id referenced in the videoPlayer method and the cld-video-player class. The video player also receives the cld-video-player cld-fluid class, which will dynamically adjust the player size to fit its container or window.

Let's import the VideoPlayers component into our App.js file. Replace everything in your App.js file with the following:

1import React from "react";
2 import "cloudinary-video-player/dist/cld-video-player.min.css";
3 import VideoPlayers from "./components/videoPlayer";
4
5 export default function App() {
6 return (
7 <div className="App">
8 <VideoPlayers />
9 </div>
10 );
11 };

Head over to your browser, you should see the following:

You can interact with the video if you click on the areas of interaction we added.

Video Playlist Player

Let's set up a video player with a playlist functionality since we already uploaded and tagged our videos earlier.

Create a file named videoPlaylist.js in your components folder and add the following to it:

1import "cloudinary-video-player";
2
3 function videoPlaylist(cld) {
4
5 const player = cld.videoPlayer("playlist", {
6 controls: true,
7 bigPlayButton: true,
8 playlistWidget: {
9 direction: "horizontal",
10 total: 6,
11 },
12 showJumpControls: true,
13 });
14
15 player.playlistByTag("myTag", {
16 autoAdvance: false,
17 repeat: true,
18 });
19 return;
20 }
21 export default videoPlaylist;

Here, we created a function called videoPlaylist that accepts cld as a parameter. We also instantiate the video player using the videoPlayer method, which returns a player object.

The difference between this player and the first one we created is that we're calling the playlistByTag method and passing it a tag (the tag name we specified for our videos) to automatically retrieve and create a playlist of six videos with the specified tag.

We added the playlist widget as a constructor parameter and set the direction for displaying upcoming videos to horizontal.

Now let’s import the videoPlaylist component into our videoPlayer.js file. Update videoPlayer.js with the following:

1// import videoPlaylist
2 import VideoPlaylist from "./videoPlaylist";
3
4 const cld = new Cloudinary({ cloud_name: "ifeomaimoh", secure: true });
5
6 const VideoPlayers = () => {
7
8 useEffect(() => {
9 interactivePlayer(cld);
10 videoPlaylist(cld);
11 }, []);
12
13 return (
14 <div className="container">
15 //...
16
17 <div style={{ width: "600px", height: "400", margin: "20px" }}>
18 <video
19 id="player"
20 controls
21 muted
22 className="cld-video-player cld-fluid cld-video-player-skin-dark"
23 ></video>
24 </div>
25 {/* Add the following */}
26 <div style={{ width: "600px", height: "400" }} className="video-card">
27 <video
28 id="playlist-player"
29 className="cld-video-player cld-fluid cld-video-player-skin-dark"
30 ></video>
31 </div>
32 </div>
33 </div>
34 );
35 };
36
37 export default VideoPlayers;

Ifeoma Imoh

Software Developer

Ifeoma is a software developer and technical content creator in love with all things JavaScript.