This Stream Deck plugin uses a two-component architecture to enable system command execution from the browser-like Stream Deck plugin environment.
- Location:
src/directory - Runtime: Stream Deck software (Chromium-based)
- Limitations: Cannot execute system commands directly
- Technologies: Vanilla JavaScript, React (setup page), Tailwind CSS
- Location:
companion-service/directory - Runtime: Node.js local HTTP server
- Purpose: Executes SoundSwitch.CLI.exe commands
- Port:
http://localhost:8765
graph TB
A[Stream Deck Button Press] --> B[Plugin Action Handler]
B --> C[executeSystemCommand]
C --> D[HTTP Request to localhost:8765]
D --> E[Companion Service]
E --> F[Execute SoundSwitch.CLI.exe]
F --> G[Parse ANSI Output]
G --> H[Return JSON Response]
H --> I[Update Button State]
I --> J[Visual Feedback - Red/Blue]
The plugin uses a fallback strategy for maximum compatibility:
fetch('http://localhost:8765/execute-command', {
method: 'POST',
body: JSON.stringify({
command: 'C:\\Program Files\\SoundSwitch\\SoundSwitch.CLI.exe',
args: ['mute', '-t']
})
})// Stream Deck 6.0+ native command execution
window.streamDeckApi.system.executeCommand({
command: fullCommand,
shell: true
})// For testing without SoundSwitch installed
resolve({
output: 'Microfone (NVIDIA Broadcast) is now muted',
error: null
})stream-deck-mute-soundswitch/
├── src/ # Stream Deck Plugin
│ ├── js/
│ │ ├── main.js # Plugin entry point
│ │ ├── pi.js # Property inspector
│ │ ├── lib/
│ │ │ └── streamDeck.js # Stream Deck SDK wrapper
│ │ └── actions/
│ │ └── mutetoggle.js # Main action logic
│ ├── components/
│ │ └── Setup.jsx # React setup page
│ ├── assets/ # Icons (SVG)
│ ├── css/ # Stylesheets
│ └── *.html # HTML entry points
├── companion-service/ # Local HTTP Service
│ ├── server.js # HTTP server
│ ├── install-service.js # Windows service installer
│ └── package.json # Node.js dependencies
└── dist/ # Built plugin files
Execute SoundSwitch CLI commands
Request:
{
"command": "C:\\Program Files\\SoundSwitch\\SoundSwitch.CLI.exe",
"args": ["mute", "-t"]
}Response:
{
"success": true,
"output": "Microfone (NVIDIA Broadcast) is now muted",
"error": null
}Service health check
Test SoundSwitch installation paths
- State 0 (Unmuted): Blue icon, no text
- State 1 (Muted): Red icon, "MUTED" text
- Error State: Alert indicator, "Error"/"Configure Path" text
- Settings stored in Stream Deck's built-in storage
- State maintained per button context
- Automatic cleanup on button removal
The plugin parses SoundSwitch's colored terminal output:
// Remove ANSI escape sequences
const cleanOutput = output.replace(/\x1b\[[0-9;]*m/g, '')
// Detect mute state from text
if (cleanOutput.includes('is now muted')) return true
if (cleanOutput.includes('is now unmuted')) return false
// Fallback: detect by ANSI color codes
if (output.includes('\x1b[31m')) return true // Red = muted
if (output.includes('\x1b[32m')) return false // Green = unmuted- No direct system access from plugin code
- All commands routed through companion service
- Input validation and sanitization
- Localhost-only binding (
127.0.0.1:8765) - CORS configured for Stream Deck origins only
- Command whitelist (SoundSwitch.CLI.exe only)
- No elevated privileges required
cd companion-service
npm install
npm startcd companion-service
npm install
node install-service.js| Stream Deck Software | Plugin Support | API Method |
|---|---|---|
| 4.1 - 5.x | ✅ Full | Web API |
| 6.0+ | ✅ Full | Web API + Native |
| Mobile | Simulation only |
- Graceful degradation to simulation mode
- User-friendly error messages
- Automatic retry mechanisms
- Visual feedback for all states
- Process timeout protection (10s)
- ANSI output sanitization
- Detailed error logging
- Graceful shutdown handling
- Command Execution: ~100-500ms typical
- HTTP Round-trip: ~5-50ms local
- Memory Usage: <10MB plugin + <50MB service
- CPU Impact: Minimal, event-driven
- Windows Only: SoundSwitch is Windows-specific
- Local Service: Requires companion service installation
- Port Dependency: Port 8765 must be available
- CLI Dependency: Requires SoundSwitch with CLI support
- Direct Stream Deck API: Once/if Stream Deck adds native command execution
- Multiple Audio Devices: Support for device selection
- Hotkey Integration: Direct hotkey binding
- Status Polling: Automatic state synchronization