docs: comprehensive README update with all API endpoints and features
Lint & Test / test (push) Successful in 9s

- Add display control API endpoints and monitor response schema
- Add header links section with CRUD API and configuration
- Add visualizer API endpoints (status, devices, device selection)
- Add album artwork endpoint documentation
- Add audio devices endpoint
- Add script/callback CRUD endpoints (create, update, delete)
- Add browser folder management CRUD endpoints
- Add play-folder and download endpoints
- Add WebSocket protocol documentation (all message types)
- Add full config.yaml example with all sections
- Document Dynamic WebGL background feature
- Fix all markdown lint warnings (duplicate headings, table alignment,
  missing code fence languages, blank lines around fences)
This commit is contained in:
2026-03-23 02:33:03 +03:00
parent c76ffb9997
commit 02168519b7
+314 -117
View File
@@ -7,10 +7,12 @@ A REST API server for controlling system media playback on Windows, Linux, macOS
- **Built-in Web UI** for real-time media control and monitoring - **Built-in Web UI** for real-time media control and monitoring
- **Installable PWA** - Add to home screen on mobile for a native app experience - **Installable PWA** - Add to home screen on mobile for a native app experience
- **Audio Visualizer** - Real-time spectrum analyzer with beat-reactive album art effects - **Audio Visualizer** - Real-time spectrum analyzer with beat-reactive album art effects
- **Dynamic WebGL Background** - Audio-reactive animated background with album art color extraction
- **Media Browser** - Browse and play media files from configured folders - **Media Browser** - Browse and play media files from configured folders
- **Display Control** - Monitor brightness and power management - **Display Control** - Monitor brightness and power management
- **Quick Actions & Scripts** - Execute custom scripts with one click - **Quick Actions & Scripts** - Execute custom scripts with one click
- **Callbacks** - Trigger commands on media events (play, pause, volume, etc.) - **Callbacks** - Trigger commands on media events (play, pause, volume, etc.)
- **Header Links** - Configurable quick-access links in the UI header
- Control any media player via system-wide media transport controls - Control any media player via system-wide media transport controls
- Play/Pause/Stop/Next/Previous track - Play/Pause/Stop/Next/Previous track
- Volume control and mute - Volume control and mute
@@ -28,7 +30,7 @@ The media server includes a built-in web interface for controlling and monitorin
![Web UI](docs/web-ui.PNG) ![Web UI](docs/web-ui.PNG)
### Features ### Web UI Highlights
- **Real-time status updates** via WebSocket connection - **Real-time status updates** via WebSocket connection
- **Album artwork display** with glow effect and automatic updates - **Album artwork display** with glow effect and automatic updates
@@ -40,7 +42,9 @@ The media server includes a built-in web interface for controlling and monitorin
- **Connection status indicator** - Know when you're connected - **Connection status indicator** - Know when you're connected
- **Token authentication** - Saved in browser localStorage - **Token authentication** - Saved in browser localStorage
- **Audio spectrum visualizer** - Real-time frequency bars with beat-reactive album art scaling and glow (on-demand WASAPI loopback capture) - **Audio spectrum visualizer** - Real-time frequency bars with beat-reactive album art scaling and glow (on-demand WASAPI loopback capture)
- **Dynamic WebGL background** - Fragment shader-based animated background that reacts to audio beats and extracts colors from album art (toggle on/off in header)
- **Display control** - Monitor brightness adjustment and power on/off - **Display control** - Monitor brightness adjustment and power on/off
- **Header quick links** - Configurable external URLs with icons shown in the header bar
- **Installable PWA** - Add to home screen on mobile/desktop for standalone app experience with safe area support for notched phones - **Installable PWA** - Add to home screen on mobile/desktop for standalone app experience with safe area support for notched phones
- **Responsive design** - Works on desktop, tablet, and mobile - **Responsive design** - Works on desktop, tablet, and mobile
- **Dark and light themes** - Toggle between dark and light modes with dynamic status bar theming - **Dark and light themes** - Toggle between dark and light modes with dynamic status bar theming
@@ -51,12 +55,14 @@ The media server includes a built-in web interface for controlling and monitorin
### Accessing the Web UI ### Accessing the Web UI
1. Start the media server: 1. Start the media server:
```bash ```bash
python -m media_server.main python -m media_server.main
``` ```
2. Open your browser and navigate to: 2. Open your browser and navigate to:
```
```text
http://localhost:8765/ http://localhost:8765/
``` ```
@@ -78,12 +84,15 @@ The Web UI includes a real-time audio spectrum visualizer that captures system a
- **On-demand capture** - Audio capture starts only when a client enables the visualizer, and stops when the last client disconnects - **On-demand capture** - Audio capture starts only when a client enables the visualizer, and stops when the last client disconnects
- **Beat-reactive effects** - Album art pulses and glows in response to bass frequencies - **Beat-reactive effects** - Album art pulses and glows in response to bass frequencies
- **Dynamic WebGL background** - Animated shader background that reacts to bass frequencies and adapts colors from current album art
- **Configurable device** - Select which audio output device to capture in Settings - **Configurable device** - Select which audio output device to capture in Settings
Requires `soundcard` and `numpy` Python packages. Enable in `config.yaml`: Requires `soundcard` and `numpy` Python packages. Enable in `config.yaml`:
```yaml ```yaml
visualizer_enabled: true visualizer_enabled: true
visualizer_fps: 30 # Frame rate (10-60)
visualizer_bins: 32 # Frequency bins (8-128)
# visualizer_device: "Speakers" # optional: specific device name # visualizer_device: "Speakers" # optional: specific device name
``` ```
@@ -135,7 +144,7 @@ The Media Browser feature allows you to browse and play media files from configu
![Media Browser](docs/media-browser.PNG) ![Media Browser](docs/media-browser.PNG)
### Browser Features ### Browser Highlights
- **Folder Configuration** - Mount multiple media folders (music/video directories) - **Folder Configuration** - Mount multiple media folders (music/video directories)
- **Recursive Navigation** - Browse through folder hierarchies with breadcrumb navigation - **Recursive Navigation** - Browse through folder hierarchies with breadcrumb navigation
@@ -143,13 +152,14 @@ The Media Browser feature allows you to browse and play media files from configu
- **Thumbnail Display** - Automatically generated thumbnails from album art (lazy-loaded) - **Thumbnail Display** - Automatically generated thumbnails from album art (lazy-loaded)
- **Metadata Extraction** - View title, artist, album, duration, bitrate, file size, and more - **Metadata Extraction** - View title, artist, album, duration, bitrate, file size, and more
- **Remote Playback** - Play files on the PC running the media server (not in the browser) - **Remote Playback** - Play files on the PC running the media server (not in the browser)
- **Play All** - Play all media files in the current folder - **Play All** - Play all media files in the current folder (generates M3U playlist)
- **File Download** - Download individual media files directly from the browser - **File Download** - Download individual media files directly from the browser
- **Search & Filter** - Real-time search across files in the current folder - **Search & Filter** - Real-time search across files in the current folder
- **Pagination** - Navigate large folders with configurable page sizes (25, 50, 100, 200, 500) - **Pagination** - Navigate large folders with configurable page sizes (25, 50, 100, 200, 500)
- **Last Path Memory** - Automatically returns to your last browsed location - **Last Path Memory** - Automatically returns to your last browsed location
- **Folder Management** - Create, edit, and delete media folders from the UI
### Configuration ### Browser Setup
Add media folders in your `config.yaml`: Add media folders in your `config.yaml`:
@@ -179,9 +189,9 @@ When you play a file from the Media Browser:
### Media Player Compatibility ### Media Player Compatibility
**⚠️ Important Limitation:** Not all media players expose their playback information to the Windows Media Session API. This means some players will open and play the file, but the Media Server UI won't show playback status, track information, or allow remote control. **Important Limitation:** Not all media players expose their playback information to the Windows Media Session API. This means some players will open and play the file, but the Media Server UI won't show playback status, track information, or allow remote control.
**Compatible Players** (work with playback tracking): **Compatible Players** (work with playback tracking):
- **VLC Media Player** - Full support - **VLC Media Player** - Full support
- **Groove Music** (Windows 10/11 built-in) - Full support - **Groove Music** (Windows 10/11 built-in) - Full support
@@ -189,39 +199,84 @@ When you play a file from the Media Browser:
- **Chrome/Edge/Firefox** - Full support for web players - **Chrome/Edge/Firefox** - Full support for web players
- **foobar2000** - Full support (with proper configuration/plugins) - **foobar2000** - Full support (with proper configuration/plugins)
**Limited/No Support:** **Limited/No Support:**
- **Windows Media Player Classic** - Opens files but doesn't expose session info - **Windows Media Player Classic** - Opens files but doesn't expose session info
- **Windows Media Player** (classic version) - Limited session support - **Windows Media Player** (classic version) - Limited session support
**Recommendation:** Set **VLC Media Player** or **Groove Music** as your default audio player for the best experience with the Media Browser. **Recommendation:** Set **VLC Media Player** or **Groove Music** as your default audio player for the best experience with the Media Browser.
#### Changing Your Default Media Player (Windows) #### Changing Your Default Media Player (on Windows)
1. Open Windows Settings Apps Default apps 1. Open Windows Settings > Apps > Default apps
2. Search for "Music player" or "Video player" 2. Search for "Music player" or "Video player"
3. Select VLC Media Player or Groove Music 3. Select VLC Media Player or Groove Music
4. Files opened from Media Browser will now use the selected player 4. Files opened from Media Browser will now use the selected player
### API Endpoints ## Display Control
The Media Browser exposes several REST API endpoints: The Display Control feature allows you to manage monitor brightness and power state from the Web UI or via API.
| Endpoint | Method | Description | - **Brightness adjustment** - Set brightness (0-100%) for each monitor
|--------------------------|--------|-----------------------------------| - **Power management** - Turn monitors on or off
| `/api/browser/folders` | GET | List configured media folders | - **Multi-monitor support** - See all connected monitors with model, manufacturer, and resolution info
| `/api/browser/browse` | GET | Browse directory contents | - **Technology**: DDC-CI on Windows, XRandR/ACPI on Linux, IOKit on macOS
| `/api/browser/metadata` | GET | Get media file metadata |
| `/api/browser/thumbnail` | GET | Get thumbnail image |
| `/api/browser/play` | POST | Open file with default player |
All endpoints require bearer token authentication. ### Display API
### Security Notes | Endpoint | Method | Body | Description |
|------------------------------------------|----------|---------------------------|--------------------------------------------------|
| `/api/display/monitors` | GET | - | List monitors (use `?refresh=true` to refresh) |
| `/api/display/brightness/{monitor_id}` | POST | `{"brightness": 0-100}` | Set monitor brightness |
| `/api/display/power/{monitor_id}` | POST | `{"on": true\ | false}` |
- **Path Traversal Protection** - All paths are validated to prevent directory traversal attacks **Monitor response:**
- **Folder Restrictions** - Only configured folders are accessible
- **Authentication Required** - All endpoints require a valid API token ```json
{
"id": 0,
"name": "Monitor Name",
"brightness": 100,
"power_supported": true,
"power_on": true,
"model": "Model Number",
"manufacturer": "Manufacturer",
"resolution": "1920x1080",
"is_primary": true
}
```
## Header Links
Configure quick-access links that appear in the Web UI header bar with custom icons.
### Links Setup
Add links in your `config.yaml`:
```yaml
links:
spotify:
url: "https://open.spotify.com"
icon: "mdi:spotify"
label: "Spotify"
settings:
url: "https://your-server.com/settings"
icon: "mdi:cog"
label: "Settings"
description: "System settings"
```
### Links API
| Endpoint | Method | Body | Description |
|-----------------------------------|----------|-------------------------------------|------------------|
| `/api/links/list` | GET | - | List all links |
| `/api/links/create/{link_name}` | POST | `{url, icon, label, description}` | Create link |
| `/api/links/update/{link_name}` | PUT | `{url, icon, label, description}` | Update link |
| `/api/links/delete/{link_name}` | DELETE | - | Delete link |
All connected WebSocket clients receive a `links_changed` notification when links are modified.
## Requirements ## Requirements
@@ -230,7 +285,7 @@ All endpoints require bearer token authentication.
## Installation ## Installation
### Windows ### Installing on Windows
```bash ```bash
pip install -r requirements.txt pip install -r requirements.txt
@@ -238,7 +293,7 @@ pip install -r requirements.txt
Required packages: `winsdk`, `pywin32`, `pycaw`, `comtypes` Required packages: `winsdk`, `pywin32`, `pycaw`, `comtypes`
### Linux ### Installing on Linux
```bash ```bash
# Install system dependencies # Install system dependencies
@@ -247,7 +302,7 @@ sudo apt-get install python3-dbus python3-gi libdbus-1-dev libglib2.0-dev
pip install -r requirements.txt pip install -r requirements.txt
``` ```
### macOS ### Installing on macOS
```bash ```bash
pip install -r requirements.txt pip install -r requirements.txt
@@ -255,7 +310,7 @@ pip install -r requirements.txt
No additional dependencies - uses built-in `osascript`. No additional dependencies - uses built-in `osascript`.
### Android (Termux) ### Installing on Android (Termux)
```bash ```bash
# In Termux # In Termux
@@ -268,26 +323,31 @@ Requires Termux and Termux:API apps from F-Droid.
## Quick Start ## Quick Start
1. Generate configuration with API token: 1. Generate configuration with API token:
```bash ```bash
python -m media_server.main --generate-config python -m media_server.main --generate-config
``` ```
2. View your API token: 2. View your API token:
```bash ```bash
python -m media_server.main --show-token python -m media_server.main --show-token
``` ```
3. Start the server: 3. Start the server:
```bash ```bash
python -m media_server.main python -m media_server.main
``` ```
4. **Open the Web UI** (recommended): 4. **Open the Web UI** (recommended):
- Navigate to `http://localhost:8765/` in your browser - Navigate to `http://localhost:8765/` in your browser
- Enter your API token from step 2 - Enter your API token from step 2
- Start playing media and control it from the web interface! - Start playing media and control it from the web interface!
5. Or test via API: 5. Or test via API:
```bash ```bash
# Health check (no auth required) # Health check (no auth required)
curl http://localhost:8765/api/health curl http://localhost:8765/api/health
@@ -296,13 +356,14 @@ Requires Termux and Termux:API apps from F-Droid.
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:8765/api/media/status curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:8765/api/media/status
``` ```
## Configuration ## Configuration Reference
Configuration file locations: Configuration file locations:
- Windows: `%APPDATA%\media-server\config.yaml` - Windows: `%APPDATA%\media-server\config.yaml`
- Linux/macOS: `~/.config/media-server/config.yaml` - Linux/macOS: `~/.config/media-server/config.yaml`
### config.yaml ### Full config.yaml Example
```yaml ```yaml
host: 0.0.0.0 host: 0.0.0.0
@@ -316,29 +377,75 @@ api_tokens:
poll_interval: 1.0 poll_interval: 1.0
log_level: INFO log_level: INFO
# Audio device for system volume control (null = default device)
audio_device: null
# Audio visualizer (requires soundcard + numpy)
visualizer_enabled: true
visualizer_fps: 30
visualizer_bins: 32
visualizer_device: null # null = auto-detect loopback
# Media folders for browser
media_folders:
music:
path: "C:\\Users\\YourUsername\\Music"
label: "My Music"
enabled: true
# Thumbnail size: "small" (150x150), "medium" (300x300), or "both"
thumbnail_size: "medium"
# Custom scripts (execute via API/UI)
scripts:
lock_screen:
command: "rundll32.exe user32.dll,LockWorkStation"
label: "Lock Screen"
description: "Lock the workstation"
icon: "mdi:lock"
timeout: 5
shell: true
# Callbacks (execute after media actions)
callbacks:
on_turn_off:
command: "rundll32.exe user32.dll,LockWorkStation"
timeout: 5
shell: true
# Header quick links
links:
spotify:
url: "https://open.spotify.com"
icon: "mdi:spotify"
label: "Spotify"
``` ```
### Authentication ### Authentication
The media server supports multiple API tokens with friendly labels. This allows you to: The media server supports multiple API tokens with friendly labels. This allows you to:
- Issue different tokens for different clients (Home Assistant, mobile apps, web UI, etc.) - Issue different tokens for different clients (Home Assistant, mobile apps, web UI, etc.)
- Identify which client is making requests in the server logs - Identify which client is making requests in the server logs
- Revoke individual tokens without affecting other clients - Revoke individual tokens without affecting other clients
**Token labels** appear in all server logs, making it easy to track and debug client connections: **Token labels** appear in all server logs, making it easy to track and debug client connections:
``` ```text
2026-02-06 03:36:20,806 - media_server.services.websocket_manager - [home_assistant] - INFO - WebSocket client connected 2026-02-06 03:36:20,806 - media_server.services.websocket_manager - [home_assistant] - INFO - WebSocket client connected
2026-02-06 03:28:24,258 - media_server.routes.scripts - [mobile] - INFO - Executing script: lock_screen 2026-02-06 03:28:24,258 - media_server.routes.scripts - [mobile] - INFO - Executing script: lock_screen
``` ```
**Viewing your tokens:** **Viewing your tokens:**
```bash ```bash
python -m media_server.main --show-token python -m media_server.main --show-token
``` ```
Output: Output:
```
```text
Config directory: C:\Users\...\AppData\Roaming\media-server Config directory: C:\Users\...\AppData\Roaming\media-server
API Tokens: API Tokens:
@@ -363,13 +470,14 @@ export MEDIA_SERVER_LOG_LEVEL=DEBUG
### Health Check ### Health Check
``` ```text
GET /api/health GET /api/health
``` ```
No authentication required. Returns server status and platform info. No authentication required. Returns server status and platform info.
**Response:** **Response:**
```json ```json
{ {
"status": "healthy", "status": "healthy",
@@ -380,12 +488,13 @@ No authentication required. Returns server status and platform info.
### Get Media Status ### Get Media Status
``` ```text
GET /api/media/status GET /api/media/status
Authorization: Bearer <token> Authorization: Bearer <token>
``` ```
**Response:** **Response:**
```json ```json
{ {
"state": "playing", "state": "playing",
@@ -401,60 +510,66 @@ Authorization: Bearer <token>
} }
``` ```
### Album Artwork
```text
GET /api/media/artwork
Authorization: Bearer <token>
```
Returns current album artwork as PNG/JPEG/WebP binary. Also accepts token as a query parameter.
### Media Controls ### Media Controls
All control endpoints require authentication and return `{"success": true}` on success. All control endpoints require authentication and return `{"success": true}` on success.
| Endpoint | Method | Body | Description | | Endpoint | Method | Body | Description |
|----------|--------|------|-------------| |-------------------------|----------|------------------------|--------------------------------|
| `/api/media/play` | POST | - | Resume playback | | `/api/media/play` | POST | - | Resume playback |
| `/api/media/pause` | POST | - | Pause playback | | `/api/media/pause` | POST | - | Pause playback |
| `/api/media/stop` | POST | - | Stop playback | | `/api/media/stop` | POST | - | Stop playback |
| `/api/media/next` | POST | - | Next track | | `/api/media/next` | POST | - | Next track |
| `/api/media/previous` | POST | - | Previous track | | `/api/media/previous` | POST | - | Previous track |
| `/api/media/volume` | POST | `{"volume": 75}` | Set volume (0-100) | | `/api/media/volume` | POST | `{"volume": 75}` | Set volume (0-100) |
| `/api/media/mute` | POST | - | Toggle mute | | `/api/media/mute` | POST | - | Toggle mute |
| `/api/media/seek` | POST | `{"position": 60.0}` | Seek to position (seconds) | | `/api/media/seek` | POST | `{"position": 60.0}` | Seek to position (seconds) |
| `/api/media/turn_on` | POST | - | Execute on_turn_on callback | | `/api/media/turn_on` | POST | - | Execute on_turn_on callback |
| `/api/media/turn_off` | POST | - | Execute on_turn_off callback | | `/api/media/turn_off` | POST | - | Execute on_turn_off callback |
| `/api/media/toggle` | POST | - | Execute on_toggle callback | | `/api/media/toggle` | POST | - | Execute on_toggle callback |
### Script Execution ### Visualizer API
The server supports executing pre-defined scripts via API and the Web UI. Scripts and callbacks can be managed directly from the Web UI — add, edit, delete, and execute with real-time output display. | Endpoint | Method | Body | Description |
|-----------------------------------|----------|-----------------------------------------|----------------------------------------|
| `/api/media/visualizer/status` | GET | - | Check availability and running state |
| `/api/media/visualizer/devices` | GET | - | List loopback audio devices |
| `/api/media/visualizer/device` | POST | `{"device_name": "..." \ | null}` |
### Audio Devices
```text
GET /api/audio/devices
Authorization: Bearer <token>
```
Returns a list of available audio output devices.
### Script Management
Scripts can be managed via API or directly from the Web UI (Quick Actions tab).
![Script and Callback Management](docs/scripts-management.PNG) ![Script and Callback Management](docs/scripts-management.PNG)
#### List Scripts | Endpoint | Method | Body | Description |
|----------------------------------------|----------|---------------------------------------------------------|--------------------|
| `/api/scripts/list` | GET | - | List all scripts |
| `/api/scripts/execute/{script_name}` | POST | `{"args": []}` | Execute a script |
| `/api/scripts/create/{script_name}` | POST | `{command, label, description, icon, timeout, shell}` | Create a script |
| `/api/scripts/update/{script_name}` | PUT | `{command, label, description, icon, timeout, shell}` | Update a script |
| `/api/scripts/delete/{script_name}` | DELETE | - | Delete a script |
``` **Execute response:**
GET /api/scripts/list
Authorization: Bearer <token>
```
**Response:**
```json
[
{
"name": "lock_screen",
"label": "Lock Screen",
"description": "Lock the workstation",
"timeout": 5
}
]
```
#### Execute Script
```
POST /api/scripts/execute/{script_name}
Authorization: Bearer <token>
Content-Type: application/json
{"args": []}
```
**Response:**
```json ```json
{ {
"success": true, "success": true,
@@ -465,7 +580,7 @@ Content-Type: application/json
} }
``` ```
### Configuring Scripts ### Script Config Options
Add scripts in your `config.yaml`: Add scripts in your `config.yaml`:
@@ -507,21 +622,33 @@ scripts:
shell: true shell: true
``` ```
Script configuration options: Script fields:
| Field | Required | Description | | Field | Required | Description |
|-------|----------|-------------| |-----------------|------------|--------------------------------------------------------|
| `command` | Yes | Command to execute | | `command` | Yes | Command to execute |
| `label` | No | User-friendly display name (defaults to script name) | | `label` | No | User-friendly display name (defaults to script name) |
| `description` | No | Description of what the script does | | `description` | No | Description of what the script does |
| `icon` | No | Custom MDI icon (e.g., `mdi:power`) | | `icon` | No | Custom MDI icon (e.g., `mdi:power`) |
| `timeout` | No | Execution timeout in seconds (default: 30, max: 300) | | `timeout` | No | Execution timeout in seconds (default: 30, max: 300) |
| `working_dir` | No | Working directory for the command | | `working_dir` | No | Working directory for the command |
| `shell` | No | Run in shell (default: true) | | `shell` | No | Run in shell (default: true) |
### Configuring Callbacks ### Callback Management
Callbacks are optional commands executed after media actions. Add them in your `config.yaml`: Callbacks are commands executed after media actions. They can be managed via API or the Web UI (Quick Actions tab).
| Endpoint | Method | Body | Description |
|-------------------------------------------|----------|--------------------------------------------|--------------------------|
| `/api/callbacks/list` | GET | - | List all callbacks |
| `/api/callbacks/execute/{callback_name}` | POST | - | Execute (for debugging) |
| `/api/callbacks/create/{callback_name}` | POST | `{command, timeout, working_dir, shell}` | Create a callback |
| `/api/callbacks/update/{callback_name}` | PUT | `{command, timeout, working_dir, shell}` | Update a callback |
| `/api/callbacks/delete/{callback_name}` | DELETE | - | Delete a callback |
### Callback Config Options
Add callbacks in your `config.yaml`:
```yaml ```yaml
callbacks: callbacks:
@@ -585,28 +712,83 @@ callbacks:
Available callbacks: Available callbacks:
| Callback | Triggered by | Description | | Callback | Triggered by | Description |
|----------|--------------|-------------| |-----------------|-------------------------|---------------------------------|
| `on_play` | `/api/media/play` | After play succeeds | | `on_play` | `/api/media/play` | After play succeeds |
| `on_pause` | `/api/media/pause` | After pause succeeds | | `on_pause` | `/api/media/pause` | After pause succeeds |
| `on_stop` | `/api/media/stop` | After stop succeeds | | `on_stop` | `/api/media/stop` | After stop succeeds |
| `on_next` | `/api/media/next` | After next track succeeds | | `on_next` | `/api/media/next` | After next track succeeds |
| `on_previous` | `/api/media/previous` | After previous track succeeds | | `on_previous` | `/api/media/previous` | After previous track succeeds |
| `on_volume` | `/api/media/volume` | After volume change succeeds | | `on_volume` | `/api/media/volume` | After volume change succeeds |
| `on_mute` | `/api/media/mute` | After mute toggle | | `on_mute` | `/api/media/mute` | After mute toggle |
| `on_seek` | `/api/media/seek` | After seek succeeds | | `on_seek` | `/api/media/seek` | After seek succeeds |
| `on_turn_on` | `/api/media/turn_on` | Callback-only action | | `on_turn_on` | `/api/media/turn_on` | Callback-only action |
| `on_turn_off` | `/api/media/turn_off` | Callback-only action | | `on_turn_off` | `/api/media/turn_off` | Callback-only action |
| `on_toggle` | `/api/media/toggle` | Callback-only action | | `on_toggle` | `/api/media/toggle` | Callback-only action |
Callback configuration options: Callback fields:
| Field | Required | Description | | Field | Required | Description |
|-------|----------|-------------| |-----------------|------------|--------------------------------------------------------|
| `command` | Yes | Command to execute | | `command` | Yes | Command to execute |
| `timeout` | No | Execution timeout in seconds (default: 30, max: 300) | | `timeout` | No | Execution timeout in seconds (default: 30, max: 300) |
| `working_dir` | No | Working directory for the command | | `working_dir` | No | Working directory for the command |
| `shell` | No | Run in shell (default: true) | | `shell` | No | Run in shell (default: true) |
### Browser API
| Endpoint | Method | Body | Description |
|---------------------------------------------|----------|----------------------------------------|--------------------------------------------|
| `/api/browser/folders` | GET | - | List configured media folders |
| `/api/browser/browse` | GET | - | Browse directory (query: folder_id, path) |
| `/api/browser/metadata` | GET | - | Get file metadata (query: file_path) |
| `/api/browser/thumbnail` | GET | - | Get thumbnail image (query: file_path) |
| `/api/browser/download` | GET | - | Download file (query: folder_id, path) |
| `/api/browser/play` | POST | `{"file_path": "..."}` | Open file with default player |
| `/api/browser/play-folder` | POST | `{"folder_id": "...", "path": ""}` | Play all files in folder (M3U) |
| `/api/browser/folders/create` | POST | `{folder_id, label, path, enabled}` | Create folder config |
| `/api/browser/folders/update/{folder_id}` | PUT | `{label, path, enabled}` | Update folder config |
| `/api/browser/folders/delete/{folder_id}` | DELETE | - | Delete folder config |
All endpoints require bearer token authentication.
### Security Notes
- **Path Traversal Protection** - All paths are validated to prevent directory traversal attacks
- **Folder Restrictions** - Only configured folders are accessible
- **Authentication Required** - All endpoints require a valid API token
- **Output Limits** - Script stdout/stderr capped at 10KB
### WebSocket
```text
WebSocket /api/media/ws
Authorization: Bearer <token>
```
The WebSocket connection provides real-time updates and low-latency control.
**Messages from server:**
| Type | Data | Description |
|---------------------|------------------------|----------------------------------------|
| `status` | Media status object | Initial status on connection |
| `status_update` | Media status object | Status changes during playback |
| `audio_data` | `[0.1, 0.2, ...]` | Visualizer frequency data (30 fps) |
| `scripts_changed` | `{}` | Scripts were created/updated/deleted |
| `links_changed` | `{}` | Links were created/updated/deleted |
| `pong` | - | Response to client ping |
| `error` | `{"message": "..."}` | Error messages |
**Messages from client:**
| Type | Data | Description |
|-----------------------|------------------------|------------------------------------------------------------|
| `ping` | - | Keepalive ping |
| `get_status` | - | Request current status |
| `volume` | `{"volume": 0-100}` | Low-latency volume control via WebSocket |
| `enable_visualizer` | - | Subscribe to audio data (starts capture) |
| `disable_visualizer` | - | Unsubscribe from audio data (stops capture on last client) |
## Running as a Service ## Running as a Service
@@ -624,20 +806,23 @@ To remove the scheduled task:
Unregister-ScheduledTask -TaskName "MediaServer" -Confirm:$false Unregister-ScheduledTask -TaskName "MediaServer" -Confirm:$false
``` ```
### Windows Service ### Windows Service (Alternative)
Install: Install:
```bash ```bash
python -m media_server.service.install_windows install python -m media_server.service.install_windows install
``` ```
Start/Stop: Start/Stop:
```bash ```bash
python -m media_server.service.install_windows start python -m media_server.service.install_windows start
python -m media_server.service.install_windows stop python -m media_server.service.install_windows stop
``` ```
Remove: Remove:
```bash ```bash
python -m media_server.service.install_windows remove python -m media_server.service.install_windows remove
``` ```
@@ -645,24 +830,27 @@ python -m media_server.service.install_windows remove
### Linux (systemd) ### Linux (systemd)
Install: Install:
```bash ```bash
sudo ./service/install_linux.sh install sudo ./service/install_linux.sh install
``` ```
Enable and start for your user: Enable and start for your user:
```bash ```bash
sudo systemctl enable media-server@$USER sudo systemctl enable media-server@$USER
sudo systemctl start media-server@$USER sudo systemctl start media-server@$USER
``` ```
View logs: View logs:
```bash ```bash
journalctl -u media-server@$USER -f journalctl -u media-server@$USER -f
``` ```
## Command Line Options ## Command Line Options
``` ```text
python -m media_server.main [OPTIONS] python -m media_server.main [OPTIONS]
Options: Options:
@@ -681,15 +869,19 @@ Options:
## Supported Media Players ## Supported Media Players
### Windows ### Players on Windows
- Spotify - Spotify
- Windows Media Player - Windows Media Player
- VLC - VLC
- Groove Music - Groove Music
- Web browsers (Chrome, Edge, Firefox) - foobar2000
- AIMP
- Web browsers (Chrome, Edge, Firefox, Opera, Brave)
- Any app using Windows Media Transport Controls - Any app using Windows Media Transport Controls
### Linux ### Players on Linux
- Any MPRIS-compliant player: - Any MPRIS-compliant player:
- Spotify - Spotify
- VLC - VLC
@@ -698,28 +890,33 @@ Options:
- Web browsers - Web browsers
- MPD (with MPRIS bridge) - MPD (with MPRIS bridge)
### macOS ### Players on macOS
- Spotify - Spotify
- Apple Music - Apple Music
- VLC (partial) - VLC (partial)
- QuickTime Player - QuickTime Player
### Android (via Termux) ### Players on Android (via Termux)
- System media controls - System media controls
- Limited seek support - Limited seek support
## Troubleshooting ## Troubleshooting
### "No active media session" ### "No active media session"
- Ensure a media player is running and has played content - Ensure a media player is running and has played content
- On Windows, check that the app supports media transport controls - On Windows, check that the app supports media transport controls
- On Linux, verify MPRIS with: `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.ListNames | grep mpris` - On Linux, verify MPRIS with: `dbus-send --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.ListNames | grep mpris`
### Permission errors on Linux ### Permission errors on Linux
- Ensure your user has access to the D-Bus session bus - Ensure your user has access to the D-Bus session bus
- For systemd service, the `DBUS_SESSION_BUS_ADDRESS` must be set correctly - For systemd service, the `DBUS_SESSION_BUS_ADDRESS` must be set correctly
### Volume control not working ### Volume control not working
- Windows: Run as administrator if needed - Windows: Run as administrator if needed
- Linux: Ensure PulseAudio/PipeWire is running - Linux: Ensure PulseAudio/PipeWire is running