let currentTrackIndex = 0;
let tracks = [];
const audio = new Audio();
let isPlaying = false;
// DOM Elements
const playBtn = document.getElementById('playBtn');
const trackList = document.getElementById('track-list');
const currentTimeElem = document.getElementById('current-time');
const durationElem = document.getElementById('duration-time');
const progressContainer = document.getElementById('progress-container');
const progressBar = document.getElementById('progress-bar');
// Fetch tracks and initialize
fetch('/tracks')
.then(response => response.json())
.then(data => {
tracks = data;
renderPlaylist();
loadTrack(currentTrackIndex);
});
function renderPlaylist() {
trackList.innerHTML = tracks.map((track, index) => `
${track.title} ${track.artist}
${track.explicit === 'true' ? '' : ''}
`).join('');
}
function playTrack(index) {
currentTrackIndex = index;
const items = document.querySelectorAll('.list-group-item')
items.forEach(item => item.classList.remove('active'));
items[index].classList.add('active');
items[index].scrollIntoView( { behavior: 'smooth', block: 'nearest'})
loadTrack(index);
audio.play();
isPlaying = true;
updatePlayButton();
}
function loadTrack(index) {
const track = tracks[index];
audio.src = `/audio/${track.file}`;
document.getElementById('cover').src = `/cover/${track.cover}`;
document.getElementById('song-title').textContent = track.title;
document.getElementById('song-artist').textContent = track.artist;
}
function togglePlay() {
if (isPlaying) {
audio.pause();
} else {
audio.play();
}
isPlaying = !isPlaying;
updatePlayButton();
}
function updatePlayButton() {
const icon = playBtn.querySelector('i');
icon.classList.toggle('bi-play-fill', !isPlaying);
icon.classList.toggle('bi-pause-fill', isPlaying);
}
function nextTrack() {
currentTrackIndex = (currentTrackIndex + 1) % tracks.length;
playTrack(currentTrackIndex);
}
function previousTrack() {
currentTrackIndex = (currentTrackIndex - 1 + tracks.length) % tracks.length;
playTrack(currentTrackIndex);
}
// Time formatting
function formatTime(seconds) {
const minutes = Math.floor(seconds / 60);
seconds = Math.floor(seconds % 60);
return `${minutes}:${seconds.toString().padStart(2, '0')}`;
}
// Audio event listeners
audio.addEventListener('timeupdate', () => {
const progressPercent = (audio.currentTime / audio.duration) * 100;
progressBar.style.width = `${progressPercent}%`;
currentTimeElem.textContent = formatTime(audio.currentTime);
durationElem.textContent = formatTime(duration);
});
audio.addEventListener('loadedmetadata', () => {
durationElem.textContent = formatTime(audio.duration);
});
audio.addEventListener('ended', nextTrack);
audio.addEventListener('play', () => {
isPlaying = true;
updatePlayButton();
});
audio.addEventListener('pause', () => {
isPlaying = false;
updatePlayButton();
});
progressContainer.addEventListener('click', (e) => {
if (!audio.duration) return;
const rect = progressContainer.getBoundingClientRect();
const x = e.clientX - rect.left;
const percentage = x / progressContainer.offsetWidth;
const seekTime = percentage * audio.duration;
audio.currentTime = seekTime;
});