JavaScript Audio Player With Visualization

JavaScript Audio Player With Visualization
Project: Audio Player
Author: Christina g
Edit Online: View on CodePen
License: MIT

This JavaScript code snippet helps you to create an audio player with visualization. It is based on a simple idea to provide a visual representation of the sound wave animation and allow the user to control playback. The audio player comes with a play/pause button. When the “play” button is clicked, the sound starts playing and the progress bar and sound wave animation are animated over a calculated duration.

The player toggles between play and pause states when the respective buttons are clicked. The purpose of the code is to provide a visual representation of the progress of the sound and allow the user to control playback.

How to Create JavaScript Audio Player With Visualization

First, create the HTML structure for the audio player as follows:

<div class="sound-wave">
  <svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.com/svgjs" preserveAspectRatio="none" viewBox="0 0 1440 560">
    <g mask='url("#SvgjsMask1099")' fill="none">
      <rect fill="#0e2a47"></rect>
      <g transform="translate(0, 0)" stroke-linecap="round" stroke="url(#SvgjsLinearGradient1100)">
        <path d="M375 202.15 L375 357.85" stroke-width="17.25" class="bar-scale2 stop-animation"></path>
        <path d="M398 155.33 L398 404.67" stroke-width="17.25" class="bar-scale3 stop-animation"></path>
        <path d="M421 196.44 L421 363.56" stroke-width="17.25" class="bar-scale3 stop-animation"></path>
        <path d="M444 259.91 L444 300.09" stroke-width="17.25" class="bar-scale1 stop-animation"></path>
        <path d="M467 208.25 L467 351.75" stroke-width="17.25" class="bar-scale3 stop-animation"></path>
        <path d="M490 184.8 L490 375.2" stroke-width="17.25" class="bar-scale2 stop-animation"></path>
        <path d="M513 249.28 L513 310.72" stroke-width="17.25" class="bar-scale2 stop-animation"></path>
        <path d="M536 220.75 L536 339.25" stroke-width="17.25" class="bar-scale3 stop-animation"></path>
        <path d="M559 254.8 L559 305.2" stroke-width="17.25" class="bar-scale1 stop-animation"></path>
        <path d="M582 186.77 L582 373.23" stroke-width="17.25" class="bar-scale3 stop-animation"></path>
        <path d="M605 210.13 L605 349.87" stroke-width="17.25" class="bar-scale1 stop-animation"></path>
        <path d="M628 234.45 L628 325.55" stroke-width="17.25" class="bar-scale3 stop-animation"></path>
        <path d="M651 241.1 L651 318.89" stroke-width="17.25" class="bar-scale2 stop-animation"></path>
        <path d="M674 202.95 L674 357.05" stroke-width="17.25" class="bar-scale3 stop-animation"></path>
        <path d="M697 165.81 L697 394.19" stroke-width="17.25" class="bar-scale2 stop-animation"></path>
        <path d="M720 224.51 L720 335.49" stroke-width="17.25" class="bar-scale2 stop-animation"></path>
        <path d="M743 157.59 L743 402.4" stroke-width="17.25" class="bar-scale1 stop-animation"></path>
        <path d="M766 164.98 L766 395.02" stroke-width="17.25" class="bar-scale1 stop-animation"></path>
        <path d="M789 158.93 L789 401.07" stroke-width="17.25" class="bar-scale3 stop-animation"></path>
        <path d="M812 224.24 L812 335.76" stroke-width="17.25" class="bar-scale2 stop-animation"></path>
        <path d="M835 171.73 L835 388.27" stroke-width="17.25" class="bar-scale1 stop-animation"></path>
        <path d="M858 264.89 L858 295.11" stroke-width="17.25" class="bar-scale2 stop-animation"></path>
        <path d="M881 175.14 L881 384.86" stroke-width="17.25" class="bar-scale1 stop-animation"></path>
        <path d="M904 248.17 L904 311.83" stroke-width="17.25" class="bar-scale3 stop-animation"></path>
        <path d="M927 185.4 L927 374.6" stroke-width="17.25" class="bar-scale1 stop-animation"></path>
        <path d="M950 234.82 L950 325.18" stroke-width="17.25" class="bar-scale3 stop-animation"></path>
        <path d="M973 229.9 L973 330.1" stroke-width="17.25" class="bar-scale3 stop-animation"></path>
        <path d="M996 194.25 L996 365.75" stroke-width="17.25" class="bar-scale2 stop-animation"></path>
        <path d="M1019 162.47 L1019 397.53" stroke-width="17.25" class="bar-scale1 stop-animation"></path>
        <path d="M1042 205.06 L1042 354.94" stroke-width="17.25" class="bar-scale3 stop-animation"></path>
        <path d="M1065 240.52 L1065 319.48" stroke-width="17.25" class="bar-scale1 stop-animation"></path>
      </g>
    </g>
    <defs>
      <mask id="SvgjsMask1099">
        <rect width="1440" height="560" fill="#ffffff"></rect>
      </mask>
      <linearGradient x1="360" y1="280" x2="1080" y2="280" gradientUnits="userSpaceOnUse" id="SvgjsLinearGradient1100">
        <stop stop-color="#3a7cc3" offset="0"></stop>
        <stop stop-color="#dd1133" offset="1"></stop>
      </linearGradient>
    </defs>
  </svg>
  <div class="progress-bar">
    <div class="progress-color"></div>
  </div>
  <div class="audio-buttons">
    <div class="play-button">
      <?xml version="1.0" ?><svg height="48" viewBox="0 0 48 48" width="48" xmlns="http://www.w3.org/2000/svg">
        <path d="M0 0h48v48H0z" fill="none" />
        <path d="M24 4C12.95 4 4 12.95 4 24s8.95 20 20 20 20-8.95 20-20S35.05 4 24 4zm-4 29V15l12 9-12 9z" fill="#ffffff" />
      </svg>
    </div>
    <div class="pause-button d-none">
      <?xml version="1.0" ?><svg height="48" viewBox="0 0 48 48" width="48" xmlns="http://www.w3.org/2000/svg">
        <path d="M12 38h8V10h-8v28zm16-28v28h8V10h-8z" fill="#ffffff" />
        <path d="M0 0h48v48H0z" fill="none" />
      </svg>
    </div>
  </div>
</div>

Style the audio player using the following CSS styles:

body {
  background-color: grey !important;
  margin: 0;
  box-sizing: border-box;
}
.play-button{
background-color: blue !important;
}
.play-layer-wrapper {
  position: relative;
}

.play-layer {
  background-color: rgba(0, 0, 0, 0.3);
  backdrop-filter: blur(4px);
  display: flex;
  align-items: center;
  justify-content: center;
  position: fixed;
  width: 100%;
  height: 100vh;
}

.sound-wave {
  width: 100%;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  position: relative;
}
.sound-wave svg {
  display: block;
  max-width: 63rem;
  height: auto;
}

.sound-wave:after {
  content: "";
  position: absolute;
  width: 100%;
  height: 40rem;
  z-index: -1;
  top: 0;
  border-radius: 50%;
  left: 50%;
  transform: translateX(-50%);
  background: radial-gradient(#1389e933, transparent 60%, transparent 100%);
}

.progress-bar {
  height: 10px;
  width: 35%;
  border-radius: 30px;
  border: 2px solid #fff;
  background-color: #fff;
  margin: -2rem auto 6rem;
}

.progress-color {
  background: #1389e9;
  height: 100%;
  width: 0;
  border-radius: 30px;
  transition: width 4s linear;
}

.d-none {
  display: none;
}

@keyframes scale1 {
  0% {
    transform: scaleY(0.6);
  }
  40% {
    transform: scaleY(1.2);
  }
  100% {
    transform: scaleY(0.6);
  }
}
.bar-scale1 {
  animation: scale1 0.6s infinite;
  transform-origin: center;
}

@keyframes scale2 {
  0% {
    transform: scaleY(0.5);
  }
  30% {
    transform: scaleY(1.6);
  }
  100% {
    transform: scaleY(0.5);
  }
}
.bar-scale2 {
  animation: scale2 0.6s infinite;
  transform-origin: center;
}

@keyframes scale3 {
  0% {
    transform: scaleY(1.5);
  }
  70% {
    transform: scaleY(0.5);
  }
  100% {
    transform: scaleY(1.5);
  }
}
.bar-scale3 {
  animation: scale3 0.6s infinite;
  transform-origin: center;
}

.stop-animation {
  animation-duration: 0s;
}

.audio-buttons {
  position: relative;
}

.play-button svg {
  box-shadow: 0px 0px 32px rgba(0, 0, 0, 0.65);
  border-radius: 50px;
}

.play-button,
.pause-button {
  width: 46px;
  height: 46px;
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
}

Now, load the jQuery (JavaScript library) by adding the following CDN link to your project.

<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js'></script>

Finally, add the following JavaScript audio player function:

const DURATION = 4000;
var counter, parentbar, childbar;
var flag = true;

$(".play-button").on("click", function () {
  if ($(".progress-color").width() === 0) {
    flag = true;
  }
  manageProgress(flag);
  flag = !flag;

  $(".pause-button").removeClass("d-none");
  $(".play-button").addClass("d-none");
});

$(".pause-button").on("click", function () {
  manageProgress(flag);
  flag = !flag;
  $(".play-button").removeClass("d-none");
  $(".pause-button").addClass("d-none");
});

function manageProgress(flag) {
  if (!flag) {
    let activeWidth = $(".progress-color").width();
    $(".progress-color").css("width", activeWidth);
    $(".sound-wave").find(".bar-scale1").addClass("stop-animation");
    $(".sound-wave").find(".bar-scale2").addClass("stop-animation");
    $(".sound-wave").find(".bar-scale3").addClass("stop-animation");
    if (counter) {
      clearTimeout(counter);
    }
  } else {
    parentbar = $(".progress-bar").width();
    childbar = $(".progress-color").width();
    let duration = ((parentbar - childbar) * (DURATION / 1000)) / parentbar;
    $(".progress-color")
      .css("width", parentbar)
      .css("transition", "width " + duration + "s linear");
    $(".sound-wave").find(".bar-scale1").removeClass("stop-animation");
    $(".sound-wave").find(".bar-scale2").removeClass("stop-animation");
    $(".sound-wave").find(".bar-scale3").removeClass("stop-animation");
    counter = setTimeout(() => {
      $(".sound-wave").find(".bar-scale1").addClass("stop-animation");
      $(".sound-wave").find(".bar-scale2").addClass("stop-animation");
      $(".sound-wave").find(".bar-scale3").addClass("stop-animation");
      $(".play-button").removeClass("d-none");
      $(".pause-button").addClass("d-none");
      $(".progress-color").css("width", 0).css("transition-duration", "0s");
    }, duration * 1000);
  }
}

That’s all! hopefully, you have successfully created an audio player with visualization in JavaScript. If you have any questions or suggestions, feel free to comment below.

Leave a Comment

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply