Skip to main content

PWA remote control for cmus

Project description

cmus-web

PyPI - Version PyPI - Python Version

image

A self-hosted PWA remote control for cmus. Control your player from any device on your network.


Table of contents

Features

  • Real-time player state via SSE (track, position, volume, shuffle/repeat)
  • Embedded album art extraction (MP3, FLAC, M4A, etc.)
  • Installable PWA with offline caching
  • Keyboard shortcuts for all playback controls
  • Customizable accent color (persisted in localStorage)
  • Zero-build frontend (vanilla HTML/CSS/JS + Alpine.js)

A note on PWA and HTTPS

The install/Add to Home Screen prompt only works over HTTPS. Browsers require a secure context for service workers and PWA installation. If you're only accessing cmus-web over LAN on http://192.168.x.x:8000, the app still works fine as a regular web page, you just won't get the install prompt.

If you want full PWA support, you need a domain name with a TLS certificate. This is straightforward with a reverse proxy like Traefik, which handles automatic HTTPS via Let's Encrypt. Put cmus-web behind Traefik and you're done.

Prerequisites

  • Python 3.13+
  • cmus running with a socket (default: $XDG_RUNTIME_DIR/cmus-socket or /tmp/cmus-socket)
  • cmus-remote on your PATH

Installation

From PyPI

pip install cmus-web

Or with pipx (isolated, recommended for CLI tools):

pipx install cmus-web

From source

git clone https://github.com/FawkesOficial/cmus-web.git
cd cmus-web
uv sync

Usage

Make sure cmus is running, then:

cmus-web

Open http://127.0.0.1:8000 in your browser.

CLI options

cmus-web [OPTIONS]

Options:
  --host TEXT       Bind address (default: 127.0.0.1)
  --port INTEGER    Port (default: 8000)
  --socket TEXT     cmus socket path (overrides CMUS_SOCKET env)
  --music-dir TEXT  Path to music directory for album art in Docker
  --prefix TEXT     Host path prefix from cmus-remote to strip (for Docker)
  --help            Show this message and exit.

Examples

# Bind to all interfaces (accessible from other devices)
cmus-web --host 0.0.0.0

# Use a custom socket path
cmus-web --socket /run/user/1000/cmus-socket

# Run on a different port
cmus-web --port 9090

Docker

Important: cmus socket

cmus-web communicates with cmus through a Unix domain socket. If the socket path you mount does not exist on the host, Docker will silently create a directory in its place, which will break the connection and can be confusing to debug.

Use this helper script to verify the socket exists before starting the container:

#!/usr/bin/env bash
# start-cmus-web.sh - verify cmus socket exists, then start the container

SOCKET="${CMUS_SOCKET:-$XDG_RUNTIME_DIR/cmus-socket}"

if [ ! -S "$SOCKET" ]; then
  echo "Error: cmus socket not found at $SOCKET"
  echo "Make sure cmus is running and the socket path is correct."
  exit 1
fi

docker run -d \
  -v "$SOCKET":/tmp/cmus-socket \
  -v ~/Music:/music \
  -e CMUS_WEB_PREFIX="$HOME/Music" \
  -p 8000:8000 \
  cmus-web

docker run

docker build -t cmus-web .

docker run -d \
  -v /run/user/1000/cmus-socket:/tmp/cmus-socket \
  -v ~/Music:/music \
  -e CMUS_WEB_PREFIX=/home/user/Music \
  -p 8000:8000 \
  cmus-web

The music volume mount enables album art extraction. Use CMUS_WEB_PREFIX to tell cmus-web what host path to strip from cmus-remote file paths so they resolve correctly inside the container.

docker compose

services:
  cmus-web:
    build: .
    container_name: cmus-web
    ports:
      - "8000:8000"
    volumes:
      - /run/user/1000/cmus-socket:/tmp/cmus-socket
      - ~/Music:/music
    environment:
      - CMUS_WEB_PREFIX=/home/user/Music
    restart: unless-stopped
docker compose up -d

Keyboard shortcuts

Key Action
Space / C Play / Pause
B Next track
Z Previous track
S Toggle shuffle
R Toggle repeat
L Search lyrics online
+ / - Volume up / down
Arrow Left / Right Seek -5s / +5s
Arrow Up / Down Volume up / down

Tech stack

  • Backend: Python, FastAPI, uvicorn, Mutagen, SSE-Starlette
  • Frontend: Vanilla HTML/CSS/JS, Alpine.js
  • Packaging: uv, Hatchling
  • Container: Debian slim, uv

License

cmus-web is distributed under the terms of the GPL-3.0 license.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cmus_web-0.1.2.tar.gz (132.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cmus_web-0.1.2-py3-none-any.whl (103.6 kB view details)

Uploaded Python 3

File details

Details for the file cmus_web-0.1.2.tar.gz.

File metadata

  • Download URL: cmus_web-0.1.2.tar.gz
  • Upload date:
  • Size: 132.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for cmus_web-0.1.2.tar.gz
Algorithm Hash digest
SHA256 4ba8abd8a273a2ebdc69c4559348cd8360284c10a400d721c11be83477643728
MD5 e6f12cfa3c78b47360e49293284c6b0a
BLAKE2b-256 4d8bfeac3328833312c1a4d2bd5d3170c722ba0d681ee4fa292da4ed9842d252

See more details on using hashes here.

Provenance

The following attestation bundles were made for cmus_web-0.1.2.tar.gz:

Publisher: python-publish.yml on FawkesOficial/cmus-web

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cmus_web-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: cmus_web-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 103.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for cmus_web-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 e746e0cadb002ba249a80293af84a1c8da1ddde870306ce2517605e5777330f0
MD5 a853b45e596cb893538f8d875b115f95
BLAKE2b-256 5f173fee3769ca6dbc21c89c6e195b9d2214584b10129e16352862f3ae1eedb4

See more details on using hashes here.

Provenance

The following attestation bundles were made for cmus_web-0.1.2-py3-none-any.whl:

Publisher: python-publish.yml on FawkesOficial/cmus-web

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page