Files
media-player-mixed/media-server/README.md
alexei.dolgolyov e26df64e4b Refactor project into two standalone components
Split monorepo into separate units for future independent repositories:
- media-server/: Standalone FastAPI server with own README, requirements,
  config example, and CLAUDE.md
- haos-integration/: HACS-ready Home Assistant integration with hacs.json,
  own README, and CLAUDE.md

Both components now have their own .gitignore files and can be easily
extracted into separate repositories.

Also adds custom icon support for scripts configuration.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 14:36:23 +03:00

384 lines
7.6 KiB
Markdown

# Media Server
A REST API server for controlling system media playback on Windows, Linux, macOS, and Android.
## Features
- Control any media player via system-wide media transport controls
- Play/Pause/Stop/Next/Previous track
- Volume control and mute
- Seek within tracks
- Get current track info (title, artist, album, artwork)
- Token-based authentication
- Cross-platform support
## Requirements
- Python 3.10+
- Platform-specific dependencies (see below)
## Installation
### Windows
```bash
pip install -r requirements.txt
```
Required packages: `winsdk`, `pywin32`, `pycaw`, `comtypes`
### Linux
```bash
# Install system dependencies
sudo apt-get install python3-dbus python3-gi libdbus-1-dev libglib2.0-dev
pip install -r requirements.txt
```
### macOS
```bash
pip install -r requirements.txt
```
No additional dependencies - uses built-in `osascript`.
### Android (Termux)
```bash
# In Termux
pkg install python termux-api
pip install -r requirements.txt
```
Requires Termux and Termux:API apps from F-Droid.
## Quick Start
1. Generate configuration with API token:
```bash
python -m media_server.main --generate-config
```
2. View your API token:
```bash
python -m media_server.main --show-token
```
3. Start the server:
```bash
python -m media_server.main
```
4. Test the connection:
```bash
curl http://localhost:8765/api/health
```
5. Test with authentication:
```bash
curl -H "Authorization: Bearer YOUR_TOKEN" http://localhost:8765/api/media/status
```
## Configuration
Configuration file locations:
- Windows: `%APPDATA%\media-server\config.yaml`
- Linux/macOS: `~/.config/media-server/config.yaml`
### config.yaml
```yaml
host: 0.0.0.0
port: 8765
api_token: your-secret-token-here
poll_interval: 1.0
log_level: INFO
```
### Environment Variables
All settings can be overridden with environment variables (prefix: `MEDIA_SERVER_`):
```bash
export MEDIA_SERVER_HOST=0.0.0.0
export MEDIA_SERVER_PORT=8765
export MEDIA_SERVER_API_TOKEN=your-token
export MEDIA_SERVER_LOG_LEVEL=DEBUG
```
## API Reference
### Health Check
```
GET /api/health
```
No authentication required. Returns server status and platform info.
**Response:**
```json
{
"status": "healthy",
"platform": "Windows",
"version": "1.0.0"
}
```
### Get Media Status
```
GET /api/media/status
Authorization: Bearer <token>
```
**Response:**
```json
{
"state": "playing",
"title": "Song Title",
"artist": "Artist Name",
"album": "Album Name",
"album_art_url": "https://...",
"duration": 240.5,
"position": 120.3,
"volume": 75,
"muted": false,
"source": "Spotify"
}
```
### Media Controls
All control endpoints require authentication and return `{"success": true}` on success.
| Endpoint | Method | Body | Description |
|----------|--------|------|-------------|
| `/api/media/play` | POST | - | Resume playback |
| `/api/media/pause` | POST | - | Pause playback |
| `/api/media/stop` | POST | - | Stop playback |
| `/api/media/next` | POST | - | Next track |
| `/api/media/previous` | POST | - | Previous track |
| `/api/media/volume` | POST | `{"volume": 75}` | Set volume (0-100) |
| `/api/media/mute` | POST | - | Toggle mute |
| `/api/media/seek` | POST | `{"position": 60.0}` | Seek to position (seconds) |
### Script Execution
The server supports executing pre-defined scripts via API.
#### List Scripts
```
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
{
"success": true,
"script": "lock_screen",
"exit_code": 0,
"stdout": "",
"stderr": ""
}
```
### Configuring Scripts
Add scripts in your `config.yaml`:
```yaml
scripts:
lock_screen:
command: "rundll32.exe user32.dll,LockWorkStation"
label: "Lock Screen"
description: "Lock the workstation"
timeout: 5
shell: true
shutdown:
command: "shutdown /s /t 0"
label: "Shutdown"
description: "Shutdown the PC immediately"
timeout: 10
shell: true
restart:
command: "shutdown /r /t 0"
label: "Restart"
description: "Restart the PC"
timeout: 10
shell: true
hibernate:
command: "shutdown /h"
label: "Hibernate"
description: "Hibernate the PC"
timeout: 10
shell: true
sleep:
command: "rundll32.exe powrprof.dll,SetSuspendState 0,1,0"
label: "Sleep"
description: "Put PC to sleep"
timeout: 10
shell: true
```
Script configuration options:
| Field | Required | Description |
|-------|----------|-------------|
| `command` | Yes | Command to execute |
| `label` | No | User-friendly display name (defaults to script name) |
| `description` | No | Description of what the script does |
| `icon` | No | Custom MDI icon (e.g., `mdi:power`) |
| `timeout` | No | Execution timeout in seconds (default: 30, max: 300) |
| `working_dir` | No | Working directory for the command |
| `shell` | No | Run in shell (default: true) |
## Running as a Service
### Windows Task Scheduler (Recommended)
Run in **Administrator PowerShell** from the project root:
```powershell
.\media_server\service\install_task_windows.ps1
```
To remove the scheduled task:
```powershell
Unregister-ScheduledTask -TaskName "MediaServer" -Confirm:$false
```
### Windows Service
Install:
```bash
python -m media_server.service.install_windows install
```
Start/Stop:
```bash
python -m media_server.service.install_windows start
python -m media_server.service.install_windows stop
```
Remove:
```bash
python -m media_server.service.install_windows remove
```
### Linux (systemd)
Install:
```bash
sudo ./service/install_linux.sh install
```
Enable and start for your user:
```bash
sudo systemctl enable media-server@$USER
sudo systemctl start media-server@$USER
```
View logs:
```bash
journalctl -u media-server@$USER -f
```
## Command Line Options
```
python -m media_server.main [OPTIONS]
Options:
--host TEXT Host to bind to (default: 0.0.0.0)
--port INTEGER Port to bind to (default: 8765)
--generate-config Generate default config file and exit
--show-token Show current API token and exit
```
## Security Recommendations
1. **Use HTTPS in production** - Set up a reverse proxy (nginx, Caddy) with SSL
2. **Strong tokens** - Default tokens are 32 random characters; don't use weak tokens
3. **Firewall** - Only expose the port to trusted networks
4. **Secrets management** - Don't commit tokens to version control
## Supported Media Players
### Windows
- Spotify
- Windows Media Player
- VLC
- Groove Music
- Web browsers (Chrome, Edge, Firefox)
- Any app using Windows Media Transport Controls
### Linux
- Any MPRIS-compliant player:
- Spotify
- VLC
- Rhythmbox
- Clementine
- Web browsers
- MPD (with MPRIS bridge)
### macOS
- Spotify
- Apple Music
- VLC (partial)
- QuickTime Player
### Android (via Termux)
- System media controls
- Limited seek support
## Troubleshooting
### "No active media session"
- Ensure a media player is running and has played content
- 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`
### Permission errors on Linux
- Ensure your user has access to the D-Bus session bus
- For systemd service, the `DBUS_SESSION_BUS_ADDRESS` must be set correctly
### Volume control not working
- Windows: Run as administrator if needed
- Linux: Ensure PulseAudio/PipeWire is running
## License
MIT License