Spaces:
Running
Running
File size: 4,265 Bytes
33993ef 4a9156b 33993ef 74ebac0 93b8c11 74ebac0 33993ef 39d7e53 74ebac0 33993ef d59aea4 74ebac0 d59aea4 74ebac0 33993ef d59aea4 74ebac0 d59aea4 74ebac0 33993ef d59aea4 74ebac0 d59aea4 74ebac0 d59aea4 74ebac0 d59aea4 74ebac0 33993ef d59aea4 74ebac0 33993ef d59aea4 74ebac0 d59aea4 74ebac0 d59aea4 74ebac0 d59aea4 74ebac0 d59aea4 74ebac0 d59aea4 74ebac0 39d7e53 74ebac0 33993ef 74ebac0 33993ef 74ebac0 33993ef |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
// Simple MySpace-style music player with fake EQ bars
document.addEventListener("DOMContentLoaded", () => {
// === PLAYLIST ===
const playlist = [
{
title: "The Ocean",
artist: "Super Fuzz",
src: "https://cdn-uploads.huggingface.co/production/uploads/693f06e4c231c8267144eb68/WwdKDnPZAW9q7tXWomfSY.mpga",
},
];
// === GRAB ELEMENTS FROM THE PAGE ===
const audioEl = document.getElementById("audio-player");
const titleEl = document.getElementById("track-title");
const artistEl = document.getElementById("track-artist");
const playPauseBtn = document.getElementById("play-pause-btn");
const prevBtn = document.getElementById("prev-btn");
const nextBtn = document.getElementById("next-btn");
const seekBar = document.getElementById("seek-bar");
const eqBars = document.querySelectorAll(".eq-visualizer .eq-bar");
// Safety check – if something's missing, don't crash
if (
!audioEl ||
!titleEl ||
!artistEl ||
!playPauseBtn ||
!prevBtn ||
!nextBtn ||
!seekBar
) {
console.warn("Music player: required elements not found.");
return;
}
let currentTrackIndex = 0;
let isPlaying = false;
let isSeeking = false;
let eqInterval = null;
// === EQ BAR ANIMATION (FAKE VISUALIZER) ===
function startEq() {
if (!eqBars.length || eqInterval) return;
eqInterval = setInterval(() => {
eqBars.forEach((bar) => {
const height = 20 + Math.random() * 80; // 20%–100%
bar.style.height = `${height}%`;
});
}, 120);
}
function stopEq() {
if (eqInterval) {
clearInterval(eqInterval);
eqInterval = null;
}
eqBars.forEach((bar) => {
bar.style.height = "25%"; // idle height
});
}
// === CORE FUNCTIONS ===
function loadTrack(index) {
const track = playlist[index];
if (!track) return;
titleEl.textContent = track.title;
artistEl.textContent = track.artist;
audioEl.src = track.src;
}
function playTrack() {
if (!audioEl.src) {
// just in case loadTrack didn't run for some reason
loadTrack(currentTrackIndex);
}
const playPromise = audioEl.play();
if (playPromise !== undefined) {
playPromise
.then(() => {
isPlaying = true;
playPauseBtn.textContent = "⏸"; // pause icon
startEq();
})
.catch((err) => {
console.warn("Autoplay/play blocked or failed:", err);
});
}
}
function pauseTrack() {
audioEl.pause();
isPlaying = false;
playPauseBtn.textContent = "▶"; // play icon
stopEq();
}
function togglePlay() {
if (isPlaying) {
pauseTrack();
} else {
playTrack();
}
}
function playNext() {
currentTrackIndex = (currentTrackIndex + 1) % playlist.length;
loadTrack(currentTrackIndex);
playTrack();
}
function playPrev() {
currentTrackIndex =
(currentTrackIndex - 1 + playlist.length) % playlist.length;
loadTrack(currentTrackIndex);
playTrack();
}
// === EVENT LISTENERS ===
// Play / Pause button
playPauseBtn.addEventListener("click", togglePlay);
// Next / Previous
nextBtn.addEventListener("click", playNext);
prevBtn.addEventListener("click", playPrev);
// Keep seek bar in sync with audio
audioEl.addEventListener("timeupdate", () => {
if (!audioEl.duration || isSeeking) return;
const progress = (audioEl.currentTime / audioEl.duration) * 100;
seekBar.value = progress;
});
// Scrub / seek when user drags the slider
seekBar.addEventListener("input", () => {
if (!audioEl.duration) return;
isSeeking = true;
const newTime = (seekBar.value / 100) * audioEl.duration;
audioEl.currentTime = newTime;
});
seekBar.addEventListener("change", () => {
isSeeking = false;
});
// When a track ends, loop playlist
audioEl.addEventListener("ended", () => {
playNext();
});
// If there's an audio error (bad URL, etc.)
audioEl.addEventListener("error", (e) => {
console.warn("Audio element error:", e);
});
// === INITIALIZE ===
// Load first track
loadTrack(currentTrackIndex);
// Try autoplay on load (browser may block this until user clicks)
playTrack();
});
|