[javascript] mp3파일 기본 재생기 + 주파수 분석

기본적인 재생기 기능에 추가적으로 1초마다 주파수 분석 값을 콘솔에 출력하는 코드입니다.

상황에 알맞게 수정해서 사용하면 되겠습니다.

<!DOCTYPE html>
<html>

<head>
      <meta charset="UTF-8">
      <title>MP3 분석 및 재생</title>
      <style>
            #progressBar {
                  background-color: black;
            }

            #progress {
                  display: inline-block;
                  height: 10px;
                  background-color: red;
            }
      </style>
</head>

<body>
      <button id="playPauseButton">재생/일시정지</button>
      <button id="stopButton">정지</button>
      <button id="muteButton">음소거</button>
      <input type="range" id="volumeControl" min="0" max="1" step="0.1" value="1">
      <div id="progressBar">
            <div id="progress"></div>
      </div>
      <div id="currentTime"></div>
      <div id="totalTime"></div>

      <script>
            // MP3 파일과 이미지 파일의 경로
            const mp3Url = '/1.mp3';
            // const imageUrl = '/1.png';

            // 오디오 요소 생성
            const audio = new Audio(mp3Url);
            audio.controls = true;

            // 분석 버튼 활성화
            audio.addEventListener('canplaythrough', () => {
                  console.log('MP3 파일 로드 완료');
                  document.getElementById('playPauseButton').disabled = false;
            });

            // 재생/일시정지 버튼 클릭 이벤트 핸들러
            const playPauseButton = document.getElementById('playPauseButton');
            playPauseButton.addEventListener('click', function () {
                  if (audio.paused) {
                        audio.play();
                        playPauseButton.textContent = '일시정지';
                  } else {
                        audio.pause();
                        playPauseButton.textContent = '재생';
                  }
            });

            // 정지 버튼 클릭 이벤트 핸들러
            const stopButton = document.getElementById('stopButton');
            stopButton.addEventListener('click', function () {
                  audio.pause();
                  audio.currentTime = 0;
                  playPauseButton.textContent = '재생';
            });

            // 음소거 토글 버튼 클릭 이벤트 핸들러
            const muteButton = document.getElementById('muteButton');
            muteButton.addEventListener('click', function () {
                  audio.muted = !audio.muted;
                  muteButton.textContent = audio.muted ? '음소거 해제' : '음소거';
            });

            // 볼륨 컨트롤 변경 이벤트 핸들러
            const volumeControl = document.getElementById('volumeControl');
            volumeControl.addEventListener('input', function () {
                  audio.volume = parseFloat(volumeControl.value);
            });

            // 재생바 업데이트 함수
            function updateProgressBar() {
                  const progress = (audio.currentTime / audio.duration) * 100;
                  document.getElementById('progress').style.width = progress + '%';
                  document.getElementById('currentTime').textContent = formatTime(audio.currentTime);
            }

            // 현재 재생 시간 포맷 함수
            function formatTime(time) {
                  const minutes = Math.floor(time / 60);
                  const seconds = Math.floor(time % 60);
                  return `${minutes}:${seconds < 10 ? '0' : ''}${seconds}`;
            }

            // 전체 재생 시간 표시
            const totalTime = document.getElementById('totalTime');
            audio.addEventListener('canplay', () => {
                  totalTime.textContent = formatTime(audio.duration);
            });

            // 재생바 클릭 이벤트 핸들러
            const progressBar = document.getElementById('progressBar');
            progressBar.addEventListener('click', function (event) {
                  const progressWidth = progressBar.clientWidth;
                  const clickX = event.pageX - progressBar.offsetLeft;
                  const seekTime = (clickX / progressWidth) * audio.duration;
                  audio.currentTime = seekTime;
            });

            // 오디오 컨텍스트 생성
            const audioCtx = new (window.AudioContext || window.webkitAudioContext)();

            // 오디오 소스 노드 생성
            const audioSourceNode = audioCtx.createMediaElementSource(audio);

            // 오디오 분석기 생성
            const analyser = audioCtx.createAnalyser();
            analyser.fftSize = Math.pow(2, 6);
            const bufferLength = analyser.frequencyBinCount;
            const dataArray = new Uint8Array(bufferLength);

            // 오디오 노드 네트워크 설정
            audioSourceNode.connect(analyser);
            analyser.connect(audioCtx.destination);

            // 데이터 로깅 및 재생바 업데이트
            setInterval(() => {
                  analyser.getByteFrequencyData(dataArray);
                  console.log('분석 데이터(배열)', Array.from(dataArray));

                  const frequencyData = {}; // 분석 데이터를 담을 객체

                  for (let i = 0; i < bufferLength; i++) {
                        const frequency = i * (audioCtx.sampleRate / analyser.fftSize); // 인덱스를 실제 주파수로 변환
                        const amplitude = dataArray[i]; // 해당 주파수 영역의 음량
                        const calculVol = Math.round(amplitude * 100 / 255);

                        frequencyData[frequency] = calculVol; // 객체에 키와 값을 저장
                  }

                  console.log('분석 데이터', frequencyData);

                  updateProgressBar();
            }, 1000); // 1초마다 데이터 로깅 및 재생바 업데이트

            // HTML 요소에 오디오 추가
            document.body.appendChild(audio);
      </script>
</body>

</html>

Leave a Comment