
window.onerror = function(message, source, lineno, colno, error) {console.error("An error occurred:", message, "at", source, ":", lineno);return true;
};
if (typeof particlesJS !== 'undefined') {document.addEventListener('DOMContentLoaded', function() {particlesJS('particles-js', {particles: {number: { value: 80, density: { enable: true, value_area: 800 } },color: { value: '#ffffff' },shape: { type: 'circle', stroke: { width: 0, color: '#000000' } },opacity: { value: 0.5, random: true, anim: { enable: true, speed: 1, opacity_min: 0.1, sync: false } },size: { value: 3, random: true, anim: { enable: true, speed: 4, size_min: 0.3, sync: false } },line_linked: { enable: true, distance: 150, color: '#ffffff', opacity: 0.4, width: 1 },move: { enable: true, speed: 1, direction: 'none', random: true, straight: false, out_mode: 'out', bounce: false }},interactivity: {detect_on: 'canvas',events: { onhover: { enable: true, mode: 'repulse' }, onclick: { enable: true, mode: 'push' }, resize: true },modes: { repulse: { distance: 100, duration: 0.4 }, push: { particles_nb: 4 } }},retina_detect: true});console.log('Particles initialized');});
} else {console.error("particlesJS is not defined. The library may not have loaded correctly.");
}
let wavesurfer;function initWaveSurfer() {wavesurfer = WaveSurfer.create({container: '#visualizer',waveColor: 'rgba(255, 255, 255, 0.5)',progressColor: 'rgba(29, 185, 84, 0.7)',cursorColor: 'transparent',barWidth: 2,barRadius: 3,cursorWidth: 0,height: 40,barGap: 2,responsive: true});wavesurfer.on('ready', onWavesurferReady);wavesurfer.on('audioprocess', updateProgress);wavesurfer.on('audioprocess', updateLyrics);console.log('WaveSurfer initialized');bindPlayPauseButton();
}function bindPlayPauseButton() {playPauseButton.addEventListener('click', togglePlayPause);
}function togglePlayPause() {if (wavesurfer) {wavesurfer.playPause();updatePlayPauseIcon();} else {console.error('WaveSurfer is not initialized');}
}function updatePlayPauseIcon() {const icon = playPauseButton.querySelector('i');if (wavesurfer && wavesurfer.isPlaying()) {icon.classList.remove('fa-play');icon.classList.add('fa-pause');} else {icon.classList.remove('fa-pause');icon.classList.add('fa-play');}
}
document.addEventListener('click', function initAudioContext() {if (!wavesurfer) {initWaveSurfer();}document.removeEventListener('click', initAudioContext);
}, { once: true });
const playPauseButton = document.getElementById('play-pause');
const prevButton = document.getElementById('prev');
const nextButton = document.getElementById('next');
const shuffleButton = document.getElementById('shuffle');
const repeatButton = document.getElementById('repeat');
const fileInput = document.getElementById('file-input');
const songTitle = document.getElementById('song-title');
const artistName = document.getElementById('artist-name');
const albumCover = document.getElementById('album-cover');
const lyricsContainer = document.getElementById('lyrics');
const progressContainer = document.getElementById('progress-container');
const progressBar = document.getElementById('progress-bar');
const currentTime = document.getElementById('current-time');
const totalTime = document.getElementById('total-time');
function initializeControls() {playPauseButton.addEventListener('click', togglePlayPause);prevButton.addEventListener('click', playPreviousTrack);nextButton.addEventListener('click', playNextTrack);shuffleButton.addEventListener('click', toggleShuffle);repeatButton.addEventListener('click', toggleRepeat);progressContainer.addEventListener('click', seekToPosition);
}
fileInput.addEventListener('change', (e) => {const file = e.target.files[0];if (file) {if (!wavesurfer) {initWaveSurfer();}const objectURL = URL.createObjectURL(file);wavesurfer.load(objectURL);updateSongInfo(file);console.log('File loaded:', file.name);}
});function updateSongInfo(file) {songTitle.textContent = file.name.replace(/\.[^/.]+$/, "");artistName.textContent = "未知艺术家"; console.log('Song info updated');
}
function updateProgress() {if (wavesurfer) {const progress = wavesurfer.getCurrentTime() / wavesurfer.getDuration();progressBar.style.width = `${progress * 100}%`;currentTime.textContent = formatTime(wavesurfer.getCurrentTime());}
}progressContainer.addEventListener('click', function(e) {if (wavesurfer) {const clickPosition = (e.clientX - this.getBoundingClientRect().left) / this.offsetWidth;wavesurfer.seekTo(clickPosition);}
});
function formatTime(time) {const minutes = Math.floor(time / 60);const seconds = Math.floor(time % 60);return `${minutes}:${seconds.toString().padStart(2, '0')}`;
}
function onWavesurferReady() {playPauseButton.disabled = false;totalTime.textContent = formatTime(wavesurfer.getDuration());updatePlayPauseIcon();console.log('Wavesurfer ready');wavesurfer.play();
}
function updateLyrics(time) {if (!showingLyrics) return;if (window.parsedLyrics && window.parsedLyrics.length > 0) {const currentLyric = window.parsedLyrics.find(lyric => lyric.time <= time);if (currentLyric) {lyricsContainer.textContent = currentLyric.text;}} else {lyricsContainer.textContent = `正在播放: ${Math.floor(time)}秒`;}console.log('Lyrics updated:', lyricsContainer.textContent);
}
prevButton.addEventListener('click', () => console.log('上一首'));
nextButton.addEventListener('click', () => console.log('下一首'));
shuffleButton.addEventListener('click', () => console.log('随机播放'));
repeatButton.addEventListener('click', () => console.log('重复播放'));
document.addEventListener('DOMContentLoaded', () => {initializeControls();initWaveSurfer();
});const coverLyricsContainer = document.getElementById('cover-lyrics-container');
const lyricsInput = document.getElementById('lyrics-input');
let showingLyrics = false;coverLyricsContainer.addEventListener('click', toggleLyrics);function toggleLyrics() {showingLyrics = !showingLyrics;albumCover.style.display = showingLyrics ? 'none' : 'block';lyricsContainer.style.display = showingLyrics ? 'flex' : 'none';console.log('Lyrics toggled:', showingLyrics);
}lyricsInput.addEventListener('change', (e) => {const file = e.target.files[0];if (file) {const reader = new FileReader();reader.onload = function(e) {const cueContent = e.target.result;const lyrics = parseCueFile(cueContent);updateLyricsDisplay(lyrics);};reader.readAsText(file);}
});function parseCueFile(cueContent) {const lines = cueContent.split('\n');const lyrics = [];let currentTime = 0;for (let line of lines) {if (line.startsWith(' TRACK')) {currentTime = 0;} else if (line.startsWith(' INDEX 01')) {const timeStr = line.split('INDEX 01')[1].trim();const [min, sec, frame] = timeStr.split(':').map(Number);currentTime = min * 60 + sec + frame / 75;} else if (line.startsWith(' TITLE')) {const lyric = line.split('TITLE')[1].trim().replace(/"/g, '');lyrics.push({ time: currentTime, text: lyric });}}return lyrics;
}function updateLyricsDisplay(lyrics) {lyricsContainer.innerHTML = '';for (let lyric of lyrics) {const p = document.createElement('p');p.textContent = lyric.text;lyricsContainer.appendChild(p);}
}
const fileInputContainer = document.getElementById('file-input-container');
let isDragging = false;
let startX, startY, initialLeft, initialTop;fileInputContainer.addEventListener('mousedown', startDragging);
document.addEventListener('mousemove', drag);
document.addEventListener('mouseup', stopDragging);function startDragging(e) {isDragging = true;startX = e.clientX;startY = e.clientY;initialLeft = fileInputContainer.offsetLeft;initialTop = fileInputContainer.offsetTop;
}function drag(e) {if (!isDragging) return;e.preventDefault();const dx = e.clientX - startX;const dy = e.clientY - startY;fileInputContainer.style.left = `${initialLeft + dx}px`;fileInputContainer.style.top = `${initialTop + dy}px`;
}function stopDragging() {isDragging = false;
}
body {margin: 0;display: flex;justify-content: center;align-items: center;height: 100vh;background: linear-gradient(45deg, #1a1a1a, #2a2a2a);font-family: 'Poppins', sans-serif;color: white;
}#player {position: relative;width: 340px;height: 600px;background-color: rgba(255, 255, 255, 0.1);border-radius: 30px;overflow: hidden;box-shadow: 0 10px 30px rgba(0,0,0,0.3);transition: all 0.3s ease;padding: 20px;display: flex;flex-direction: column;justify-content: space-between;z-index: 1;
}#album-cover {width: 220px;height: 220px;border-radius: 50%;margin: 20px auto;display: block;box-shadow: 0 10px 30px rgba(0,0,0,0.3);animation: rotate 20s linear infinite;transition: all 0.3s ease;
}#info-container {text-align: center;margin-bottom: 15px;
}#song-title {font-size: 22px;margin: 0;font-weight: 600;text-shadow: 0 2px 4px rgba(0,0,0,0.3);
}#artist-name {font-size: 16px;margin: 5px 0 0;opacity: 0.8;
}#lyrics {height: 40px;overflow-y: auto;margin: 10px 0;text-align: center;font-size: 14px;opacity: 0.9;
}#progress-container {position: relative;width: 100%;height: 40px;background-color: rgba(255,255,255,0.1);margin: 10px 0;border-radius: 20px;overflow: hidden;cursor: pointer;
}#time-info {display: flex;justify-content: space-between;width: 100%;margin: 5px 0;font-size: 12px;opacity: 0.8;
}#controls {display: flex;justify-content: space-between;align-items: center;margin-top: 15px;
}.control-btn {background: none;border: none;color: white;font-size: 20px;cursor: pointer;transition: all 0.2s;opacity: 0.8;
}.main-btn {font-size: 40px;opacity: 1;
}#file-input-container {position: absolute;bottom: 20px;right: 20px;z-index: 10;cursor: move;display: flex;flex-direction: column;align-items: center;
}#file-input {display: none;
}.file-input-label, .lyrics-input-label {width: 40px;height: 40px;font-size: 18px;display: flex;justify-content: center;align-items: center;background-color: rgba(128, 128, 128, 0.8); color: white;border-radius: 50%;cursor: pointer;transition: all 0.2s;box-shadow: 0 2px 5px rgba(0,0,0,0.2);margin-bottom: 10px;
}.file-input-label:hover, .lyrics-input-label:hover {background-color: rgba(160, 160, 160, 0.9); transform: scale(1.1);box-shadow: 0 4px 8px rgba(0,0,0,0.3);
}
.file-input-label::after, .lyrics-input-label::after {content: none;
}.file-input-label:hover::after, .lyrics-input-label:hover::after {opacity: 1;
}#particle-container, #blur-overlay, #visualizer {position: absolute;top: 0;left: 0;width: 100%;height: 100%;
}#blur-overlay {backdrop-filter: blur(5px);z-index: 1;
}#visualizer {z-index: 2;
}#album-cover:hover {transform: scale(1.05);box-shadow: 0 15px 35px rgba(0,0,0,0.4);
}@keyframes rotate {from { transform: rotate(0deg); }to { transform: rotate(360deg); }
}#progress-bar {position: absolute;top: 0;left: 0;height: 100%;background-color: rgba(29, 185, 84, 0.5);z-index: 3;transition: width 0.1s linear;
}#time-info {display: flex;justify-content: space-between;width: 100%;margin: 5px 0;font-size: 12px;opacity: 0.8;
}#controls {display: flex;justify-content: space-between;align-items: center;margin-top: 15px;
}.control-btn:hover {transform: scale(1.2);opacity: 1;
}.main-btn {font-size: 40px;opacity: 1;
}#file-input-container {position: absolute;bottom: 20px;right: 20px;z-index: 10;
}#file-input {display: none;
}.file-input-label {width: 40px;height: 40px;font-size: 18px;
}#cover-lyrics-container {position: relative;width: 220px;height: 220px;margin: 20px auto;cursor: pointer;
}#album-cover, #lyrics {position: absolute;top: 0;left: 0;width: 100%;height: 100%;border-radius: 50%;transition: all 0.3s ease;
}#lyrics {background-color: rgba(0, 0, 0, 0.7);color: white;display: flex;align-items: center;justify-content: center;text-align: center;padding: 10px;overflow-y: auto;font-size: 14px;
}.lyrics-input-label {width: 40px;height: 40px;font-size: 18px;display: flex;justify-content: center;align-items: center;background-color: rgba(29, 185, 84, 0.8);color: white;border-radius: 50%;cursor: pointer;transition: all 0.2s;box-shadow: 0 2px 5px rgba(0,0,0,0.2);margin-top: 10px;
}.lyrics-input-label:hover {background-color: rgba(30, 215, 96, 0.9);transform: scale(1.1);box-shadow: 0 4px 8px rgba(0,0,0,0.3);
}#particles-js {position: fixed;top: 0;left: 0;width: 100%;height: 100%;z-index: -1;
}