Files
vue-pult/server/enhanced-music-player.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

257 lines
10 KiB
JavaScript
Raw Permalink 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 path = require('path');
class EnhancedMusicPlayer {
constructor() {
this.currentProcess = null;
this.currentTrack = null;
this.currentTrackIndex = -1;
this.isPlaying = false;
this.isPaused = false;
this.pausedPosition = 0; // Позиция в секундах где была пауза
this.startTime = null; // Время начала воспроизведения
this.volume = 70;
this.playlist = [];
// Для Windows - использование VLC или MPV для точной позиции
this.playerCommand = this._detectPlayer();
console.log('[ENHANCED-MUSIC] 🎵 Музыкальный плеер инициализирован');
console.log('[ENHANCED-MUSIC] 🎮 Используемый плеер:', this.playerCommand);
}
// Определение доступного плеера
_detectPlayer() {
if (process.platform === 'win32') {
// Проверяем наличие VLC
const vlcPath = 'C:\\Program Files\\VideoLAN\\VLC\\vlc.exe';
const vlcPath64 = 'C:\\Program Files (x86)\\VideoLAN\\VLC\\vlc.exe';
if (fs.existsSync(vlcPath) || fs.existsSync(vlcPath64)) {
return fs.existsSync(vlcPath) ? vlcPath : vlcPath64;
}
// Проверяем MPV
const mpvPath = path.join(__dirname, 'tools', 'mpv.exe');
if (fs.existsSync(mpvPath)) {
return mpvPath;
}
// Fallback на PowerShell
return 'powershell';
}
// Для Linux - mpv, vlc или mplayer
return 'mpv'; // или 'vlc', 'mplayer'
}
// Остановка воспроизведения
stop() {
console.log('[ENHANCED-MUSIC] ⏹️ Остановка воспроизведения');
if (this.currentProcess) {
try {
if (this.playerCommand.includes('vlc')) {
// VLC команда остановки
this.currentProcess.stdin.write('quit\n');
} else if (this.playerCommand.includes('mpv')) {
// MPV команда остановки
this.currentProcess.stdin.write('q');
} else {
// Обычное завершение процесса
this.currentProcess.kill();
}
} catch (err) {
console.log('[ENHANCED-MUSIC] ⚠️ Ошибка при остановке:', err.message);
}
this.currentProcess = null;
}
this.isPlaying = false;
this.isPaused = false;
this.pausedPosition = 0;
this.startTime = null;
this.currentTrack = null;
return this;
}
// Воспроизведение трека с позиции
play(trackPath, startPosition = 0) {
console.log('[ENHANCED-MUSIC] 🎵 Запуск воспроизведения:', trackPath, 'с позиции:', startPosition);
// Останавливаем текущее воспроизведение
this.stop();
if (!fs.existsSync(trackPath)) {
console.error('[ENHANCED-MUSIC] ❌ Файл не найден:', trackPath);
return this;
}
this.currentTrack = trackPath;
this.startTime = Date.now() - (startPosition * 1000);
let command, args;
if (this.playerCommand.includes('vlc')) {
// VLC с позицией воспроизведения
command = this.playerCommand;
args = [
'--intf', 'dummy',
'--play-and-exit',
'--no-video',
'--start-time', startPosition.toString(),
'--volume', Math.floor(this.volume * 2.56).toString(),
trackPath
];
} else if (this.playerCommand.includes('mpv')) {
// MPV с позицией воспроизведения
command = this.playerCommand;
args = [
'--no-video',
'--really-quiet',
'--start=' + startPosition,
'--volume=' + this.volume,
'--input-ipc-server=\\\\.\\pipe\\mpv-socket',
trackPath
];
} else {
// PowerShell fallback (без поддержки позиции)
console.log('[ENHANCED-MUSIC] ⚠️ PowerShell не поддерживает возобновление с позиции');
command = 'powershell';
args = ['-WindowStyle', 'Hidden', '-Command', `
Add-Type -AssemblyName presentationCore
$player = New-Object System.Windows.Media.MediaPlayer
$player.Open([Uri]"${trackPath}")
$player.Volume = ${this.volume / 100}
Start-Sleep -Milliseconds 500
$player.Play()
while ($player.Position -lt $player.NaturalDuration.TimeSpan) {
Start-Sleep -Milliseconds 100
}
$player.Close()
`];
}
// Запускаем процесс
this.currentProcess = spawn(command, args, {
stdio: ['pipe', 'pipe', 'pipe'],
windowsHide: true
});
this.isPlaying = true;
this.isPaused = false;
this.currentProcess.on('close', (code) => {
console.log('[ENHANCED-MUSIC] ⏹️ Воспроизведение завершено');
this.isPlaying = false;
this.currentProcess = null;
});
this.currentProcess.on('error', (error) => {
console.error('[ENHANCED-MUSIC] ❌ Ошибка процесса:', error.message);
this.isPlaying = false;
this.currentProcess = null;
});
return this;
}
// Пауза с сохранением позиции
pause() {
if (!this.isPlaying || this.isPaused) return this;
console.log('[ENHANCED-MUSIC] ⏸️ Пауза');
// Вычисляем текущую позицию
const elapsedTime = (Date.now() - this.startTime) / 1000;
this.pausedPosition = elapsedTime;
console.log('[ENHANCED-MUSIC] 💾 Сохранена позиция:', this.pausedPosition, 'сек');
// Останавливаем процесс
if (this.currentProcess) {
if (this.playerCommand.includes('vlc') || this.playerCommand.includes('mpv')) {
// Для VLC/MPV отправляем команду паузы
this.currentProcess.stdin.write('p');
} else {
// Для других - останавливаем процесс
this.currentProcess.kill();
this.currentProcess = null;
}
}
this.isPaused = true;
this.isPlaying = false;
return this;
}
// Возобновление с сохраненной позиции
resume() {
if (!this.isPaused || !this.currentTrack) return this;
console.log('[ENHANCED-MUSIC] ▶️ Возобновление с позиции:', this.pausedPosition, 'сек');
if (this.currentProcess && (this.playerCommand.includes('vlc') || this.playerCommand.includes('mpv'))) {
// Для VLC/MPV просто снимаем с паузы
this.currentProcess.stdin.write('p');
this.isPaused = false;
this.isPlaying = true;
} else {
// Для других - запускаем заново с позиции
const track = this.currentTrack;
const position = this.pausedPosition;
this.play(track, position);
}
return this;
}
// Установка громкости
setVolume(volume) {
this.volume = Math.max(0, Math.min(100, volume));
console.log('[ENHANCED-MUSIC] 🔊 Установлена громкость:', this.volume);
if (this.isPlaying && this.currentProcess) {
if (this.playerCommand.includes('vlc')) {
// VLC команда громкости (0-256)
const vlcVolume = Math.floor(this.volume * 2.56);
this.currentProcess.stdin.write(`volume ${vlcVolume}\n`);
} else if (this.playerCommand.includes('mpv')) {
// MPV команда громкости через JSON IPC
const mpvCommand = JSON.stringify({
command: ["set_property", "volume", this.volume]
});
this.currentProcess.stdin.write(mpvCommand + '\n');
}
}
return this;
}
// Получение информации о плеере
getPlayerInfo() {
if (this.playerCommand.includes('vlc')) {
return {
name: 'VLC Media Player',
features: ['позиция воспроизведения', 'управление громкостью', 'пауза без остановки']
};
} else if (this.playerCommand.includes('mpv')) {
return {
name: 'MPV Player',
features: ['позиция воспроизведения', 'управление громкостью', 'пауза без остановки']
};
} else {
return {
name: 'Windows Media (PowerShell)',
features: ['базовое воспроизведение'],
limitations: ['нет сохранения позиции', 'системная громкость']
};
}
}
}
module.exports = EnhancedMusicPlayer;