// ==UserScript==
// @name Drawaria - Music Player PRO (Fixed)
// @namespace http://violentmonkey.com/
// @version 6.6
// @description Мод-меню для прослушивания музыки
// @match *://drawaria.com/*
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// Стили
const style = document.createElement('style');
style.textContent = `
#music-mod {
position: fixed;
top: 20px;
right: 20px;
width: 320px;
max-height: 80vh;
background: rgba(10, 15, 25, 0.95);
border: 1px solid #1e3a5a;
border-radius: 12px;
padding: 0;
z-index: 9999;
color: white;
font-family: 'Segoe UI', sans-serif;
box-shadow: 0 10px 25px rgba(0, 50, 100, 0.5);
backdrop-filter: blur(8px);
overflow: hidden;
transition: all 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28);
}
#music-mod-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px;
background: linear-gradient(to right, #0a1a2a, #0d2b40);
cursor: move;
user-select: none;
}
#music-mod-title {
margin: 0;
color: #00e1ff;
font-size: 18px;
font-weight: 600;
text-shadow: 0 0 10px rgba(0, 225, 255, 0.5);
}
#music-mod-controls {
display: flex;
gap: 8px;
}
.mod-btn-control {
width: 24px;
height: 24px;
border: none;
border-radius: 6px;
background: rgba(0, 150, 255, 0.2);
color: #00e1ff;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.2s;
}
.mod-btn-control:hover {
background: rgba(0, 180, 255, 0.4);
transform: scale(1.1);
}
#music-mod-content {
padding: 15px;
overflow-y: auto;
max-height: calc(80vh - 60px);
}
.mod-btn {
width: 100%;
padding: 12px 15px;
margin: 8px 0;
border: none;
border-radius: 8px;
background: linear-gradient(135deg, #0d2b40, #003366);
color: white;
font-weight: 500;
font-size: 14px;
cursor: pointer;
transition: all 0.3s;
position: relative;
overflow: hidden;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
}
.mod-btn::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(135deg, rgba(0, 200, 255, 0.3), transparent);
opacity: 0;
transition: opacity 0.3s;
}
.mod-btn:hover {
background: linear-gradient(135deg, #0e3a5a, #004488);
box-shadow: 0 6px 10px rgba(0, 100, 200, 0.3);
transform: translateY(-2px);
}
.mod-btn:hover::before {
opacity: 1;
}
.mod-btn:active {
transform: translateY(0);
}
.mod-btn i {
font-size: 16px;
}
.mod-section {
margin: 15px 0;
padding: 15px;
background: rgba(5, 15, 25, 0.5);
border-radius: 10px;
border: 1px solid #1a3a5a;
}
.mod-section-title {
margin: 0 0 12px 0;
color: #00a8ff;
font-size: 14px;
font-weight: 500;
display: flex;
align-items: center;
gap: 8px;
}
#music-mod-content::-webkit-scrollbar {
width: 6px;
}
#music-mod-content::-webkit-scrollbar-track {
background: rgba(10, 20, 30, 0.3);
border-radius: 3px;
}
#music-mod-content::-webkit-scrollbar-thumb {
background: linear-gradient(#00a8ff, #0088ff);
border-radius: 3px;
}
@keyframes pulse {
0% { box-shadow: 0 0 0 0 rgba(0, 200, 255, 0.4); }
70% { box-shadow: 0 0 0 12px rgba(0, 200, 255, 0); }
100% { box-shadow: 0 0 0 0 rgba(0, 200, 255, 0); }
}
.playing {
animation: pulse 2s infinite;
}
select, input[type="text"], input[type="range"] {
width: 100%;
padding: 8px;
margin: 5px 0;
background: rgba(0, 20, 40, 0.7);
border: 1px solid #1a3a5a;
border-radius: 6px;
color: white;
}
input[type="range"] {
padding: 0;
height: 6px;
-webkit-appearance: none;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 16px;
height: 16px;
background: #00e1ff;
border-radius: 50%;
cursor: pointer;
box-shadow: 0 0 5px rgba(0, 225, 255, 0.5);
}
`;
document.head.appendChild(style);
// HTML структура
const mod = document.createElement('div');
mod.id = 'music-mod';
mod.innerHTML = `
<div id="music-mod-header">
<h3 id="music-mod-title">MUSIC PLAYER PRO</h3>
<div id="music-mod-controls">
<button id="collapse-btn" class="mod-btn-control">−</button>
<button id="close-btn" class="mod-btn-control">×</button>
</div>
</div>
<div id="music-mod-content">
<div class="mod-section">
<div class="mod-section-title">🎵 УПРАВЛЕНИЕ МУЗЫКОЙ</div>
<button id="add-music-btn" class="mod-btn"><i>🎵</i> ДОБАВИТЬ ТРЕКИ</button>
<input type="file" id="file-input" accept=".mp3,audio/*" multiple style="display:none">
<select id="song-list" size="4"></select>
<div style="display:flex; gap:8px; margin-top:10px;">
<button id="play-btn" class="mod-btn" style="flex:1;"><i>▶️</i> ИГРАТЬ</button>
<button id="stop-btn" class="mod-btn" style="flex:1;"><i>⏹</i> СТОП</button>
</div>
<div style="display:flex; gap:8px;">
<button id="prev-btn" class="mod-btn" style="flex:1;"><i>⏮</i> НАЗАД</button>
<button id="next-btn" class="mod-btn" style="flex:1;"><i>⏭</i> ВПЕРЕД</button>
</div>
</div>
<div class="mod-section">
<div class="mod-section-title">⚙️ НАСТРОЙКИ</div>
<div style="margin:12px 0;">
<div style="display:flex; justify-content:space-between; margin-bottom:5px;">
<span style="color:#88ccff;">СКОРОСТЬ:</span>
<span id="speed-value" style="color:#00e1ff;">1.0x</span>
</div>
<input type="range" id="speed-slider" min="0.5" max="2" step="0.1" value="1">
</div>
<div style="margin:12px 0;">
<div style="display:flex; justify-content:space-between; margin-bottom:5px;">
<span style="color:#88ccff;">ГРОМКОСТЬ:</span>
<span id="volume-value" style="color:#00e1ff;">70%</span>
</div>
<input type="range" id="volume-slider" min="0" max="1" step="0.1" value="0.7">
</div>
<div style="display:flex; gap:8px;">
<button id="loop-btn" class="mod-btn" style="flex:1;"><i>🔁</i> ПОВТОР</button>
<button id="shuffle-btn" class="mod-btn" style="flex:1;"><i>🔀</i> МИКС</button>
</div>
</div>
<div class="mod-section">
<div class="mod-section-title">💾 УПРАВЛЕНИЕ ПЛЕЙЛИСТАМИ</div>
<input type="text" id="playlist-name" placeholder="Имя плейлиста">
<button id="save-playlist-btn" class="mod-btn"><i>💾</i> СОХРАНИТЬ</button>
<select id="playlist-select"></select>
<div style="display:flex; gap:8px;">
<button id="load-playlist-btn" class="mod-btn" style="flex:1;"><i>📂</i> ЗАГРУЗИТЬ</button>
<button id="delete-playlist-btn" class="mod-btn" style="flex:1;"><i>🗑️</i> УДАЛИТЬ</button>
</div>
</div>
</div>
`;
document.body.appendChild(mod);
// Инициализация плеера
const audio = new Audio();
let songs = [];
let currentSongIndex = 0;
let isPlaying = false;
let loopMode = true;
let isShuffled = false;
let originalPlaylist = [];
// Получаем все элементы
const modElement = document.getElementById('music-mod');
const header = document.getElementById('music-mod-header');
const content = document.getElementById('music-mod-content');
const collapseBtn = document.getElementById('collapse-btn');
const closeBtn = document.getElementById('close-btn');
const addBtn = document.getElementById('add-music-btn');
const fileInput = document.getElementById('file-input');
const songList = document.getElementById('song-list');
const playBtn = document.getElementById('play-btn');
const stopBtn = document.getElementById('stop-btn');
const prevBtn = document.getElementById('prev-btn');
const nextBtn = document.getElementById('next-btn');
const loopBtn = document.getElementById('loop-btn');
const shuffleBtn = document.getElementById('shuffle-btn');
const speedSlider = document.getElementById('speed-slider');
const volumeSlider = document.getElementById('volume-slider');
const playlistNameInput = document.getElementById('playlist-name');
const savePlaylistBtn = document.getElementById('save-playlist-btn');
const playlistSelect = document.getElementById('playlist-select');
const loadPlaylistBtn = document.getElementById('load-playlist-btn');
const deletePlaylistBtn = document.getElementById('delete-playlist-btn');
// Ключ для хранения плейлистов
const PLAYLIST_STORAGE_KEY = "music_player_playlists";
// Функция сохранения плейлиста
function savePlaylist() {
const name = playlistNameInput.value.trim();
if (!name) {
alert("Пожалуйста, введите название плейлиста!");
return;
}
// Получаем текущий список плейлистов
const playlists = JSON.parse(localStorage.getItem(PLAYLIST_STORAGE_KEY) || "{}");
// Сохраняем плейлист
playlists[name] = {
songs: songs.map(song => ({
name: song.name,
url: song.url
})),
currentIndex: currentSongIndex
};
localStorage.setItem(PLAYLIST_STORAGE_KEY, JSON.stringify(playlists));
updatePlaylists();
alert(`Плейлист "${name}" успешно сохранен!`);
playlistNameInput.value = '';
}
// Функция загрузки плейлиста
function loadPlaylist() {
const name = playlistSelect.value;
if (!name) return;
const playlists = JSON.parse(localStorage.getItem(PLAYLIST_STORAGE_KEY) || "{}");
const playlist = playlists[name];
if (playlist) {
songs = playlist.songs;
currentSongIndex = playlist.currentIndex || 0;
updateSongList();
alert(`Плейлист "${name}" загружен!`);
} else {
alert("Плейлист не найден!");
}
}
// Функция удаления плейлиста
function deletePlaylist() {
const name = playlistSelect.value;
if (!name) return;
if (confirm(`Вы уверены, что хотите удалить плейлист "${name}"?`)) {
const playlists = JSON.parse(localStorage.getItem(PLAYLIST_STORAGE_KEY) || "{}");
delete playlists[name];
localStorage.setItem(PLAYLIST_STORAGE_KEY, JSON.stringify(playlists));
updatePlaylists();
alert(`Плейлист "${name}" удален!`);
}
}
// Обновление списка плейлистов в выпадающем меню
function updatePlaylists() {
const playlists = JSON.parse(localStorage.getItem(PLAYLIST_STORAGE_KEY) || "{}");
const playlistNames = Object.keys(playlists);
// Очищаем список
playlistSelect.innerHTML = '';
if (playlistNames.length === 0) {
const option = document.createElement('option');
option.textContent = "Нет сохраненных плейлистов";
playlistSelect.appendChild(option);
} else {
playlistNames.forEach(name => {
const option = document.createElement('option');
option.value = name;
option.textContent = name;
playlistSelect.appendChild(option);
});
}
}
// Назначаем обработчики для кнопок плейлистов
savePlaylistBtn.addEventListener('click', savePlaylist);
loadPlaylistBtn.addEventListener('click', loadPlaylist);
deletePlaylistBtn.addEventListener('click', deletePlaylist);
// Функции плеера
function playMusic() {
if (songs.length === 0) {
alert("Добавьте музыку сначала!");
return;
}
const song = songs[currentSongIndex];
audio.src = song.url;
audio.play()
.then(() => {
isPlaying = true;
playBtn.innerHTML = '<i>⏸</i> ПАУЗА';
playBtn.classList.add('playing');
})
.catch(err => alert("Ошибка воспроизведения: " + err.message));
}
function stopMusic() {
audio.pause();
audio.currentTime = 0;
isPlaying = false;
playBtn.innerHTML = '<i>▶️</i> ИГРАТЬ';
playBtn.classList.remove('playing');
}
function playNext() {
if (songs.length === 0) return;
currentSongIndex = (currentSongIndex + 1) % songs.length;
songList.selectedIndex = currentSongIndex;
if (isPlaying) playMusic();
}
function playPrev() {
if (songs.length === 0) return;
currentSongIndex = (currentSongIndex - 1 + songs.length) % songs.length;
songList.selectedIndex = currentSongIndex;
if (isPlaying) playMusic();
}
function toggleLoop() {
loopMode = !loopMode;
audio.loop = loopMode;
loopBtn.innerHTML = loopMode ? '<i>🔁</i> ПОВТОР' : '<i>🔂</i> ОДНА';
loopBtn.style.background = loopMode
? 'linear-gradient(135deg, #0d2b40, #003366)'
: 'linear-gradient(135deg, #0d3b40, #005566)';
}
function toggleShuffle() {
isShuffled = !isShuffled;
if (isShuffled) {
originalPlaylist = [...songs];
const currentSong = songs[currentSongIndex];
songs = songs.filter((_, i) => i !== currentSongIndex);
// Перемешиваем
for (let i = songs.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[songs[i], songs[j]] = [songs[j], songs[i]];
}
songs.unshift(currentSong);
currentSongIndex = 0;
} else {
if (originalPlaylist.length > 0) {
currentSongIndex = originalPlaylist.findIndex(
song => song.url === songs[currentSongIndex].url
);
songs = [...originalPlaylist];
}
}
shuffleBtn.innerHTML = isShuffled ? '<i>🔀</i> ОБЫЧНЫЙ' : '<i>🔀</i> МИКС';
shuffleBtn.style.background = isShuffled
? 'linear-gradient(135deg, #0d3b40, #005566)'
: 'linear-gradient(135deg, #0d2b40, #003366)';
updateSongList();
}
function updateSongList() {
songList.innerHTML = songs.map((song, i) =>
`<option value="${i}" ${i === currentSongIndex ? 'selected' : ''}>${song.name}</option>`
).join('');
}
// Обработчики кнопок плеера
playBtn.addEventListener('click', () => {
if (isPlaying) {
audio.pause();
isPlaying = false;
playBtn.innerHTML = '<i>▶️</i> ИГРАТЬ';
playBtn.classList.remove('playing');
} else {
playMusic();
}
});
stopBtn.addEventListener('click', stopMusic);
nextBtn.addEventListener('click', playNext);
prevBtn.addEventListener('click', playPrev);
loopBtn.addEventListener('click', toggleLoop);
shuffleBtn.addEventListener('click', toggleShuffle);
// Добавление музыки
addBtn.addEventListener('click', () => fileInput.click());
fileInput.addEventListener('change', (e) => {
const files = Array.from(e.target.files);
files.forEach(file => {
if (file.type.startsWith('audio/')) {
songs.push({
name: file.name.replace('.mp3', ''),
url: URL.createObjectURL(file),
file: file
});
}
});
updateSongList();
});
songList.addEventListener('change', (e) => {
currentSongIndex = e.target.selectedIndex;
if (isPlaying) playMusic();
});
// Настройки звука
speedSlider.addEventListener('input', () => {
audio.playbackRate = speedSlider.value;
document.getElementById('speed-value').textContent = `${speedSlider.value}x`;
});
volumeSlider.addEventListener('input', () => {
audio.volume = volumeSlider.value;
document.getElementById('volume-value').textContent = `${Math.round(volumeSlider.value * 100)}%`;
});
// Управление окном
let isDragging = false;
let offsetX, offsetY;
header.addEventListener('mousedown', (e) => {
if (e.target.classList.contains('mod-btn-control')) return;
isDragging = true;
const rect = modElement.getBoundingClientRect();
offsetX = e.clientX - rect.left;
offsetY = e.clientY - rect.top;
modElement.style.transition = 'none';
e.preventDefault();
});
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
modElement.style.left = `${e.clientX - offsetX}px`;
modElement.style.top = `${e.clientY - offsetY}px`;
});
document.addEventListener('mouseup', () => {
isDragging = false;
modElement.style.transition = 'all 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28)';
});
let isCollapsed = false;
collapseBtn.addEventListener('click', () => {
isCollapsed = !isCollapsed;
content.style.display = isCollapsed ? 'none' : 'block';
collapseBtn.textContent = isCollapsed ? '+' : '−';
});
closeBtn.addEventListener('click', () => {
modElement.style.transform = 'scale(0.8)';
modElement.style.opacity = '0';
setTimeout(() => modElement.remove(), 300);
});
// Обработка окончания трека
audio.addEventListener('ended', () => {
if (loopMode) {
audio.currentTime = 0;
audio.play();
} else {
playNext();
}
});
// Инициализация
audio.volume = volumeSlider.value;
audio.playbackRate = speedSlider.value;
updatePlaylists();
updateSongList();
})();