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; });