Video Player Using Js

Posted on October 05, 2025 by Vishesh Namdev
Python C C++ Javascript Java
Video Player Project using JS

In this article, I’ll walk you through how we can create a Custom Video Player using HTML, CSS, and JavaScript. This project allows you to control video playback with custom buttons for play, pause, rewind, forward, volume, and fullscreen. It also includes a dynamic progress bar and time display that updates in real time as the video plays. By building this project, you’ll learn how to work with HTML5 video events, handle user interactions, and customize the default video controls to create your own modern media player.

🧩 Project Overview

The main idea of this project is simple:

  • Create a custom video player interface using HTML, CSS, and JavaScript.
  • Display the current playback time and total duration dynamically.
  • Allow users to play, pause, rewind, and forward the video using custom buttons.
  • Include a progress bar that updates in real-time and lets users jump to any part of the video.
  • Add volume control and fullscreen functionality for a complete viewing experience.
  • DOMContentLoaded Event

    We wrap the entire code inside DOMContentLoaded to ensure the script runs only after the HTML is fully loaded. This prevents errors when trying to access elements that aren’t available yet.

    document.addEventListener("DOMContentLoaded", () => {
      // all code goes here
    });

    2. Selecting Elements

    Here, we grab all the required elements from our HTML. These references allow us to manipulate the video, buttons, progress bar, and time display dynamically with JavaScript.

    const video = document.getElementById("video");
    const playPauseBtn = document.getElementById("play-pause");
    const rewindBtn = document.getElementById("rewind");
    const forwardBtn = document.getElementById("forward");
    const volumeSlider = document.getElementById("volume");
    const fullscreenBtn = document.getElementById("fullscreen");
    const videoContainer = document.querySelector(".video-container");
    
    const progressBar = document.getElementById("progress-bar");
    const progressFilled = document.getElementById("progress-filled");
    const currentTimeEl = document.getElementById("current-time");
    const durationEl = document.getElementById("duration");

    3. Formatting Time

    This function converts raw seconds into a user-friendly format (mm:ss). For example, 125 seconds becomes 2:05. This makes the time display readable.

    function formatTime(seconds) {
      const mins = Math.floor(seconds / 60);
      const secs = Math.floor(seconds % 60);
      return `${mins}:${secs < 10 ? "0" : ""}${secs}`;
    }

    4. Updating Progress & Time

    This function updates both the progress bar width and the current/duration time. It’s called whenever the video plays or loads metadata. The isNaN(total) check ensures the duration shows 0:00 if the video hasn’t loaded yet.

    Code:-

    function updateProgress() {
      const current = video.currentTime;
      const total = video.duration || 0;
      const progress = (current / total) * 100;
      progressFilled.style.width = `${progress}%`;
    
      currentTimeEl.textContent = formatTime(current);
      durationEl.textContent = isNaN(total) ? "0:00" : formatTime(total);
    }

    5. Play / Pause Button

    Clicking the button toggles between Play and Pause. We also change the button icon dynamically (▶️ for play, ⏸️ for pause).

    Code:-

    playPauseBtn.addEventListener("click", () => {
      if (video.paused) {
        video.play();
        playPauseBtn.textContent = "⏸️";
      } else {
        video.pause();
        playPauseBtn.textContent = "▶️";
      }
    });

    6. Rewind & Forward

    These buttons allow the user to jump backward or forward by 10 seconds. We use Math.max and Math.min to prevent the time from going below 0 or beyond the total duration.

    Code:-

    rewindBtn.addEventListener("click", () => {
      video.currentTime = Math.max(0, video.currentTime - 10);
    });
    
    forwardBtn.addEventListener("click", () => {
      video.currentTime = Math.min(video.duration, video.currentTime + 10);
    });

    7. Volume Control

    This lets users adjust the volume using a range slider. The slider value (between 0 and 1) is directly applied to the video’s volume property.

    Code:-

    volumeSlider.addEventListener("input", () => {
      video.volume = volumeSlider.value;
    });

    8. Fullscreen Mode

    The fullscreen button toggles between entering and exiting fullscreen. The optional chaining (?.) ensures compatibility with browsers that might not support these methods.

    Code:-

    fullscreenBtn.addEventListener("click", () => {
      if (!document.fullscreenElement) {
        videoContainer.requestFullscreen?.();
      } else {
        document.exitFullscreen?.();
      }
    });

    9. Progress Bar Seeking

    Clicking anywhere on the progress bar jumps the video to that specific point. We calculate the clicked position relative to the bar’s width and convert it into a time value.

    Code:-

    progressBar.addEventListener("click", (e) => {
      const rect = progressBar.getBoundingClientRect();
      const clickX = e.clientX - rect.left;
      const newTime = (clickX / rect.width) * video.duration;
      video.currentTime = newTime;
    });

    10. Updating Progress with Video Events

  • timeupdate: Fires while the video is playing, updating the bar and current time.
  • loadedmetadata: Runs once the video metadata (like duration) is available.
  • Code:-

    video.addEventListener("timeupdate", updateProgress);
    video.addEventListener("loadedmetadata", updateProgress);

    Full Code:-

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <title>Simple Custom Video Player</title>
    
      <style>
        body {
          background: #222222;
          display: flex;
          align-items: center;
          justify-content: center;
          height: 100vh;
          margin: 0;
          font-family: Arial, sans-serif;
          color: #fff;
        }
    
        .video-container {
          position: relative;
          width: 800px;
          max-width: 100%;
          background: #000;
          border-radius: 8px;
          overflow: hidden;
        }
    
        video {
          width: 100%;
          display: block;
        }
    
        /* ✅ Progress bar */
        .progress-container {
          padding: 8px 10px;
        }
    
        .progress-bar {
          height: 6px;
          background: #444;
          cursor: pointer;
          width: 100%;
          border-radius: 3px;
        }
    
        .progress-filled {
          height: 100%;
          background: #ff5252;
          width: 0%;
          border-radius: 3px;
        }
    
        .time-display {
          text-align: right;
          font-size: 14px;
          margin-bottom: 4px;
          opacity: 0.8;
        }
    
        .controls {
          display: flex;
          align-items: center;
          justify-content: space-around;
          padding: 10px;
          background: rgba(0, 0, 0, 0.6);
        }
    
        button {
          background: transparent;
          border: none;
          color: white;
          font-size: 16px;
          cursor: pointer;
        }
    
        button:hover {
          color: #ff5252;
        }
    
        input[type="range"] {
          width: 100px;
          cursor: pointer;
        }
      </style>
    </head>
    
    <body>
      <div class="video-container">
        <video id="video">
          <source src="js.mp4" type="video/mp4" />
          Your browser does not support HTML5 video.
        </video>
    
        <!-- ✅ Time + Progress -->
        <div class="progress-container">
          <div class="time-display">
            <span id="current-time">0:00</span> / <span id="duration">0:00</span>
          </div>
    
          <div class="progress-bar" id="progress-bar">
            <div class="progress-filled" id="progress-filled"></div>
          </div>
        </div>
    
        <div class="controls">
          <button id="play-pause">▶️</button>
          <button id="rewind">⏪ 10s</button>
          <button id="forward">10s ⏩</button>
    
          <input type="range" id="volume" min="0" max="1" step="0.05" value="1" />
    
          <button id="fullscreen">⛶</button>
        </div>
      </div>
    
      <script>
        document.addEventListener("DOMContentLoaded", () => {
          const video = document.getElementById("video");
          const playPauseBtn = document.getElementById("play-pause");
          const rewindBtn = document.getElementById("rewind");
          const forwardBtn = document.getElementById("forward");
          const volumeSlider = document.getElementById("volume");
          const fullscreenBtn = document.getElementById("fullscreen");
          const videoContainer = document.querySelector(".video-container");
    
          const progressBar = document.getElementById("progress-bar");
          const progressFilled = document.getElementById("progress-filled");
          const currentTimeEl = document.getElementById("current-time");
          const durationEl = document.getElementById("duration");
    
          // Format time as mm:ss
          function formatTime(seconds) {
            const mins = Math.floor(seconds / 60);
            const secs = Math.floor(seconds % 60);
            return `${mins}:${secs < 10 ? "0" : ""}${secs}`;
          }
    
          // Update progress bar + time
          function updateProgress() {
            const current = video.currentTime;
            const total = video.duration || 0;
            const progress = (current / total) * 100;
            progressFilled.style.width = `${progress}%`;
    
            currentTimeEl.textContent = formatTime(current);
            durationEl.textContent = isNaN(total) ? "0:00" : formatTime(total);
          }
    
          // Play / Pause toggle
          playPauseBtn.addEventListener("click", () => {
            if (video.paused) {
              video.play();
              playPauseBtn.textContent = "⏸️";
            } else {
              video.pause();
              playPauseBtn.textContent = "▶️";
            }
          });
    
          // Rewind 10s
          rewindBtn.addEventListener("click", () => {
            video.currentTime = Math.max(0, video.currentTime - 10);
          });
    
          // Forward 10s
          forwardBtn.addEventListener("click", () => {
            video.currentTime = Math.min(video.duration, video.currentTime + 10);
          });
    
          // Volume Control
          volumeSlider.addEventListener("input", () => {
            video.volume = volumeSlider.value;
          });
    
          // Fullscreen Toggle
          fullscreenBtn.addEventListener("click", () => {
            if (!document.fullscreenElement) {
              videoContainer.requestFullscreen?.();
            } else {
              document.exitFullscreen?.();
            }
          });
    
          // Progress Bar Click (Seek)
          progressBar.addEventListener("click", (e) => {
            const rect = progressBar.getBoundingClientRect();
            const clickX = e.clientX - rect.left;
            const newTime = (clickX / rect.width) * video.duration;
            video.currentTime = newTime;
          });
    
          // Update progress while playing
          video.addEventListener("timeupdate", updateProgress);
          video.addEventListener("loadedmetadata", updateProgress);
    
          // Reset button when video ends
          video.addEventListener("ended", () => {
            playPauseBtn.textContent = "▶️";
          });
        });
      </script>
    </body>
    </html>
    📢Important Note📢

    How did you feel about this post?

    😍 🙂 😐 😕 😡

    Was this helpful?

    👍 👎