161 lines
4.1 KiB
JavaScript
161 lines
4.1 KiB
JavaScript
// Music playlist manager
|
|
(function() {
|
|
'use strict';
|
|
|
|
const MUSIC_FOLDER = 'music/';
|
|
const PLAYLIST = [
|
|
'Knights Of The Old Republic II - The Sith Lords — The Temple of Freedon Nadd (www.lightaudio.ru).mp3',
|
|
'Soundtrack — StarWars (www.lightaudio.ru) (1).mp3',
|
|
'Soundtrack — Starwars (www.lightaudio.ru).mp3',
|
|
'StarWars — Across The Stars Love Theme (www.lightaudio.ru).mp3'
|
|
];
|
|
|
|
let currentAudio = null;
|
|
let currentTrackIndex = -1;
|
|
let playedTracks = [];
|
|
let volume = 0.5;
|
|
let isPlaying = false;
|
|
let isEnabled = true;
|
|
|
|
function getRandomTrack() {
|
|
if (playedTracks.length >= PLAYLIST.length) {
|
|
playedTracks = [];
|
|
}
|
|
let available = PLAYLIST.filter((_, i) => !playedTracks.includes(i));
|
|
if (available.length === 0) {
|
|
playedTracks = [];
|
|
available = PLAYLIST;
|
|
}
|
|
const randomIndex = Math.floor(Math.random() * available.length);
|
|
const trackName = available[randomIndex];
|
|
const trackIndex = PLAYLIST.indexOf(trackName);
|
|
playedTracks.push(trackIndex);
|
|
return { trackName, trackIndex };
|
|
}
|
|
|
|
function loadTrack(trackName) {
|
|
return new Promise((resolve, reject) => {
|
|
const audio = new Audio(MUSIC_FOLDER + trackName);
|
|
audio.volume = volume;
|
|
audio.addEventListener('loadeddata', () => resolve(audio));
|
|
audio.addEventListener('error', (e) => reject(e));
|
|
audio.load();
|
|
});
|
|
}
|
|
|
|
function playNext() {
|
|
if (!isEnabled) return;
|
|
|
|
if (currentAudio) {
|
|
currentAudio.pause();
|
|
currentAudio = null;
|
|
}
|
|
|
|
const { trackName, trackIndex } = getRandomTrack();
|
|
currentTrackIndex = trackIndex;
|
|
|
|
loadTrack(trackName)
|
|
.then((audio) => {
|
|
currentAudio = audio;
|
|
currentAudio.volume = volume;
|
|
currentAudio.addEventListener('ended', () => {
|
|
playNext();
|
|
});
|
|
currentAudio.addEventListener('error', () => {
|
|
console.warn('Failed to load track:', trackName);
|
|
playNext();
|
|
});
|
|
currentAudio.play().catch((e) => {
|
|
console.warn('Failed to play track:', e);
|
|
});
|
|
isPlaying = true;
|
|
updateUI();
|
|
})
|
|
.catch((e) => {
|
|
console.warn('Failed to load track:', trackName, e);
|
|
playNext();
|
|
});
|
|
}
|
|
|
|
function stop() {
|
|
if (currentAudio) {
|
|
currentAudio.pause();
|
|
currentAudio = null;
|
|
}
|
|
isPlaying = false;
|
|
updateUI();
|
|
}
|
|
|
|
function setVolume(newVolume) {
|
|
volume = Math.max(0, Math.min(1, newVolume));
|
|
if (currentAudio) {
|
|
currentAudio.volume = volume;
|
|
}
|
|
localStorage.setItem('musicVolume', volume.toString());
|
|
updateUI();
|
|
}
|
|
|
|
function toggle() {
|
|
isEnabled = !isEnabled;
|
|
localStorage.setItem('musicEnabled', isEnabled.toString());
|
|
if (isEnabled && !isPlaying) {
|
|
playNext();
|
|
} else if (!isEnabled) {
|
|
stop();
|
|
}
|
|
updateUI();
|
|
}
|
|
|
|
function updateUI() {
|
|
const volumeSlider = document.getElementById('music-volume-slider');
|
|
const volumeValue = document.getElementById('music-volume-value');
|
|
const musicToggle = document.getElementById('music-toggle');
|
|
|
|
if (volumeSlider) {
|
|
volumeSlider.value = volume;
|
|
}
|
|
if (volumeValue) {
|
|
volumeValue.textContent = Math.round(volume * 100) + '%';
|
|
}
|
|
if (musicToggle) {
|
|
musicToggle.textContent = isEnabled ? 'Выключить' : 'Включить';
|
|
musicToggle.classList.toggle('active', isEnabled);
|
|
}
|
|
}
|
|
|
|
function init() {
|
|
const savedVolume = localStorage.getItem('musicVolume');
|
|
if (savedVolume !== null) {
|
|
volume = parseFloat(savedVolume);
|
|
} else {
|
|
volume = 0.5;
|
|
}
|
|
|
|
const savedEnabled = localStorage.getItem('musicEnabled');
|
|
if (savedEnabled !== null) {
|
|
isEnabled = savedEnabled === 'true';
|
|
} else {
|
|
isEnabled = true;
|
|
}
|
|
|
|
updateUI();
|
|
|
|
if (isEnabled) {
|
|
setTimeout(() => {
|
|
playNext();
|
|
}, 500);
|
|
}
|
|
}
|
|
|
|
window.Music = {
|
|
play: playNext,
|
|
stop: stop,
|
|
setVolume: setVolume,
|
|
toggle: toggle,
|
|
getVolume: () => volume,
|
|
isEnabled: () => isEnabled,
|
|
isPlaying: () => isPlaying,
|
|
init: init
|
|
};
|
|
})();
|