Hey everyone. Welcome to today’s tutorial. In today’s tutorial, we will create a custom music player. To build this project we need HTML, CSS and Javascript.
This project is well suited for javascript intermediates. Even javascript beginners can try this project since I have explained each step with the help of comments.
The music player project might seem to be lengthy and complicated at first but I have divided the javascript code into 15 easy steps. You can easily create and customize the music player with these 15 steps.
Video Tutorial:
If you are interested to learn by coding along with a video tutorial rather than reading this blog post, you should check out the video down below. Also, I post new tricks, tips and tutorials on my youtube channel regularly. So do subscribe to my channel to stay updated with the latest tutorials.
Project Folder Structure:
Before we start coding let us take a look at the project folder structure. We create a project folder with the name – Custom Music Player. Inside this folder, we have three files – index.html, style.css and script.js. These are the HTML document, the stylesheet and the script file respectively.
HTML:
We start with the HTML code. First, copy the code below and paste it into your HTML document. This creates the elements necessary to build the structure of the music player.
<!DOCTYPE html> <html lang="en"> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Custom Music Player</title> <!-- Font Awesome Icons --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/css/all.min.css" integrity="sha512-KfkfwYDsLkIlwQp6LFnl8zNdLGxu9YAA1QvwINks4PhcElQSvqcyVLLD9aMhXd13uQjoXtEKNosOWaZqXgel0g==" crossorigin="anonymous" referrerpolicy="no-referrer" /> <!-- Google Fonts --> <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600&family=Roboto+Mono&display=swap" rel="stylesheet" /> <!-- Stylesheet --> <link rel="stylesheet" href="style.css" /> </head> <body> <div class="music-player"> <button id="playlist"> <i class="fa-solid fa-angle-down"></i> </button> <img id="song-image" src="make-me-move.jpg" /> <div class="song-details"> <p id="song-name">Make Me Move</p> <p id="song-artist">Culture Code</p> </div> <div class="player-options"> <button id="shuffle"> <i class="fa-solid fa-shuffle"></i> </button> <button id="prev"> <i class="fa-solid fa-backward-step"></i> </button> <button id="play"> <i class="fa-solid fa-play"></i> </button> <button id="pause" class="hide"> <i class="fa-solid fa-pause"></i> </button> <button id="next"> <i class="fa-solid fa-forward-step"></i> </button> <button id="repeat"> <i class="fa-solid fa-repeat"></i> </button> </div> <audio id="audio" preload="metadata"></audio> <div id="progress-bar"> <div id="current-progress"></div> </div> <div class="time-container"> <span id="current-time">0:00</span> <span id="max-duration">0:00</span> </div> <div id="playlist-container" class="hide"> <button id="close-button"> <i class="fa-solid fa-xmark"></i> </button> <ul id="playlist-songs"></ul> </div> </div> <!-- Script --> <script src="script.js"></script> </body> </html>
CSS:
Next, we need to style these elements to make the music player look attractive. For this we use CSS. Now copy the code below and paste it into your stylesheet.
* { padding: 0; margin: 0; box-sizing: border-box; } body { height: 100vh; background: linear-gradient(to bottom, #2887e3 50%, #16191e 50%); } .music-player { font-size: 16px; width: 80vw; max-width: 25em; background-color: #ffffff; padding: 3em 1.8em; position: absolute; transform: translate(-50%, -50%); top: 50%; left: 50%; border-radius: 0.5em; box-shadow: 0.6em 1.2em 3em rgba(0, 0, 0, 0.25); } img { width: 100%; margin-top: 1.25em; } #playlist { float: right; } .song-details { font-family: "Poppins", sans-serif; text-align: center; } .song-details #song-name { font-size: 1.3em; font-weight: 600; letter-spacing: 0.3px; } .song-details #song-artist { font-size: 0.8em; } .player-options { display: flex; align-items: center; justify-content: space-around; padding: 0 1.25em; margin: 1.25em 0 0.6em 0; } .music-player button { border: none; background-color: transparent; } #play, #pause { height: 2.5em; width: 2.5em; font-size: 1.8em; background-color: #2887e3; color: #ffffff; border-radius: 50%; } #prev, #next { color: #16191e; font-size: 1.4em; } #shuffle, #repeat { color: #949494; font-size: 1em; } .hide { display: none; } #progress-bar { position: relative; width: 100%; height: 0.3em; background-color: #eeeeee; margin: 1em 0; border-radius: 0.18em; cursor: pointer; } #current-progress { position: absolute; left: 0; top: 0; display: inline-block; height: 100%; width: 20%; background-color: #2887e3; border-radius: 0.18em; } .time-container { display: flex; align-items: center; justify-content: space-between; font-family: "Roboto Mono", monospace; } #playlist-container { background-color: #ffffff; position: absolute; width: 100%; height: 100%; transform: translate(-50%, -50%); top: 50%; left: 50%; border-radius: 0.6em; padding: 2em 1em; font-family: "Poppins", sans-serif; } #close-button { background-color: transparent; border: none; height: 2em; width: 2em; cursor: pointer; margin-left: 90%; } ul { list-style-type: none; } li { display: flex; align-items: center; margin: 1em 0; cursor: pointer; } .playlist-song-details { margin-left: 1em; } .playlist-song-details > span { display: block; } #playlist-song-artist-album { color: #949494; font-size: 0.8em; } button.active i { color: #2887e3; } @media screen and (max-width: 450px) { .music-player { font-size: 14px; } } .playlist-image-container { width: 3em; }
Javascript:
Lastly, we implement the functionality using javascript. Once again, copy the code below and paste it into your script file. We create the music player in 15 easy steps. These steps are:
- Create Initial References
- Create An Array For Song List
- Detect If It Is A Touch Device
- Format Time
- A Function To Set Song
- Function To Play Song
- Implement Function To Toggle Repeat Mode
- Function To Play Next Song
- Function To Pause Song
- Create Function To Play Previous Song
- Function To Toggle Shuffle Mode
- Adding Event Listener to Progress Bar
- Updating Progress Bar and Time
- Function To Create Playlist
- Function To Show & Hide Playlist
const prevButton = document.getElementById("prev"); const nextButton = document.getElementById("next"); const repeatButton = document.getElementById("repeat"); const shuffleButton = document.getElementById("shuffle"); const audio = document.getElementById("audio"); const songImage = document.getElementById("song-image"); const songName = document.getElementById("song-name"); const songArtist = document.getElementById("song-artist"); const pauseButton = document.getElementById("pause"); const playButton = document.getElementById("play"); const playlistButton = document.getElementById("playlist"); const maxDuration = document.getElementById("max-duration"); const currentTimeRef = document.getElementById("current-time"); const progressBar = document.getElementById("progress-bar"); const playlistContainer = document.getElementById("playlist-container"); const closeButton = document.getElementById("close-button"); const playlistSongs = document.getElementById("playlist-songs"); const currentProgress = document.getElementById("current-progress"); //index for songs let index; //initially loop=true let loop = true; const songsList = [ { name: "Make Me Move", link: "make-me-move.mp3", artist: "Culture Code", image: "make-me-move.jpg", }, { name: "Where We Started", link: "where-we-started.mp3", artist: "Lost Sky", image: "where-we-started.jpg", }, { name: "On & On", link: "on-on.mp3", artist: "Cartoon", image: "on-on.jpg", }, { name: "Throne", link: "throne.mp3", artist: "Rival", image: "throne.jpg", }, { name: "Need You Now", link: "need-you-now.mp3", artist: "Venemy", image: "need-you-now.jpg", }, ]; //events object let events = { mouse: { click: "click", }, touch: { click: "touchstart", }, }; let deviceType = ""; //Detect touch device const isTouchDevice = () => { try { //We try to create TouchEvent(it would fail for desktops and throw error) document.createEvent("TouchEvent"); deviceType = "touch"; return true; } catch (e) { deviceType = "mouse"; return false; } }; //Format time (convert ms to seconds, minutes and add 0 id less than 10) const timeFormatter = (timeInput) => { let minute = Math.floor(timeInput / 60); minute = minute < 10 ? "0" + minute : minute; let second = Math.floor(timeInput % 60); second = second < 10 ? "0" + second : second; return `${minute}:${second}`; }; //set song const setSong = (arrayIndex) => { //this extracts all the variables from the object let { name, link, artist, image } = songsList[arrayIndex]; audio.src = link; songName.innerHTML = name; songArtist.innerHTML = artist; songImage.src = image; //display duration when metadata loads audio.onloadedmetadata = () => { maxDuration.innerText = timeFormatter(audio.duration); }; }; //play song const playAudio = () => { audio.play(); pauseButton.classList.remove("hide"); playButton.classList.add("hide"); }; //repeat button repeatButton.addEventListener("click", () => { if (repeatButton.classList.contains("active")) { repeatButton.classList.remove("active"); audio.loop = false; console.log("repeat off"); } else { repeatButton.classList.add("active"); audio.loop = true; console.log("repeat on"); } }); //Next song const nextSong = () => { //if loop is true then continue in normal order if (loop) { if (index == songsList.length - 1) { //If last song is being played index = 0; } else { index += 1; } setSong(index); playAudio(); } else { //else find a random index and play that song let randIndex = Math.floor(Math.random() * songsList.length); console.log(randIndex); setSong(randIndex); playAudio(); } }; //pause song const pauseAudio = () => { audio.pause(); pauseButton.classList.add("hide"); playButton.classList.remove("hide"); }; //previous song ( you can't go back to a randomly played song) const previousSong = () => { if (index > 0) { pauseAudio(); index -= 1; } else { //if first song is being played index = songsList.length - 1; } setSong(index); playAudio(); }; //next song when current song ends audio.onended = () => { nextSong(); }; //Shuffle songs shuffleButton.addEventListener("click", () => { if (shuffleButton.classList.contains("active")) { shuffleButton.classList.remove("active"); loop = true; console.log("shuffle off"); } else { shuffleButton.classList.add("active"); loop = false; console.log("shuffle on"); } }); //play button playButton.addEventListener("click", playAudio); //next button nextButton.addEventListener("click", nextSong); //pause button pauseButton.addEventListener("click", pauseAudio); //prev button prevButton.addEventListener("click", previousSong); //if user clicks on progress bar isTouchDevice(); progressBar.addEventListener(events[deviceType].click, (event) => { //start of progressBar let coordStart = progressBar.getBoundingClientRect().left; //mouse click position let coordEnd = !isTouchDevice() ? event.clientX : event.touches[0].clientX; let progress = (coordEnd - coordStart) / progressBar.offsetWidth; //set width to progress currentProgress.style.width = progress * 100 + "%"; //set time audio.currentTime = progress * audio.duration; //play audio.play(); pauseButton.classList.remove("hide"); playButton.classList.add("hide"); }); //update progress every second setInterval(() => { currentTimeRef.innerHTML = timeFormatter(audio.currentTime); currentProgress.style.width = (audio.currentTime / audio.duration.toFixed(3)) * 100 + "%"; }); //update time audio.addEventListener("timeupdate", () => { currentTimeRef.innerText = timeFormatter(audio.currentTime); }); //Creates playlist const initializePlaylist = () => { for (let i in songsList) { playlistSongs.innerHTML += `<li class='playlistSong' onclick='setSong(${i})'> <div class="playlist-image-container"> <img src="${songsList[i].image}"/> </div> <div class="playlist-song-details"> <span id="playlist-song-name"> ${songsList[i].name} </span> <span id="playlist-song-artist-album"> ${songsList[i].artist} </span> </div> </li>`; } }; //display playlist playlistButton.addEventListener("click", () => { playlistContainer.classList.remove("hide"); }); //hide playlist closeButton.addEventListener("click", () => { playlistContainer.classList.add("hide"); }); window.onload = () => { //initially first song index = 0; setSong(index); //create playlist initializePlaylist(); };
Â
That’s it for this tutorial. Our music player is now ready. If you have any issues while creating this code you can download the source code by clicking on the download code button below. Also, if you have any queries, suggestions or feedback you can drop them in the comments below. Happy Coding!
Good morning !
It just lacks a slider to adjust the volume.
Can you add it?
Thanks !
Awesome! You are so clever! Thankyou.