본문 바로가기
Today I Learned/Task

[Task] 영상배경 자연스러운 전환 처리하기

by YES_developNewbie 2024. 8. 24.

최근 웹 프로젝트에서 배경에 여러 개의 영상을 삽입하고, 이를 번갈아 자동으로 재생시키는 작업을 하던 중 흥미로운 문제를 마주하게 되었다. 최종적으로 문제를 해결하는 과정에서, 어떻게 문제를 분석하고 해결했는지를 정리해보았다. 이 글을 통해 문제를 해결하는 방식과 이를 구현하기 위해 어떤 접근 방식을 취했는지를 소개하고자 한다.

 

문제 발견

 

처음에는 단일 <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> 태그를 번갈아가며 사용하니, 영상 전환 시 화면 깜빡임 현상이 완벽하게 사라졌다. 이번 경험을 통해 문제를 해결하는 데 있어 다양한 시도를 하고, 문제의 근본 원인을 파악하는 과정이 얼마나 중요한지를 다시 한 번 느낄 수 있었다. 앞으로도 이러한 접근 방식을 통해 새로운 문제를 해결하고, 보다 나은 사용자 경험을 제공하는 데 기여하고자 한다.