Skip to content

Latest commit

 

History

History
222 lines (176 loc) · 5.96 KB

File metadata and controls

222 lines (176 loc) · 5.96 KB

SoundSwitch Stream Deck Plugin Architecture

Overview

This Stream Deck plugin uses a two-component architecture to enable system command execution from the browser-like Stream Deck plugin environment.

Architecture Components

1. Stream Deck Plugin (Browser Environment)

  • Location: src/ directory
  • Runtime: Stream Deck software (Chromium-based)
  • Limitations: Cannot execute system commands directly
  • Technologies: Vanilla JavaScript, React (setup page), Tailwind CSS

2. Companion Service (Native Environment)

  • Location: companion-service/ directory
  • Runtime: Node.js local HTTP server
  • Purpose: Executes SoundSwitch.CLI.exe commands
  • Port: http://localhost:8765

Communication Flow

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]
Loading

Command Execution Strategy

The plugin uses a fallback strategy for maximum compatibility:

Method 1: Web API (Primary)

fetch('http://localhost:8765/execute-command', {
  method: 'POST',
  body: JSON.stringify({
    command: 'C:\\Program Files\\SoundSwitch\\SoundSwitch.CLI.exe',
    args: ['mute', '-t']
  })
})

Method 2: Stream Deck API (Fallback)

// Stream Deck 6.0+ native command execution
window.streamDeckApi.system.executeCommand({
  command: fullCommand,
  shell: true
})

Method 3: Simulation (Development)

// For testing without SoundSwitch installed
resolve({
  output: 'Microfone (NVIDIA Broadcast) is now muted',
  error: null
})

File Structure

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

Protocol Specification

HTTP API Endpoints

POST /execute-command

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
}

GET /health

Service health check

GET /test

Test SoundSwitch installation paths

State Management

Button States

  • State 0 (Unmuted): Blue icon, no text
  • State 1 (Muted): Red icon, "MUTED" text
  • Error State: Alert indicator, "Error"/"Configure Path" text

State Persistence

  • Settings stored in Stream Deck's built-in storage
  • State maintained per button context
  • Automatic cleanup on button removal

ANSI Output Parsing

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

Security Considerations

Plugin Security

  • No direct system access from plugin code
  • All commands routed through companion service
  • Input validation and sanitization

Service Security

  • 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

Deployment Options

Development Mode

cd companion-service
npm install  
npm start

Windows Service (Production)

cd companion-service
npm install
node install-service.js

Compatibility Matrix

Stream Deck Software Plugin Support API Method
4.1 - 5.x ✅ Full Web API
6.0+ ✅ Full Web API + Native
Mobile ⚠️ Limited Simulation only

Error Handling

Plugin Level

  • Graceful degradation to simulation mode
  • User-friendly error messages
  • Automatic retry mechanisms
  • Visual feedback for all states

Service Level

  • Process timeout protection (10s)
  • ANSI output sanitization
  • Detailed error logging
  • Graceful shutdown handling

Performance Characteristics

  • Command Execution: ~100-500ms typical
  • HTTP Round-trip: ~5-50ms local
  • Memory Usage: <10MB plugin + <50MB service
  • CPU Impact: Minimal, event-driven

Limitations & Known Issues

  1. Windows Only: SoundSwitch is Windows-specific
  2. Local Service: Requires companion service installation
  3. Port Dependency: Port 8765 must be available
  4. CLI Dependency: Requires SoundSwitch with CLI support

Future Enhancements

  • 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