- Клиентская часть Vue 3 + Vite - Серверная часть Node.js + WebSocket - Система авторизации и смен - Управление игровыми портами - Поддержка тем (светлая/темная) - Адаптивный дизайн 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
162 lines
4.9 KiB
JavaScript
162 lines
4.9 KiB
JavaScript
// Windows Audio Player с управлением через stdin
|
||
const { spawn } = require('child_process');
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
class WindowsStdinAudio {
|
||
constructor() {
|
||
this.currentProcess = null;
|
||
this.currentFile = null;
|
||
this.isPlaying = false;
|
||
this.volume = 70;
|
||
this.playerReady = false;
|
||
}
|
||
|
||
play(filePath, startPosition = 0) {
|
||
this.stop();
|
||
|
||
if (!fs.existsSync(filePath)) {
|
||
console.error('[STDIN-AUDIO] Файл не найден:', filePath);
|
||
return this;
|
||
}
|
||
|
||
this.currentFile = filePath;
|
||
const volumeValue = this.volume / 100;
|
||
|
||
console.log('[STDIN-AUDIO] Запуск воспроизведения:', path.basename(filePath));
|
||
console.log('[STDIN-AUDIO] Начальная громкость:', this.volume + '%');
|
||
|
||
// PowerShell скрипт с чтением команд из stdin
|
||
const script = `
|
||
Add-Type -AssemblyName presentationcore
|
||
$player = New-Object System.Windows.Media.MediaPlayer
|
||
$player.Volume = ${volumeValue}
|
||
$player.Open("${filePath.replace(/\\/g, '\\\\')}")
|
||
|
||
# Ждем загрузки
|
||
$timeout = 0
|
||
while ($player.NaturalDuration.HasTimeSpan -eq $false -and $timeout -lt 50) {
|
||
Start-Sleep -Milliseconds 100
|
||
$timeout++
|
||
}
|
||
|
||
if ($player.NaturalDuration.HasTimeSpan -eq $false) {
|
||
Write-Host "ERROR:Failed to load"
|
||
exit 1
|
||
}
|
||
|
||
# Запускаем воспроизведение
|
||
$player.Play()
|
||
Write-Host "PLAYING"
|
||
Write-Host "VOLUME:$([int]($player.Volume * 100))"
|
||
|
||
# Создаем поток для чтения stdin
|
||
$reader = [System.IO.StreamReader]::new([Console]::OpenStandardInput())
|
||
$task = $null
|
||
|
||
# Главный цикл
|
||
while ($true) {
|
||
# Неблокирующее чтение stdin
|
||
if ($reader.Peek() -ge 0) {
|
||
$line = $reader.ReadLine()
|
||
if ($line -match "^VOLUME:(\d+)$") {
|
||
$newVolume = [int]$matches[1] / 100
|
||
$player.Volume = $newVolume
|
||
Write-Host "VOLUME_CHANGED:$($matches[1])"
|
||
} elseif ($line -eq "STOP") {
|
||
break
|
||
}
|
||
}
|
||
|
||
# Проверяем завершение
|
||
if ($player.Position -ge $player.NaturalDuration.TimeSpan) {
|
||
Write-Host "FINISHED"
|
||
break
|
||
}
|
||
|
||
Start-Sleep -Milliseconds 50
|
||
}
|
||
|
||
$player.Stop()
|
||
$player.Close()
|
||
`;
|
||
|
||
this.currentProcess = spawn('powershell', [
|
||
'-NoProfile',
|
||
'-Command', script
|
||
], {
|
||
windowsHide: true,
|
||
stdio: ['pipe', 'pipe', 'pipe'] // stdin, stdout, stderr
|
||
});
|
||
|
||
this.isPlaying = true;
|
||
|
||
// Обработка вывода
|
||
this.currentProcess.stdout.on('data', (data) => {
|
||
const output = data.toString().trim();
|
||
if (output) {
|
||
console.log('[STDIN-AUDIO]', output);
|
||
if (output === 'PLAYING') {
|
||
this.playerReady = true;
|
||
}
|
||
}
|
||
});
|
||
|
||
this.currentProcess.stderr.on('data', (data) => {
|
||
console.error('[STDIN-AUDIO] Ошибка:', data.toString());
|
||
});
|
||
|
||
this.currentProcess.on('close', (code) => {
|
||
console.log('[STDIN-AUDIO] Процесс завершен:', code);
|
||
this.isPlaying = false;
|
||
this.currentProcess = null;
|
||
this.playerReady = false;
|
||
});
|
||
|
||
return this;
|
||
}
|
||
|
||
stop() {
|
||
if (this.currentProcess) {
|
||
console.log('[STDIN-AUDIO] Остановка');
|
||
try {
|
||
// Отправляем команду через stdin
|
||
this.currentProcess.stdin.write('STOP\n');
|
||
setTimeout(() => {
|
||
if (this.currentProcess) {
|
||
this.currentProcess.kill();
|
||
}
|
||
}, 100);
|
||
} catch (e) {
|
||
this.currentProcess.kill();
|
||
}
|
||
this.currentProcess = null;
|
||
}
|
||
|
||
this.isPlaying = false;
|
||
this.playerReady = false;
|
||
|
||
return this;
|
||
}
|
||
|
||
setVolume(volume) {
|
||
this.volume = Math.max(0, Math.min(100, volume));
|
||
console.log('[STDIN-AUDIO] Установка громкости:', this.volume);
|
||
|
||
if (this.isPlaying && this.currentProcess && this.currentProcess.stdin) {
|
||
try {
|
||
this.currentProcess.stdin.write(`VOLUME:${this.volume}\n`);
|
||
console.log('[STDIN-AUDIO] Команда громкости отправлена через stdin');
|
||
} catch (e) {
|
||
console.error('[STDIN-AUDIO] Ошибка отправки команды:', e.message);
|
||
}
|
||
}
|
||
|
||
return this;
|
||
}
|
||
}
|
||
|
||
// Экспортируем как WindowsAudioPlayer для совместимости
|
||
module.exports = {
|
||
WindowsAudioPlayer: WindowsStdinAudio
|
||
}; |