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:
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.
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 (9)
Nice post
Thanks 👍
Thank you, please do more proyects with React
Glad that you like it. Sure will do more of such projects.
Thank you for this post, Really insightful
Amazing I love it
Thanks, Ahmed. Add more features to it.
Your setInterval is running when video is paused. You should check condition to run interval. If isPlaying is false then stop it.
how about mute and quality control of video