최근 웹 프로젝트에서 배경에 여러 개의 영상을 삽입하고, 이를 번갈아 자동으로 재생시키는 작업을 하던 중 흥미로운 문제를 마주하게 되었다. 최종적으로 문제를 해결하는 과정에서, 어떻게 문제를 분석하고 해결했는지를 정리해보았다. 이 글을 통해 문제를 해결하는 방식과 이를 구현하기 위해 어떤 접근 방식을 취했는지를 소개하고자 한다.
문제 발견
처음에는 단일 <video> 태그를 사용해 영상 여러 개를 번갈아 재생시키는 방식을 시도했다. video ended 이벤트 리스너를 사용해 영상이 끝날 때마다 src 속성을 변경하여 다음 영상을 재생시키는 방식이었다.
const backgroundVideoList = document.querySelectorAll('main .inner video');
const videoSrcList = {
morning: [
'https://cdn.pixabay.com/video/2023/03/04/153167-817186036_large.mp4',
'https://cdn.pixabay.com/video/2024/08/05/225046_large.mp4'
],
afternoon: [
'https://cdn.pixabay.com/video/2024/03/03/202752-918944239_large.mp4',
'https://cdn.pixabay.com/video/2023/05/28/164781-831084852_large.mp4',
],
night: [
'https://cdn.pixabay.com/video/2024/05/28/214087_tiny.mp4',
'https://cdn.pixabay.com/video/2019/02/25/21640-319452373_tiny.mp4'
]
}
let today = new Date();
let hour = today.getHours();
let src = '';
let now = '';
// morning
if (hour < 12) {
src = videoSrcList.morning;
now = 'morning';
}
// afternoon
else if (hour < 17) {
src = videoSrcList.afternoon;
now = 'afternoon';
}
// night
else {
src = videoSrcList.night;
now = 'night';
}
backgroundVideoList[0].setAttribute('src', `${src[0]}`);
backgroundVideoList[0].addEventListener('ended', () => {
backgroundVideoList[0].setAttribute('src', `${src[1]}`);
backgroundVideoList[0].play();
});
이 코드는 영상이 끝날 때마다 src를 변경해 다음 영상을 재생하는 방식으로 동작했다. 하지만 이 방식에서는 영상이 전환될 때마다 화면이 깜빡이는 문제가 발생했다. 이는 새로운 영상을 로드하는 과정에서 짧은 순간 화면이 비어있는 상태가 되기 때문에 발생한 현상이었다.
문제 분석
깜빡임 문제의 원인을 분석해본 결과, <video> 태그의 src 속성을 변경할 때마다 브라우저가 새로운 영상을 로드하는 과정에서 발생하는 지연이 문제였다. 이 지연 동안 화면이 비어 있는 상태가 되어 깜빡임 현상이 나타났던 것이다.
막힌 부분
이 문제를 해결하기 위해 기본적으로 video태그를 하나 생성해둔 후. video가 끝날 때에 video태그를 새로 생성하여 영상을 송출한 후, 기존 video 태그를 삭제하는 방식을 사용해보았지만, 결과는 만족스럽지 않았다.
문제 해결
근본적인 해결책으로 두 개의 <video> 태그를 사용하는 방법을 구현했다. 하나의 <video> 태그는 현재 화면에 표시되는 영상을 재생하고, 다른 하나의 <video> 태그는 다음에 재생될 영상을 미리 로드해 준비해두는 방식이다.
const backgroundVideoList = document.querySelectorAll('main .inner video');
let today = new Date();
let hour = today.getHours();
let src = '';
let now = '';
// morning
if (hour < 12) {
src = videoSrcList.morning;
dayStyle();
now = 'morning';
}
// afternoon
else if (hour < 17) {
src = videoSrcList.afternoon;
dayStyle();
now = 'afternoon';
}
// night
else {
src = videoSrcList.night;
nightStyle();
now = 'night';
}
backgroundVideoList.forEach((video, idx) => {
video.setAttribute('src', `${src[idx]}`);
video.addEventListener('ended', (e) => {
let videoCnt = 0;
switch (idx) {
case 0: videoCnt = 1; break;
case 1: videoCnt = 2; break;
}
backgroundVideoList[videoCnt == 1 ? 0 : 1].style.display = 'none';
backgroundVideoList[videoCnt == 1 ? 1 : 0].style.display = 'block';
backgroundVideoList[videoCnt == 1 ? 1 : 0].play();
})
});
document.querySelectorAll('video').forEach((video, idx) => {
console.log(video.src);
})
var promise = document.querySelector('video').play();
if (promise !== undefined) {
promise.then(_ => {
backgroundVideoList[0].play();
}).catch(error => {
console.log(error);
});
}
이 방식으로 두 개의 <video> 태그를 번갈아가며 사용하니, 영상 전환 시 화면 깜빡임 현상이 완벽하게 사라졌다. 이번 경험을 통해 문제를 해결하는 데 있어 다양한 시도를 하고, 문제의 근본 원인을 파악하는 과정이 얼마나 중요한지를 다시 한 번 느낄 수 있었다. 앞으로도 이러한 접근 방식을 통해 새로운 문제를 해결하고, 보다 나은 사용자 경험을 제공하는 데 기여하고자 한다.
'Today I Learned > Task' 카테고리의 다른 글
[Task] Express & React 연동하기 (0) | 2024.09.20 |
---|---|
[Task] 최소화 상태의 검색바에서 가상선택자 스타일 없애기 (0) | 2024.09.03 |
[Task] 실습 코드리뷰 - 에이블런 프론트엔드부트캠프 29일차 (0) | 2024.08.23 |
[Task] 기업화면에 TabFocus/TabIndex 적용해보기 (0) | 2024.08.23 |
[Task] swiper.js를 활용한 슬라이드 리팩토링 - 에이블런 프론트엔드부트캠프 17일차 (0) | 2024.08.07 |