비디오 플레이어의 컨트롤러 기능을 직접 구현해 보자.
제목, 비디오, 컨트롤러 영역을 구분해 만들었다. 컨트롤 패널에는 버튼과 range 타입의 input을 기능에 맞게 배치했다.
재생 버튼 또는 화면을 클릭했을 때 영상이 정지 상태라면 재생하고, 재생 중이라면 정지한다.
비디오가 재생되거나 중지되면 이벤트가 발생하는데, 이를 각각 감지하여 재생 버튼의 아이콘을 바꿔 주었다.
프로그레스 바는 range 타입의 input이다. input은 값이 바뀔 때마다 input 이벤트를 발생시키는데, 이를 감지하여 영상의 시간을 이동하였다. 반대로 영상의 시간이 바뀌었을 때도 input에 반영되도록 하였다.
또한 0:00 / 0:00 형식의 타임스탬프도 영상 시간에 따라 재설정되도록 했다. 영상의 현재 위치를 나타내는 currentTime과 영상의 길이를 나타내는 duration은 초 단위의 실수이기 때문에 이에 유의하여 값을 변환해야 한다.
영상 길이는 video.duration으로 받아올 수 있는데, 메타데이터를 불러오기 전에 해당 값은 NaN으로 표시된다. 그래서 메타데이터를 로드했을 때 발생하는 loadedmetadata 이벤트를 이용해서 영상 길이를 불러오면 된다.
음소거 버튼을 통해 음소거를 적용하고 해제할 수 있도록 했다. 음소거 기능만이라면 video.muted = !video.muted
로 한 줄만 있어도 됐겠지만 버튼의 아이콘을 바꿔야 하기 때문에 if~else 문을 사용했다.
음량도 input[type="range"]를 이용해서 직접 변경할 수 있다. video.volume으로 [0, 1]의 값을 전달하면 음량을 설정할 수 있다. 여기에 더해 크롬의 기본 플레이어는 음량이 0인 상태를 음소거로 간주하는 추가 로직이 들어가는데, 음량과 음소거를 별개로 처리하는 게 사용하기 더 직관적일 것 같아 이는 제외했다.
보통 비디오 플레이어는 0.5x, 1x, 2x 등의 속도 프리셋을 주고 선택하는 방식이지만 원하는 값을 직접 선택할 수 있게 만들고 싶어서 input[type="range"]를 이용해서 구현했다.
input의 값을 변경해서 배속을 조정하거나 초기화 버튼을 눌러서 1배속으로 돌아올 수 있다. 재생 속도는 video.playbackRate로 조절할 수 있고, 정상 속도에 대한 배율로 계산된다. 값을 처리할 때 2에 대한 로그 스케일로 반영되도록 했는데, 1배속을 기준으로 2배속과 0.5배속이 대칭을 이루도록 하고 싶었기 때문이다. 또 막대 형식으로 값을 조절하면 정확히 얼마인지 알기 힘들기 때문에 "1.0x"와 같은 형식의 레이블로 명시해 주었다.
탐색 버튼을 이용해 10초 단위로 앞 혹은 뒤로 이동할 수 있다.
컨트롤 패널은 평소에는 보이지 않다가 플레이어에 커서를 올리면 살짝 올라오면서 나타나도록 하였다.
프로그레스 바에 스타일을 입히기 위해서는 기존 스타일을 해제해야 한다. appearance를 none으로 설정하면 프리셋을 해제할 수 있다. 크롬에서 개발하고 있기 때문에 벤더는 -webkit만 설정했고, slider-runnable-track으로 전체 스크롤 바를, slider-thumb으로 움직이는 막대 부분을 커스터마이즈 할 수 있다.
음량과 속도를 조절하는 막대는 수직으로 설정했으며, 역시 평소에는 보이지 않다가 커서를 가져갔을 때만 보이도록 했다.
완성된 컨트롤 패널의 모습은 위와 같다.
이번에는 video 태그를 주로 사용해 봤다. 강의에서 사용하지는 않았지만 autoplay, loop, controls 등 유용한 속성이 많았다. 플레이어와 컨트롤러를 양방향으로 연결해줘야 해서 꽤나 번거로웠다.
JS에서는 필요한 속성이 뭔지 검색하는 시간이 좀 걸렸을 뿐 어려운 건 딱히 없었는데 CSS에서 많이 헤맸다. 슬라이드 바 위치를 버튼 위에 배치하기 위해 position: absolute;
를 이용했는데, absolute와 relative가 어떻게 작동하는지 정확히 알지 못해서 계속 이상한 모양으로 나왔다. 어떻게 만들기는 했는데, 결과물도 flex와 absolute가 섞인 이상한 형태라서 내가 한 게 맞는 건지도 잘 모르겠다.
input[type="range"] 스타일링도 복잡했다. track과 thumb를 각각 디자인해야 하기도 하고, thumb는 위치도 직접 지정해줘야 해서 시행착오 과정이 길었다. 강의에서는 input이 아니라 div를 이용해서 만들었는데, 진행률에 따른 시각적 변화를 주고 싶으면 이렇게 하는 게 더 좋을 것 같긴 하다.
그리고 유튜브를 보면 스크럽 중에 위나 아래로 끌어서 탐색 배속을 조절하고 프레임별로 볼 수 있는 기능도 있는데 이런 건 어떻게 만들 수 있는지 궁금하다.