Programming/JavaScript

자바스크립트 비디오 파일 길이 구하기

Chanho. 2020. 3. 19. 20:21
반응형

비디오 플레이어 컨트롤러 부분을 커스텀으로 만들고 재생시간과 재생길이를 ex) 00:00 / 01:36 이런식으로 표현하게 하는데

비디오 파일의 전체 길이를 가져오는데 제대로 값을 가져와 표현해줄 때가 있고 반대로 아무값도 못가져 올때도 있었다.

위와 같이 npm package 인 get-blob-duration을 이용해서 비디오의 전체 길이를 가져오는 소스를 작성하고 전체 길이를 가져와 formatDate(seconds) 함수에서 시 분 초를 나눠서 표현한다.

문제가 발생했던 코드

// 비디오 링크를 클릭하여 해당 비디오 페이지에 들어왔을때
const videoContainer = document.getElementById('jsVideoPlayer')

// 초를 시,분,초로 변환
function formatDate(seconds) {
  const secondsNumber = parseInt(seconds, 10)
  let hours = Math.floor(secondsNumber / 3600)
  let minutes = Math.floor((secondsNumber - hours * 3600) / 60)
  let totalSeconds = secondsNumber - hours * 3600 - minutes * 60

  if (hours < 10) {
    hours = `0${hours}`
  }
  if (minutes < 10) {
    minutes = `0${minutes}`
  }
  if (totalSeconds < 10) {
    totalSeconds = `0${totalSeconds}`
  }
  return `${hours}:${minutes}:${totalSeconds}`
}

// 비디오 전체 길이를 가져오는 함수
async function setTotalTime() {
  const duration = await getBlobDuration(videoPlayer.src)
  setInterval(getCurrentTime, 1000)
  totalTime.innerHTML = formatDate(duration)
}

// 비디오 페이지에 들어왔다면 실행되는 init 함수
function init() {
  videoPlayer.volume = 1
  playBtn.addEventListener('click', handlePlayClick)
  volumeIcon.addEventListener('click', handleVolumeClick)
  screenBtn.addEventListener('click', fullScreenClick)
  videoId.addEventListener('loadedmetadata', setTotalTime)
  videoId.addEventListener('ended', handleEnded)
  volumeRange.addEventListener('input', handleDrag)
}

// 비디오 링크를 클릭하여 해당 비디오 페이지에 들어왔을때
if (videoContainer) {
  init()
}

 

문제를 해결한 코드

// 비디오 링크를 클릭하여 해당 비디오 페이지에 들어왔을때
const videoContainer = document.getElementById('jsVideoPlayer')

// 초를 시,분,초로 변환
function formatDate(seconds) {
  const secondsNumber = parseInt(seconds, 10)
  let hours = Math.floor(secondsNumber / 3600)
  let minutes = Math.floor((secondsNumber - hours * 3600) / 60)
  let totalSeconds = secondsNumber - hours * 3600 - minutes * 60

  if (hours < 10) {
    hours = `0${hours}`
  }
  if (minutes < 10) {
    minutes = `0${minutes}`
  }
  if (totalSeconds < 10) {
    totalSeconds = `0${totalSeconds}`
  }
  return `${hours}:${minutes}:${totalSeconds}`
}

// 비디오 전체 길이를 가져오는 함수
async function setTotalTime() {
  const duration = await getBlobDuration(videoPlayer.src)
  setInterval(getCurrentTime, 1000)
  totalTime.innerHTML = formatDate(duration)
}

// 비디오 페이지에 들어왔다면 실행되는 init 함수
function init() {
  videoPlayer.volume = 1
  playBtn.addEventListener('click', handlePlayClick)
  volumeIcon.addEventListener('click', handleVolumeClick)
  screenBtn.addEventListener('click', fullScreenClick)
  videoId.addEventListener('ended', handleEnded)
  volumeRange.addEventListener('input', handleDrag)
}

// 비디오 링크를 클릭하여 해당 비디오 페이지에 들어왔을때
if (videoContainer) {
  init()
  setTotalTime() 
}

 

차이점으로는 init 함수에서 videoId.addEventListener('loadedmetadata', setTotalTime) 이벤트리스너를 지워버리고 비디오 페이지에 들어왔을 때 stTotalTime() 바로 실행하여 클릭하여 접속한 비디오의 전체 길이를 가져옴

 

버그가 발생한 이유 

// 비디오 전체 길이를 가져오는 함수
async function setTotalTime() {
  const duration = await getBlobDuration(videoPlayer.src)
  setInterval(getCurrentTime, 1000)
  totalTime.innerHTML = formatDate(duration)
}
  • 처음 예시의 코드처럼 videoId에 loadedmetadata를 다 읽었을 때 이벤트를 실행하여 setTotalTime() 함수를 실행하고 await GetBlobDuration(videoPlayer.src) 비동기 처리로 비디오의 전체 길이(duration)을 가져 오는데 await는 함수의 작업이 끝나고 결과값을 반환할 때까지 대기하게 된다. 여기까지는 이상없이 값을 받아오는 것을 확인

  • 문제점은 videoId.addEventListener('loadedmetadata(media event)', setTotalTime)이 제대로 실행이 될때가 있고 안될때가 있었다. 그래서 미디어 이벤트에 있는 이벤트는 다 테스트 해봤지만 나의 실력 부족으로 인한 원인을 찾을 수 없어 init()함수 실행과 동시에 setTotalTime() 함수도 같이 실행하여 해결하였다..


get-blob-duration  ? 

https://www.npmjs.com/package/get-blob-duration

blob이란

  • 자바스크립트에서 이미지, 사운드, 멀티미디어 데이터를 다룰 때 사용한다. 

  • 데이터의 크기(Byte) 및 MIME 타입을 알아냄 

  • 조금더 자세한 정보는 해당 블로그에 잘 설명되어 있다.