오늘은 최종 발표를 하게 된다.
왠지, 블로그를 쓰는 것이 주저되어 계속 쓰지 못했다.
계속 WIL 쓰기를 미뤄오다가..
이렇게 일기 느낌으로라도 적어둔다.
지난 6주 간 팀 노션 페이지에 매일매일 기록하는 습관을 들이며 작업을 했는데,
이를 블로그에 빨리 옮겨 적어야 겠다는 생각을 한다. 정리 용도로!
일단 오늘은 package.json 과 각 컴포넌트에서 import 해 온 것들을 중심으로,
이번 프로젝트에서 사용한 기술들을 정리해본다.
발표 잘 마치고 옮기자!
1. CRA 프로젝트 생성
2. React hooks
- useState, useEffect, useEffect, useCallback, useRef, useLayoutEffect
- React.memo()
3. React-redux
- useDispatch, useSelector
4. React-router-dom
- useNavigate, useParams
5. React-responsive
- useMediaQuery
6. React-helmet
- Helmet
7. Styled-components
- styled
// 예제
const Container = styled.div`
background-image: url(${starBG});
background-size: contain;
background-color: ${props => props.bgColor};
width: 100%;
height: 100vh;
z-index: 1;
@media only screen and (max-width: 420px) {
background-color: #060E32;
background-image: none;
height: 100vh;
}
`;
8. zustand
- useStore
9. lodash
- _
10. Axios
11. react-device-detect
- isMobile
12. react-slick
- Slider
- import slick-carousel/slick/slick.css
- import sick-carousel/slick/slick-theme.css
13. Audio
import React, { useState, useEffect } from "react";
export default function useRecordVoice() {
const [stream, setStream] = useState();
const [media, setMedia] = useState();
const [source, setSource] = useState();
const [onRec, setOnRec] = useState(true);
const [finishRecord, setFinishRecord] = useState(false);
const [isShowSpeaker, setIsShowSpeaker] = useState(false);
const [isPlaying, setIsPlaying] = useState(false);
const [isListening, setIsListening] = useState(false);
const [isListeningPaused, setIsListeningPaused] = useState(false);
const [isPaused, setIsPaused] = useState(false);
const [analyser, setAnalyser] = useState();
const [audioUrl, setAudioUrl] = useState();
const [audioCtx, setAudioCtx] = useState();
const [myAudio, setMyAudio] = useState();
useEffect(() => {
if (audioUrl) {
// new Audio ()
//
// 객체 속성 loop, volume 등
// URL.createObjectURL()
//
let audio = new Audio(URL.createObjectURL(audioUrl));
audio.loop = false;
audio.volume = 1;
//오디오가 종료되면 일시정지에서 다시 재생버튼으로 돌아오세요...
audio.onended = (e) => {
toggleListening();
};
setMyAudio(audio);
}
}, [audioUrl]);
//재생중인지, 일시정지인지
const toggleListening = () => {
setIsListening((prev) => !prev);
setIsPlaying((prev) => !prev);
};
//음성 녹음하기
const recordVoice = () => {
// 음원 정보를 담은 노드를 생성한다.
// Web Audio API 사용을 위해 오디오 컨텍스트 인스턴스 생성
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
// 자바스크립트를 통해 음원의 진행상태에 직접접근에 사용된다.
// createScriptProcessor(bufferSize, numberOfInputChannels, numberOfOutputChannels)
// bufferSize 에 0을 입력하면, 환경에서 가장 최적의 butter size 를 찾음
const analyser = audioCtx.createScriptProcessor(0, 1, 1);
setAnalyser(analyser);
function makeSound(stream) {
// 내 컴퓨터의 마이크나 다른 소스를 통해 발생한 오디오 스트림의 정보를 보여준다.
const source = audioCtx.createMediaStreamSource(stream);
setAudioCtx(audioCtx);
setSource(source);
// AudioBufferSourceNode 연결
source.connect(analyser);
analyser.connect(audioCtx.destination);
}
//유저 마이크 사용 권한 획득 후 녹음 시작
navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
//사용자가 허용을 눌렀을때, 녹음을 시작할 수 있다. audio stream을 통해 녹음 객체를 만들어준다.
const mediaRecorder = new MediaRecorder(stream);
mediaRecorder.start();
setStream(stream);
setMedia(mediaRecorder);
makeSound(stream);
//음성 녹음이 시작됐을 때, onRec state를 false로 변경
analyser.onaudioprocess = function (e) {
setOnRec(false);
};
});
};
const stopRecord = () => {
// blob 객체를 내보내는 메서드
media.ondataavailable = function (e) {
setAudioUrl(e.data);
setOnRec(true);
setFinishRecord(true);
};
// 모든 트랙에서 stop()을 호출해 오디오 스트림을 정지
stream.getAudioTracks().forEach(function (track) {
track.stop();
});
// 미디어 캡처 중지
media.stop();
// 메서드가 호출 된 노드 연결 해제
analyser.disconnect();
source.disconnect();
};
//녹음 조건 정하기
if (analyser) {
analyser.onaudioprocess = function (e) {
// 3분(180초) 지나면 자동으로 음성 저장 및 녹음 중지
if (e.playbackTime > 180) {
stream.getAudioTracks().forEach(function (track) {
track.stop();
});
media.stop();
// 메서드가 호출 된 노드 연결 해제
analyser.disconnect();
audioCtx.createMediaStreamSource(stream).disconnect();
//오디오 저장해주기
media.ondataavailable = function (e) {
setAudioUrl(e.data);
setOnRec(true);
};
} else {
setOnRec(false);
}
};
}
//일시 정지
const recordPause = () => {
media.pause();
setIsPaused(true);
};
const replay = () => {
// if(media.state === "recording"){
// media.pause();
// }
if (media.state === "paused") {
media.resume();
setIsPaused(false);
}
};
// 파일 출력 & 재생
const play = () => {
if (myAudio) {
myAudio.play();
setIsPlaying(true);
}
};
const playingPause = () => {
if (myAudio) {
myAudio.pause();
}
};
const playingStop = () => {
if (myAudio) {
myAudio.currentTime = 0;
myAudio.pause();
}
};
//파일 삭제
const deleteVoice = () => {
setFinishRecord(false);
setOnRec(true);
setAudioUrl("");
};
//녹음을 완전히 끝내기
const completeRecord = () => {
setIsShowSpeaker(true);
};
const resetShowSpeaker = () => {
setIsShowSpeaker(false);
};
const playingHandler = (bool) => {
setIsPlaying(bool);
};
//모든 상태 초기화
const recordReset = () => {
setOnRec(true);
setFinishRecord(false);
setIsPlaying(false);
setIsPaused(false);
};
return {
recordVoice,
stopRecord,
recordPause,
replay,
play,
audioUrl,
deleteVoice,
onRec,
finishRecord,
isPlaying,
isPaused,
completeRecord,
isShowSpeaker,
recordReset,
playingPause,
playingHandler,
toggleListening,
isListening,
playingStop,
myAudio,
resetShowSpeaker,
};
}
14. Timer
- setInterval()
15. prop-types
- PropTypes
16. react-query
- useMutation, useQueryClient
17. react-timer-hook
- useTimer
---
폴더구조
util 폴더
- designSystem
- cookie
- convertDate
'개발일지 Dev Diaries > 항해99 Hanghae99' 카테고리의 다른 글
[항해99 92일차] (22.06.06.) WIL_실전 프로젝트 정리 Q&A (0) | 2022.06.06 |
---|---|
[항해99 70일차] WIL_실전 프로젝트 3주차 종료 (0) | 2022.05.15 |
[항해99 63일차] (22.05.08) WIL_실전 프로젝트 2주차 종료. (0) | 2022.05.08 |
[항해99 58일차] (22.05.03) TIL_실전 프로젝트 2주차. (0) | 2022.05.03 |
[항해99 56일차] (22.05.01) WIL_실전 프로젝트 1주차 종료 (0) | 2022.05.01 |
댓글