
사실 요즘은 자체적으로 이렇게 동영상 플레이어를 구현하는 것이 아니라,
유튜브와 같은 플랫폼에 이미 업로드 되어있는 영상을 불러오는 형식을 더 자주 사용하기 때문에, 실용적인 챕터일까? 라는 생각을 하기도 했다.
하지만…
JS를 통해 CSS적인 요소를 컨트롤 하는 부분과 valueChange를 하는 등의 연습은 큰 도움이 됐던 것 같다.
로직
- 다양한 객체들 const로 정의
 
- 이벤트 리스너 (재생버튼, 프로그레스바, 볼륨바, 속도바, 스킵버튼)
 
- 재생 기능과 CSS 제어
 
- 프로그레스바 구현
 
- 볼륨 컨트롤 구현
 
- 속도 설정 구현
 
- 스킵버튼 구현
 
Const!!
💡 이번 챕터에선 정의해줘야 할 객체들이 많다….
1 2 3 4 5 6 7
   | const player = document.querySelector('.player'); const video = player.querySelector('.viewer'); const toggle = player.querySelector('.toggle'); const progress = player.querySelector('.progress'); const progressBar = player.querySelector('.progress__filled'); const skipButtons = player.querySelectorAll('[data-skip]'); const ranges = player.querySelectorAll('.player__slider');
  | 
 
이벤트리스너
💡 구현해야 할 기능들이 많기 때문에… 이벤트 또한 역시나 많다…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   |  toggle.addEventListener('click', pause); toggle.addEventListener('click', updateButton);
 
  video.addEventListener('click', pause); video.addEventListener('click', updateButton); video.addEventListener('timeupdate', handleProgress);
 
  ranges.forEach((range) => range.addEventListener('mousemove', valueChange)); ranges.forEach((range) => range.addEventListener('change', valueChange));
 
  skipButtons.forEach((button) => button.addEventListener('click', skip));
 
  | 
 
재생과 버튼 업데이트
💡 재생 버튼을 누르면 재생이 되고, 버튼 아이콘도 변경되어야 한다.
필자는 if문을 쓰는게 더 쉽고 간편할 것 같아서…
if문을 통해 재생 및 일시정지, 그리고 재생버튼 업데이트 기능을 구현해봤다.
❗ 재생버튼 뿐만 아니라, 유튜브와 같이 비디오 플레이어 화면을 클릭했을 때도 재생 또는 일시정지가 될 수 있도록 구현하기 위해 pause함수가 video와 toggle에도 작동할 수 있도록 이벤트리스너를 작성했다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
   |  function pause() {      if (video.paused) {     video.play();   }      else {     video.pause();   } }
  function updateButton() {      if (video.paused) {     toggle.textContent = '►';   }      else {     toggle.textContent = '❚ ❚';   } }
 
  | 
 
그 외 기능들
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
   |  function valueChange() {      video[this.name] = this.value; }
  function skip() {   video.currentTime += parseFloat(this.dataset.skip); }
  function scrub(e) {   video.currentTime = (e.offsetX / progress.offsetWidth) * video.duration; }
  function handleProgress() {   const percent = (video.currentTime / video.duration) * 100;   progressBar.style.flexBasis = `${percent}%`; }
 
  | 
 
최종 완성 코드
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
   | const player = document.querySelector('.player'); const video = player.querySelector('.viewer'); const toggle = player.querySelector('.toggle'); const progress = player.querySelector('.progress'); const progressBar = player.querySelector('.progress__filled'); const skipButtons = player.querySelectorAll('[data-skip]'); const ranges = player.querySelectorAll('.player__slider');
  function pause() {   if (video.paused) {     video.play();   } else {     video.pause();   } }
  function updateButton() {   if (video.paused) {     toggle.textContent = '►';   } else {     toggle.textContent = '❚ ❚';   } }
  function valueChange() {   video[this.name] = this.value; }
  function skip() {   video.currentTime += parseFloat(this.dataset.skip); }
  function scrub(e) {   video.currentTime = (e.offsetX / progress.offsetWidth) * video.duration; }
  function handleProgress() {   const percent = (video.currentTime / video.duration) * 100;   progressBar.style.flexBasis = `${percent}%`; }
  toggle.addEventListener('click', pause); toggle.addEventListener('click', updateButton);
  video.addEventListener('click', pause); video.addEventListener('click', updateButton); video.addEventListener('timeupdate', handleProgress);
  ranges.forEach((range) => range.addEventListener('mousemove', valueChange)); ranges.forEach((range) => range.addEventListener('change', valueChange));
  skipButtons.forEach((button) => button.addEventListener('click', skip));
  let mousedown = false; progress.addEventListener('click', scrub); progress.addEventListener('mouseup', (e) => mousedown && scrub(e)); progress.addEventListener('mousedown', () => (mousedown = true)); progress.addEventListener('mousemove', () => (mousedown = false));
  |