- haos-integration → 97c1784: v0.3.0 server compat (WS subprotocol auth, 429 retry, HTTPS support, X-Request-ID) plus the in-flight v0.3.1/v0.3.2 releases that had not yet been recorded in the parent pointer. - media-server → 82710c6: pulls in v0.3.0 (production-readiness hardening: scope hierarchy, rate limiter, audit log, etc.) and v0.3.1 (same-origin WS allow-list fix). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Remote Media Player
Control your PC's media playback from Home Assistant or a standalone web UI.
This repository contains two independent components as git submodules:
- media-server -- FastAPI media server with web UI (repo)
- haos-integration -- HACS-ready Home Assistant integration (repo)
Architecture
┌─────────────────────┐ HTTP/WebSocket ┌─────────────────────────┐
│ Home Assistant │◄────────────────────────►│ Your PC │
│ │ (Token Auth) │ │
│ ┌───────────────┐ │ │ ┌───────────────────┐ │
│ │ Media Player │ │ │ │ Media Server │ │
│ │ Entity │ │ │ │ (FastAPI) │ │
│ ├───────────────┤ │ │ ├───────────────────┤ │
│ │ Script Button │ │ Web UI │ │ Media Controller │ │
│ │ Entities │ │◄────────(PWA)──────────►│ │ Audio Visualizer │ │
│ ├───────────────┤ │ │ │ Browser Service │ │
│ │ Display │ │ │ │ Display Service │ │
│ │ Brightness/ │ │ │ │ Script Runner │ │
│ │ Power │ │ │ │ Callback System │ │
│ └───────────────┘ │ │ └───────────────────┘ │
└─────────────────────┘ └─────────────────────────┘
Features
Media Control
- Play / Pause / Stop / Next / Previous
- Volume control (0-100%) and mute toggle
- Seek within tracks
- Real-time track info (title, artist, album, artwork)
- Status updates via WebSocket with HTTP polling fallback
Audio Visualizer
- Real-time FFT spectrum analysis (32 frequency bins)
- On-demand WASAPI loopback capture (Windows), PulseAudio (Linux), CoreAudio (macOS)
- Beat detection with reactive album art effects
- Configurable FPS (10-60), bin count (8-128), and device selection
- Dynamic WebGL background with audio reactivity
Web UI (PWA)
- Installable Progressive Web App with offline support
- Dark / light theme with accent color picker (9 presets + custom)
- Tabbed interface: Player, Display, Browser, Quick Actions, Settings
- Sticky mini-player when scrolling
- Vinyl record animation with groove effect
- Responsive layout (desktop, tablet, mobile with safe area support)
- Localization: English and Russian (auto-detected)
- Header quick links (configurable external URLs)
Media Browser
- Browse configured media folders with breadcrumb navigation
- Grid, compact grid, and list view modes
- Thumbnail generation and caching
- Metadata display (artist, album, duration, bitrate)
- Search, filter, and pagination
- Play files or entire folders with the system default player
Display Control
- Monitor brightness adjustment (0-100%) via DDC-CI
- Monitor power on/off
- Multi-monitor support with model/resolution info
Scripts & Callbacks
- Scripts: Define and execute custom commands (shutdown, lock, sleep, etc.)
- Callbacks: Hook into media events (
on_play,on_pause,on_turn_off, etc.) - Full CRUD management from the web UI
- Timeout enforcement and output capture (max 10KB)
Home Assistant Integration
- Standard
media_playerentity with full playback controls - Button entities for each configured script
- Number entities for monitor brightness sliders
- Switch entities for monitor power
- Config flow UI or YAML configuration
- Multiple server instances supported
Security
- Bearer token authentication with multiple named tokens
- Path validation to prevent directory traversal
- Command argument sanitization
- No shell injection (proper subprocess API)
- GZip compression for responses > 1KB
Platform Support
| Platform | Media Control | Volume | Visualizer | Display |
|---|---|---|---|---|
| Windows | WinRT (winsdk) | pycaw (COM) | WASAPI loopback | DDC-CI |
| Linux | MPRIS (D-Bus) | PulseAudio/PipeWire | PulseAudio | XRandR / ACPI |
| macOS | osascript | CoreAudio | CoreAudio | IOKit |
| Android | Termux API | Termux API | - | - |
Supported players include Spotify, Chrome, Edge, Firefox, VLC, foobar2000, Windows Media Player, Groove Music, and any MPRIS2-compliant player on Linux.
Quick Start
1. Media Server (on your PC)
cd media-server
pip install . # or pip install .[windows] on Windows
python -m media_server.main --generate-config # create config.yaml
python -m media_server.main --show-token # view API tokens
python -m media_server.main # start server
Open http://localhost:8765 in a browser and enter your token.
See Media Server README for service installation (Windows Task Scheduler / Linux systemd), configuration reference, and API documentation.
2. Home Assistant Integration
HACS (recommended): Add https://git.dolgolyov-family.by/alexei.dolgolyov/haos-hacs-integration-media-player as a custom repository, then install "Remote Media Player".
Manual: Copy haos-integration/custom_components/remote_media_player/ to your HA custom_components/ folder.
Configure via Settings > Devices & Services > Add Integration > "Remote Media Player", providing your server host, port, and API token.
See HAOS Integration README for detailed instructions.
Configuration
The media server is configured via config.yaml:
host: 0.0.0.0
port: 8765
api_tokens:
home_assistant: "your-token-here"
mobile: "another-token"
visualizer_enabled: true
visualizer_fps: 30
visualizer_bins: 32
media_folders:
music:
path: "C:\\Users\\You\\Music"
label: "Music"
scripts:
lock_screen:
command: "rundll32.exe user32.dll,LockWorkStation"
label: "Lock Screen"
icon: "mdi:lock"
shutdown:
command: "shutdown /s /t 0"
label: "Shutdown"
callbacks:
on_turn_off:
command: "rundll32.exe user32.dll,LockWorkStation"
links:
spotify:
url: "https://open.spotify.com"
icon: "mdi:spotify"
label: "Spotify"
Cloning
# Clone with submodules
git clone --recurse-submodules https://git.dolgolyov-family.by/alexei.dolgolyov/media-player-mixed.git
# Or initialize submodules after cloning
git submodule update --init --recursive
License
MIT License
haos-integration) and the FastAPI media-server backend (media-server) as submodules so cross-component releases stay version-locked.