1. 스팩 정의
기능 스팩
-
아래와 같은 영상을 띄운다.
-
현재 얼마나 재생했는 지를 보여주는 progrssbar, 배속 버튼, 언어 선택 버튼이 있다.
-
Prograssbar를 눌러서, 시간을 이동할 수 있다.
개발 스팩
- 라이브러리에 대한 의존성 최소화 및 video태그에 익숙해지고자 video 태그를 이용한다.
- 프로그래스바에서 특정 영역을 클릭시, 해당 영역이 전체에서 어느 부분인 지 체크하여, 해당 시간으로 영상을 이동한다.
2. 개발
개발 구상
- 관리할 상태값 : 현재 시간(currentTime), 전체 시간(duration), 배속(playbackRate)
onLoadedMetedata를 이용하여, 전체 시간을 업데이트한다.onTimeUpdate를 이용하여, 현재 시간을 업데이트한다.- 2,3번의
현재 시간/전체 시간을 이용하여 상태바를 보여준다.
- 2,3번의
select버튼을 이용하여 배속을 업데이트한다.- 프로그래스바에 onClick을 추가하여, 클릭 시 현재 비디오의 재생 시간을 수정한다.
개발
1. 전체 시간과 현재 시간을 관리한다
- 이벤트 함수 :
onLoadedMetadata,onTimeUpdate - 값 :
videoRef.current.duration,videoRef.current.currentTime
const [currentTime, setCurrentTime] = React.useState(0);
<video
onTimeUpdate={() => {
if (!videoRef.current) {
return;
}
setCurrentTime(videoRef.current.currentTime ?? 0);
}}
onLoadedMetadata={() => {
if (!videoRef.current) {
return;
}
setDuration(videoRef.current.duration ?? 0);
}}
>
</video>
여기서 핵심이 되는 이벤트가 두 개 있다.
-
onLoadedMetadata
: 비디오 메타데이터가 로드되면 발생하는 이벤트다. 비디오의 길이, 해상도 같은 메타 정보들이 준비되는 시점이라, 전체 duration을 가져오기 좋다.
-
onTimeUpdate
: 재생 중에 currentTime이 변경될 때마다 발생한다. 보통 250ms 정도마다 한 번씩 발생하는데, 이 정도면 프로그레스바를 부드럽게 업데이트하기에 적당하다.
이 두 값으로 (currentTime / duration) * 100을 계산하면 프로그레스바의 퍼센트를 구할 수 있다.
2. 배속을 관리한다
- 이벤트 함수 :
onClick(Select) - 값 :
videoRef.current.playbackRate
<select onClick={(e)=>{
onChange(e.target.value)};
videoRef.current.playbackRate = e.target.value;
}>
<option />
<option />
</select>
playbackRate는 0.5(절반 속도)부터 2.0(2배속)까지 설정할 수 있다. 브라우저마다 지원 범위가 조금씩 다를 수 있는데, 보통 0.25~4.0 정도는 문제없이 동작한다.
참고로 playbackRate를 변경해도 음정은 그대로 유지된다. 브라우저가 알아서 피치 보정을 해준다.
3. 프로그레스바를 관리한다
const handleProgrssBarClick = (e: React.MouseEvent<HTMLDivElement>) => {
if (!progressBarRef.current || !videoRef.current) {
return;
}
const { left, width } = progressBarRef.current.getBoundingClientRect();
const clickPosition = e.clientX;
const seekTime = ((clickPosition - left) / width) * duration;
videoRef.current.currentTime = seekTime;
};
// ..
return (
<ProgressBar
ref={progressBarRef}
onClick={handleProgressBarClick}
/>
)
getBoundingClientRect: 엘리먼트의 크기와 뷰포트에 상대적인 위치 정보를 제공하는 DOMRect 객체를 반환한다.- left, top, right, bottom, x, y, width, height 프로퍼티를 반환한다.
e.clientX: 뷰포트 내에서 마우스 클릭의 수평 좌표를 제공한다.
즉, 위 코드는 현재 클릭한 요소의 뷰포트 기준 왼쪽 길이, 너비, 그리고 클릭한 곳의 뷰포트 기준 왼쪽 길이를 구하고 그것들을 이용하여 현재 클릭한 곳이 프로그레스바 기준 어느 정도를 차지하는지 구하는 것이다.