-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ab3103f
commit accaf0e
Showing
12 changed files
with
496 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# Custom video player | ||
|
||
The default html video player has limited capabilities also its different for different browsers. | ||
So, I decided built a custom one with some of the important features like `play pause` on click over the video, `volume control`, `playback control`, `full screen mode`, `skip`, `scrub` etc all this using plain javascript and css. | ||
|
||
# Challenges | ||
- video element | ||
- video properties | ||
- progress bar | ||
- scrubbing | ||
- skipping | ||
- css | ||
|
||
|
||
|
||
# demo | ||
![demo picture](demo.png) | ||
![full screen mode](full.png) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Custom video player</title> | ||
<link rel="stylesheet" href="style.css"> | ||
<script defer src="main.js"></script> | ||
</head> | ||
<body> | ||
<div class="container"> | ||
<h1>Custom video player using vanilla JS</h1> | ||
<div class="player"> | ||
<video class="player__video viewer" src="Funny Birds Animated Short Film.mp4"></video> | ||
|
||
<div class="player__controls"> | ||
<div class="progress"> | ||
<div class="progress__filled"></div> | ||
</div> | ||
<button class="player__button toggle" title="Toggle Play">►</button> | ||
<input type="range" name="volume" class="player__slider" min="0" max="1" step="0.05" value="1"> | ||
<div class="player__button unmute" id="mute"></div> | ||
<input type="range" name="playbackRate" class="player__slider" min="0.5" max="2" step="0.1" value="1"> | ||
<button data-skip="-10" class="player__button">« 10s</button> | ||
<button data-skip="25" class="player__button">25s »</button> | ||
<div class="player__button zoom"></div> | ||
</div> | ||
</div> | ||
|
||
|
||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
Bugs : | ||
- progressbar isn't working | ||
- unresponsiveness | ||
- bad icons | ||
- full-screen no control on hover | ||
- no feedback for keyboard keys like space, right, left, |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
//get hold of each element | ||
const player = document.querySelector('.player'); | ||
const viewer = player.querySelector('.viewer') | ||
const toggle = player.querySelector('.toggle') | ||
//anything with data-skip | ||
const skipButtons = player.querySelectorAll('[data-skip]'); | ||
const mute = player.querySelector('#mute'); | ||
const progress = player.querySelector('.progress'); | ||
const progressBar = player.querySelector('.progress__filled'); | ||
const ranges = player.querySelectorAll('.player__slider'); | ||
const fullscreen = player.querySelector('.zoom'); | ||
|
||
|
||
//functions | ||
function togglePlay(){ | ||
const status = viewer.paused ? 'play':'pause'; | ||
viewer[status](); | ||
} | ||
|
||
function toggleButton(){ | ||
const icon = this.paused ? '►' : '❚ ❚'; | ||
toggle.textContent = icon; | ||
|
||
} | ||
|
||
function skip() { | ||
viewer.currentTime += parseFloat(this.dataset.skip); | ||
} | ||
|
||
function handleVolumeAndPlayback(){ | ||
//name will be either 'volume', 'playbackrate' | ||
viewer[this.name] = this.value; | ||
} | ||
|
||
function toggleMute(){ | ||
viewer.muted =!viewer.muted; | ||
if(mute.classList.contains('unmute')){ | ||
mute.classList.remove('unmute') | ||
mute.classList.add('mute') | ||
} | ||
|
||
|
||
if(mute.classList.contains('mute')){ | ||
mute.classList.remove('mute') | ||
mute.classList.add('unmute') | ||
} | ||
} | ||
|
||
function handleProgress(){ | ||
//change the flex-basis based on the width or the played/duration | ||
const currentWidth = (viewer.currentTime / viewer.duration) * 100 || 0; | ||
progressBar.style.flexBasis = `${currentWidth}%` | ||
} | ||
|
||
function scrub(e){ | ||
const scrubTime = (e.offsetX / progress.offsetWidth) * viewer.duration; | ||
viewer.currentTime = scrubTime; | ||
} | ||
|
||
function handleFullscreen(e){ | ||
if (isFullScreen()) { | ||
if (document.exitFullscreen) document.exitFullscreen(); | ||
else if (document.mozCancelFullScreen) document.mozCancelFullScreen(); | ||
else if (document.webkitCancelFullScreen) document.webkitCancelFullScreen(); | ||
else if (document.msExitFullscreen) document.msExitFullscreen(); | ||
setFullscreenData(false); | ||
} | ||
else { | ||
if (viewer.requestFullscreen) viewer.requestFullscreen(); | ||
else if (viewer.mozRequestFullScreen) viewer.mozRequestFullScreen(); | ||
else if (viewer.webkitRequestFullScreen) viewer.webkitRequestFullScreen(); | ||
else if (viewer.msRequestFullscreen) viewer.msRequestFullscreen(); | ||
setFullscreenData(true); | ||
} | ||
} | ||
|
||
const setFullscreenData = function(state) { | ||
viewer.setAttribute('data-fullscreen', !!state); | ||
} | ||
|
||
//check if fullscreenApi is supported | ||
const fullScreenEnabled = !!(document.fullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled || document.webkitSupportsFullscreen || document.webkitFullscreenEnabled || document.createElement('video').webkitRequestFullScreen); | ||
if (!fullScreenEnabled) { | ||
fullscreen.style.display = 'none'; | ||
} | ||
|
||
//check status if fullscreen | ||
const isFullScreen = function() { | ||
return !!(document.fullScreen || document.webkitIsFullScreen || document.mozFullScreen || document.msFullscreenElement || document.fullscreenElement); | ||
} | ||
|
||
|
||
//event listeners | ||
viewer.addEventListener('click', togglePlay); | ||
viewer.addEventListener('play', toggleButton); | ||
viewer.addEventListener('pause', toggleButton); | ||
viewer.addEventListener('timeupdate', handleProgress) | ||
|
||
toggle.addEventListener('click', togglePlay) | ||
mute.addEventListener('click',toggleMute) | ||
skipButtons.forEach(button => button.addEventListener('click', skip)); | ||
|
||
ranges.forEach(range => range.addEventListener('change',handleVolumeAndPlayback)); | ||
ranges.forEach(range => range.addEventListener('mousemove',handleVolumeAndPlayback)); | ||
|
||
progress.addEventListener('click', scrub) | ||
|
||
let mousedownFlag = false; | ||
progress.addEventListener('mousedown', ()=> mousedownFlag = true) | ||
progress.addEventListener('mouseup', ()=> mousedownFlag = false) | ||
//listen to mousemove only when user has clicked the left mouse button | ||
progress.addEventListener('mousemove', (e)=> mousedownFlag && scrub(e)) | ||
fullscreen.addEventListener('click', handleFullscreen) | ||
|
||
// fullscreen events | ||
document.addEventListener('fullscreenchange', function(e) { | ||
setFullscreenData(!!(document.fullScreen || document.fullscreenElement)); | ||
}); | ||
document.addEventListener('webkitfullscreenchange', function() { | ||
setFullscreenData(!!document.webkitIsFullScreen); | ||
}); | ||
document.addEventListener('mozfullscreenchange', function() { | ||
setFullscreenData(!!document.mozFullScreen); | ||
}); | ||
document.addEventListener('msfullscreenchange', function() { | ||
setFullscreenData(!!document.msFullscreenElement); | ||
}); |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.