Skip to content

Commit f6e87f7

Browse files
committed
Custom Video Player
1 parent bc429e9 commit f6e87f7

3 files changed

Lines changed: 244 additions & 0 deletions

File tree

11-Custom Video Player/index.html

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<title>HTML Video Player</title>
8+
<link rel="stylesheet" href="style.css">
9+
</head>
10+
<body>
11+
<div class="player">
12+
<video src="https://player.vimeo.com/external/194837908.sd.mp4?s=c350076905b78c67f74d7ee39fdb4fef01d12420&profile_id=164" class="player__video viewer"></video>
13+
<div class="player__controls">
14+
<div class="progess">
15+
<div class="progress_filled"></div>
16+
</div>
17+
<button class="player__button toggle" title="Toggle Play"></button>
18+
<input type="range" name="volume" class="player__slider" min="0" max="1" step="0.05" value="1">
19+
<input type="range" name="playbackRate" class="player__slider" min="0.5" max="2" step="0.1" value="1">
20+
<button data-skip="-10" class="player__button">« 10s</button>
21+
<button data-skip="25" class="player__button">25s »</button>
22+
</div>
23+
</div>
24+
<script src="script.js"></script>
25+
</body>
26+
</html>

11-Custom Video Player/script.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Get Our Elements
2+
const player = document.querySelector('.player');
3+
const video = player.querySelector('.viewer');
4+
const progress = player.querySelector('.progress');
5+
const progressBar = player.querySelector('.progress__filled');
6+
const toggle = player.querySelector('.toggle');
7+
const skipButtons = player.querySelector('[data-skip]');
8+
const ranges = player.querySelector('.player__slider');
9+
10+
// Build out Function
11+
function togglePlay() {
12+
const method = video.paused ? 'play' : 'pause';
13+
video[method()];
14+
}
15+
16+
function updateButton() {
17+
const icon = this.paused ? '►' : '❚ ❚';
18+
console.log(icon);
19+
toggle.textContent = icon;
20+
}
21+
22+
function skip() {
23+
video.currentTime += parseFloat(this.dataset.skip);
24+
}
25+
26+
function handleRangeUpdate() {
27+
video[this.name] = this.value;
28+
}
29+
30+
function handleProgress() {
31+
const percent = (video.currentTime / video.duration) * 100;
32+
progressBar.style.flexBasis = `${percent}%`;
33+
}
34+
35+
function scurb(e) {
36+
const scrubTime = (e.offsetX / progress.offsetWidth) * video.duration;
37+
video.currentTime = scrubTime;
38+
}
39+
40+
// Hook Up the event listeners
41+
video.addEventListener('click', togglePlay);
42+
video.addEventListener('play', updateButton);
43+
video.addEventListener('pause', updateButton);
44+
video.addEventListener('timeupdate', handleProgress);
45+
46+
toggle.addEventListener('click', togglePlay);
47+
skipButtons.forEach(button => button.addEventListener('click', skip));
48+
ranges.forEach(range => range.addEventListener('change', handleRangeUpdate));
49+
ranges.forEach(range => range.addEventListener('mousemove', handleRangeUpdate));
50+
51+
let mousedown = false;
52+
progress.addEventListener('click', scurb);
53+
progress.addEventListener('mousemove', (e) => mousedown && scrub(e));
54+
progress.addEventListener('mousedown', () => mousedown = true);
55+
progress.addEventListener('mouseup', () => mousedown = false);

11-Custom Video Player/style.css

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
html {
2+
box-sizing: border-box;
3+
}
4+
5+
*, *:before, *:after {
6+
box-sizing: inherit;
7+
}
8+
9+
body {
10+
margin: 0;
11+
padding: 0;
12+
display: flex;
13+
background: #7A419B;
14+
min-height: 100vh;
15+
background: linear-gradient(135deg, #7c1599 0%,#921099 48%,#7e4ae8 100%);
16+
background-size: cover;
17+
align-items: center;
18+
justify-content: center;
19+
}
20+
21+
.player {
22+
max-width: 750px;
23+
border: 5px solid rgba(0,0,0,0.2);
24+
box-shadow: 0 0 20px rgba(0,0,0,0.2);
25+
position: relative;
26+
font-size: 0;
27+
overflow: hidden;
28+
}
29+
30+
/* This css is only applied when fullscreen is active. */
31+
.player:fullscreen {
32+
max-width: none;
33+
width: 100%;
34+
}
35+
36+
.player:-webkit-full-screen {
37+
max-width: none;
38+
width: 100%;
39+
}
40+
41+
.player__video {
42+
width: 100%;
43+
}
44+
45+
.player__button {
46+
background: none;
47+
border: 0;
48+
line-height: 1;
49+
color: white;
50+
text-align: center;
51+
outline: 0;
52+
padding: 0;
53+
cursor: pointer;
54+
max-width: 50px;
55+
}
56+
57+
.player__button:focus {
58+
border-color: #ffc600;
59+
}
60+
61+
.player__slider {
62+
width: 10px;
63+
height: 30px;
64+
}
65+
66+
.player__controls {
67+
display: flex;
68+
position: absolute;
69+
bottom: 0;
70+
width: 100%;
71+
transform: translateY(100%) translateY(-5px);
72+
transition: all .3s;
73+
flex-wrap: wrap;
74+
background: rgba(0,0,0,0.1);
75+
}
76+
77+
.player:hover .player__controls {
78+
transform: translateY(0);
79+
}
80+
81+
.player:hover .progress {
82+
height: 15px;
83+
}
84+
85+
.player__controls > * {
86+
flex: 1;
87+
}
88+
89+
.progress {
90+
flex: 10;
91+
position: relative;
92+
display: flex;
93+
flex-basis: 100%;
94+
height: 5px;
95+
transition: height 0.3s;
96+
background: rgba(0,0,0,0.5);
97+
cursor: ew-resize;
98+
}
99+
100+
.progress__filled {
101+
width: 50%;
102+
background: #ffc600;
103+
flex: 0;
104+
flex-basis: 50%;
105+
}
106+
107+
/* unholy css to style input type="range" */
108+
109+
input[type=range] {
110+
-webkit-appearance: none;
111+
background: transparent;
112+
width: 100%;
113+
margin: 0 5px;
114+
}
115+
116+
input[type=range]:focus {
117+
outline: none;
118+
}
119+
120+
input[type=range]::-webkit-slider-runnable-track {
121+
width: 100%;
122+
height: 8.4px;
123+
cursor: pointer;
124+
box-shadow: 1px 1px 1px rgba(0, 0, 0, 0), 0 0 1px rgba(13, 13, 13, 0);
125+
background: rgba(255,255,255,0.8);
126+
border-radius: 1.3px;
127+
border: 0.2px solid rgba(1, 1, 1, 0);
128+
}
129+
130+
input[type=range]::-webkit-slider-thumb {
131+
height: 15px;
132+
width: 15px;
133+
border-radius: 50px;
134+
background: #ffc600;
135+
cursor: pointer;
136+
-webkit-appearance: none;
137+
margin-top: -3.5px;
138+
box-shadow:0 0 2px rgba(0,0,0,0.2);
139+
}
140+
141+
input[type=range]:focus::-webkit-slider-runnable-track {
142+
background: #bada55;
143+
}
144+
145+
input[type=range]::-moz-range-track {
146+
width: 100%;
147+
height: 8.4px;
148+
cursor: pointer;
149+
box-shadow: 1px 1px 1px rgba(0, 0, 0, 0), 0 0 1px rgba(13, 13, 13, 0);
150+
background: #ffffff;
151+
border-radius: 1.3px;
152+
border: 0.2px solid rgba(1, 1, 1, 0);
153+
}
154+
155+
input[type=range]::-moz-range-thumb {
156+
box-shadow: 0 0 0 rgba(0, 0, 0, 0), 0 0 0 rgba(13, 13, 13, 0);
157+
height: 15px;
158+
width: 15px;
159+
border-radius: 50px;
160+
background: #ffc600;
161+
cursor: pointer;
162+
}
163+

0 commit comments

Comments
 (0)