DEV Community

Cover image for Building a Video Player in React
Suraj Vishwakarma for Documatic

Posted on • Updated on

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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>
)
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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

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

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);
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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]);
Enter fullscreen mode Exit fullscreen mode

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,
    };
  };
Enter fullscreen mode Exit fullscreen mode

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

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

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;
  }}
/>;
Enter fullscreen mode Exit fullscreen mode

CodeSandbox

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

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.

Top comments (8)

Collapse
 
kumarakh profile image
akhilesh kumar ojha

Nice post

Collapse
 
surajondev profile image
Suraj Vishwakarma

Thanks πŸ‘

Collapse
 
jvbass profile image
Juan V. Pino Contreras

Thank you, please do more proyects with React

Collapse
 
surajondev profile image
Suraj Vishwakarma

Glad that you like it. Sure will do more of such projects.

Collapse
 
dashdave profile image
Dashdave

Thank you for this post, Really insightful

Collapse
 
ahmedmannai profile image
Ahmed Mannai

Amazing I love it

Collapse
 
surajondev profile image
Suraj Vishwakarma

Thanks, Ahmed. Add more features to it.

Collapse
 
sahilatahar profile image
Sahil Atahar

Your setInterval is running when video is paused. You should check condition to run interval. If isPlaying is false then stop it.

useEffect(() => {
        let interval;

        if (isPlaying) {
            interval = setInterval(() => {
                const { min, sec } = formatTime(videoRef.current.currentTime);
                setCurrentTimeSec(videoRef.current.currentTime);
                setCurrentTime([min, sec]);
            }, 1000);
        } else {
            clearInterval(interval);
        }
        return () => clearInterval(interval);
    }, [isPlaying]);
Enter fullscreen mode Exit fullscreen mode