Blog /

Building a Video Player in React

javascript

Building a Video Player in React

March 23, 20236 minutes
Building a Video Player in React

Introduction

React has been the most popular JavaScript framework for building frontend. As a web developer, I recommend you learn React. For learning, nothing is better than building a project with that.

I have written many articles about building stuff in React. In this last one, I wrote about Building a Music Player in React. This time, I will guide you on building a video player in React.

In this article, we are going to look into the following topics:

  • Prerequisite and Setting up the Environment
  • Playing Video with the default player
  • Building a Custom player with Play/Pause functionality
  • Adding the current time and duration of the video in the player
  • Adding a range timeline to display the video

In the end, our player will look like this:

Video Player

I hope that the above topics got you excited. Now, let's get started with the project.

Prerequisite and Setting up the Environment

I assume that you know of the following technologies as a prerequisite:

  • JavaScript
  • HTML/CSS
  • Basic React

The environment setup is easy. You should have node.js pre-installed for running the node-related command in the terminal.

Navigate to the directory in which you want to create the project. Now, run the terminal and enter the below command to install react project.

npx create-react-app video-player

Remove all the boilerplate and unnecessary code.

Dependiencies

We need only one library to install. Here it is:

react-icons: For adding icons of play, pause, next and previous into our player.

Install it with the below command:

npm i react-icons

Now, We are good to go.

Playing Video with the default player

Let's first import and play a video file in the browser. We can do that with the video HTML tag.

Open App.js. Here is the code for it.

import video from "./assets/video.mp4";

return(
 <video controls width="70%" className="videoPlayer" src={video}></video>
)

This will play the video in the browser with the default player. It will be able to do the post of the work.

Now, it's time to build our own controls with custom icons.

Builiding Custom player with Play/Pause functionality

First, we need to hide the controls from the default player. We can do that by removing controls properties from the video tag.

Now, it's to add custom icons to the player.


           <div className="controls">
            <IconContext.Provider value={{ color: "white", size: "2em" }}>
              <BiSkipPrevious />
            </IconContext.Provider>
            {isPlaying ? (
              <button className="controlButton" onClick={handlePlay}>
                <IconContext.Provider value={{ color: "white", size: "2em" }}>
                  <BiPause />
                </IconContext.Provider>
              </button>
            ) : (
              <button className="controlButton" onClick={handlePlay}>
                <IconContext.Provider value={{ color: "white", size: "2em" }}>
                  <BiPlay />
                </IconContext.Provider>
              </button>
            )}
            <IconContext.Provider value={{ color: "white", size: "2em" }}>
              <BiSkipNext />
            </IconContext.Provider>

We also need to store the video properties in useRef hook to prevent re-render on changes. Also, we need some states to store data running. Here is the code for imports and useState.

import { useEffect, useRef, useState } from "react";
import { IconContext } from "react-icons";
import { BiPlay, BiSkipNext, BiSkipPrevious, BiPause } from "react-icons/bi";


function App() {
   const videoRef = useRef(null);
   const [isPlaying, setIsPlaying] = useState(false); // a boolean for storing state of the play
}

To useRef we just need to use the ref attribute in the video tag.

<video
   className="videoPlayer"
   width="70%"
   ref={videoRef}
   src={video}
></video>

We can do the play pause of the video with the handlePlay function. I have added it as the onClick button event in the icon's parent div.

Here is the code for the handlePlay()

const handlePlay = () => {
  if (isPlaying) {
    videoRef.current.pause();
    setIsPlaying(false);
  } else {
    videoRef.current.play();
    setIsPlaying(true);
}

For CSS, you can see the below code:

.container {
  display: flex;
  margin: 0 auto;
  justify-content: center;
  width: 80%;
  /* overflow: hidden; */
}

.playerContainer {
  display: flex;
  flex-direction: column;
  margin-top: 5em;
  border-radius: 1em;
  overflow: hidden;
}

.videoPlayer {
  border-radius: 1em;
  z-index: -1;
}

.controlsContainer {
  margin-top: -3.5em;
}

.controls {
  display: flex;
  z-index: 1;
  color: white;
  width: 200px;
  justify-content: space-between;
}

.controlButton {
  border: none;
  background: none;
}

.timeline {
  width: 70%;
}

.duration {
  display: flex;
  justify-content: center;
  align-items: center;
}

.controlButton:hover {
  cursor: pointer;
}

Now, our custom player can play/pause the video with our custom icon.

Adding the current time and duration of the video in the player

Let's first add a few more states for storing data related to the duration of the video. I have used the

  const [currentTime, setCurrentTime] = useState([0, 0]); // current time of the video in array. The first value represents the minute and the second represents seconds.
  const [currentTimeSec, setCurrentTimeSec] = useState(); //current time of the video in seconds
  const [duration, setDuration] = useState([0, 0]); // // total duration of the video in the array. The first value represents the minute and the second represents seconds.
  const [durationSec, setDurationSec] = useState(); // // current duration of the video in seconds

To get all the above data, we have the useEffect function.

useEffect(() => {
    const { min, sec } = sec2Min(videoRef.current.duration);
    setDurationSec(videoRef.current.duration);
    setDuration([min, sec]);

    console.log(videoRef.current.duration);
    const interval = setInterval(() => {
      const { min, sec } = sec2Min(videoRef.current.currentTime);
      setCurrentTimeSec(videoRef.current.currentTime);
      setCurrentTime([min, sec]);
    }, 1000);
    return () => clearInterval(interval);
  }, [isPlaying]);

To update the current time of the video, we have passed it as setTimeout function. This will update the current time of the video every second.

Also, there is a function sec2Min() for converting seconds into minutes. Here is the code for it.

const sec2Min = (sec) => {
    const min = Math.floor(sec / 60);
    const secRemain = Math.floor(sec % 60);
    return {
      min: min,
      sec: secRemain,
    };
  };

Let's add it to the return of the app.

<div className="duration">
    {currentTime[0]}:{currentTime[1]} / {duration[0]}:{duration[1]}
</div>

Adding a range timeline to display the video

Now, let's add a timeline to our player. We can do that by adding an input with type="range". Here, the second of the current time and duration time will be helpful.

<input
  type="range"
  min="0"
  max={durationSec}
  default="0"
  value={currentTimeSec}
  className="timeline"
  onChange={(e) => {
    videoRef.current.currentTime = e.target.value;
  }}
/>;

CodeSandbox

You look for the code and the output in the below codesandbox.

{% codesandbox immutable-sun-1bptx8 %}

Adding more features to the player

You can extend the project to add features such as:

  • Making the player more responsive
  • Implementing full-screen button on the right
  • Show controls only when hovering
  • More features for your player according to what you

Conclusion

We have created our own custom video player with play/pause and a timeline. I hope that the project has helped you in handling video in React.

Thanks for reading the article.

Explore other topics