Skip to content

Instantly share code, notes, and snippets.

@JinsoRaj
Created June 7, 2025 17:55
Show Gist options
  • Save JinsoRaj/8938e7c2d11a77487af7602ff7281374 to your computer and use it in GitHub Desktop.
Save JinsoRaj/8938e7c2d11a77487af7602ff7281374 to your computer and use it in GitHub Desktop.
video prinaut
<!DOCTYPE html>
<html>
<head>
<!-- Material Symbols font -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined" rel="stylesheet" />
<style>
.video-wrapper {
position: relative;
width: 800px;
max-width: 100%;
margin: 50px auto;
background: #000;
}
video {
width: 100%;
display: block;
}
.controls {
position: absolute;
left: 0; right: 0; bottom: 0;
background: rgba(30, 30, 30, 0.32); /* More transparent */
color: #fff;
display: flex;
align-items: center;
gap: 10px;
padding: 8px 12px;
transition: opacity 0.2s;
border-radius: 0 0 8px 8px;
font-family: 'Material Symbols Outlined', Arial, sans-serif;
font-size: 24px;
z-index: 2;
}
button, input[type=range] {
background: none;
border: none;
color: inherit;
cursor: pointer;
outline: none;
display: flex;
align-items: center;
opacity: 0.85;
transition: opacity 0.2s;
padding: 0 2px;
height: 36px;
}
button:hover, input[type=range]:hover {
opacity: 1;
}
.material-symbols-outlined {
font-size: 28px;
vertical-align: middle;
user-select: none;
pointer-events: none;
}
input[type=range].progress {
flex: 1;
margin: 0 8px;
accent-color: #fff;
height: 4px;
background: transparent;
}
input[type=range] {
width: 90px;
accent-color: #fff;
}
/* Hide number input arrows on Chrome/Safari */
input[type=range]::-webkit-slider-thumb {
background: #fff;
border-radius: 50%;
width: 14px;
height: 14px;
box-shadow: 0 0 2px #0004;
}
input[type=range]::-webkit-slider-runnable-track {
height: 4px;
background: #fff7;
border-radius: 2px;
}
input[type=range]:focus {
outline: none;
}
</style>
</head>
<body>
<div class="video-wrapper">
<video id="myVideo"
src="https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"
preload="metadata"
autoplay
muted
playsinline>
</video>
<div class="controls" id="controls">
<button id="playPause" aria-label="Play/Pause">
<span id="playIcon" class="material-symbols-outlined">play_arrow</span>
<span id="pauseIcon" class="material-symbols-outlined" style="display:none;">pause</span>
</button>
<button id="rewind" aria-label="Rewind 10 seconds">
<span class="material-symbols-outlined">replay_10</span>
</button>
<button id="forward" aria-label="Forward 10 seconds">
<span class="material-symbols-outlined">forward_10</span>
</button>
<input type="range" id="progress" class="progress" min="0" max="100" value="0" aria-label="Seek">
<button id="mute" aria-label="Mute/Unmute">
<span id="volumeOnIcon" class="material-symbols-outlined">volume_up</span>
<span id="volumeOffIcon" class="material-symbols-outlined" style="display:none;">volume_off</span>
</button>
<input type="range" id="volume" min="0" max="1" step="0.05" value="1" aria-label="Volume">
<button id="fullscreen" aria-label="Fullscreen">
<span class="material-symbols-outlined">fullscreen</span>
</button>
</div>
</div>
<script>
const video = document.getElementById('myVideo');
const playPause = document.getElementById('playPause');
const playIcon = document.getElementById('playIcon');
const pauseIcon = document.getElementById('pauseIcon');
const rewind = document.getElementById('rewind');
const forward = document.getElementById('forward');
const progress = document.getElementById('progress');
const mute = document.getElementById('mute');
const volume = document.getElementById('volume');
const fullscreen = document.getElementById('fullscreen');
const volumeOnIcon = document.getElementById('volumeOnIcon');
const volumeOffIcon = document.getElementById('volumeOffIcon');
const controls = document.getElementById('controls');
let userPaused = false;
// Viewport logic: restart video when entering viewport
let observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
video.currentTime = 0;
video.play();
userPaused = false;
} else {
video.pause();
video.currentTime = 0;
}
});
}, { threshold: 0.5 });
observer.observe(video);
// Play/Pause
playPause.onclick = () => {
if (video.paused) {
video.play();
userPaused = false;
} else {
video.pause();
userPaused = true;
}
};
video.onplay = () => {
playIcon.style.display = "none";
pauseIcon.style.display = "";
};
video.onpause = () => {
playIcon.style.display = "";
pauseIcon.style.display = "none";
};
// Rewind/Forward
rewind.onclick = () => video.currentTime = Math.max(0, video.currentTime - 10);
forward.onclick = () => video.currentTime = Math.min(video.duration, video.currentTime + 10);
// Progress bar
video.ontimeupdate = () => progress.value = (video.currentTime / video.duration) * 100 || 0;
progress.oninput = () => video.currentTime = (progress.value / 100) * video.duration;
// Mute/Volume
mute.onclick = () => {
video.muted = !video.muted;
updateVolumeIcon();
};
volume.oninput = () => {
video.volume = volume.value;
video.muted = video.volume == 0;
updateVolumeIcon();
};
function updateVolumeIcon() {
if (video.muted || video.volume == 0) {
volumeOnIcon.style.display = "none";
volumeOffIcon.style.display = "";
} else {
volumeOnIcon.style.display = "";
volumeOffIcon.style.display = "none";
}
}
updateVolumeIcon();
// Fullscreen
fullscreen.onclick = () => {
if (document.fullscreenElement) {
document.exitFullscreen();
} else {
video.parentElement.requestFullscreen();
}
};
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment