I'm trying to build a music-player with JavaScript, I already have a playlist with four songs in it.
I filled in the songs in my script.js but I want to give the users an opportunity to load their own songs in the player by using Windows File Explorer.
I've already implemented the File Explorer but the selected song do not get into the playlist. How can I get the File Explorer "communicating" with my existing 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");
const loadContainer = document.getElementById("load-container");
const loadButton = document.getElementById("load-button");
//index for songs
let index;
//initially loop=true
let loop = true;
const songsList = [
{
name: "So Long Rastafari Calling (Live)",
link: "So Long Rastafari Calling (Live).mp3",
artist: "Culture",
image: "tree.jpg"
},
{
name: "Conquering Lion Of Judah (Live)",
link: "Conquering Lion Of Judah (Live).mp3",
artist: "Culture",
image: "culture.jpg"
},
{
name: "War Is In Di Air",
link: "War Is In Di Air.mp3",
artist: "Mavado",
image: "mavado.jpg"
},
{
name: "Final Destination",
link: "Final Destination.mp3",
artist: "Mavado",
image: "mavado.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();
};
//display fileExplorer
function create_playlist(playlistSongs){
console.log(playlistSongs);
}
* {
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;
cursor: pointer;
}
.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;
}
#load-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;
}
#load-button {
background-color: transparent;
border: none;
height: 2em;
cursor: pointer;
margin-right: 90%;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Music Player Test</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"
integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg=="
crossorigin="anonymous"></script>
<!-- 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="load-button" input type="file" onclick="document.getElementById('fileInput').click();">
<i class="fa-solid fa-angle-down"></i>
</button>
<input id="fileInput" type="file" onchange="create_playlist(this.files)" style="display:none;" multiple/>
<button id="playlist">
<i class="fa-solid fa-angle-down"></i>
</button>
<img id="song-image" src="tree.jpg" />
<div class="song-details">
<p id="song-name">So Long Rastafari Calling (Live)</p>
<p id="song-artist">Culture</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>
<!-- Script -->
<script src="script.js"></script>
</body>
</html>