https://github.com/deathmaz/mpd-web-ui
A web-based frontend for MPD (Music Player Daemon) with browser audio streaming. Control playback and listen to your music library from any device on your network.
https://github.com/deathmaz/mpd-web-ui
mpd mpd-client snapcast snapcast-client webui
Last synced: about 2 months ago
JSON representation
A web-based frontend for MPD (Music Player Daemon) with browser audio streaming. Control playback and listen to your music library from any device on your network.
- Host: GitHub
- URL: https://github.com/deathmaz/mpd-web-ui
- Owner: deathmaz
- Created: 2026-03-14T21:29:15.000Z (3 months ago)
- Default Branch: main
- Last Pushed: 2026-03-15T06:23:57.000Z (3 months ago)
- Last Synced: 2026-03-15T06:48:53.486Z (3 months ago)
- Topics: mpd, mpd-client, snapcast, snapcast-client, webui
- Language: TypeScript
- Homepage: https://github.com/deathmaz/mpd-web-ui
- Size: 109 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# mpd-web-ui
A web-based frontend for [MPD](https://www.musicpd.org/) (Music Player Daemon) with browser audio streaming. Control playback and listen to your music library from any device on your network.
## Features
- Playback control (play, pause, stop, skip, seek, volume)
- Queue management (add, remove, reorder, shuffle, clear)
- Library browsing by artist and album with album art
- Full-text search across your music library
- Stored playlist support
- Playback modes (repeat, random, single, consume)
- Audio output toggling
- Browser audio streaming via MPD's httpd output
- Snapcast integration for synchronized multiroom audio playback
- Real-time state sync across all connected clients via WebSocket
- Mobile-friendly dark UI
## Prerequisites
- [Node.js](https://nodejs.org/) >= 18
- [pnpm](https://pnpm.io/) >= 9
- MPD running with:
- TCP socket enabled (default port 6600)
- httpd output enabled for browser streaming (default port 8000)
### MPD httpd output
To stream audio to the browser, enable an httpd output in your `mpd.conf`:
```
audio_output {
type "httpd"
name "HTTP Stream"
encoder "opus"
port "8000"
bitrate "128000"
format "48000:16:2"
always_on "yes"
}
```
## Setup
```sh
git clone mpd-web-ui
cd mpd-web-ui
pnpm install
```
## Development
```sh
# Start both server and client in dev mode
MPD_HOST=your-mpd-host pnpm dev
```
Open the **Vite dev server** URL shown in the terminal (default `http://localhost:5173/`). Vite proxies `/api` and `/ws` to the backend automatically and provides hot module replacement for instant client updates.
The backend only serves API and WebSocket endpoints in dev mode — client files are served by Vite.
## Production
```sh
pnpm build
pnpm start
```
The server serves the built client SPA and exposes everything on a single port (default 3000).
### Running as a systemd service
A service file example is provided. To start mpd-web-ui automatically with your system:
```sh
# Copy and edit the example service file
cp mpd-web-ui.service.example mpd-web-ui.service
# Edit WorkingDirectory and paths to match your setup
vim mpd-web-ui.service
# Link the service file (stays in the project directory)
systemctl --user link $(pwd)/mpd-web-ui.service
systemctl --user daemon-reload
systemctl --user enable --now mpd-web-ui
# Allow user services to start at boot without login
loginctl enable-linger $USER
```
### Running with Docker
No Node.js or pnpm needed on the host — only Docker:
```sh
git clone mpd-web-ui
cd mpd-web-ui
# Copy and edit the example compose file
cp docker-compose.example.yml docker-compose.yml
# Edit MPD_HOST, PORT, etc. to match your setup
docker compose up -d --build
```
The default config uses `network_mode: host` so the container can reach MPD on localhost.
**Rootless Docker**: `network_mode: host` is silently ignored. Set `MPD_HOST` to your machine's IP address (e.g. `192.168.1.50`), add `ports: ["3000:3000"]`, and remove `network_mode: host`. See the comments in `docker-compose.example.yml`.
## Configuration
Environment variables:
| Variable | Default | Description |
|---|---|---|
| `HOST` | `0.0.0.0` | Server bind address |
| `PORT` | `3000` | Server port |
| `MPD_HOST` | `localhost` | MPD server address |
| `MPD_PORT` | `6600` | MPD TCP port |
| `MPD_PASSWORD` | — | MPD password (if set) |
| `MPD_STREAM_PORT` | `8000` | MPD httpd stream port |
| `CLIENT_DIST_PATH` | `../client/dist` | Path to built client files |
## Project structure
```
mpd-web-ui/
├── packages/
│ ├── shared/ # Shared TypeScript types
│ └── mpd-client/ # MPD TCP protocol client library
├── apps/
│ ├── server/ # Fastify backend (REST + WebSocket + stream proxy)
│ └── client/ # Vue 3 SPA (Vite + Pinia + Tailwind CSS v4)
│ └── src/snapcast/ # Snapcast client (binary protocol, FLAC decoder, Web Audio)
├── package.json
└── pnpm-workspace.yaml
```
## Architecture
```
Browser ──WebSocket──▶ Fastify ──TCP──▶ MPD (control)
Browser ──GET /api/stream──▶ Fastify ──HTTP──▶ MPD httpd (audio)
Browser ──WebSocket──▶ Snapserver (audio via Snapcast, optional)
```
The server maintains two persistent TCP connections to MPD:
- **Command connection** — serialized command queue for playback control, library queries, album art
- **Idle connection** — permanent `idle` loop that receives subsystem change events and broadcasts them to all WebSocket clients in real time
The `/api/stream` endpoint proxies MPD's httpd output so only one port needs to be exposed on your network.
### Snapcast integration
The UI can optionally act as a [Snapcast](https://github.com/snapcast/snapcast) client for synchronized multiroom audio. The browser connects directly to your snapserver — no backend proxy needed.
To use Snapcast:
1. Configure MPD with a FIFO output for Snapcast:
```
audio_output {
type "fifo"
name "Snapcast"
path "/tmp/snapfifo"
format "48000:16:2"
mixer_type "software"
}
```
2. Start snapserver with the FIFO as a source:
```sh
snapserver -s pipe:///tmp/snapfifo?name=default
```
3. In the web UI, click the **Snapcast** button on the Now Playing page, enter your snapserver address (e.g. `192.168.1.50:1780`), and connect. The address is saved for future sessions.
The MPD stream ("Listen") and Snapcast are mutually exclusive — activating one stops the other. Snapcast volume and connection settings are also available in the Settings page.
## License
MIT