Files
vue-pult/server/music-player.backup.js
sasha 3e90269b0b Initial commit: Vue.js тир управления система
- Клиентская часть Vue 3 + Vite
- Серверная часть Node.js + WebSocket
- Система авторизации и смен
- Управление игровыми портами
- Поддержка тем (светлая/темная)
- Адаптивный дизайн

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-09-19 12:24:22 +03:00

249 lines
10 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Универсальный музыкальный плеер для фоновой музыки
const { spawn } = require('child_process');
const fs = require('fs');
const os = require('os');
const path = require('path');
class MusicPlayer {
constructor() {
this.process = null;
this.isPlaying = false;
this.isPaused = false;
this.currentTrack = null;
this.volume = 70; // Громкость от 0 до 100
this.duckedVolume = 20; // Приглушенная громкость во время баркера
this.isDucked = false;
this.repeatMode = false;
this.onTrackEnd = null;
this.platform = os.platform();
console.log('[MUSIC] Музыкальный плеер инициализирован для платформы:', this.platform);
}
// Получение списка музыкальных файлов
getAvailableTracks() {
const musicDir = path.resolve('./music/background');
console.log('[MUSIC] Проверяем папку с музыкой:', musicDir);
if (!fs.existsSync(musicDir)) {
console.log('[MUSIC] Папка с музыкой не найдена:', musicDir);
return [];
}
try {
const files = fs.readdirSync(musicDir);
console.log('[MUSIC] Все файлы в папке:', files);
const musicFiles = files.filter(file =>
file.endsWith('.mp3') || file.endsWith('.wav') || file.endsWith('.ogg')
);
console.log('[MUSIC] Музыкальные файлы:', musicFiles);
const tracks = musicFiles.map(file => ({
id: path.parse(file).name,
name: path.parse(file).name,
path: path.join(musicDir, file)
}));
console.log('[MUSIC] Готовый список треков:', tracks);
return tracks;
} catch (error) {
console.error('[MUSIC] Ошибка чтения папки с музыкой:', error);
return [];
}
}
// Остановка текущего воспроизведения
stop() {
if (this.process && this.isPlaying) {
console.log('[MUSIC] Останавливаем воспроизведение музыки');
this.process.kill('SIGTERM');
this.process = null;
}
this.isPlaying = false;
this.isPaused = false;
this.currentTrack = null;
this.isDucked = false;
return this;
}
// Воспроизведение трека
play(trackPath, onStart = null, onEnd = null) {
console.log('[MUSIC] 🎵 Запуск воспроизведения:', trackPath);
console.log('[MUSIC] 📊 Текущее состояние перед запуском:', {
isPlaying: this.isPlaying,
currentTrack: this.currentTrack,
volume: this.volume,
repeatMode: this.repeatMode
});
// Останавливаем предыдущее воспроизведение
this.stop();
console.log('[MUSIC] ⏹️ Предыдущее воспроизведение остановлено');
// Проверяем существование файла
if (!fs.existsSync(trackPath)) {
console.error('[MUSIC] ❌ Файл не найден:', trackPath);
return this;
}
console.log('[MUSIC] ✅ Файл найден, размер:', fs.statSync(trackPath).size, 'байт');
this.currentTrack = trackPath;
this.onTrackEnd = onEnd;
// Запускаем воспроизведение
console.log('[MUSIC] 🚀 Вызываем _startPlayback');
this._startPlayback(trackPath, onStart, onEnd);
return this;
}
// Внутренний метод запуска воспроизведения
_startPlayback(trackPath, onStart, onEnd) {
console.log('[MUSIC] 🎛️ _startPlayback вызван для:', trackPath);
console.log('[MUSIC] 🖥️ Платформа:', this.platform);
let command, args;
const currentVolume = this.isDucked ? this.duckedVolume : this.volume;
console.log('[MUSIC] 🔊 Громкость:', currentVolume);
// Выбираем команду в зависимости от ОС
if (this.platform === 'linux') {
// Используем mpg123 для MP3 или aplay для WAV
if (trackPath.endsWith('.mp3')) {
command = 'mpg123';
args = ['-g', Math.floor(currentVolume / 10), trackPath]; // mpg123 использует gain от 0 до 10
} else {
command = 'aplay';
args = [trackPath];
}
} else if (this.platform === 'win32') {
// Для Windows используем PowerShell MediaPlayer
command = 'powershell';
const escapedPath = trackPath.replace(/\\/g, '\\\\').replace(/"/g, '""');
args = ['-c', `
Add-Type -AssemblyName presentationCore;
$mediaPlayer = New-Object system.windows.media.mediaplayer;
$mediaPlayer.open('${escapedPath}');
$mediaPlayer.Volume = ${currentVolume / 100};
$mediaPlayer.Play();
while($mediaPlayer.Position -lt $mediaPlayer.NaturalDuration) {
Start-Sleep -Milliseconds 100;
}
`];
} else if (this.platform === 'darwin') {
// Для macOS используем afplay
command = 'afplay';
args = ['-v', currentVolume / 100, trackPath];
} else {
console.error('[MUSIC] Неподдерживаемая ОС:', this.platform);
return;
}
console.log('[MUSIC] 🚀 Выполняем команду:', command);
console.log('[MUSIC] 📝 Аргументы (первые 2):', args.slice(0, 2));
// Запускаем процесс
console.log('[MUSIC] 🎯 Вызываем spawn...');
this.process = spawn(command, args);
console.log('[MUSIC] ✅ Процесс запущен, PID:', this.process.pid);
this.isPlaying = true;
this.isPaused = false;
if (onStart) onStart();
this.process.on('close', (code) => {
console.log('[MUSIC] Воспроизведение завершено:', trackPath, ', код:', code);
if (this.isPlaying && this.repeatMode && this.currentTrack) {
// Повторное воспроизведение
console.log('[MUSIC] Повторное воспроизведение трека');
setTimeout(() => {
if (this.repeatMode && this.currentTrack) {
this._startPlayback(this.currentTrack, null, this.onTrackEnd);
}
}, 1000);
} else {
this.isPlaying = false;
this.currentTrack = null;
if (onEnd) onEnd();
}
});
this.process.on('error', (error) => {
console.error('[MUSIC] Ошибка процесса:', error.message);
this.isPlaying = false;
this.currentTrack = null;
});
}
// Установка громкости
setVolume(volume) {
this.volume = Math.max(0, Math.min(100, volume));
console.log('[MUSIC] Установлена громкость:', this.volume);
// Если музыка играет, перезапускаем с новой громкостью
if (this.isPlaying && this.currentTrack) {
const currentTrack = this.currentTrack;
this.stop();
this._startPlayback(currentTrack, null, this.onTrackEnd);
}
return this;
}
// Приглушение звука (во время баркера)
duck() {
if (!this.isDucked && this.isPlaying) {
console.log('[MUSIC] Приглушаем музыку для баркера');
this.isDucked = true;
if (this.currentTrack) {
const currentTrack = this.currentTrack;
this.stop();
this._startPlayback(currentTrack, null, this.onTrackEnd);
}
}
return this;
}
// Восстановление звука (после баркера)
unduck() {
if (this.isDucked && this.isPlaying) {
console.log('[MUSIC] Восстанавливаем громкость музыки');
this.isDucked = false;
if (this.currentTrack) {
const currentTrack = this.currentTrack;
this.stop();
this._startPlayback(currentTrack, null, this.onTrackEnd);
}
}
return this;
}
// Включение/отключение повтора
setRepeat(repeat) {
console.log('[MUSIC] setRepeat вызван с параметром:', repeat, 'тип:', typeof repeat);
console.log('[MUSIC] Текущий режим повтора до изменения:', this.repeatMode);
this.repeatMode = Boolean(repeat);
console.log('[MUSIC] Режим повтора установлен на:', this.repeatMode ? 'включен' : 'отключен');
return this;
}
// Получение состояния плеера
getStatus() {
return {
isPlaying: this.isPlaying,
isPaused: this.isPaused,
currentTrack: this.currentTrack ? path.basename(this.currentTrack) : null,
volume: this.volume,
repeatMode: this.repeatMode,
isDucked: this.isDucked
};
}
}
module.exports = MusicPlayer;