win-stream-audio
Version:
š§ Stream Windows system audio to Android devices over WiFi with professional audio controls, EQ, pitch shifting, and effects
194 lines (167 loc) ⢠7.91 kB
JavaScript
/**
* Win Stream Audio - CLI Interface
* Professional Windows audio streaming to Android devices
*/
const chalk = require('chalk');
const inquirer = require('inquirer');
const ora = require('ora');
const boxen = require('boxen');
const path = require('path');
const { spawn } = require('child_process');
const ip = require('ip');
// ASCII Art Banner
const banner = `
āāā āāāāāāāāāā āāā āāāāāāāāāāāāāāāāāāāāāāāā āāāāāāāā āāāāāā āāāā āāāā
āāā āāāāāāāāāāā āāā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā āāāāā
āāā āā āāāāāāāāāāāā āāā āāāāāāāā āāā āāāāāāāāāāāāāā āāāāāāāāāāāāāāāāāāā
āāāāāāāāāāāāāāāāāāāāāāā āāāāāāāā āāā āāāāāāāāāāāāāā āāāāāāāāāāāāāāāāāāā
āāāāāāāāāāāāāāāā āāāāāā āāāāāāāā āāā āāā āāāāāāāāāāāāāā āāāāāā āāā āāā
āāāāāāāā āāāāāā āāāāā āāāāāāāā āāā āāā āāāāāāāāāāāāāā āāāāāā āāā
š§ AudioPilot Professional Audio Streaming š§
`;
class WinStreamAudio {
constructor() {
this.defaultPort = 8080;
this.selectedPort = null;
this.serverProcess = null;
}
async start() {
console.clear();
// Show banner
console.log(chalk.cyan(banner));
console.log(boxen(
chalk.white.bold('šµ Stream Windows system audio to Android devices over WiFi\n') +
chalk.gray('Professional audio controls ⢠EQ ⢠Pitch shifting ⢠Effects'),
{
padding: 1,
margin: 1,
borderStyle: 'round',
borderColor: 'cyan'
}
));
try {
await this.promptForSettings();
await this.startServer();
} catch (error) {
console.error(chalk.red('ā Error:'), error.message);
process.exit(1);
}
}
async promptForSettings() {
const questions = [
{
type: 'input',
name: 'port',
message: 'š Enter port number:',
default: this.defaultPort.toString(),
validate: (input) => {
const port = parseInt(input);
if (isNaN(port) || port < 1024 || port > 65535) {
return 'Please enter a valid port number (1024-65535)';
}
return true;
}
},
{
type: 'confirm',
name: 'openBrowser',
message: 'š Open browser automatically?',
default: true
}
];
const answers = await inquirer.prompt(questions);
this.selectedPort = parseInt(answers.port);
this.openBrowser = answers.openBrowser;
}
async startServer() {
const spinner = ora('š Starting AudioPilot server...').start();
try {
// Get network info
const localIP = ip.address();
const serverPath = path.join(__dirname, '..', 'server.js');
// Set environment variables
process.env.PORT = this.selectedPort.toString();
process.env.AUTO_OPEN = this.openBrowser ? 'true' : 'false';
// Start server process
this.serverProcess = spawn('node', [serverPath], {
stdio: 'pipe',
env: process.env
});
// Handle server output
this.serverProcess.stdout.on('data', (data) => {
const output = data.toString();
if (output.includes('Server running')) {
spinner.succeed('ā
AudioPilot server started successfully!');
this.showConnectionInfo(localIP);
}
});
this.serverProcess.stderr.on('data', (data) => {
spinner.fail('ā Server error');
console.error(chalk.red(data.toString()));
});
this.serverProcess.on('close', (code) => {
if (code !== 0) {
spinner.fail(`ā Server exited with code ${code}`);
} else {
console.log(chalk.yellow('\nš AudioPilot server stopped'));
}
});
// Handle graceful shutdown
process.on('SIGINT', () => {
console.log(chalk.yellow('\nš Shutting down AudioPilot server...'));
if (this.serverProcess) {
this.serverProcess.kill('SIGTERM');
}
process.exit(0);
});
// Wait a bit for server to start
await new Promise(resolve => setTimeout(resolve, 2000));
} catch (error) {
spinner.fail('ā Failed to start server');
throw error;
}
}
showConnectionInfo(localIP) {
const urls = {
local: `http://localhost:${this.selectedPort}`,
network: `http://${localIP}:${this.selectedPort}`,
source: `http://${localIP}:${this.selectedPort}/simple-source.html`,
audiopilot: `http://${localIP}:${this.selectedPort}/audiopilot.html`
};
console.log('\n' + boxen(
chalk.white.bold('šÆ AudioPilot Connection URLs\n\n') +
chalk.cyan('š± Main Interface:\n') +
chalk.white(` ${urls.network}\n\n`) +
chalk.cyan('š¤ PC Audio Source:\n') +
chalk.white(` ${urls.source}\n\n`) +
chalk.cyan('š§ AudioPilot Receiver (Android):\n') +
chalk.white(` ${urls.audiopilot}\n\n`) +
chalk.yellow('š” Quick Start:\n') +
chalk.gray(' 1. On PC: Open "PC Audio Source" and select "Stereo Mix"\n') +
chalk.gray(' 2. On Android: Open "AudioPilot Receiver" and connect\n') +
chalk.gray(' 3. Enjoy professional audio streaming with EQ & effects!'),
{
padding: 1,
margin: 1,
borderStyle: 'double',
borderColor: 'green'
}
));
console.log(chalk.gray('\nš” Server running on:'));
console.log(chalk.white(` Local: ${urls.local}`));
console.log(chalk.white(` Network: ${urls.network}`));
console.log(chalk.yellow('\nšļø Features:'));
console.log(chalk.gray(' ⢠Professional cockpit interface'));
console.log(chalk.gray(' ⢠3-band EQ (Bass, Mid, Treble)'));
console.log(chalk.gray(' ⢠Pitch shifting with voice presets'));
console.log(chalk.gray(' ⢠Audio effects (Reverb, Echo, Distortion, Chorus)'));
console.log(chalk.gray(' ⢠Real-time audio visualization'));
console.log(chalk.gray(' ⢠Screen wake system for Android'));
console.log(chalk.gray(' ⢠Auto-reconnection'));
console.log(chalk.cyan('\nš Press Ctrl+C to stop the server'));
}
}
// Start the application
const app = new WinStreamAudio();
app.start().catch(console.error);