[유튜브 클론코딩] 8.5 ~ 8.6 Volume Bar part.1 / part.2

2021. 3. 18. 15:07Projects/유튜브 클론코딩

728x90
반응형

8.5 Volume Bar part.1

비디오가 끝났을 때 시간을 처음으로 다시 돌려 놓을거고 비디오를 멈출것이다.

(현재는 비디오가 예를 들어 52초짜리면 다 재생되면 00:00:52/ 00:00:52 라고 떠있다.

그리고 플레이버튼은 ⏸ 에 머물러있다. 우리는 ▶이 되기를 원한다.)

 

function handleEnded(){

    videoPlayer.currentTime = 0;
    
    playBtn.innerHTML = '<i class="fas fa-play"></i>';



}

function init(){

    playBtn.addEventListener("click", handlePlayClick);

    volumeBtn.addEventListener("click", handleVolumeClick);

    fullScreenBtn.addEventListener("click", goFullScreen);

    videoPlayer.addEventListener("loadedmetadata", setTotalTime);

    videoPlayer.addEventListener("ended", handleEnded);

}

영상이 끝나면(ended) videoPlayer의 currentTime은 0이 되고 play버튼의 innerHTML이 ▶가 되도록 작성했다.

그런데 나는 영상이 한번 끝나면 되돌리는 아이콘으로 하고 싶어서 나중에 수정했다!

 

🥪videoPlayer.pug에서 볼륨바에 해당하는 것을 작성해주기

mixin videoPlayer(video = {})

    .videoPlayer#jsVideoPlayer

        video(src=`/${video.src}`)

        .videoPlayer__controls

            .videoPlayer__column

                span#jsPlayButton

                    i.fas.fa-play

            .videoPlayer__column

                .videoPlayer__volumeControl

                    span#jsVolumeButton

                        i.fas.fa-volume-up

                    input.videoPlayer__volume#jsVolume(type="range", min="0", max="1", step="0.1", value="0.5")

                span

                    span#currentTime 00:00:00 

                    |/ 

                    span#totalTime 00:00:00

            .videoPlayer__column

                span#jsFullScreen

                    i.fas.fa-expand

8.6 Volume Bar part.2

본격적으로 volume bar를 작업해보자

css를 작업한 후에 videoPlayer.js로 와서 작업을 한다.

input의 값이 변할 때 마다 어떤 작업을 해주고 싶은거니까 addEventListener를 이용한다.

여기선 event를 신경써야 하는데 어디서 발생했는지 알아야 하기 때문이다.

event의 target을 콘솔로 찍어보면 <input class="videoPlayer__volume" id="jsVolume" type="range" min="0" max="1" step="0.1" value="0.5"> 라고 다음과 같이 나온다.

 

event.target.value를 하게 되면?

0.6 0.7 0.8 이런식으로 값이 출력된다. 우리는 이것이 필요한 것이다.

 

function init(){

    videoPlayer.volume = 0.5;

    playBtn.addEventListener("click", handlePlayClick);

    volumeBtn.addEventListener("click", handleVolumeClick);

    fullScreenBtn.addEventListener("click", goFullScreen);

    videoPlayer.addEventListener("loadedmetadata", setTotalTime);

    videoPlayer.addEventListener("ended", handleEnded);

    volumeRange.addEventListener("input", handleDrag);

}

우리는 처음에 비디오플레이어의 볼륨을 0.5로 설정을 해주고

volumeRange의 input에 변화가 생기면 handleDrag 함수를 실행한다.

 

function handleDrag(event){

    const { target: { value }} = event;

    videoPlayer.volume = value;

}

handleDrag 함수는 event를 가져오는데, event.target.value에 값이 들어있기 때문에 비구조화 할당을 이용해서 value를 저렇게 가져오고, videoPlayer.volume을 value로 설정해주면 된다.

 

🥪음소거 상태가 되었을 때는 볼륨바의 볼륨도 같이 줄어들어 보이게 수정하기 / 음소거를 다시 풀면 이전의 볼륨으로 돌아가기

 

function handleVolumeClick(){

    if(videoPlayer.muted){ //비디오가 음소거 되어 있으면

        videoPlayer.muted = false;  //음소거를 해제한다.

        volumeBtn.innerHTML = '<i class="fas fa-volume-up"></i>'; // 소리나는 아이콘

        volumeRange.value = videoPlayer.volume;

        

    }else{ // 비디오가 음소거되어있지 않으면

        volumeRange.value = 0;

        videoPlayer.muted = true; // 음소거 상태로 만든다.

        volumeBtn.innerHTML = '<i class="fas fa-volume-mute"></i>' // 음소거 아이콘

    }

}

그러니까, else 부분에서 음소거를 하려고 눌렀을 때 range가 0이 되는 것은 눈에 보이는 range만 줄어든거고 실제 볼륨을 끈거는 다음 줄의 muted가 볼륨을 끄게 된다

그러니까 다시 음소거를 해제했을 때 , if 부분에서 range의 값은 현재 videoPlayer의 볼륨값으로 된다.(videoPlayer.volume 값이 사라지는게 아님. 조금만 생각하면 이해할 수 있다 어려운거 아님)

muted 하더라도 handleDrag 함수에서 videoPlayer.volume을 저장하고 있다.

 

 

볼륨을 최대로 올리면 소리가큰아이콘, 볼륨을 중간으로 내리면 소리가 작은 아이콘, 볼륨을 끝까지 내리면 음소거 아이콘으로 설정하기까지 구현한 코드이다. 그 외에 조금씩 수정했다.

const videoContainer = document.getElementById("jsVideoPlayer");
const videoPlayer = document.querySelector("#jsVideoPlayer video");
const playBtn = document.getElementById("jsPlayButton");
const volumeBtn = document.getElementById("jsVolumeButton");
const fullScreenBtn = document.getElementById("jsFullScreen");
const currentTime = document.getElementById("currentTime");
const totalTime = document.getElementById("totalTime");
const volumeRange = document.getElementById("jsVolume");

function handlePlayClick(){
    if(videoPlayer.paused){
        videoPlayer.play();
        playBtn.innerHTML = '<i class="fas fa-pause"></i>';
    }else{
        videoPlayer.pause();
        playBtn.innerHTML = '<i class="fas fa-play"></i>';
    }
}

function handleVolumeClick(){
    if(videoPlayer.muted){ //비디오가 음소거 되어 있으면
        videoPlayer.muted = false;  //음소거를 해제한다.
        volumeRange.value = videoPlayer.volume;
        if(volumeRange.value >= 0.6){
            volumeBtn.innerHTML = '<i class="fas fa-volume-up"></i>';
        }else if(volumeRange.value >= 0.3){
            volumeBtn.innerHTML = '<i class="fas fa-volume-down"></i>';
        }else if(volumeRange.value >= 0.0){
            volumeBtn.innerHTML = '<i class="fas fa-volume-off"></i>';
        }
        
    }else{ // 비디오가 음소거되어있지 않으면
        volumeRange.value = 0;
        videoPlayer.muted = true; // 음소거 상태로 만든다.
        volumeBtn.innerHTML = '<i class="fas fa-volume-mute"></i>' // 음소거 아이콘
    }
}
function exitFullScreen(){
    // document.exitFullscreen();//전체화면을 종료하기
    if(document.exitFullscreen){
        document.exitFullscreen();
    }else if(document.mozCancelFullScreen){
        document.mozCancelFullScreen();
    }else if(document.webkitExitFullscreen){
        document.webkitExitFullscreen();
    }else if(document.msExitFullscreen){
        document.msExitFullscreen();
    }
    fullScreenBtn.innerHTML = '<i class="fas fa-expand"></i>'; // 아이콘 변경하기(전체 화면 아이콘)
    fullScreenBtn.removeEventListener("click", exitFullScreen);
    fullScreenBtn.addEventListener("click", goFullScreen);
}

function goFullScreen(){
    if(videoContainer.requestFullscreen){
        videoContainer.requestFullscreen();
    }else if(videoContainer.mozRequestFullScreen){
        videoContainer.mozRequestFullScreen();
    }else if(videoContainer.webkitRequestFullscreen){
        videoContainer.webkitRequestFullscreen();
    }else if(videoContainer.msRequestFullscreen){
        videoContainer.msRequestFullscreen();
    }
    fullScreenBtn.innerHTML = '<i class="fas fa-compress"></i>'//아이콘 변경하기(작은 화면 아이콘)
    fullScreenBtn.removeEventListener("click", goFullScreen);
    fullScreenBtn.addEventListener("click", exitFullScreen);
}

const 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}`;
}

function getCurrentTime(){
    currentTime.innerHTML = formatDate(Math.round(videoPlayer.currentTime));
}

function setTotalTime(){
    const totalTimeString = formatDate(videoPlayer.duration);
    totalTime.innerHTML = totalTimeString;
    setInterval(getCurrentTime, 1000);
}

function handleEnded(){
    videoPlayer.currentTime = 0;
    playBtn.innerHTML = '<i class="fas fa-redo"></i>';

}

function handleDrag(event){
    const { target: { value }} = event;
    videoPlayer.volume = value;
    if(videoPlayer.muted){ //비디오가 음소거 되어 있으면
        volumeBtn.innerHTML = '<i class="fas fa-volume-mute"></i>' 
    }else{
        if(value >= 0.6){
            volumeBtn.innerHTML = '<i class="fas fa-volume-up"></i>';
        }else if(value >= 0.3){
            volumeBtn.innerHTML = '<i class="fas fa-volume-down"></i>';
        }else if(value > 0.0){
            volumeBtn.innerHTML = '<i class="fas fa-volume-off"></i>';
        }
    }
}

function init(){
    videoPlayer.volume = 0.5;
    playBtn.addEventListener("click", handlePlayClick);
    volumeBtn.addEventListener("click", handleVolumeClick);
    volumeRange.addEventListener("input", handleDrag);
    fullScreenBtn.addEventListener("click", goFullScreen);
    videoPlayer.addEventListener("loadedmetadata", setTotalTime);
    videoPlayer.addEventListener("ended", handleEnded);
}

if(videoContainer){
    init();
}

 

 

 

 

 

 

 

728x90
반응형