Popular Posts

Creating Custom Music Player App using HTML, CSS & JavaScript

This Post is about how to create a music player app using HTML , CSS and JavaScript. This music player app supports play/pause, forward/backward, seek bar, playlist etc.. You have to store music and thumbnail files in files directory and define JavaScript object which will stores information of song name, artist, its mp3 file and thumbnail file.
HTML
<!DOCTYPE html>
<html>
<head>
	<title></title>
	<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
	<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
	<div class="player">
		<div class="main">
			<audio></audio>
			<div class="thumbnail">
				<img src="">
			</div>
			<div class="seekbar">
				<input type="range">
			</div>
			<div class="details">
				<h2></h2>
				<p></p>
			</div>
			<div class="controls">
				<div class="prev-control">
					<i class="fa fa-backward"></i>
				</div>
				<div class="play-pause-control paused">
					<i class="fa fa-play"></i>
					<i class="fa fa-pause"></i>
				</div>
				<div class="next-control">
					<i class="fa fa-forward"></i>
				</div>
			</div>
		</div>
		<div class="player-list">
			<div class="toggle-list">
				<i class="fa fa-angle-up"></i>
				<i class="fa fa-angle-down"></i>
			</div>
			<div class="list">
			</div>
		</div>
	</div>
	<script type="text/javascript" src="code.js"></script>
</body>
</html>
CSS
* {
	margin:0px;
	padding: 0px;
	box-sizing: border-box;
}
body {
	height: 100vh;
	font-family: "Raleway";
}
.player {
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%,-50%);
	width: 320px;
	height: 480px;
	overflow: hidden;
}
.player .main {
	width: 100%;
	height: 100%;
	background: #222;
	transition:all 500ms ease-in-out;
}
.player .main .thumbnail img {
	width: 100%;
}
.player .main .seekbar {
	margin-top: -15px;
}
.player .main .seekbar input[type="range"] {
	-webkit-appearance:none;
	width: 100%;
	height: 4px;
	outline: none;
	background: #aaa;
	overflow: hidden;
}
.player .main .seekbar input[type="range"]::-webkit-slider-thumb {
	-webkit-appearance:none;
	width: 0px;
	height: 0px;
	box-shadow: -300px 0px 0px 300px #00acee;
}
.player .main .details {
	text-align: center;
	padding: 15px 0px;
}
.player .main .details h2 {
	font-size: 18px;
	color:#eee;
	margin-bottom: 5px;
}
.player .main .details p {
	font-size: 15px;
	color: #aaa;
}
.player .main .controls {
	display: flex;
	justify-content: center;
	margin:8px 0px;
}
.player .main .controls > div {
	margin:0px 30px;
	cursor: pointer;
}
.player .main .controls i.fa {
	font-size:25px;
	color: #ddd;
}
.player .main .controls > div.play-pause-control i.fa-play {
	display: none;
}
.player .main .controls > div.play-pause-control.paused i.fa-play {
	display: block;
}
.player .main .controls > div.play-pause-control.paused i.fa-pause {
	display: none;
}
.player .player-list {
	position: absolute;
	width: 100%;
	margin-top:-20px;
	height: 350px;
	overflow-y: scroll;
	background: rgba(0,0,0,0.8);
	z-index:2;
	transition:all 500ms ease-in-out;
}
.player .player-list .toggle-list {
	position: sticky;
	top:0px;
	text-align: center;
	height: 20px;
	line-height: 20px;
	background: #555;
}
.player .player-list .toggle-list i.fa {
	color: #ccc;
	font-size: 20px;
	font-weight: 600;
}
.player .player-list .toggle-list i.fa-angle-down {
	display: none;
}
.player .player-list .toggle-list.active i.fa-angle-up {
	display: block;
}
.player .player-list .toggle-list.active i.fa-angle-down {
	display: none;
}
.player .list {
	padding: 10px;
}
.player .list .item {
	display: flex;
	padding: 5px 0px;
	border-bottom: 1px solid #222;
	cursor: pointer;
}
.player .list .item .thumbnail {
	width: 50px;
	height: 50px;
	overflow: hidden;
}
.player .list .thumbnail img {
	width: 100%;
	height: 100%;
}
.player .list .item .details {
	display: flex;
	flex-direction: column;
	justify-content: center;
	padding: 0px 10px;
}
.player .list .item .details h2 {
	color: #eee;
	font-size: 16px;
}
.player .list .item .details p {
	color: #aaa;
	font-size: 15px;
}
.player .player-list::-webkit-scrollbar {
	width: 5px;
	background: #222;
}
.player .player-list::-webkit-scrollbar-thumb {
	background: #00acee;
}
.player.activeSongList .player-list {
	margin-top: -350px;
}
.player.activeSongList .main {
	filter:blur(5px);
}
JS
function _(query){
	return document.querySelector(query);
}
function _all(query){
	return document.querySelectorAll(query);
}
let songList = [
	{
		thumbnail:"Bright_Future.jpg",
		audio:"Bright_Future.mp3",
		songname:"Bright Future",
		artistname:"Silent Partner"
	},
	{
		thumbnail:"Bovi.jpg",
		audio:"Bovi.mp3",
		songname:"Bovi",
		artistname:"The Grand Affair",
	},
	{
		thumbnail:"Sunny_Looks_Good_on_You.jpg",
		audio:"Sunny_Looks_Good_on_You.mp3",
		songname:"Sunny Looks Good on You",
		artistname:"Midnight North",
	},
	{
		thumbnail:"Bright_Eyed_Blues.jpg",
		audio:"Bright_Eyed_Blues.mp3",
		songname:"Bright Eyed Blues",
		artistname:"Unicorn Heads",
	},
	{
		thumbnail:"How_it_Began.jpg",
		audio:"How_it_Began.mp3",
		songname:"How it Began",
		artistname:"Silent Partner",
	},
	{
		thumbnail:"Simon_s_Song.jpg",
		audio:"Simon_s_Song.mp3",
		songname:"Simon's Song",
		artistname:"Dan Lebowitz",
	},
	{
		thumbnail:"Scanline.jpg",
		audio:"Scanline.mp3",
		songname:"Scanline",
		artistname:"Mike Relm",
	},
	{
		thumbnail:"Flight_To_Tunisia.jpg",
		audio:"Flight_To_Tunisia.mp3",
		songname:"Flight To Tunisia",
		artistname:"Causmic",
	},
	{
		thumbnail:"Calimba.jpg",
		audio:"Calimba.mp3",
		songname:"Calimba",
		artistname:"E's Jammy Jams",
	},
	{
		thumbnail:"Everglow.jpg",
		audio:"Everglow.mp3",
		songname:"Everglow",
		artistname:"Patrick Patrikios",
	}
];

let currentSongIndex = 0;

let player = _(".player"),
	toggleSongList = _(".player .toggle-list");

let main = {
	audio:_(".player .main audio"),
	thumbnail:_(".player .main img"),
	seekbar:_(".player .main input"),
	songname:_(".player .main .details h2"),
	artistname:_(".player .main .details p"),
	prevControl:_(".player .main .controls .prev-control"),
	playPauseControl:_(".player .main .controls .play-pause-control"),
	nextControl:_(".player .main .controls .next-control")
}

toggleSongList.addEventListener("click", function(){
	toggleSongList.classList.toggle("active");
	player.classList.toggle("activeSongList");
});

_(".player .player-list .list").innerHTML = (songList.map(function(song,songIndex){
	return `
		<div class="item" songIndex="${songIndex}">
			<div class="thumbnail">
				<img src="./files/${song.thumbnail}">
			</div>
			<div class="details">
				<h2>${song.songname}</h2>
				<p>${song.artistname}</p>
			</div>
		</div>
	`;
}).join(""));

let songListItems = _all(".player .player-list .list .item");
for(let i=0;i<songListItems.length;i++){
	songListItems[i].addEventListener("click",function(){
		currentSongIndex = parseInt(songListItems[i].getAttribute("songIndex"));
		loadSong(currentSongIndex);
		player.classList.remove("activeSongList");
	});
}

function loadSong(songIndex){
	let song = songList[songIndex];
	main.thumbnail.setAttribute("src","./files/"+song.thumbnail);
	document.body.style.background = `linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.8)), url("./files/${song.thumbnail}") center no-repeat`;
	document.body.style.backgroundSize = "cover";	
	main.songname.innerText = song.songname;
	main.artistname.innerText = song.artistname;
	main.audio.setAttribute("src","./files/"+song.audio);
	main.seekbar.setAttribute("value",0);
	main.seekbar.setAttribute("min",0);
	main.seekbar.setAttribute("max",0);
	main.audio.addEventListener("canplay",function(){
		main.audio.play();
		if(!main.audio.paused){
			main.playPauseControl.classList.remove("paused");
		}
		main.seekbar.setAttribute("max",parseInt(main.audio.duration));
		main.audio.onended = function(){
			main.nextControl.click();
		}
	})
}
setInterval(function(){
	main.seekbar.value = parseInt(main.audio.currentTime);
},1000);

main.prevControl.addEventListener("click",function(){
	currentSongIndex--;
	if(currentSongIndex < 0){
		currentSongIndex = songList.length + currentSongIndex;
	}
	loadSong(currentSongIndex);
});
main.nextControl.addEventListener("click",function(){
	currentSongIndex = (currentSongIndex+1) % songList.length;
	loadSong(currentSongIndex);
});
main.playPauseControl.addEventListener("click",function(){
	if(main.audio.paused){
		main.playPauseControl.classList.remove("paused");
		main.audio.play();
	} else {
		main.playPauseControl.classList.add("paused");
		main.audio.pause();
	}
});
main.seekbar.addEventListener("change",function(){
	main.audio.currentTime = main.seekbar.value;
});
loadSong(currentSongIndex);