본문 바로가기
개발일지 Dev Diaries/항해99 Hanghae99

[항해99 89일차] (22.06.03) WIL_실전 프로젝트 6주차 종료

by 이땡칠 2022. 6. 3.

오늘은 최종 발표를 하게 된다.

 

 

왠지, 블로그를 쓰는 것이 주저되어 계속 쓰지 못했다.

계속 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

 

 

 

댓글