본문 바로가기

오디오 비주얼라이저 플레이어 만들기 연속 재생

반응형

실 판매사이트 제작에 사용된 오디오 비주얼라이저 플레이어 입니다.

실적용 예제

https://d.cafe24.com/product/product_detail?productCode=PTWD836035

 

카페24 디자인센터

디자이너스마트디자인문의하기 제품코드PTWD836035 카테고리엔터테인먼트 제작솔루션카페24 매니지드워드프레스제작솔루션

d.cafe24.com

 

audio.html

<!DOCTYPE html>
<html lang="ko" >
<head>
  <meta charset="UTF-8">
  <title>Smart Web - Audio visualizer continuous play</title>
  <link rel="stylesheet" href="./style.css">
</head>
<body>
<div class="music-player music-active-js">
 <canvas class="opacity-js" id="myCanvas" width="800" height="400"></canvas>
 <audio crossorigin="anonymous" id="myAudio"></audio>
 <div class="music-player-element icon-circle-mid">
 <img src="https://i.ibb.co/dKbwbMV/circle.png" alt="">
 <div class="music-name"></div>
 <div class="next-prev-arrows">
 <div class="music-prev">
 <img src="https://i.ibb.co/Svgdrz3/music-prev.png" alt="">
 </div>
 <div class="music-stop">
 <img src="https://i.ibb.co/wYdY2jx/music-stop.png" alt="">
 </div>
 <div class="music-next">
 <img src="https://i.ibb.co/Q6fXNGX/music-next.png" alt="">
 </div>
 </div>
 </div>
 <div class="music-player-element icon-play-pause play">
 <img src="https://i.ibb.co/MBFjvcj/play.png" alt="">
 </div>
 <div class="music-arrow-left">
 <img src="https://i.ibb.co/pd4Jgcq/line-left.png" alt="">
 </div>
 <div class="music-arrow-right">
 <img src="https://i.ibb.co/qBYnqf7/line-right.png" alt="">
 </div>
</div>
<div class="song-selection">
<p class="song-select" data-author="제목" data-name="가수" data-path="음악주소"></p>
<p class="song-select" data-author="제목" data-name="가수" data-path="음악주소"></p>
<p class="song-select" data-author="제목" data-name="가수" data-path="음악주소"></p>
<p class="song-select" data-author="제목" data-name="가수" data-path="음악주소"></p>
<p class="song-select" data-author="제목" data-name="가수" data-path="음악주소"></p>
<p class="song-select" data-author="제목" data-name="가수" data-path="음악주소"></p>
</div>
<script  src="./script.js"></script>
</body>
</html>

 

script.js

let canvas = document.getElementById("myCanvas");
let audio = document.getElementById("myAudio");

audio.crossOrigin = "anonymous";

// 오디오 소스
// 오디오 컨텍스트 생성
// let audioCtx = new AudioContext() || new webkitAudioContext(); -- for safari
let audioCtx = new AudioContext();

// 분석기가 작업할 수 있도록 오디오 노드를 만듭니다.
let source = audioCtx.createMediaElementSource(audio);

// 분석기 만들기
let analyser = audioCtx.createAnalyser();

// 2D 컨텍스트 만들기
let ctx = canvas.getContext("2d");

// 연결하기
source.connect(analyser);
source.connect(audioCtx.destination);

// analyser.fftSize = 2048;
analyser.smoothingTimeConstant = 0.6;
analyser.fftSize = 512;

// 버퍼 길이
let bufferLength = analyser.frequencyBinCount;
let data = new Uint8Array(bufferLength);

// 그리기 기능
function draw(data) {
 let gradient = ctx.createLinearGradient(0, 0, 0, 300);
 gradient.addColorStop(1, "#ff0033");
 ctx.fillStyle = gradient;
 ctx.shadowBlur = 20;
 ctx.shadowColor = "#ffffff";

 let cx = canvas.width / 2;
 let cy = canvas.height / 2;
 let radius = 140;
 let barWidth = 2;
 let barHeight = 2;
 let barSpacing = 7;
 let maxBarNum = Math.floor((radius * 2 * Math.PI) / (barWidth + barSpacing));
 let slicedPercent = Math.floor((maxBarNum * 25) / 100);
 let barNum = maxBarNum - slicedPercent;
 let freqJump = Math.floor(data.length / maxBarNum);

 for (let i = 0; i < barNum; i++) {
 let amplitude = data[i * freqJump];
 let alfa = (i * 2 * Math.PI) / maxBarNum;
 let beta = ((3 * 45 - barWidth) * Math.PI) / 280;
 let x = 0;
 let y = radius - (amplitude / 12 - barHeight);
 let w = barWidth;
 let h = amplitude / 6 + barHeight;

 ctx.save();
 ctx.translate(cx + barSpacing, cy + barSpacing);
 ctx.rotate(alfa - beta);
 ctx.fillRect(x, y, w, h);
 ctx.restore();
 }
}

// 루프 기능
function loopingFunction() {
 requestAnimationFrame(loopingFunction);
 analyser.getByteFrequencyData(data);
 ctx.clearRect(0, 0, canvas.width, canvas.height);
 draw(data);
}

loopingFunction();

// 음악 재생
let play = document.querySelector(".play");
let musicIcon = document.querySelector(".icon-play-pause img");

function playMusic() {
 audioCtx.resume();
 canvas.classList.remove("opacity-js");

 if (audio.paused) {
 audio.play();
 musicIcon.src = "https://i.ibb.co/2hWV9L6/pause.png";
 } else {
 audio.pause();
 musicIcon.src = "https://i.ibb.co/MBFjvcj/play.png";
 }
}

play.addEventListener("click", playMusic);

// 음악 중지
let stop = document.querySelector(".music-stop");
function stopMusic() {
 audio.pause();
 audio.currentTime = 0;
 musicIcon.src = "https://i.ibb.co/MBFjvcj/play.png";
}

stop.addEventListener("click", stopMusic);

// 로드 트랙 기능
let songs = document.querySelectorAll(".song-select");
let songArr = [];

songs.forEach(function (song) {
 songArr.push({
 songName: song.dataset.name,
 songAuthor: song.dataset.author,
 songPath: song.dataset.path
 });
});

let musicName = document.querySelector(".music-name");
let counter = 0;
let maxSongs = songArr.length;

function loadMusic(counter) {
 audio.src = `${songArr[counter].songPath}`;
 audio.load();
 musicName.textContent = `${songArr[counter].songAuthor} - ${songArr[counter].songName}`;
}

loadMusic(counter);

// 다음 및 이전 노래
let next = document.querySelector(".music-next");
let prev = document.querySelector(".music-prev");
next.addEventListener("click", function () {
 if (counter < maxSongs - 1) {
 counter++;
 loadMusic(counter);
 } else {
 counter = 0;
 loadMusic(counter);
 }
 playMusic();
});

prev.addEventListener("click", function () {
 if (counter > 0) {
 counter--;
 loadMusic(counter);
 } else {
 if (counter === 0) counter = maxSongs;
 counter--;
 loadMusic(counter);
 }
 playMusic();
});

// 음악종료
audio.addEventListener("ended", function () {
  if (counter < maxSongs - 1) {
    counter++;
  } else {
    counter = 0;
  }
  loadMusic(counter);
  playMusic();// 다음 곡을 로드하고 재생합니다.
});

 

style.css

* {
 padding: 0;
 margin: 0;
 -webkit-tap-highlight-color :transparent;
}

.music-player {
 background: #0e0929;
 color: white;
 position: relative;
 top: 0%;
 left: 0%;
 width: 100vw;
 height: 100vh;
 z-index: 5;
 transition: 0.2s;
 overflow: hidden;
}
.music-player #myAudio {
 position: relative;
 z-index: 55;
}
.music-player #myCanvas {
 position: absolute;
 top: 48%;
 left: 49.5%;
 transform: translate(-50%, -50%);
 transition: 0.2s;
}
.music-player .music-player-element {
 position: absolute;
 top: 50%;
 left: 50%;
 transform: translate(-50%, -50%);
}
.music-player .icon-circle-mid {
 width: 556px;
 height: 556px;
}
.music-player .icon-circle-mid .music-name {
 position: absolute;
 top: 7%;
 left: 58%;
 font-family: monospace;
 font-size: 14px;
}
.music-player .icon-circle-mid .next-prev-arrows {
 position: absolute;
 top: 15%;
 left: 70%;
 display: flex;
 width: 110px;
 justify-content: space-around;
 align-items: center;
 z-index: 11;
}
.music-player .icon-circle-mid .next-prev-arrows div {
 cursor: pointer;
}
.music-player .icon-play-pause {
 width: 162px;
 height: 162px;
 cursor: pointer;
 z-index: 5;
}
.music-player .music-arrow-left,
.music-player .music-arrow-right {
 position: absolute;
 top: 50%;
 transform: translateY(-50%);
 width: 200px;
}
.music-player .music-arrow-left {
 left: 0;
}
.music-player .music-arrow-right {
 right: 0;
}

.opacity-js {
 opacity: 0;
}

@media only screen and (max-width: 850px) {
 .music-arrow-left,
.music-arrow-right {
 display: none;
 }
}
@media only screen and (max-width: 500px) {
 .music-player .icon-circle-mid img {
 transform: scale(0.6);
 }
 .music-player .icon-circle-mid .next-prev-arrows {
 top: 32%;
 left: 55%;
 }
 .music-player .icon-circle-mid .music-name {
 top: 24%;
 left: 55%;
 font-size:12px;
 width: 170px;
 }
}
@media (min-width: 560px) and (max-height: 480px) and (orientation: landscape) {
 .music-player .icon-circle-mid {
 width: auto;
 height: auto;
 }
 .music-player .icon-circle-mid .music-name {
 top: 8%;
 }
 .music-player .icon-circle-mid .next-prev-arrows {
 top: 22%;
 left: 75%;
 }
 .music-player .music-arrow-left,
.music-player .music-arrow-right {
 display: none;
 }
}

 

반응형

댓글


Copyright ⓒ SmartWeb All rights reserved.