How to make Music Player using HTML, CSS, JS

Piyush608 top freelancer india 1 3

Creating a basic music player using HTML, CSS, and JavaScript involves setting up the HTML structure, styling it with CSS, and using JavaScript to handle the playback functionality. Here’s a simple example to get you started:

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Music Player</title>
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.2/font/bootstrap-icons.min.css"
    />

    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <div class="player">
      <div class="header">
        <button class="menu">
          <i class="bi bi-grid-fill"></i>
        </button>

        <strong>Now Playing</strong>

        <button class="show">
          <i class="bi bi-music-note-list"></i>
        </button>
      </div>

      <div class="track-info">
        <img src="https://placehold.co/200" alt="" class="artwork" />
        <h2 class="name"></h2>
        <h3 class="artist"></h3>
        <audio id="audio-player"></audio>
      </div>

      <div class="seek-slider">
        <input type="range" min="1" max="100" value="0" step="0.01" />
        <span class="current-time">0:00</span>
        <span class="duration">0:00</span>
      </div>

      <div class="audio-controls">
        <button class="prev">
          <i class="bi bi-skip-start-fill"></i>
        </button>

        <button class="play-pause paused">
          <i class="bi bi-play-circle-fill"></i>
        </button>

        <button class="next">
          <i class="bi bi-skip-end-fill"></i>
        </button>
      </div>

      <div class="volume-slider">
        <i class="bi bi-volume-off-fill"></i>
        <input type="range" min="1" max="100" />
        <i class="bi bi-volume-up-fill"></i>
      </div>

      <div class="playlist">
        <div class="playlist-header">
          <button class="hide">
            <i class="bi bi-chevron-right"></i>
          </button>

          <strong>My PlayList</strong>
        </div>

        <div class="playlist-content"></div>
      </div>
    </div>

    <script src="tracks.js"></script>
    <script src="script.js"></script>
  </body>
</html>

 

CSS (styles.css)

@import url("https://fonts.googleapis.com/css2?family=Gabarito:wght@400;500;600&display=swap");

:root {
  --main-color: #885a89;
  --dark-color: #363537;
  --light-color: #fff;
  --gray-color: #efefef;
  --width: 320px;
}

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
  font-family: "Gabarito", sans-serif;
}

body {
  min-height: 100svh;
  display: grid;
  place-items: center;
  background-color: var(--main-color);
  color: var(--dark-color);
}

button {
  border: none;
  cursor: pointer;
  background-color: transparent;
  color: var(--dark-color);
}

button:active,
button:hover {
  color: var(--main-color);
}

input {
  appearance: none;
  background-color: var(--gray-color);
  outline: none;
  cursor: pointer;
  overflow: hidden;
  width: 100%;
}

/* firefox */
input::-moz-range-thumb {
  appearance: none;
  width: 0;
  height: 0;
  box-shadow: calc(-1 * var(--width)) 0 0 var(--width) var(--main-color);
}

/* webkit */
input::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 0;
  height: 0;
  box-shadow: calc(-1 * var(--width)) 0 0 var(--width) var(--main-color);
}

.player {
  background-color: var(--light-color);
  width: 90%;
  max-width: var(--width);
  padding: 20px;
  border-radius: 10px;
  display: grid;
  gap: 20px;
  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.25);
  position: relative;
  overflow: hidden;
}

.header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 1.25rem;
}

.header .bi {
  font-size: 1.25rem;
}

.track-info {
  text-align: center;
}

.track-info img {
  width: 200px;
  height: 200px;
  border-radius: 5px;
  box-shadow: 0 3px 5px rgba(0, 0, 0, 0.15);
}

.track-info .name {
  font-size: 1.25rem;
  font-weight: 500;
  color: var(--main-color);
  margin-block: 20px 5px;
}

.track-info .artist {
  font-size: 1rem;
  font-weight: 500;
}

.seek-slider {
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
}

.seek-slider input {
  height: 6px;
  border-radius: 6px;
}

.seek-slider span {
  padding: 5px 0;
  user-select: none;
}

.audio-controls {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 20px;
}

.audio-controls button {
  width: 48px;
  height: 48px;
  font-size: 3rem;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.play-pause.paused .bi::before {
  content: "\F4F2";
}

.play-pause:not(.paused) .bi::before {
  content: "\F4C1";
}

.volume-slider {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.volume-slider input {
  height: 3px;
}

.volume-slider .bi {
  font-size: 1.25rem;
}

.playlist {
  position: absolute;
  inset: 0;
  background-color: var(--light-color);
  padding: 20px;
  display: grid;
  align-content: start;
  gap: 20px;
  border: 1px solid var(--gray-color);
  transform: translateX(100%);
  transition: transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
}

.playlist.show {
  transform: none;
}

.playlist-header {
  position: relative;
  text-align: center;
  font-size: 1.25rem;
}

.playlist-header button {
  font-size: 1.25rem;
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
}

.playlist-content {
  overflow: hidden auto;
}

.item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 10px;
  cursor: pointer;
}

.item:not(:last-child) {
  border-bottom: 1px solid var(--gray-color);
}

.item.active,
.item:hover {
  background-color: var(--gray-color);
}

.item:not(.active)::after {
  content: "";
  width: 24px;
  height: 24px;
}

.item img {
  width: 48px;
  height: 48px;
  border-radius: 3px;
}

.item div {
  flex: 1;
}

.item h4 {
  font-size: 1rem;
  color: var(--main-color);
}

.item p {
  font-size: 0.85rem;
}

.item button {
  width: 24px;
  height: 24px;
  line-height: 1;
  font-size: 1.5rem;
  display: flex;
  align-items: center;
  justify-content: center;
}

 

JavaScript (script.js)

//* state

const state = { activeTrack: 0, initPlay: false };

//* selectors

const audio = document.getElementById("audio-player");

const ui = {
  // sliders
  seekBar: document.querySelector(".seek-slider input"),
  volumeBar: document.querySelector(".volume-slider input"),

  // buttons
  showPlayListBtn: document.querySelector(".show"),
  hidePlayListBtn: document.querySelector(".hide"),
  prevBtn: document.querySelector(".prev"),
  nextBtn: document.querySelector(".next"),
  playPauseBtn: document.querySelector(".play-pause"),

  // text and image
  playList: document.querySelector(".playlist"),
  playListContent: document.querySelector(".playlist-content"),
  artwork: document.querySelector(".artwork"),
  trackName: document.querySelector(".name"),
  artist: document.querySelector(".artist"),
  currentTime: document.querySelector(".current-time"),
  duration: document.querySelector(".duration"),
};

//* event listeners

const setupEventListeners = () => {
  document.addEventListener("DOMContentLoaded", loadTrack);

  // player events
  ui.playPauseBtn.addEventListener("click", playPauseTrack);
  ui.seekBar.addEventListener("input", updateSeek);
  ui.volumeBar.addEventListener("input", updateVolume);
  ui.nextBtn.addEventListener("click", nextTrack);
  ui.prevBtn.addEventListener("click", prevTrack);
  ui.showPlayListBtn.addEventListener("click", showPlayList);
  ui.hidePlayListBtn.addEventListener("click", hidePlayList);

  // audio events
  audio.addEventListener("ended", nextTrack);
  audio.addEventListener("timeupdate", updateTime);
  audio.addEventListener("loadedmetadata", updateTrackInfo);
  audio.addEventListener("durationchange", updateDuration);
};

//* event handlers

const updateVolume = () => {
  audio.volume = ui.volumeBar.value / 100;
};

const updateSeek = () => {
  audio.currentTime = (ui.seekBar.value / 100) * audio.duration;
};

const updateTime = () => {
  ui.seekBar.value = (audio.currentTime / audio.duration) * 100;
  ui.currentTime.textContent = formatTime(audio.currentTime);
};

const updateDuration = () => {
  ui.seekBar.value = 0;
  ui.duration.textContent = formatTime(audio.duration);
};

const updateTrackInfo = () => {
  ui.artwork.src = tracks[state.activeTrack].artwork;
  ui.trackName.textContent = tracks[state.activeTrack].name;
  ui.artist.textContent = tracks[state.activeTrack].artist;
};

const playPauseTrack = () => {
  audio.paused ? audio.play() : audio.pause();
  ui.playPauseBtn.classList.toggle("paused", audio.paused);
  if (!state.initPlay) state.initPlay = true;
  renderPlayList();
};

const prevTrack = () => {
  state.activeTrack = (state.activeTrack - 1 + tracks.length) % tracks.length;
  loadTrack();
};

const nextTrack = () => {
  state.activeTrack = (state.activeTrack + 1) % tracks.length;
  loadTrack();
};

const playTrack = (index) => {
  if (index === state.activeTrack) {
    playPauseTrack();
  } else {
    state.activeTrack = index;
    loadTrack();
  }
};

const loadTrack = () => {
  audio.src = tracks[state.activeTrack].path;
  state.initPlay ? playPauseTrack() : renderPlayList();
};

const formatTime = (time) => {
  const minutes = Math.floor(time / 60);
  const seconds = Math.floor(time % 60);

  return `${minutes}:${seconds.toString().padStart(2, "0")}`;
};

const showPlayList = () => {
  ui.playList.classList.add("show");
};

const hidePlayList = () => {
  ui.playList.classList.remove("show");
};

const renderPlayList = () => {
  ui.playListContent.innerHTML = "";

  tracks.forEach((track, index) => {
    const isActive = index === state.activeTrack;
    const icon = audio.paused ? "bi-play-fill" : "bi-pause-fill";

    const item = document.createElement("div");
    item.classList.add("item");
    item.classList.toggle("active", isActive);
    item.addEventListener("click", () => playTrack(index));
    item.innerHTML = `
    <img src="${track.artwork}" alt="${track.name}" />
    <div class="item-detail">
      <h4>${track.name}</h4>
      <p>${track.artist}</p>
    </div>
    ${isActive ? `<button><i class="bi ${icon}"></i></button>` : ""}`;

    ui.playListContent.appendChild(item);
  });
};

renderPlayList();
setupEventListeners();

Track .js

//* Track Source: PixaBay

const tracks = [
  {
    artwork:
      "https://cdn.pixabay.com/audio/2022/05/27/23-46-21-714_200x200.jpg",
    name: "Best Time",
    artist: "FAS Sounds",
    path: "./media/112194.mp3",
  },
  {
    artwork:
      "https://cdn.pixabay.com/audio/2023/10/24/15-08-22-671_200x200.jpg",
    name: "Drive Breakbeat",
    artist: "Rockot",
    path: "./media/173062.mp3",
  },
  {
    artwork:
      "https://cdn.pixabay.com/audio/2023/07/22/02-53-18-138_200x200.jpg",
    name: "Tokyo Cafe",
    artist: "TVARI",
    path: "./media/159065.mp3",
  },
  {
    artwork:
      "https://cdn.pixabay.com/audio/2023/03/19/12-27-22-207_200x200.jpg",
    name: "Smoke",
    artist: "Soul Prod Music",
    path: "./media/143172.mp3",
  },
  {
    artwork:
      "https://cdn.pixabay.com/audio/2022/04/13/11-20-13-185_200x200.jpg",
    name: "Electronic Rock",
    artist: "Alex Grohl",
    path: "./media/15045.mp3",
  },
];

 

download

Explanation

  1. HTML:
    • A basic structure for the music player, including audio controls, play/pause and stop buttons, and a progress bar.
  2. CSS:
    • Basic styling for the music player, buttons, and progress bar.
  3. JavaScript:
    • Event listeners for play/pause and stop buttons.
    • timeupdate event listener to update the progress bar and time display.
    • Input listener on the progress bar to allow seeking within the audio.
    • loadedmetadata event listener to set the duration of the audio once it’s loaded.

Replace "path/to/your/music/file.mp3" with the actual path to your audio file. This basic example can be expanded with additional features such as playlists, volume control, and more advanced styling.

CEO Piyush Gupta


Reviews

There are no reviews yet. Be the first one to write one.


0.0
Rated 0 out of 5
0 out of 5 stars (based on 0 reviews)
Excellent0%
Very good0%
Average0%
Poor0%
Terrible0%