티스토리 뷰
Custom HTML5 Video Player
비디오 플레이어 만들기
1.재생버튼 누르면 비디오 시작/중지 하기
2.게이지값 설정하면 소리/재생속도 조절하기
3.10초전과 20초 후 클릭시 해당 시간으로 가기
4.10초 전과 20초 후 클릭하거나, 재생, 마우스 클릭 및 마우스 무브시 progress바 움직이기
코드
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>HTML Video Player</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="player">
<video class="player__video viewer" >
<source src="652333414.mp4"
type="video/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">
<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>
</div>
<script src="scripts.js"></script>
</body>
</html>
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
body {
margin: 0;
padding: 0;
display: flex;
background: #7A419B;
min-height: 100vh;
background: linear-gradient(135deg, #7c1599 0%,#921099 48%,#7e4ae8 100%);
background-size: cover;
align-items: center;
justify-content: center;
}
.player {
max-width: 750px;
border: 5px solid rgba(0,0,0,0.2);
box-shadow: 0 0 20px rgba(0,0,0,0.2);
position: relative;
font-size: 0;
overflow: hidden;
}
/* This css is only applied when fullscreen is active. */
.player:fullscreen {
max-width: none;
width: 100%;
}
.player:-webkit-full-screen {
max-width: none;
width: 100%;
}
.player__video {
width: 100%;
}
.player__button {
background: none;
border: 0;
line-height: 1;
color: white;
text-align: center;
outline: 0;
padding: 0;
cursor: pointer;
max-width: 50px;
}
.player__button:focus {
border-color: #ffc600;
}
.player__slider {
width: 10px;
height: 30px;
}
.player__controls {
display: flex;
position: absolute;
bottom: 0;
width: 100%;
transform: translateY(100%) translateY(-5px);
transition: all .3s;
flex-wrap: wrap;
background: rgba(0,0,0,0.1);
}
.player:hover .player__controls {
transform: translateY(0);
}
.player:hover .progress {
height: 15px;
}
.player__controls > * {
flex: 1;
}
.progress {
flex: 10;
position: relative;
display: flex;
flex-basis: 100%;
height: 5px;
transition: height 0.3s;
background: rgba(0,0,0,0.5);
cursor: ew-resize;
}
.progress__filled {
width: 50%;
background: #ffc600;
flex: 0;
flex-basis: 50%;
}
/* unholy css to style input type="range" */
input[type=range] {
-webkit-appearance: none;
background: transparent;
width: 100%;
margin: 0 5px;
}
input[type=range]:focus {
outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 8.4px;
cursor: pointer;
box-shadow: 1px 1px 1px rgba(0, 0, 0, 0), 0 0 1px rgba(13, 13, 13, 0);
background: rgba(255,255,255,0.8);
border-radius: 1.3px;
border: 0.2px solid rgba(1, 1, 1, 0);
}
input[type=range]::-webkit-slider-thumb {
height: 15px;
width: 15px;
border-radius: 50px;
background: #ffc600;
cursor: pointer;
-webkit-appearance: none;
margin-top: -3.5px;
box-shadow:0 0 2px rgba(0,0,0,0.2);
}
input[type=range]:focus::-webkit-slider-runnable-track {
background: #bada55;
}
input[type=range]::-moz-range-track {
width: 100%;
height: 8.4px;
cursor: pointer;
box-shadow: 1px 1px 1px rgba(0, 0, 0, 0), 0 0 1px rgba(13, 13, 13, 0);
background: #ffffff;
border-radius: 1.3px;
border: 0.2px solid rgba(1, 1, 1, 0);
}
input[type=range]::-moz-range-thumb {
box-shadow: 0 0 0 rgba(0, 0, 0, 0), 0 0 0 rgba(13, 13, 13, 0);
height: 15px;
width: 15px;
border-radius: 50px;
background: #ffc600;
cursor: pointer;
}
const player = document.querySelector('.player');
const video = player.querySelector('.viewer');
const toggle = player.querySelector('.toggle');
const skipBtn = player.querySelectorAll('[data-skip]');
const ranges = player.querySelectorAll('.player__slider');
const progress = player.querySelector('.progress');
const progressBar = player.querySelector('.progress__filled');
function togglePlay(){
const method = video.paused? 'play':'pause';
video[method]();
// if(video.paused){
// video.play()
// console.log('시작');
// }else{
// video.pause();
// console.log('중지');
// }
}
function updateBtn(){
const icon = this.paused?'►':'| |';
toggle.textContent =icon;
console.log('log')
}
function skip(){
video.currentTime += parseFloat(this.dataset.skip);//.currentTime : 재생시간 지정, .parseFloat : ''되어있는 숫자를 실수로 바꿈
console.log(parseFloat(this.dataset.skip));
}
function handleRangeUpdate(){
video[this.name]=this.value;
console.log(this.value);
}
function handleProgress(){
const percent = (video.currentTime/video.duration)*100;
//(현재 재생시간/전체 재생기간)*100
console.log(percent)
progressBar.style.flexBasis=`${percent}%`;
}
function scrub(e){
const scrubTime = (e.offsetX/progress.offsetWidth)*video.duration;
video.currentTime = scrubTime;
}
skipBtn.forEach(btn=>btn.addEventListener('click',skip));
video.addEventListener('click',togglePlay);
video.addEventListener('play',updateBtn);
video.addEventListener('pause',updateBtn);
video.addEventListener('timeupdate',handleProgress);//오디오,비디오의 재생위치가 변경될때 timeupdate이벤트 사용
toggle.addEventListener('click',togglePlay);
ranges.forEach(range => range.addEventListener('change',handleRangeUpdate));
ranges.forEach(range => range.addEventListener('mousemove',handleRangeUpdate));
let mousedown = false;
progress.addEventListener('click',scrub);
progress.addEventListener('mousemove',(e)=>{
mousedown&&scrub(e);//scrub(e)를 하면 마우스 타겟을 따라 게이지가 올라가거나 내려감
});
progress.addEventListener('mousedown',()=>mousedown = true);
progress.addEventListener('mouseup',()=>mousedown = false);
알게 된 문법
css
flex-basis (script에서는 flexBasis로 쓰인다)
플렉스 아이템의 초기 크기를 지정한다.(아마 초기 가로값)
JAVASCRIPT
.volume() / .playbackRate()
.volume() : 미디어가 재생되는 볼륨을 설정합니다.
.playbackRate() : 미디어가 재생되고있는 속도를 설정한다.
.currentTime() / .duration()
.currentTime : 현재 재생시간 지정.
.parseFloat : 전체 재생기간 설정
.parseFloat()
문자를 실수로 변경한다.
timeupdate EVENT
오디오,비디오의 재생위치가 변경될때 timeupdate이벤트 사용
video[method]();
메서드 설정시 video.method() 뿐만 아니라 video[method]() 해도 동일함
'javascript > javascript30' 카테고리의 다른 글
[javascript30]Object and Arrays - Reference VS Copy,얕은복사와 깊은복사 (0) | 2021.07.19 |
---|---|
[javascript30]Key Sequence Detection (KONAMI CODE) (0) | 2021.07.16 |
[javascript30]Hold Shift to Check Multiple Checkboxes (0) | 2021.07.16 |
[javascript30]14 Must Know Dev Tools Tricks (0) | 2021.07.15 |
[javascript30]Fun with HTML5 Canvas (0) | 2021.07.15 |
댓글
최근에 올라온 글
최근에 달린 댓글
링크
TAG
- 무조곤 비공개
- 객체의 참조값
- 중복숫자찾기
- 한번에 받는건 id로 받기
- 생성자함수에서의 this
- 메서드오버라이드
- 화살표함수에서 this의 바인딩
- if문 중첩없애기
- httponly cookie
- 복수는 한번에 안댐
- 프로토타입 체인
- 문자열실수변경
- NextJS13
- 지뢰찾기 게임도 못하는데
- 배열단순값 객체엔 속성값
- debugger라도 해서 다풀어버리자
- 이 쉬운걸 4시간동안....
- login연장
- .fill
- 콜백함수에서의 this
- 타입스크립트 프로그래밍
- 틀리면 말씀해주세요
- var과 let의 차이
- https://www.ncloud.com/support/notice/all/1424
- while문활용
- MDN 참조
- 게임은 더못만든다
- react 공식문서
- 무조건 비공개..
- refresh token
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
글 보관함