Final project - Dev9

Jaemin Jung·2021년 9월 13일
0

Final Project

목록 보기
9/27

MusicPlayer

랜덤 재생 기능 구현

랜덤 재생 상태에서 이전곡 재생 구현

순차 재생 상태에서 이전곡 재생은 저장된 state 값의 인덱스 -1로 핸들링 하였다.
하지만 랜덤 재생 상태에서 다음곡 재생은 랜덤한 값만 주면 되서 구현에 문제 없었으나,
이전곡 재생은 꽤나 복잡하고 구현에 꽤 애를 먹었다.

  • 랜덤 재생에서 이전곡 재생 조건
  1. 랜덤 재생된 곡들의 순서를 기억해야함

  2. 순서를 기억한 곡들이 모두 재생 되면 다시 랜덤 재생 해야함

  3. 재생 목록에서 곡을 삭제하면 기억한 곡들에서도 그 곡은 삭제되어야함

예를 들어서 랜덤 재생으로 곡이 [0, 2, 1, 4] 순서로 재생 되었다면
이전 곡 버튼을 눌렀을때 마다 [4, 1, 2, 0] 순서의 곡이 재생 되어야 하고,
재생 목록에서 1이 삭제 되었다면 이전 곡을 기억한 저장소에도 1이 사라져야한다.

  function handlePreviousMusic (action, music) {
    if (action === 'push') {
     const newPreviousMusic = previousMusic.slice(0, previousMusic.length);
      newPreviousMusic.push(music);
      setPreviousMusic(newPreviousMusic);
    } else if (action === 'pop') {
     const newPreviousMusic = previousMusic.slice(0, previousMusic.length);
      newPreviousMusic.pop();
      setPreviousMusic(newPreviousMusic);
    }
  }

우선 이전 곡을 기억할 배열을 previousMusic이라는 이름의 state로 선언해주고,
state핸들링은 STACK으로 구현했다.
STACK은 LIFO이니 배열의 push pop을 활용했다.
이전곡 list에 저장된 이전곡을 하나 가져오면 pop 실행,
이전곡 list에 이전곡을 저장할땐 push 실행 하도록 했다.

여기서 에러가 발생한게, previousMusic에 저장할 데이터를 인덱스 값을 저장하니
곡을 삭제했을시, 인덱스 값이 모두 그에 맞게 변경이 되어야하는데
previousMusic의 데이터는 변경되질 않으니 값이 undefined가 될 경우가 있었다.

//playList 마지막 인덱스값 3
//previousMusic에서 가져온값 4

playList[previousMusic[previousMusic.length-1]] // => undefined

그래서 곡 삭제가 실행될때 previousMusic도 refresh 되도록 함수를 작성했다.
그리고 previousMusic에 저장된 인덱스 값으로는 핸들링할 값이 많으니,
crrentMusic값(객체)을 그대로 저장하기로 했다.

  function refreshPreviousMusic (deleted) {
    const newPreviousMusic = previousMusic.slice(0, previousMusic.length);
    const filteredPreviousMusic = newPreviousMusic.filter(el => el.id !== deleted.id);
    setPreviousMusic(filteredPreviousMusic);
  }

...

 onClickPrevious={() => {
  if (!isRandom) {
    if (isValid('playList', playList.indexOf(crrentMusic) - 1)) {
     setCrrentMusic(playList[playList.indexOf(crrentMusic) - 1]);
    } else {
     setCrrentMusic(playList[playList.length - 1]);
    }
  } else {
    if (!previousMusic.length) {
     console.log('랜덤-이전곡 없음');
     setCrrentMusic(playList[getRandomNumber(0, playList.length - 1)]);
    } else {
     console.log('랜덤-이전곡 있음');
     setCrrentMusic(previousMusic[previousMusic.length - 1]);
     handlePreviousMusic('pop');
    }
  }
}}

랜덤재생 상태에서 이전곡 재생 기능 구현 완료

랜덤 인덱스 생성 중복값 제외

랜덤 재생시 다음곡으로 넘어갈때, 다음곡 버튼을 눌러도 동작하지 않을때가 있었다.
설마 코드가 복잡해져서 안먹히나..? 싶었는데 console.log를 확인해보니,
중복된 인덱스 값을 생성해서 audioPlayer가 변화를 감지 못한것이었다.
랜덤 인덱스 생성 함수를 재귀 함수로 수정했다.
crrentMusic의 인덱스 값과 생성한 랜덤 인덱스 값이 같지 않을때까지 자신을 호출했다.

  function getRandomNumber (min, max) {
    const randomIndex = parseInt(Math.random() * ((Number(max) - Number(min)) + 1));

    if (randomIndex === playList.indexOf(crrentMusic)) {
      return getRandomNumber(min, max);
    } else {
      return randomIndex;
    }
  }

오늘은 여기까지..

원래 알고리즘에 많이 약해서 기능 구현할 방법을 떠올리고 문제없이 구현하는데 꽤 많은 시간이 걸렸다.
이로써 핵심 기능인 Visualizer의 기능중 음악 재생 기능은 모두 구현했다.
다음은 이 코드를 토대로 sidebar를 만들어야한다.

profile
내가 보려고 쓰는 블로그

0개의 댓글