How to Build a Video Player in Vannila Javascript and HTML

Image by storyset on Freepik

How to Build a Video Player in Vanilla Javascript And HTML5

You’ll learn how to create your own JavaScript video player using simple methods and will end up with really cool results!

Paul Knulst  in  JavaScript Oct 13, 2022 5 min read

Probably, a decade ago it was impossible to play your video or audio inside of your browser without any third-party services such as Flash or Silverlight. You needed to install a plugin and only play your media while using it, so as you can see it was very uncomfortable, with low speed and high delays. Nowadays, we have JavaScript with the new version of HTML5, with these new technologies and tools we can stream our video much quicker, easier, and without any latency. To do it you will need only a simple <video> tag that was added in HTML5 and give a link to your video stored on your computer. Then, by using one simple attribute called controls you’ll have a default video player which was built into the browser. It’s elementary and doesn’t have many features, so if you want to stream a video on your website in a more professional way using your personal video player, you’ll need to use JavaScript. And we’ll teach you how to do it in this article!

By the end of this guide you’ll have something similar to this, so if you’re excited, keep reading and follow this tutorial step-by-step!

Setting Up the Project

Assuming you are working with UNIX system (or have Git BASH on Windows) you can create all three files that are necessary to build a video player in JavaScript with this command:

mkdir video-player
cd video-player
touch index.html script.js style.css

To add a simple video player to our application we have to add the following code to our index.html:

<!DOCTYPE html>
<html lang="en">
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>How to build a video player in Javascript</title>
        <link rel="stylesheet" href="style.css" />
        <div class="player">
            <video class="video" controls>
                <p>No HTML5 video supported</p>
        <script src="script.js"></script>

Within the above code, the <video> element uses a remote video from my FTP. You can either use my default video or add any video from your local computer by adjusting the src attribute. HTML5 specification supports three different video formats and the snippet used multiple <source> tags to make the videos available in MP4 and WebM. Furthermore, the <p> tag is used to display pre-defined content to user agents that do not support the video element.

The HTML5 <video> tag accepts several native attributes. For example, the controls attribute displays the standard player controls when added or set to true. You can find out more about all video attributes here.

Before continuing you should apply all styles that are needed within this tutorial by populating your style.css with all styles from this CodePen. Save and open your index.html and load it within the browser to see the embedded video player as seen below:

Screenshot of the video player UI
Screenshot of the video player UI

Customize the Video Player With JavaScript

To customize the video player, you first have to remove the controls attribute that displays Play, Pause, Volume, etc because you will implement your own custom controls within this tutorial. Now, check your browser you will recognize that the controls are gone and you cannot play the video anymore.

Screenshot of the video player UI without controls attribute
Screenshot of the video player UI without controls attribute

Add Play and Pause

To enable play and pause the video you have to add a new button to the index.html:

<div class="controls">
            class="controls__btn playPauseBtn"
            title="Toggle Play"

Afterward, open your script.js and enable functionality by adding this code:

const videoContainer = document.querySelector(".video-container");
const playPauseBtn = document.querySelector(".playPauseBtn");
function togglePlay() {
  if (videoContainer.paused || videoContainer.ended) {;
  } else {
function updatePlayBtn() {
  playPauseBtn.innerHTML = videoContainer.paused ? "►" : "❚❚";
playPauseBtn.addEventListener("click", togglePlay);
videoContainer.addEventListener("click", togglePlay);
videoContainer.addEventListener("play", updatePlayBtn);
videoContainer.addEventListener("pause", updatePlayBtn);

Within this javascript code first the video-container element and the playPauseBtn is selected (Line 1 and 2). Then two functions will are defined: togglePlay() and updatePlayBtn(). togglePlay() is used to stop and start the video based on its actual state. updatePlayBtn is used to switch between the Icon which is shown within the video player.

In the last part of the snippet, a click event listener is added to the playPauseBtn that executes the togglePlay() function. Next, three click event listeners are added to the videoContainer that executes togglePlay() on mouse click and also executes updatePlayBtn based on the video's state.

Now you can reload your index.html and should be able to play and pause the video by either clicking the video or the button:

Animated demonstration of play and pause  of the video player
Animated demonstration of play and pause of the video player

Add A Progress Bar

Next, a progress bar will be implemented to show the current timestamp of the video when played. First, add a <div> tag to the index.html which will act as the progress bar:

<div class="controls">
    <div class="progress">
    	<div class="progress__filled"></div>
    // ..

Then open the script.js and add the following snippet:

const progress = document.querySelector(".progress");
const progressBar = document.querySelector(".progress__filled");

function handleProgress() {
  const progressPercentage = (videoContainer.currentTime / videoContainer.duration) * 100; = `${progressPercentage}%`;

function jump(e) {
  const position = (e.offsetX / progress.offsetWidth) * videoContainer.duration;
  videoContainer.currentTime = position;

videoContainer.addEventListener("timeupdate", handleProgress);
progress.addEventListener("click", jump);
let mousedown = false;
progress.addEventListener("mousedown", () => (mousedown = true));
progress.addEventListener("mousemove", (e) => mousedown && jump(e));
progress.addEventListener("mouseup", () => (mousedown = false));

In this snippet, the progress container and the progress__filled element will be selected and two functions will be added: handleProgress() and jump(e). handleProgress() will be responsible for updating the progress bar. The jump(e) function is used to enable clicking on the progress bar to jump to the position within the video.

The last part contains all event listeners that are needed for the progress bar. The handleProgress() will be called at every timeupdate event. Also clicking anywhere on the progress bar will call the jump(e) method and the video will jump to the position. Additionally, mousedown, mousemove, and mouseup will be used to enable sliding through the video while holding the mouse button down on the progress bar.

Closing Notes

Congratulations, if you followed the tutorial you learned how to implement your own video player and add custom controls using JavaScript. Now, you can use my CodePen and start implementing more controls like volume control, keyboard shortcuts, or skip controls to build your own customized video player.

At the moment, I am working on a follow-up tutorial where I extend this code to add keyboard controls and add additional functionality. It will be published here on my personal blog and later on Medium.

Have any questions? No problem, just ask in the comments section. I will answer everything.

Feel free to connect with me on Medium, LinkedIn, and Twitter.

🙌 Support this content

If you like this content, please consider supporting me. You can share it on social media, buy me a coffee, or become a paid member. Any support helps.

See the contribute page for all (free or paid) ways to say thank you!

Thanks! 🥰

By Paul Knulst

I'm a husband, dad, lifelong learner, tech lover, and Senior Engineer working as a Tech Lead. I write about projects and challenges in IT.