VELTRON.NET/javascript/music-player.js
2026-02-27 17:13:51 -05:00

152 lines
4.3 KiB
JavaScript

// ===============================
// INITIAL SETUP
// ===============================
let currentSongIndex = 0;
let SONG_LINKS = [];
let PLAYLIST = document.getElementById("playlistLeft");
let AUDIO_PLAYER = document.getElementById("navMusic");
let TRACK_NAME_DISPLAY = document.getElementById("currentSongInfo");
let NAV_PLAY = document.getElementById("navMusicPlay");
let NAV_PAUSE = document.getElementById("navMusicPause");
let NAV_NEXT = document.getElementById("navMusicNext");
let NAV_PREV = document.getElementById("navMusicPrevious");
// ===============================
// LOAD MUSIC DATA
// ===============================
async function loadMusicData() {
const response = await fetch("https://frutigeraeroarchive.org/data/music.min.json");
const data = await response.json();
const section = data.ols.find(item => item["@id"] === "frutigerAeroBliss");
if (!section) return [];
return section.li.map(item => ({
title: item.a.title,
url: "https://frutigeraeroarchive.org/music" + item.a["@data-src-mp3"],
background: item.a["@data-background"] || "",
artist: item.a["@data-artist"] || "",
spotify: item.a["@data-spotify"] || "",
youtube: item.a["@data-youtube"] || "",
description: item.a["@data-description"] || "",
copyright: item.a["@data-copyright"] || "",
date: item.a["@data-date"] || ""
}));
}
// ===============================
// CREATE PLAYLIST
// ===============================
function createAlbum(album) {
if (!PLAYLIST) return;
const existing = PLAYLIST.querySelector("ol");
if (existing) existing.remove();
const list = document.createElement("ol");
list.id = album["@id"];
const title = document.createElement("span");
title.textContent = album.span;
list.appendChild(title);
const small = document.createElement("small");
small.textContent = album.small;
list.appendChild(small);
// Build playlist in EXACT JSON ORDER
album.li.forEach((song, index) => {
const li = document.createElement("li");
const a = document.createElement("a");
a.textContent = song.a.title;
a.href = "#";
// Apply metadata
for (const key in song.a) {
if (key.startsWith("@data-")) {
a.setAttribute(key.replace("@", ""), song.a[key]);
}
}
li.appendChild(a);
list.appendChild(li);
});
PLAYLIST.appendChild(list);
SONG_LINKS = PLAYLIST.querySelectorAll("a[data-src-mp3]");
SONG_LINKS.forEach((song, index) => {
song.addEventListener("click", (e) => {
e.preventDefault();
currentSongIndex = index;
updateSong(index);
});
});
// ALWAYS START AT SONG 0
currentSongIndex = 0;
updateSong(0);
}
// ===============================
// UPDATE SONG
// ===============================
function updateSong(index) {
SONG_LINKS.forEach((song, i) => {
song.classList.toggle("activeSong", i === index);
});
const song = SONG_LINKS[index];
AUDIO_PLAYER.src = song.getAttribute("data-src-mp3");
TRACK_NAME_DISPLAY.textContent = song.getAttribute("data-title");
AUDIO_PLAYER.play().catch(console.error);
}
// ===============================
// NEXT / PREVIOUS
// ===============================
function nextTrack() {
currentSongIndex = (currentSongIndex + 1) % SONG_LINKS.length;
updateSong(currentSongIndex);
}
function previousTrack() {
currentSongIndex = (currentSongIndex - 1 + SONG_LINKS.length) % SONG_LINKS.length;
updateSong(currentSongIndex);
}
AUDIO_PLAYER.addEventListener("ended", nextTrack);
// ===============================
// NAV BUTTONS
// ===============================
NAV_PLAY.addEventListener("click", () => AUDIO_PLAYER.play());
NAV_PAUSE.addEventListener("click", () => AUDIO_PLAYER.pause());
NAV_NEXT.addEventListener("click", nextTrack);
NAV_PREV.addEventListener("click", previousTrack);
// ===============================
// LOAD ON STARTUP
// ===============================
window.addEventListener("load", async () => {
const songs = await loadMusicData();
if (songs.length > 0) {
createAlbum({
"@id": "frutigerAeroBliss",
span: "Frutiger Aero Bliss",
small: "Music that fits well with Frutiger Aero.",
li: songs.map(song => ({ a: song }))
});
}
});