import { atom, useRecoilState } from 'recoil';
import myAudio from './assets/myAudio.mp3';
import { useEffect, useRef } from 'react';
//배경음악 플레이, 일시정지
const playState = atom<boolean>({
key: 'playState',
default: false,
});
function AudioPlayer () {
const myRef = useRef<HTMLAudioElement>(null);
const [play, setPlay] = useRecoilState(playState);
// 재생
const start = () => {
if (myRef.current) {
myRef.current.play()
}
setPlay(true);
};
// 일시 정지
const stop = () => {
if (myRef.current) {
myRef.current.pause()
}
setPlay(false);
};
useEffect(() => {
if (!myRef.current) return;
if (play) {
myRef.current.play();
} else myRef.current.pause();
}, [play]);
return (
<>
<h1>AudioPlayer</h1>
<audio ref={myRef} src={myAudio} controls loop></audio>
<br />
<br />
{play ?
// 일시정지 버튼
(<button onClick={stop}>
일시정지
</button>) :
// 재생 버튼
(<button onClick={start}>
재생
</button>)
}
</>
)
}
export default AudioPlayer ;
my-app 이란 이름의 타입스크립트기반 프로젝트 생성
npx create-react-app my-app --template typescript
리코일 설치
npm install recoil
오디오 파일을 들고오려면 세 단계가 필요하다.
d.ts
을 만든다.코드와 함께 자세히 보자.
Audio라는 이름의 d.ts파일을 만든다.
위에서 생성한 Audio.d.ts 파일에 다음의 코드를 작성한다.
declare module "*.mp3" {
const value: string;
export default value;
}
파일명이 mp3로 끝나는 새로운 모듈을 선언하겠다는 뜻
참고 : 타입스크립트 + 웹팩 환경에서 mp3 파일 임포트(import) 하는 방법
import myAudio from './assets/myAudio.mp3';
myAudio
라는 이름으로 './assets/myAudio.mp3' 이 경로에 있는 음원 파일을 들고 온다.
recoil 상태를 사용하는 컴포넌트는 부모 트리 어딘가에 나타나는 RecoilRoot 가 필요하다. 루트 컴포넌트가 RecoilRoot를 넣기에 가장 좋은 장소다.
import { RecoilRoot } from 'recoil';
function App() {
return (
<RecoilRoot>
<AudioPlayer />
</RecoilRoot>
);
}
AudioPlayer컴포넌트의 부모루트에 RecoilRoot를 임포트하고
<RecoilRoot></RecoilRoot>
로 감싸준다.
import { atom } from 'recoil';
const playState = atom<boolean>({
key: 'playState',
default: false,
});
playState 라는 이름으로 atom 선언. boolean타입.
재생true중인지 일시정지false 중인지 상태를 나타낼 값이다.
import { useRecoilState } from 'recoil';
const [play, setPlay] = useRecoilState(playState);
playState값을 읽고(play) 쓰기(setPlay) 위해 useRecoilState함수에 playState를 넣어준다.
import { useRef } from 'react';
const myRef = useRef<HTMLAudioElement>(null);
미디어의 재생을 관리할 때 Ref는 render 메서드에서 생성된 DOM 노드나 React 엘리먼트에 접근하는 방법을 제공한다.
myRef라는 이름으로 useRef를 쓰겠다. 타입은 <HTMLAudioElement>
로 선언해주면 오디오를 쓰겠단소리다.
render 메서드 안에서 ref가 엘리먼트에게 전달되었을 때, 그 노드를 향한 참조는 ref의 current 어트리뷰트에 담기게 됩니다.
Ref 객체의 current
라는 프로퍼티를 사용하면 DOM 노드를 참조할 수 있다.
const start = () => {
if (myRef.current) {
myRef.current.play()
}
setPlay(true);
};
ref의 값은 노드의 유형에 따라 다른데 여기서는 오디오에 쓰였기때문에 play(), puase() 에 접근 할 수 있다.
myRef(내가 지어준이름)의 current(useRef프로퍼티)의 play()를 실행
const stop = () => {
if (myRef.current) {
myRef.current.pause()
}
setPlay(false);
};
import { useEffect } from 'react';
useEffect(() => {
if (!myRef.current) return;
if (play) {
myRef.current.play();
} else myRef.current.pause();
}, [play]);
<audio ref={myRef} src={myAudio} controls loop></audio>
audio 태그에 ref를 사용하여 play()/pause()로 재생/일시정지를 통제한다.
src에 불러온 오디오 파일을 넣는다.
controls는 기본 플레이어 제어패널을 보이도록 한다. 없으면 보이지 않는다.
loop는 재생이 끝나고 반복 재생 여부를 설정한다.
그 외에도 다양한 속성이 있다.
{play ?
// 일시정지 버튼
(<button onClick={stop}>
일시정지
</button>) :
// 재생 버튼
(<button onClick={start}>
재생
</button>)
}
play가 true이면 재생중이라는 뜻이므로 일시 정지 버튼이 보이도록 하고, 버튼을 누르면(onClick) 일시정지 함수(stop)가 실행되게 한다.
play가 false면 일시정지중이라는 뜻이므로 재생 버튼이 보이도록 하고, 버튼을 누르면(onClick) 재생 함수(start)가 실행되게 한다.
적절한 아이콘로 꾸미면 멋진 재생버튼이 될 것 같다.
타입스크립트에서 오디오 파일을 불러올땐 d.ts파일을 만들어 mp3 형식의 모듈을 선언(declare) 하고 파일을 불러오는 방법
리코일 사용 할 때 부모루트에 리코일 선언하기, atom, useRecoilState 사용 방법
ref와 Ref에 접근하는 방법
audio 태그의 여러가지 속성
브라우저에서 autoplay를 막아놨다는 에러가 자꾸 떠서 이 글 보고 따라했는데 성공했어요 감사합니다! ㅠㅠ