Este projeto [Music Player de Música em JavaScript] tem vários recursos, como você pode repetir, repetir ou embaralhar uma música, reproduzir/pausar uma música ou reproduzir a música seguinte ou anterior. Você pode visualizar sua lista de músicas e também saber qual música está tocando no momento e também pode selecionar a música da lista para tocar. Também criei um vídeo deste reprodutor de música, você pode assistir a uma demonstração ou a um vídeo de codificação completo.
<script>
let allMusic = [
{
name: "Nosso Quadro",
artist: "Ana Castela",
src: "1OzlQjwMF3BG4AQBUuVqus4yPXfsJefdq&name=ana-castela-nosso-quadro"
},
{
name: "Leão",
artist: "Marília Mendonça",
src: "19OCiga55GxKo1ETYDC3cAGzIktqh3Q2g&name=leao-marilia-mendonca"
},
{
name: "Seu Brilho Sumiu",
artist: "Israel e Rodolfo & Mari Fernandez",
src: "1TH7EZuyh0FWaZguwY5VkbPq1htB49Zjp&name=seu-brilho-sumiu-israel-e-rodolffo-marifernandez"
},
{
name: "Oi Balde",
artist: "Zé Neto e Cristiano",
src: "1J9qoSc5pzkA3BHiGX4QTVhn-egL-FidL&name=ze-neto-e-cristiano-oi-balde"
},
{
name: "Carinha de Bebê",
artist: "Ana Castelo & Pedro Sampaio",
src: "1Erf46Jjcyk4CRjvTeYmW5VeZxF4r3l4_&name=carinha-de-bebe-ana-castela-pedro-sampaio"
},
]; </script><div class="wrapper">
<div class="top-bar">
<i class="material-icons"></i>
<span>Tocando Agora</span>
<i class="material-icons"></i>
</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 class="material-icons" id="repeat-plist" title="Repetir Playlist">repeat</i>
<i class="material-icons" id="prev">skip_previous</i>
<div class="play-pause">
<i class="material-icons play">play_arrow</i>
</div>
<i class="material-icons" id="next">skip_next</i>
<i class="material-icons" id="more-music">queue_music</i>
</div>
<div class="music-list">
<div class="header">
<div class="row">
<i class="list material-icons">queue_music</i>
<span>Lista de Músicas</span>
</div>
<i class="material-icons" id="close">close</i>
</div>
<ul>
</ul>
</div>
</div><script>
const wrapper = document.querySelector(".wrapper"),
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");
let musicIndex = Math.floor((Math.random() * allMusic.length) + 1);
isMusicPaused = true;
window.addEventListener("load", ()=>{
loadMusic(musicIndex);
playingSong();
});
function loadMusic(indexNumb){
musicName.innerText = allMusic[indexNumb - 1].name;
musicArtist.innerText = allMusic[indexNumb - 1].artist;
mainAudio.src = `https://drive.google.com/uc?export=download&id=${allMusic[indexNumb - 1].src}.mp3`;
}
//play music function
function playMusic(){
wrapper.classList.add("paused");
playPauseBtn.querySelector("i").innerText = "pause";
mainAudio.play();
}
//pause music function
function pauseMusic(){
wrapper.classList.remove("paused");
playPauseBtn.querySelector("i").innerText = "play_arrow";
mainAudio.pause();
}
//prev music function
function prevMusic(){
musicIndex--; //decrement of musicIndex by 1
//if musicIndex is less than 1 then musicIndex will be the array length so the last music play
musicIndex < 1 ? musicIndex = allMusic.length : musicIndex = musicIndex;
loadMusic(musicIndex);
playMusic();
playingSong();
}
//next music function
function nextMusic(){
musicIndex++; //increment of musicIndex by 1
//if musicIndex is greater than array length then musicIndex will be 1 so the first music play
musicIndex > allMusic.length ? musicIndex = 1 : musicIndex = musicIndex;
loadMusic(musicIndex);
playMusic();
playingSong();
}
// play or pause button event
playPauseBtn.addEventListener("click", ()=>{
const isMusicPlay = wrapper.classList.contains("paused");
//if isPlayMusic is true then call pauseMusic else call playMusic
isMusicPlay ? pauseMusic() : playMusic();
playingSong();
});
//prev music button event
prevBtn.addEventListener("click", ()=>{
prevMusic();
});
//next music button event
nextBtn.addEventListener("click", ()=>{
nextMusic();
});
// update progress bar width according to music current time
mainAudio.addEventListener("timeupdate", (e)=>{
const currentTime = e.target.currentTime; //getting playing song currentTime
const duration = e.target.duration; //getting playing song total duration
let progressWidth = (currentTime / duration) * 100;
progressBar.style.width = `${progressWidth}%`;
let musicCurrentTime = wrapper.querySelector(".current-time"),
musicDuartion = wrapper.querySelector(".max-duration");
mainAudio.addEventListener("loadeddata", ()=>{
// update song total duration
let mainAdDuration = mainAudio.duration;
let totalMin = Math.floor(mainAdDuration / 60);
let totalSec = Math.floor(mainAdDuration % 60);
if(totalSec < 10){ //if sec is less than 10 then add 0 before it
totalSec = `0${totalSec}`;
}
musicDuartion.innerText = `${totalMin}:${totalSec}`;
});
// update playing song current time
let currentMin = Math.floor(currentTime / 60);
let currentSec = Math.floor(currentTime % 60);
if(currentSec < 10){ //if sec is less than 10 then add 0 before it
currentSec = `0${currentSec}`;
}
musicCurrentTime.innerText = `${currentMin}:${currentSec}`;
});
// update playing song currentTime on according to the progress bar width
progressArea.addEventListener("click", (e)=>{
let progressWidth = progressArea.clientWidth; //getting width of progress bar
let clickedOffsetX = e.offsetX; //getting offset x value
let songDuration = mainAudio.duration; //getting song total duration
mainAudio.currentTime = (clickedOffsetX / progressWidth) * songDuration;
playMusic(); //calling playMusic function
playingSong();
});
//change loop, shuffle, repeat icon onclick
const repeatBtn = wrapper.querySelector("#repeat-plist");
repeatBtn.addEventListener("click", ()=>{
let getText = repeatBtn.innerText; //getting this tag innerText
switch(getText){
case "repeat":
repeatBtn.innerText = "repeat_one";
repeatBtn.setAttribute("title", "Repetir Música");
break;
case "repeat_one":
repeatBtn.innerText = "shuffle";
repeatBtn.setAttribute("title", "Reprodução Aleatória");
break;
case "shuffle":
repeatBtn.innerText = "repeat";
repeatBtn.setAttribute("title", "Repetir Playlist");
break;
}
});
//code for what to do after song ended
mainAudio.addEventListener("ended", ()=>{
// we'll do according to the icon means if user has set icon to
// loop song then we'll repeat the current song and will do accordingly
let getText = repeatBtn.innerText; //getting this tag innerText
switch(getText){
case "repeat":
nextMusic(); //calling nextMusic function
break;
case "repeat_one":
mainAudio.currentTime = 0; //setting audio current time to 0
loadMusic(musicIndex); //calling loadMusic function with argument, in the argument there is a index of current song
playMusic(); //calling playMusic function
break;
case "shuffle":
let randIndex = Math.floor((Math.random() * allMusic.length) + 1); //genereting random index/numb with max range of array length
do{
randIndex = Math.floor((Math.random() * allMusic.length) + 1);
}while(musicIndex == randIndex); //this loop run until the next random number won't be the same of current musicIndex
musicIndex = randIndex; //passing randomIndex to musicIndex
loadMusic(musicIndex);
playMusic();
playingSong();
break;
}
});
//show music list onclick of music icon
moreMusicBtn.addEventListener("click", ()=>{
musicList.classList.toggle("show");
});
closemoreMusic.addEventListener("click", ()=>{
moreMusicBtn.click();
});
const ulTag = wrapper.querySelector("ul");
// let create li tags according to array length for list
for (let i = 0; i < allMusic.length; i++) {
//let's pass the song name, artist from the array
let liTag = `<li li-index="${i + 1}">
<div class="row">
<span>${allMusic[i].name}</span>
<p>${allMusic[i].artist}</p>
</div>
<span id="${allMusic[i].src}" class="audio-duration">3:40</span>
<audio class="${allMusic[i].src}" src="songs/${allMusic[i].src}.mp3"></audio>
</li>`;
ulTag.insertAdjacentHTML("beforeend", liTag); //inserting the li inside ul tag
let liAudioDuartionTag = ulTag.querySelector(`#${allMusic[i].src}`);
let liAudioTag = ulTag.querySelector(`.${allMusic[i].src}`);
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}`;
};
liAudioDuartionTag.innerText = `${totalMin}:${totalSec}`; //passing total duation of song
liAudioDuartionTag.setAttribute("t-duration", `${totalMin}:${totalSec}`); //adding t-duration attribute with total duration value
});
}
//play particular song from the list onclick of li tag
function playingSong(){
const allLiTag = ulTag.querySelectorAll("li");
for (let j = 0; j < allLiTag.length; j++) {
let audioTag = allLiTag[j].querySelector(".audio-duration");
if(allLiTag[j].classList.contains("playing")){
allLiTag[j].classList.remove("playing");
let adDuration = audioTag.getAttribute("t-duration");
audioTag.innerText = adDuration;
}
//if the li tag index is equal to the musicIndex then add playing class in it
if(allLiTag[j].getAttribute("li-index") == musicIndex){
allLiTag[j].classList.add("playing");
audioTag.innerText = "Tocando";
}
allLiTag[j].setAttribute("onclick", "clicked(this)");
}
}
//particular li clicked function
function clicked(element){
let getLiIndex = element.getAttribute("li-index");
musicIndex = getLiIndex; //updating current song index with clicked li index
loadMusic(musicIndex);
playMusic();
playingSong();
}</script><style>
@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);
}
.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);
}
.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);
}
</style><link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"/>
