Skip to main content

Squeezy

Minimal Squeezebox-compatible player for Lyrion Music Server (formerly Logitech Media Server). Advertises as a player on your network, receives streaming audio, and plays it back through your default audio output. Supports synchronized playback with other players.

Before you use this

If you can run a binary, use LocalPlayer instead. It's a Lyrion Music Server plugin that bundles squeezelite — a proper, mature, battle-tested C implementation. It installs in two clicks from the LMS plugin browser, handles every edge case, and just works. Nearly every protocol detail and edge case in squeezy was reverse-engineered from squeezelite's source. It is the gold standard and the direct inspiration for this project.

Squeezy exists for one narrow situation: you're on a machine where you can't run an unverified or unpackaged binary — a locked-down work laptop, a corporate machine with strict security policy, a CI environment — but you can run Python packages. That's how this project started: wanting to listen to music on a work laptop through Lyrion without having to file an IT ticket to run a compiled binary from the internet. pip install squeezy and it just works.

If that's not your situation, seriously — go use LocalPlayer. It's better in every way.


Note: This project was largely vibe-coded with Claude. It passes ~100 tests and works reliably day-to-day, but treat it accordingly.


Requirements

  • macOS, Linux, or Windows
  • Python 3.9+
  • ffmpeg

Install

Pick whichever method suits you. All three result in a squeezy command on your PATH.

# macOS
brew install ffmpeg pipx
pipx install squeezy

# Debian/Ubuntu
sudo apt install ffmpeg pipx
pipx install squeezy

Option 2: Homebrew tap (macOS only)

brew tap catcatcatcatcatcatcatcatcatcat/tap
brew trust catcatcatcatcatcatcatcatcatcat/tap
brew install squeezy

This installs ffmpeg automatically as a dependency.

Option 3: From source

git clone https://github.com/catcatcatcatcatcatcatcatcatcat/squeezy.git
cd squeezy
python3 -m venv .venv
source .venv/bin/activate
pip install .

For development (run directly without installing):

./run.sh -n "My Speaker" -vv

Squeezy checks for updates on startup and will notify you when a new version is available.

Usage

# Auto-discover server on local network
squeezy

# Specify server and player name
squeezy -s 192.168.1.100 -n "Kitchen Speaker"

# Custom MAC address (for persistent player identity)
squeezy -m aa:bb:cc:dd:ee:ff

# List available audio output devices
squeezy -l

# Use a specific audio output (substring match, case-insensitive)
squeezy -d "HDMI" -n "Living Room"

# Verbose logging (connection, playback events, volume changes)
squeezy -v

# Debug logging (protocol-level detail: strm commands, STAT packets)
squeezy -vv

# Check installed version
squeezy --version

Your player will appear in the Lyrion Music Server web UI. Select it from the player dropdown to start streaming.

macOS: Connection failed: [Errno 65] No route to host

If squeezy can't reach LMS (or discovery finds nothing) while the server is plainly up, macOS is refusing Local Network access for Python. The permission is judged per process, terminals such as iTerm2 don't pass their own grant on to the programs they run, and macOS never shows a prompt for that case — it just denies. Trigger the prompt directly:

squeezy --request-local-network -s 192.168.1.100   # click Allow when macOS asks

The grant is tied to the exact Python binary, so repeat this after upgrading Python (e.g. brew upgrade). You can also toggle Python on under System Settings → Privacy & Security → Local Network.

Project Structure

src/squeezy/
├── squeezy.py              # Main player orchestrator & audio pipeline
├── audio/
│   └── stream_decoder.py   # Thread-safe PCMBuffer
├── protocol/
│   ├── handler.py          # SlimProto message handlers (strm, audg, setd, etc.)
│   ├── slimproto.py        # Protocol constants & packet builders
│   └── lms_client.py       # LMS message operations
├── network/
│   ├── server_connection.py # TCP/UDP socket management & discovery
│   ├── local_network.py    # macOS Local Network permission hint & prompt trigger
│   ├── lms_metadata.py     # LMS JSON-RPC track metadata queries
│   └── status_server.py    # Unix socket status server
└── config/
    ├── config.py           # XDG-compliant config persistence
    └── metadata.py         # ICY metadata & LAME gapless parsing

Contributing

See DEVELOPER.md for a full walkthrough of the repo structure, how to set up a dev environment, and how to cut a release.

How it works

Squeezy implements the SlimProto protocol to communicate with Lyrion Music Server:

  1. Discovers the server via UDP broadcast on port 3483
  2. Registers as a player via TCP (HELO packet)
  3. Receives stream commands from the server
  4. Fetches audio via HTTP, decodes with ffmpeg, outputs via miniaudio
  5. Reports playback status back to the server for sync coordination

Uninstall

# If installed via pipx
pipx uninstall squeezy

# If installed via Homebrew
brew uninstall squeezy
brew untap catcatcatcatcatcatcatcatcatcat/tap

Releasing (for maintainers)

See DEVELOPER.md for the full release process. The short version: bump version in pyproject.toml, tag, build, upload to PyPI, update the Homebrew tap.

License

MIT

Metadata

Release files for squeezy 0.8.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for squeezy 0.8.0
File Size Uploaded
squeezy-0.8.0.tar.gz 78.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for squeezy 0.8.0
File Interpreter ABI Platform
squeezy-0.8.0-py3-none-any.whl Python 3 none any Details

Total release size: 143.4 kB

Release files / squeezy-0.8.0.tar.gz

Download URL squeezy-0.8.0.tar.gz
Size 78.8 kB
Tags Source
SHA-256 checksum
How to use checksums
2cb20ada7dcfe1fed0326e25e4cf0f4bc1e332ab69fef3028278750a4c798fec
BLAKE2b-256 checksum
How to use checksums
6b785ab614118e7667cf05039b4e958fc709e03efd82660eb46c06f0db7fe7f8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release files / squeezy-0.8.0-py3-none-any.whl

Download URL squeezy-0.8.0-py3-none-any.whl
Size 64.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bdccc1c368504953cc561b42eaae724a02f921eb9de056c30042dda7f19246b3
BLAKE2b-256 checksum
How to use checksums
8d5fadbbb65bc93a12e85d9a994a4118f6706d6c8f288f06115e11df3a457bd2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release history Release notifications | RSS feed

This release

0.8.0 This release

2 release files

0.7.0

2 release files

0.6.4

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page