Station Player
A music and radio player for the playlists Station Studio makes, built to replace iTunes / Music as the thing that actually plays them.
It plays three kinds of thing:
- Station Studio playlists: the iTunes XML files Station Studio exports, plus any library you export from Music / iTunes (File › Library › Export Library). Tracks play in the order the station generated them.
- Music folders: any folder of audio files (mp3, m4a/aac, flac, wav, ogg/opus, aiff). Each folder shows up as its own playlist.
- Internet radio: any stream URL, including
.plsand.m3ulinks. Rebirth Radio is set up out of the box. When a station sends the name of the song it's playing, Station Player shows it.
Song details and cover art come from the files themselves (mp3, m4a,
flac, ogg / opus, wav, aiff), or from a cover.jpg / folder.jpg in
the album's folder.
It runs as a small local server on your computer with a browser window as
the UI. It needs nothing beyond Python 3.11+ and listens only on
127.0.0.1, so nothing is reachable from your network.
Install and run
You need Python 3.11 or newer and pipx
(macOS: brew install pipx; Windows: py -m pip install --user pipx,
then py -m pipx ensurepath). No checkout of this repo is needed.
pipx install station-player
station-player
Upgrade later with pipx upgrade station-player. Each
Station Player release
also has the wheel attached, for installing without PyPI.
Open it like a normal app
In Sources & settings › App, turn on the shortcut and Station Player appears in the Start menu and on the desktop (Windows), in Applications, Launchpad and Spotlight (macOS), or in the apps menu (Linux). Opening it starts the player in the background and opens its window; opening it again while it runs just brings the window back. Use Quit Station Player in the sidebar to stop it.
Start when I log in starts it quietly in the background at login, so
the shortcut opens instantly. The same switches exist on the command
line: station-player --add-shortcut, --start-at-login and
--remove-shortcuts. Turn them off (or run --remove-shortcuts)
before pipx uninstall station-player.
When started from a shortcut there's no terminal, so messages go to
~/.station-player/station-player.log.
From a checkout, for development:
cd player
python -m station_player
A browser tab opens at http://127.0.0.1:8765/. Useful flags:
station-player ~/Music/Albums ~/exports/week-012.xml # add sources on launch
station-player --port 9000 --no-browser
Setting it up
Open Sources & settings in the sidebar.
- Playlists (iTunes XML). Add an exported
.xmlfile, or a folder of them. On first run Station Player adds Station Studio's exports folder (~/.station-studio/exports) automatically when it exists, so every week you export appears without doing anything. - Music folders. Add the folder your music lives in. Besides appearing under Folders, these files are used to find playlist tracks whose saved location no longer exists (matched by file name).
- Path rewrites. If the playlists were made on another computer, say
a Mac library played back on a PC, rewrite the start of the path:
from
/Users/rob/Music/iTunes/iTunes MediatoD:/Music.
Tracks whose audio file can't be found are greyed out and skipped. Only audio files (mp3, m4a/aac, flac, wav, ogg/opus, aiff, webm) are ever played or served, whatever a playlist file points at.
Settings live in ~/.station-player/config.json (override the folder
with $STATION_PLAYER_HOME). Song details read from your files are
cached beside them in tag-cache.json, so only new or changed files are
read again on later scans.
Playing
- Double-click a track to play from there, or ▶ Play for the whole playlist. Shuffle and repeat (all / one) sit next to the transport.
- Keyboard: Tab into the track list, move with ↑ ↓ (Home / End / Page Up / Page Down), Enter plays. Space plays and pauses; ← and → skip 10 seconds. Keyboard media keys and the OS now-playing panel work through the browser's Media Session support.
- Tracks play back to back with no gap between them, so mixes and live albums flow straight through.
- Up next: the ⋯ button on a track (or right-click, or N / Q on a focused row) offers Play next and Add to queue. Queued tracks play before the rest of the playlist; Up next in the sidebar shows them, and lets you reorder, remove or clear them.
- Search library at the top of the sidebar (or press
/) searches every track in every playlist and folder by title, artist, album or genre. - Close the window and open it again and Station Player is where you left it: the same playlist, queue and track, paused at the same point (or the same radio station). Press play to carry on.
- Volume levelling (Sources & settings › Playback) plays every track at about the same loudness. It uses ReplayGain or iTunes Sound Check information where a file has it, and otherwise measures the track in the browser the first time it plays (or while the track before it plays) and remembers the result. Files over 20 minutes are only levelled when they carry that information.
- Pausing a radio station and pressing play again reconnects to the live broadcast instead of resuming from where it stopped.
- Radio plays through Station Player itself, which is how it can read the song titles stations send (the browser can't). If a station can't be relayed that way, it plays directly, just without song titles.
New versions
Once a day Station Player asks pypi.org for the newest version number
(nothing else is sent). When there's a newer one, the sidebar says so;
update with pipx upgrade station-player and restart it. Turn this off
under Sources & settings › App.
A note on Station Studio's example stations
The example pools bundled with Station Studio are synthetic: their tracks have no audio files behind them, so they load but show as missing. Point Station Studio at an export of your own library and the playlists it generates carry each track's file location through to this player.
Development
cd player
python -m pytest
tests/test_browser.py drives the page in Chromium and is skipped unless
Playwright is installed (pip install playwright && python -m playwright install chromium).
Releasing
Bump version in player/pyproject.toml and merge to main, then run
Actions → Publish Station Player → Run workflow. It tests, builds,
smoke-installs the wheel and creates a player-v<version> GitHub
release with the files attached. Tick Also publish to PyPI to upload
the same files to pypi.org (one-time setup is described at the top of
.github/workflows/publish-player.yml).
The server is station_player/server.py (standard library
http.server), the library reader is station_player/library.py, file
tags and art are read by station_player/tags.py, the radio relay is
station_player/radio.py, shortcuts are station_player/desktop.py,
and the UI is plain HTML / CSS / JS in station_player/static/.
Metadata
Release files for station-player 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| station_player-0.3.0.tar.gz | 203.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| station_player-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 383.0 kB
Release files / station_player-0.3.0.tar.gz
| Download URL | station_player-0.3.0.tar.gz |
|---|---|
| Size | 203.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
15acb62d9abff0348875309c1ae32a72f2753e650a7f2ff4a2ea2cad68203625
|
|
BLAKE2b-256 checksum How to use checksums |
393ca19068e6fcb185902a3cdd7b27a65ae83a44a067b0090c782808f9de717f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.
Transparency logRelease files / station_player-0.3.0-py3-none-any.whl
| Download URL | station_player-0.3.0-py3-none-any.whl |
|---|---|
| Size | 179.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8718cf339bf92a8879cc62e3636b3a7acfe8b542877b183f743dd8be568f59f5
|
|
BLAKE2b-256 checksum How to use checksums |
c1c2bd7d323553b6d3ffed7905f95f5cb9909a8857cdcdb235ba476a45998513
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.
Transparency log