Create Custom Music Player in JavaScript

62

Music Player in JavaScript

Hey friends, today in this blog you’ll learn how to Create a Custom Music Player in JavaScript. We’ll use HTML CSS & Pure JavaScript to create this awesome music player. Earlier I also shared a JavaScript Project about How to Check Network Status using JavaScript and now it’s time to create a beautiful music player in JavaScript.

This project [Music Player in JavaScript] has several features such as you can loop, repeat or shuffle a song, play/pause a song or play the next or previous song. You can view your songs list and also know which song is currently playing and you can also select the song from the list to play. I have also created a video of this music player, you can watch a demo or full coding video.

Video Tutorial of Music Player in JavaScript

In the video, you have seen the beautiful music player and its several features as well as how I created it using only HTML CSS & JavaScript. I believe you love this music player and also understood some basic codes of this project. If you’re too beginner and you don’t have basic knowledge of JavaScript then definitely you won’t understand the codes of this project.

But if you know basic JavaScript then I have tried to explain each JavaScript line with written comments and please watch the video tutorial to understand easily and deeply. You may have a query on how to add more music to this player right? Well, you don’t need to do more things, just open the music-list.js duplicate the array items, and pass the music details there. I have also written comments in that file about this so don’t worry after downloading the source files of this music player you can easily do this.

You might like:

Custom Music Player in JavaScript [Source Codes]

To create this project [Custom Music Player in JavaScript]. First, you need to create four files, HTML File, CSS File, and JavaScript File. After creating these files just paste the following codes into your files. You can also download the source code files of the music player from the given download button.

First, create an HTML file with the name of index.html and paste the given codes in your HTML file. Remember, you’ve to create a file with .html extension and the images that are used on this music player won’t appear. You have to download files from the given download button to use images.

<!DOCTYPE html>
<!-- Coding By CodingNepal - youtube.com/codingnepal -->
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Music Player | CodingNepal</title>
  <link rel="stylesheet" href="style.css">
  <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
</head>
<body>
  <div class="wrapper">
    <div class="top-bar">
      <i class="material-icons">expand_more</i>
      <span>Now Playing</span>
      <i class="material-icons">more_horiz</i>
    </div>
    <div class="img-area">
      <img src="" alt="">
    </div>
    <div class="song-details">
      <p class="name"></p>
      <p class="artist"></p>
    </div>
    <div class="progress-area">
      <div class="progress-bar">
        <audio id="main-audio" src=""></audio>
      </div>
      <div class="song-timer">
        <span class="current-time">0:00</span>
        <span class="max-duration">0:00</span>
      </div>
    </div>
    <div class="controls">
      <i id="repeat-plist" class="material-icons" title="Playlist looped">repeat</i>
      <i id="prev" class="material-icons">skip_previous</i>
      <div class="play-pause">
        <i class="material-icons play">play_arrow</i>
      </div>
      <i id="next" class="material-icons">skip_next</i>
      <i id="more-music" class="material-icons">queue_music</i>
    </div>
    <div class="music-list">
      <div class="header">
        <div class="row">
          <i class= "list material-icons">queue_music</i>
          <span>Music list</span>
        </div>
        <i id="close" class="material-icons">close</i>
      </div>
      <ul>
        <!-- here li list are coming from js -->
      </ul>
    </div>
  </div>

  <script src="js/music-list.js"></script>
  <script src="js/script.js"></script>

</body>
</html>

Second, create a CSS file with the name of style.css and paste the given codes in your CSS file. Remember, you’ve to create a file with .css extension.

@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200;300;400;500;600;700&display=swap');

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

*::before,
*::after {
  padding: 0;
  margin: 0;
}

:root {
  --pink: #ff74a4;
  --violet: #9f6ea3;
  --lightblack: #515C6F;
  --white: #ffffff;
  --darkwhite: #cecaca;
  --pinkshadow: #ffcbdd;
  --lightbshadow: rgba(0, 0, 0, 0.15);
}

body {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  background: linear-gradient(var(--pink) 0%, var(--violet) 100%);
}

.wrapper {
  width: 380px;
  padding: 25px 30px;
  overflow: hidden;
  position: relative;
  border-radius: 15px;
  background: var(--white);
  box-shadow: 0px 6px 15px var(--lightbshadow);
}

.wrapper i {
  cursor: pointer;
}

.top-bar,
.progress-area .song-timer,
.controls,
.music-list .header,
.music-list ul li {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.top-bar i {
  font-size: 30px;
  color: var(--lightblack);
}

.top-bar i:first-child {
  margin-left: -7px;
}

.top-bar span {
  font-size: 18px;
  margin-left: -3px;
  color: var(--lightblack);
}

.img-area {
  width: 100%;
  height: 256px;
  overflow: hidden;
  margin-top: 25px;
  border-radius: 15px;
  /* box-shadow: 0px 6px 12px var(--lightbshadow); */
}

.img-area img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.song-details {
  text-align: center;
  margin: 30px 0;
}

.song-details p {
  color: var(--lightblack);
}

.song-details .name {
  font-size: 21px;
}

.song-details .artist {
  font-size: 18px;
  opacity: 0.9;
  line-height: 35px;
}

.progress-area {
  height: 6px;
  width: 100%;
  border-radius: 50px;
  background: #f0f0f0;
  cursor: pointer;
}

.progress-area .progress-bar {
  height: inherit;
  width: 0%;
  position: relative;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--pink) 0%, var(--violet) 100%);
}

.progress-bar::before {
  content: "";
  position: absolute;
  height: 12px;
  width: 12px;
  border-radius: 50%;
  top: 50%;
  right: -5px;
  z-index: 2;
  opacity: 0;
  pointer-events: none;
  transform: translateY(-50%);
  background: inherit;
  transition: opacity 0.2s ease;
}

.progress-area:hover .progress-bar::before {
  opacity: 1;
  pointer-events: auto;
}

.progress-area .song-timer {
  margin-top: 2px;
}

.song-timer span {
  font-size: 13px;
  color: var(--lightblack);
}

.controls {
  margin: 40px 0 5px 0;
}

.controls i {
  font-size: 28px;
  user-select: none;
  background: linear-gradient(var(--pink) 0%, var(--violet) 100%);
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
}

.controls i:nth-child(2),
.controls i:nth-child(4) {
  font-size: 43px;
}

.controls #prev {
  margin-right: -13px;
}

.controls #next {
  margin-left: -13px;
}

.controls .play-pause {
  height: 54px;
  width: 54px;
  display: flex;
  cursor: pointer;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: linear-gradient(var(--white) 0%, var(--darkwhite) 100%);
  box-shadow: 0px 0px 5px var(--pink);
}

.play-pause::before {
  position: absolute;
  content: "";
  height: 43px;
  width: 43px;
  border-radius: inherit;
  background: linear-gradient(var(--pink) 0%, var(--violet) 100%);
}

.play-pause i {
  height: 43px;
  width: 43px;
  line-height: 43px;
  text-align: center;
  background: inherit;
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  position: absolute;
}

.music-list {
  position: absolute;
  background: var(--white);
  width: 100%;
  left: 0;
  bottom: -55%;
  opacity: 0;
  pointer-events: none;
  z-index: 5;
  padding: 15px 30px;
  border-radius: 15px;
  box-shadow: 0px -5px 10px rgba(0, 0, 0, 0.1);
  transition: all 0.15s ease-out;
}

.music-list.show {
  bottom: 0;
  opacity: 1;
  pointer-events: auto;
}

.header .row {
  display: flex;
  align-items: center;
  font-size: 19px;
  color: var(--lightblack);
}

.header .row i {
  cursor: default;
}

.header .row span {
  margin-left: 5px;
}

.header #close {
  font-size: 22px;
  color: var(--lightblack);
}

.music-list ul {
  margin: 10px 0;
  max-height: 260px;
  overflow: auto;
}

.music-list ul::-webkit-scrollbar {
  width: 0px;
}

.music-list ul li {
  list-style: none;
  display: flex;
  cursor: pointer;
  padding-bottom: 10px;
  margin-bottom: 5px;
  color: var(--lightblack);
  border-bottom: 1px solid #E5E5E5;
}

.music-list ul li:last-child {
  border-bottom: 0px;
}

.music-list ul li .row span {
  font-size: 17px;
}

.music-list ul li .row p {
  opacity: 0.9;
}

ul li .audio-duration {
  font-size: 16px;
}

ul li.playing {
  pointer-events: none;
  color: var(--violet);
}

Third, create a JavaScript file with the name of music-list.js and paste the given codes in your JavaScript file. Remember, you’ve to create a file with .js extension. In this JavaScript file, we store all music details using the array.

// To add more song, just copy the following code and paste inside the array

//   {
//     name: "Here is the music name",
//     artist: "Here is the artist name",
//     img: "image name here - remember img must be in .jpg formate and it's inside the images folder of this project folder",
//     src: "music name here - remember img must be in .mp3 formate and it's inside the songs folder of this project folder"
//   }

let allMusic = [
  {
    name: "Harley Bird - Home",
    artist: "Jordan Schor",
    img: "music-1",
    src: "music-1",
  },
  {
    name: "Ikson Anywhere – Ikson",
    artist: "Audio Library",
    img: "music-2",
    src: "music-2",
  },
  {
    name: "Beauz & Jvna - Crazy",
    artist: "Beauz & Jvna",
    img: "music-3",
    src: "music-3",
  },
  {
    name: "Hardwind - Want Me",
    artist: "Mike Archangelo",
    img: "music-4",
    src: "music-4",
  },
  {
    name: "Jim - Sun Goes Down",
    artist: "Jim Yosef x Roy",
    img: "music-5",
    src: "music-5",
  },
  {
    name: "Lost Sky - Vision NCS",
    artist: "NCS Release",
    img: "music-6",
    src: "music-6",
  },
];

Last, create a JavaScript file with the name of script.js and paste the given codes in your JavaScript file. Remember, you’ve to create a file with .js extension.

const wrapper = document.querySelector(".wrapper"),
  musicImg = wrapper.querySelector(".img-area img"),
  musicName = wrapper.querySelector(".song-details .name"),
  musicArtist = wrapper.querySelector(".song-details .artist"),
  playPauseBtn = wrapper.querySelector(".play-pause"),
  prevBtn = wrapper.querySelector("#prev"),
  nextBtn = wrapper.querySelector("#next"),
  mainAudio = wrapper.querySelector("#main-audio"),
  progressArea = wrapper.querySelector(".progress-area"),
  progressBar = progressArea.querySelector(".progress-bar"),
  musicList = wrapper.querySelector(".music-list"),
  moreMusicBtn = wrapper.querySelector("#more-music"),
  closeMoreMusic = musicList.querySelector("#close"),
  repeatBtn = wrapper.querySelector("#repeat-plist"),
  ulTag = wrapper.querySelector("ul");

let musicIndex = Math.floor(Math.random() * allMusic.length);
let isMusicPaused = true;

window.addEventListener("load", () => {
  loadMusic(musicIndex);
  updatePlayingSong();
});

// Load music details
function loadMusic(index) {
  const song = allMusic[index];
  musicName.innerText = song.name;
  musicArtist.innerText = song.artist;
  musicImg.src = `images/${song.src}.jpg`;
  mainAudio.src = `songs/${song.src}.mp3`;
}

// Play music
function playMusic() {
  wrapper.classList.add("paused");
  playPauseBtn.querySelector("i").innerText = "pause";
  mainAudio.play();
}

// Pause music
function pauseMusic() {
  wrapper.classList.remove("paused");
  playPauseBtn.querySelector("i").innerText = "play_arrow";
  mainAudio.pause();
}

// Play previous song
function prevMusic() {
  musicIndex = (musicIndex - 1 + allMusic.length) % allMusic.length;
  loadMusic(musicIndex);
  playMusic();
  updatePlayingSong(); // Update list
}

// Play next song
function nextMusic() {
  musicIndex = (musicIndex + 1) % allMusic.length;
  loadMusic(musicIndex);
  playMusic();
  updatePlayingSong(); // Update list
}

// Select a song from the list
function selectSong(element) {
  const selectedIndex = element.getAttribute("li-index");
  musicIndex = selectedIndex - 1;
  loadMusic(musicIndex);
  playMusic();
  updatePlayingSong(); // Update list
}

// Play or pause event
playPauseBtn.addEventListener("click", () => {
  const isPlaying = wrapper.classList.contains("paused");
  isPlaying ? pauseMusic() : playMusic();
  updatePlayingSong();
});

// Previous and next button events
prevBtn.addEventListener("click", prevMusic);
nextBtn.addEventListener("click", nextMusic);

// Update progress bar as music plays
mainAudio.addEventListener("timeupdate", (e) => {
  if (mainAudio.duration) {
    const progressWidth = (e.target.currentTime / mainAudio.duration) * 100;
    progressBar.style.width = `${progressWidth}%`;

    updateCurrentTime(e.target.currentTime);
  }
});

// Update current time and duration
function updateCurrentTime(currentTime) {
  const currentMin = Math.floor(currentTime / 60);
  const currentSec = Math.floor(currentTime % 60)
    .toString()
    .padStart(2, "0");
  wrapper.querySelector(".current-time").innerText = `${currentMin}:${currentSec}`;
}

mainAudio.addEventListener("loadeddata", () => {
  const totalMin = Math.floor(mainAudio.duration / 60);
  const totalSec = Math.floor(mainAudio.duration % 60)
    .toString()
    .padStart(2, "0");
  wrapper.querySelector(".max-duration").innerText = `${totalMin}:${totalSec}`;
});

// Seek through the progress bar
progressArea.addEventListener("click", (e) => {
  const progressWidth = progressArea.clientWidth;
  const clickedOffsetX = e.offsetX;
  mainAudio.currentTime = (clickedOffsetX / progressWidth) * mainAudio.duration;
  playMusic();
  updatePlayingSong();
});

// Repeat/shuffle button event
repeatBtn.addEventListener("click", () => {
  switch (repeatBtn.innerText) {
    case "repeat":
      repeatBtn.innerText = "repeat_one";
      repeatBtn.setAttribute("title", "Song looped");
      break;
    case "repeat_one":
      repeatBtn.innerText = "shuffle";
      repeatBtn.setAttribute("title", "Playback shuffled");
      break;
    case "shuffle":
      repeatBtn.innerText = "repeat";
      repeatBtn.setAttribute("title", "Playlist looped");
      break;
  }
});

// Handle song end event
mainAudio.addEventListener("ended", () => {
  switch (repeatBtn.innerText) {
    case "repeat":
      nextMusic();
      break;
    case "repeat_one":
      mainAudio.currentTime = 0;
      playMusic();
      break;
    case "shuffle":
      shuffleMusic();
      break;
  }
});

// Shuffle music
function shuffleMusic() {
  let randomIndex;
  do {
    randomIndex = Math.floor(Math.random() * allMusic.length);
  } while (randomIndex === musicIndex);
  musicIndex = randomIndex;
  loadMusic(musicIndex);
  playMusic();
  updatePlayingSong();
}

// Show/hide music list
moreMusicBtn.addEventListener("click", () => {
  musicList.classList.toggle("show");
});

closeMoreMusic.addEventListener("click", () => {
  musicList.classList.remove("show");
});

// Generate song list dynamically
allMusic.forEach((song, index) => {
  const liTag = `
    <li li-index="${index + 1}">
      <div class="row">
        <span>${song.name}</span>
        <p>${song.artist}</p>
      </div>
      <span id="${song.src}" class="audio-duration">3:40</span>
      <audio class="${song.src}" src="songs/${song.src}.mp3"></audio>
    </li>`;
  ulTag.insertAdjacentHTML("beforeend", liTag);

  const liAudioTag = ulTag.querySelector(`.${song.src}`);
  liAudioTag.addEventListener("loadeddata", () => {
    const duration = liAudioTag.duration;
    const totalMin = Math.floor(duration / 60);
    const totalSec = Math.floor(duration % 60)
      .toString()
      .padStart(2, "0");
    const durationTag = ulTag.querySelector(`#${song.src}`);
    durationTag.innerText = `${totalMin}:${totalSec}`;
    durationTag.setAttribute("t-duration", `${totalMin}:${totalSec}`);
  });

  // Add click event listener to each list item
  const liItem = ulTag.querySelector(`li[li-index="${index + 1}"]`);
  liItem.addEventListener("click", () => selectSong(liItem));
});

// Update the song that is currently playing in the list
function updatePlayingSong() {
  const allLiTags = ulTag.querySelectorAll("li");

  // Remove 'playing' class from all list items
  allLiTags.forEach((li) => {
    li.classList.remove("playing");
    const audioTag = li.querySelector(".audio-duration");
    const songDuration = audioTag.getAttribute("t-duration");
    audioTag.innerText = songDuration; // Reset to original duration
  });

  // Add 'playing' class to the current song
  const currentLi = ulTag.querySelector(`li[li-index="${musicIndex + 1}"]`);
  currentLi.classList.add("playing");

  // Update the duration text to "Playing"
  const currentAudioTag = currentLi.querySelector(".audio-duration");
  currentAudioTag.innerText = "Playing";
}

That’s all, now you’ve successfully created a Custom Music Player in JavaScript. If your code doesn’t work or you’ve faced any error/problem, please download the source code files from the given download button. It’s free and a .zip file will be downloaded then you’ve to extract it.

 

Previous articleCopy Text To Clipboard in HTML CSS and JavaScript
Next articleHow To Create Admin Dashboard in HTML and CSS | Free Code

62 COMMENTS

  1. Nice music player.
    But I’m having a challenge. I have already hosted my music and I want to insert the streaming link instead of the songs in the folder. example; src=”https://sound1.mp3″. instead of the array method.

  2. i too keep getting “clicked not defiined” error in the console. the last clicked(element) function is the only thing that does not work.

  3. i keep getting “clicked not defiined” error in the console. the last clicked(element) function is the only thing that does not work.

  4. Perfect player, howeve, Most of my audio files are .m4a, any way I can make it play those. I tried removing . mp3 in script.js and specifying the music with extension in musiclist js. This however breaks some functionality, it doesn’t load the whole music list

  5. This music player is awesome, I have a small request, in this music player, while open the player in browser it will load a random song in the playlist, how to change this in song playlist index order.

    • Check any error is shown in the console or not and make sure the music details in the music-list file are the same as the actual music. Keep learning… happy coding 🙂

    • I have chacked console and its saying
      “Uncaught TypeError: Cannot read properties of null (reading ‘addEventListener’)
      at index.html:253:18”
      in your script.js , the line is
      liAudioTag.addEventListener("loadeddata", ()=>{
      let duration = liAudioTag.duration;
      let totalMin = Math.floor(duration / 60);
      let totalSec = Math.floor(duration % 60);
      if(totalSec < 10){ //if sec is less than 10 then add 0 before it
      totalSec = `0${totalSec}`;
      };
      . there is some error in th first line .
      what may i Do to resolve this problem ?

  6. This is an excellent music player CodingNepal and one which gives a lot of insight into what can be accomplished with CSS and regular JavaScript. Well done.

    You have done the world of amateur and early HTML programmers a great service with your tutorial, and your code works great with one slight exception. The function loadMusic should read

    musicImg.src = `images/${allMusic[indexNumb – 1].img}.jpg

    rather than

    musicImg.src = `images/${allMusic[indexNumb – 1].src}.jpg.

    Without that fix the name of the images used must be the same as the music, which it is in your example.

    Great work……

    and Merry Christmas

  7. Hi CodingNepal.
    It is beautiful your music player! I was wondering if it is easy to adjust the code so I can add music url links instead of the playlist with music being in a folder? so I make a list with music streaming from links, if that make sense 🙂
    Cheers!

  8. Hello, Thank you so much for the tutorial.
    Really love it and helping me so much.
    May I ask, how to turn on “autoplay” when the website window load, so we will not click the play button first for starting the music.

    Hope you see my question and reply me,
    Thank you and stay safe!

    • According to the new browser policy, the user must interact with DOM first before playing the Audio element. So you can’t play music on window load without any interaction with the DOM.

  9. Hi. Thanks so much for this easy to follow tutorial.
    On chrome, using clicking on the progress bar resets the track back to 0. On firefox it works but on chrome it doesn’t, did you experience that as well? Do you have this project on something like codepen so that I can try testing from there?
    Thank you for the tutorial

    • I tried it on chrome and didn’t see any problem. Please check your codes and run this file again.

  10. Can you add a feature of browsing music from my local disk in my computer from the player itself rather than to add it in source cofes

  11. hi
    This is a beginner from Ghana
    I’m very happy to meet you
    Thank you so much for the good job you are doing
    A beginner like me, it is really helping me
    infact, want to become a coding guru like you guys

  12. Hi @coding nepal! your new website design is very nice. I have one doubt. I had added more music but the music is not playing and in ‘src = “” ‘ i need to add music and in img = “” i need to add img but my images are in png and in another file. So i had added the file location but it is showing error pls solve it bro! i was waiting for the source code from past one month every day checking for 2 times. Please Help me

    • If you have PNG images then you can convert these images to JPG and use them on this music player but if you want to add PNG images then inside loadMusic function of script.js file there is a code line musicImg.src = images/${allMusic[indexNumb – 1].src}.jpg; just update the .jpg to png.

      If you want to use JPG and PNG images then remove this extension .jpg from this line musicImg.src = images/${allMusic[indexNumb – 1].src}.jpg and go to music-list.js file and pass the image name with extension…like this: img: “music-1.png”

  13. I am Just Appreciating you for what You are doing.God Bless
    I have one question though, please recommend me a cheaper web host because I want to host my simple website but I don’t want to spend much at the very start…So I will really appreciate it if u recommend a web host that is friendly for beginners maybe also giving free domain. THank you very much.

LEAVE A REPLY

Please enter your comment!
Please enter your name here