자바스크립트 비디오 파일 길이 구하기
비디오 플레이어 컨트롤러 부분을 커스텀으로 만들고 재생시간과 재생길이를 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 ?
blob이란
-
자바스크립트에서 이미지, 사운드, 멀티미디어 데이터를 다룰 때 사용한다.
-
데이터의 크기(Byte) 및 MIME 타입을 알아냄
-
조금더 자세한 정보는 해당 블로그에 잘 설명되어 있다.