기업협업 인턴쉽 프로그램에서 라이브러리와 <audio>
태그 사용을 최소화 해 오디오 재생기능과 시간표시 기능을 구현하라는 과제를 받고 작업을 진행했다.
나의 코드!
javascript
내장 함수 Audio()
를 이용해 구현해보았다.
import { useEffect, useRef, useState } from 'react';
import styled from 'styled-components';
const AudioPlay = () => {
const audioRef = useRef(null);
const [totalTime, setTotalTime] = useState(null);
const [currentTime, setCurrentTime] = useState(null);
const [percent, setPercent] = useState(0);
useEffect(() => {
if (audioRef.current) return;
const audio = new Audio();
audio.src = '음악 링크 or 파일';
audioRef.current = audio;
//오디오 파일의 총 시간
audioRef.current.addEventListener('loadedmetadata', () => {
const duration = audio.duration;
const minutes = Math.floor(duration / 60);
const seconds = Math.floor(duration % 60);
const time = `${minutes}:${seconds}`;
setTotalTime(time);
});
//오디오 파일의 현재 재생 중인 시간
audioRef.current.addEventListener('timeupdate', () => {
const minutes = Math.floor(audio.currentTime / 60);
const seconds = Math.floor(audio.currentTime % 60);
const time = `${minutes}:${seconds}`;
setCurrentTime(time);
setPercent((audio.currentTime / audio.duration) * 100);
}
});
}, []);
return (
<AudioPlayer>
<button
onClick={() => {
if (audioRef.current) {
setPlayToggle(!playToggle);
audioRef.current.play();
}
}}>
재생 버튼
</button>
<button
onClick={() => {
if (audioRef.current) {
setPlayToggle(!playToggle);
audioRef.current.pause();
}
}}>
일시정지 버튼
</button>
<button
onClick={() => {
if (audioRef.current) {
setPlayToggle(true);
audioRef.current.pause();
audioRef.current.currentTime = 0;
}
}}>
정지 버튼
</button>
<p>{currentTime ?? '0:0'}</p>
<p>{totalTime ?? '0:0'}</p>
//재생 바 (재생 시간 조절 가능)
<input
type='range'
min='0'
max='100'
value={percent}
onChange={(e) => {
const percent = e.target.value;
const audio = audioRef.current;
audio.currentTime = (audio.duration / 100) * percent;
setPercent(percent);
}}
/>
</AudioPlayer>
);
};
const AudioPlayer = styled.div``
지금은 간단하지만,
나중에 내가 원하는 UI와 기능을 몇 개 더 추가해서 만족할 만한 음악 플레이어 만들어보고 싶다.
이벤트핸들러 함수는 바로 지정해주는 것보다 함수 선언 후 입력해주는 것이 좋다고 하셔서 코드 리팩토링을 바로 진행해보았다.
const onChange = e => {
const percent = e.target.value;
const audio = audioRef.current;
audio.currentTime = (audio.duration / 100) * percent;
setPercent(percent);
};
return(
<input
type='range'
min='0'
max='100'
value={percent}
onChange={onChange}
/>
);
import { useEffect, useRef, useState } from 'react';
import styled from 'styled-components';
const AudioPlay = () => {
const audioRef = useRef(null);
const [totalTime, setTotalTime] = useState(null);
const [currentTime, setCurrentTime] = useState(null);
const [percent, setPercent] = useState(0);
useEffect(() => {
if (audioRef.current) return;
const audio = new Audio();
audio.src = '음악 링크 or 파일';
audioRef.current = audio;
//오디오 파일의 총 시간
audioRef.current.addEventListener('loadedmetadata', () => {
const duration = audio.duration;
const minutes = Math.floor(duration / 60);
const seconds = Math.floor(duration % 60);
const time = `${minutes}:${seconds}`;
setTotalTime(time);
});
//오디오 파일의 현재 재생 중인 시간
audioRef.current.addEventListener('timeupdate', () => {
const minutes = Math.floor(audio.currentTime / 60);
const seconds = Math.floor(audio.currentTime % 60);
const time = `${minutes}:${seconds}`;
setCurrentTime(time);
setPercent((audio.currentTime / audio.duration) * 100);
}
});
}, []);
const onChange = (e) => {
const percent = e.target.value;
const audio = audioRef.current;
audio.currentTime = (audio.duration / 100) * percent;
setPercent(percent);
};
return (
<AudioPlayer>
<button
onClick={() => {
if (audioRef.current) {
setPlayToggle(!playToggle);
audioRef.current.play();
}
}}>
재생 버튼
</button>
<button
onClick={() => {
if (audioRef.current) {
setPlayToggle(!playToggle);
audioRef.current.pause();
}
}}>
일시정지 버튼
</button>
<button
onClick={() => {
if (audioRef.current) {
setPlayToggle(true);
audioRef.current.pause();
audioRef.current.currentTime = 0;
}
}}>
정지 버튼
</button>
<p>{currentTime ?? '0:0'}</p>
<p>{totalTime ?? '0:0'}</p>
//재생 바 (재생 시간 조절 가능)
<input
type='range'
min='0'
max='100'
value={percent}
onChange={onChange}
/>
</AudioPlayer>
);
};
const AudioPlayer = styled.div``
감사합니다