Audio Player의 기능들을 구현해보면서 audio
태그를 처음 다루어 보게 되었다.
기능을 구현하면서 재생시간만큼 표시해주는 플레이어 바를 만들게 되었는데,
두가지 방법 중 선택이였는데 div로 만드는게 더 재밌어보였고, 내가 구현해야하는 요구사항이랑 맞게 떨어지는거 같아 1번으로 구현해 보았다 !
완성 된 플레이어 !
디자인은 유튜브 뮤직 따라했다.
오디오 플레이어의 ProgressBar를 핸들링 할 useProgress
hook 을 생성 후 각 state들로 상태 값들을 핸들링 하였다.
Div로 프로그레스바를 핸들링 하고 싶었기 때문에 바에서 클릭 되었을 때 위치를 구하고, 재생되어야 할 시간을 계산해서 currentTime
을 변경해주었다!
useProgress.tsx
//필요 없는 부분 생략, 각색
const useProgress = (
selectedMusicRef: React.MutableRefObject<HTMLAudioElement | null>
) => {
const handleProgressClick = (
e: MouseEvent<HTMLDivElement, globalThis.MouseEvent>
) => {
if (!selectedMusicRef.current) return;
const { duration } = selectedMusicRef.current;
const clickX = e.nativeEvent.offsetX;
const width = e.currentTarget.clientWidth;
selectedMusicRef.current.currentTime = (clickX / width) * duration;
};
return (
<Container onClick={handleProgressClick}>
<Progress width={percentage} />
</Container>
);
선택 된 audio의 값을 갖고 있는 selectedMusicRef
값을 인자로 받고
3개의 변수 값 가져오기
- duration : 미디어의 총 길이를 가진
duration
값- clickX : 클릭 이벤트가 발생한 위치의 X 좌표
- width : 클릭 이벤트가 발생한 요소의 전체 너비 가져오기
(clickX / width) * duration
위 계산식을 통해 클릭한 위치의 비율을 구한 뒤,
총 재생시간을duration
곱해 음악 재생위치(currentTime)를 변경시켜준다.
const AudioPlayer = ({ selectedMusicRef}) => {
const { currentTime, duration, renderProgressBar } =
useProgress(selectedMusicRef);
return (
<Container>
{renderProgressBar()}
<Wrapper>
<div>{formatTime(currentTime)}</div>
<div>{formatTime(duration)}</div>
</Wrapper>
</Container>
);
};
export default AudioPlayer;
프로그레스 바를 렌더링 하는 함수와 그 외 필요한 값들을 hook에서 추출하여 화면을 그려 주었다!