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>
This commit is contained in:
383
media-server/README.md
Normal file
383
media-server/README.md
Normal file
@@ -0,0 +1,383 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user