About this snippet

Embed a video using the HTML5 <video> tag and create custom player controls (play/pause, volume, fullscreen) using JavaScript for a unique viewing experience.

Size
5.2 KB
Uses
HTML, CSS, JavaScript
Loads
codeshack.io
Views
475
<div class="video-player" id="playerContainer">
  <video id="myVideo" src="https://codeshack.io/web/example.mp4" playsinline></video>
  
  <div class="controls-overlay">
    <div class="progress-area">
      <div class="progress-bar">
        <div class="progress-filled"></div>
      </div>
    </div>

    <div class="controls-main">
      <div class="controls-left">
        <button id="playPauseBtn" class="control-btn">
          <svg id="playIcon" viewBox="0 0 24 24"><path d="M8 5v14l11-7z"/></svg>
          <svg id="pauseIcon" class="hidden" viewBox="0 0 24 24"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>
        </button>
        <div class="volume-group">
          <button id="muteBtn" class="control-btn">
             <svg viewBox="0 0 24 24"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/></svg>
          </button>
          <input type="range" id="volumeSlider" min="0" max="1" step="0.05" value="1">
        </div>
        <span class="time-display"><span id="currentTime">0:00</span> / <span id="duration">0:00</span></span>
      </div>

      <div class="controls-right">
        <button id="speedBtn" class="control-btn text-icon">1x</button>
        <button id="fullScreenBtn" class="control-btn">
          <svg viewBox="0 0 24 24"><path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/></svg>
        </button>
      </div>
    </div>
  </div>
</div>
:root {
  --accent: #ffffff;
  --glass: rgba(15, 23, 42, 0.7);
  --blur: blur(12px);
}

* {
  font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  box-sizing: border-box;
}

.video-player {
  position: relative;
  max-width: 800px;
  margin: 20px auto;
  border-radius: 16px;
  overflow: hidden;
  background: #000;
  box-shadow: 0 20px 40px rgba(0,0,0,0.3);
}

video { width: 100%; display: block; }

.controls-overlay {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  padding: 20px;
  background: linear-gradient(transparent, rgba(0,0,0,0.8));
  transition: opacity 0.4s ease;
  opacity: 0; /* Hidden by default, shown on hover */
}

.video-player:hover .controls-overlay { opacity: 1; }

.controls-main {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: var(--glass);
  backdrop-filter: var(--blur);
  padding: 10px 18px;
  border-radius: 14px;
  border: 1px solid rgba(255,255,255,0.1);
}

.control-btn {
  background: none;
  border: none;
  cursor: pointer;
  padding: 5px;
  display: flex;
  align-items: center;
  color: white;
  transition: transform 0.2s ease;
}

.control-btn:hover { transform: scale(1.1); }
.control-btn svg { width: 24px; height: 24px; fill: currentColor; }
.hidden { display: none; }

/* Progress Bar Styling */
.progress-area {
  height: 5px;
  width: 100%;
  cursor: pointer;
  margin-bottom: 15px;
  display: flex;
  align-items: center;
}

.progress-bar {
  height: 4px;
  width: 100%;
  background: rgba(255,255,255,0.2);
  border-radius: 10px;
  position: relative;
}

.progress-filled {
  height: 100%;
  width: 0%;
  background: var(--accent);
  border-radius: 10px;
}

/* Volume Slider */
#volumeSlider {
  width: 0;
  opacity: 0;
  transition: all 0.3s ease;
}

.volume-group:hover #volumeSlider {
  width: 80px;
  opacity: 1;
  margin-left: 10px;
}
const player = document.getElementById('playerContainer');
const video = document.getElementById('myVideo');
const playPauseBtn = document.getElementById('playPauseBtn');
const playIcon = document.getElementById('playIcon');
const pauseIcon = document.getElementById('pauseIcon');
const progress = document.querySelector('.progress-filled');
const progressArea = document.querySelector('.progress-area');
const speedBtn = document.getElementById('speedBtn');

// Play/Pause Logic
function togglePlay() {
  if (video.paused) {
    video.play();
    playIcon.classList.add('hidden');
    pauseIcon.classList.remove('hidden');
  } else {
    video.pause();
    playIcon.classList.remove('hidden');
    pauseIcon.classList.add('hidden');
  }
}

playPauseBtn.addEventListener('click', togglePlay);
video.addEventListener('click', togglePlay);

// Update Progress Bar
video.addEventListener('timeupdate', () => {
  const percent = (video.currentTime / video.duration) * 100;
  progress.style.width = `${percent}%`;
  
  // Update Time Display
  document.getElementById('currentTime').textContent = formatTime(video.currentTime);
});

// Scrubbing / Seeking
progressArea.addEventListener('click', (e) => {
  const scrubTime = (e.offsetX / progressArea.offsetWidth) * video.duration;
  video.currentTime = scrubTime;
});

// Playback Speed
speedBtn.addEventListener('click', () => {
  let newSpeed = video.playbackRate + 0.5;
  if (newSpeed > 2) newSpeed = 0.5;
  video.playbackRate = newSpeed;
  speedBtn.textContent = `${newSpeed}x`;
});

// Format Time (Seconds to MM:SS)
function formatTime(time) {
  const minutes = Math.floor(time / 60);
  const seconds = Math.floor(time % 60);
  return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
}

// Initial Duration
video.addEventListener('loadedmetadata', () => {
  document.getElementById('duration').textContent = formatTime(video.duration);
});
Esc
↑↓ moveEnter select

Start from a template

Open an .html file, or HTML, CSS, JS, Markdown, Less or TypeScript files. You can also drop them here. Styles and scripts go into their panes.

Share

Source

Keyboard shortcuts

Save