const playerButton = document.querySelector('.player-button'), audio = document.querySelector('audio'), timeline = document.querySelector('.timeline'), soundButton = document.querySelector('.sound-button'), timeInfo = document.getElementById('timeInfo'), playIcon = ` `, pauseIcon = ` `, soundIcon = ` `, muteIcon = ` `; function toggleAudio () { if (audio.paused) { audio.play(); playerButton.innerHTML = pauseIcon; } else { audio.pause(); playerButton.innerHTML = playIcon; } } playerButton.addEventListener('click', toggleAudio); let isSeeking = false; // --- Slider (Timeline) events --- // Mouse events timeline.addEventListener('mousedown', () => { isSeeking = true; }); timeline.addEventListener('mouseup', () => { isSeeking = false; changeSeek(); // Update the audio currentTime based on the slider position }); timeline.addEventListener('change', changeSeek); // Touch events timeline.addEventListener('touchstart', () => { isSeeking = true; }); timeline.addEventListener('touchend', () => { isSeeking = false; changeSeek(); }); timeline.addEventListener('touchcancel', () => { isSeeking = false; }); // --- When metadata is loaded, set slider range in seconds --- audio.addEventListener('loadedmetadata', () => { updateTimeInfo(); timeline.min = 0; timeline.max = audio.duration; timeline.value = 0; // Ensures the thumb starts at the left. }); // --- Update the slider thumb position (in seconds) while playing --- function changeTimelinePosition() { if (!isSeeking) { timeline.value = audio.currentTime; const percentagePosition = (audio.currentTime / audio.duration) * 100; timeline.style.backgroundSize = `${percentagePosition}% 100%`; } } // --- Seek function: directly set audio.currentTime using slider's value (in seconds) --- function changeSeek() { audio.currentTime = timeline.value; } // --- Sound toggle --- function toggleSound () { audio.muted = !audio.muted; soundButton.innerHTML = audio.muted ? muteIcon : soundIcon; } soundButton.addEventListener('click', toggleSound); // --- Utility: Format seconds as mm:ss --- function formatTime(seconds) { const minutes = Math.floor(seconds / 60); const secs = Math.floor(seconds % 60); return `${minutes < 10 ? '0' : ''}${minutes}:${secs < 10 ? '0' : ''}${secs}`; } // --- Update the time display --- function updateTimeInfo() { const currentTimeFormatted = formatTime(audio.currentTime); const durationFormatted = isNaN(audio.duration) ? "00:00" : formatTime(audio.duration); timeInfo.innerHTML = `${currentTimeFormatted} / ${durationFormatted}`; } // --- Update timeline, time info, and media session on each time update --- audio.ontimeupdate = function() { changeTimelinePosition(); updateTimeInfo(); if ('mediaSession' in navigator && typeof navigator.mediaSession.setPositionState === 'function') { navigator.mediaSession.setPositionState({ duration: audio.duration, playbackRate: audio.playbackRate, position: audio.currentTime }); } }; // --- Also update media session on play (in case timeupdate lags) --- audio.onplay = function() { if ('mediaSession' in navigator && typeof navigator.mediaSession.setPositionState === 'function') { navigator.mediaSession.setPositionState({ duration: audio.duration, playbackRate: audio.playbackRate, position: audio.currentTime }); } }; // --- Handle external seek requests (e.g. from Android or Windows system controls) --- if ('mediaSession' in navigator) { navigator.mediaSession.setActionHandler('seekto', function(details) { if (details.fastSeek && 'fastSeek' in audio) { audio.fastSeek(details.seekTime); } else { audio.currentTime = details.seekTime; } changeTimelinePosition(); }); } // --- When audio ends --- audio.onended = function() { playerButton.innerHTML = playIcon; }; function downloadAudio() { // Get the current audio source URL const audioSrc = audio.currentSrc || audio.src; if (audioSrc) { // Create a temporary link element const a = document.createElement('a'); a.href = audioSrc; // Extract the file name from the URL, decode it, and set as download attribute let fileName = audioSrc.split('/').pop() || 'audio'; fileName = decodeURIComponent(fileName); a.download = fileName; document.body.appendChild(a); a.click(); document.body.removeChild(a); } }