- Rust 58.8%
- Python 22.6%
- Kotlin 14.6%
- HTML 1.5%
- JavaScript 1.1%
- Other 1.4%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
Some checks failed
Build and release / termux-alpha (push) Successful in 9m14s
Build and release / build (x64, musiczero-windows-x64, windows-2022, windows, x86_64-pc-windows-msvc, clang-cl) (push) Successful in 16m28s
Build and release / build (arm64, musiczero-windows-arm64-alpha, windows-11-arm, windows, aarch64-pc-windows-msvc, clang-cl) (push) Successful in 16m56s
Build and release / build (x64, musiczero-linux-x64, ubuntu-24.04, linux) (push) Failing after 17m0s
Build and release / build (arm64, musiczero-linux-arm64-alpha, ubuntu-24.04-arm, linux, aarch64-unknown-linux-gnu) (push) Successful in 20m7s
Build and release / android (push) Successful in 12m55s
Build and release / release (push) Has been skipped
`for (root, relative, kind) in WINDOWS_LOCATIONS` iterates a `&[(&str, &str, Kind)]` and yields &Kind, which failed the Windows build with E0308 (expected Kind, found &Kind) — the cfg(windows) code never compiles on a Linux host, so it only surfaced on CI. Two structural fixes so this class of error is caught locally instead of by the runner: the install-location scan is no longer cfg-gated (the PROGRAMFILES lookups simply return None on Linux), and portable_url selects the platform at runtime through std::env::consts instead of cfg blocks. Every branch of the new code now compiles and is type-checked on every build. |
||
| .forgejo/workflows | ||
| android | ||
| examples/module-template | ||
| mcz | ||
| modules | ||
| mz | ||
| scripts | ||
| tests | ||
| .gitattributes | ||
| .gitignore | ||
| AGENTS.md | ||
| bootstrap.sh | ||
| Cargo.lock | ||
| Cargo.toml | ||
| install-linux.py | ||
| install-windows.ps1 | ||
| install.sh | ||
| LICENSE | ||
| README.md | ||
| README_RU.md | ||
MusicZero
One player — five sources. The music stays music; the engine is one.
Yandex Music · YouTube Music · Spotify · local folder · Icecast radio
Русский · Releases · Project internals
The mz program owns audio, queue and control; sources plug in as modules —
separate executables that live beside the player. The same engine runs on
Linux, Windows and Android.
Features
- One player, swappable sources: switch without restarting, per-service playlists
- Preloads up to 8 upcoming tracks so transitions are instant
- Control from anywhere: CLI, full-screen TUI, web panel in a browser, Linux/Windows tray, MPRIS, Windows media keys, Android notification buttons
- The web panel works from a phone on the same network and can be added to the home screen
- Live Icecast radio without gaps, LIVE marker and automatic reconnection
- Five-track history with going back
- Russian and English interface
- Native Android app with Android Auto
Sources and requirements
| Module | What you listen to | What it needs |
|---|---|---|
ymz |
Yandex Music, My Wave | account + an OAuth token (see "First steps") |
youmz |
YouTube Music, jam mixes | any Chromium/Firefox browser sign-in (a portable one is downloaded otherwise), yt-dlp for audio |
spotify |
Spotify tracks and playlists | Premium account + client_id from Dashboard |
local |
your music folder | ffmpeg and ffprobe; MIDI also needs fluidsynth and an SF2 bank |
icecast |
internet radio | ffmpeg and a stream URL |
Install
Linux
curl -fsSL https://forgejo.xatacraft.ru/bbqqyt/MusicZero/raw/branch/main/install-linux.py | python3
The installer picks the right archive from the releases, verifies SHA-256, installs
into ~/.local/bin and opens a setup wizard: folder, PATH, missing packages,
service sign-ins. Re-running updates the program and keeps your settings.
- If
mzis "not found", add~/.local/binto PATH MUSICZERO_PREFIXchanges the install prefix,MUSICZERO_TAGpicks a specific release--tui --setup-onlyopens only the wizard,--non-interactiveskips all questions
Android
Install the APK from the releases
(Android 8+ ARM64). The engine and modules install on first launch; control is
what you expect from a normal app, plus Android Auto. Inside the app sandbox
ymz and youmz work (the token is pasted in the app); local sees only the
private folder.
A Termux build exists for the terminal route: pkg install yt-dlp and the usual mz commands.
Windows
Download musiczero-windows-x64.zip (or ARM64) from the releases and run:
.\install-windows.ps1 # install into %LOCALAPPDATA%\MusicZero + PATH
.\install-windows.ps1 -Check # verify the archive layout
.\install-windows.ps1 -Uninstall # remove files, PATH entry, shortcut
Tray and media keys work out of the box; MPRIS is replaced by system SMTC.
From source
git clone https://forgejo.xatacraft.ru/bbqqyt/MusicZero.git
cd MusicZero && ./install.sh # needs Rust and libasound2-dev
First steps
mz ymz # start the player with Yandex Music (or mz local, mz spotify…)
mz player # full-screen player: track, progress, queue, controls
mz web # web panel in a browser; from a phone use mz web --lan
Sign in to services once:
mz login ymz # Yandex Music
mz login youmz # YouTube Music (opens a browser)
mz set spotify client_id <32-hex> && mz login spotify
mz set local path ~/Music
Control
| Command | Action |
|---|---|
mz <module> |
start the player |
mz player |
full-screen TUI player (aliases now, np) |
mz web [--lan] |
web panel: track, seeking, volume, queue, source switching |
mz next / mz prev |
next / previous track |
mz toggle |
pause / resume |
mz seek 1:30 / +15 / -10 |
position and offsets |
mz volume 40 |
volume 0–100 |
mz history / mz replay 2 |
history and replaying a track from it |
mz playlist <id> |
choose a playlist |
mz switch <module> |
change source without restarting |
mz status |
what is playing now |
mz quit |
stop the player |
In the TUI: space — pause, n/b — tracks, ←/→ — ±5 s, s — position,
Enter — replay from history, m/l — source and playlist, Esc — exit.
On a phone the web panel is the primary remote: mz web opens the browser itself,
the page can be added to the home screen, and --lan opens access from another
device on the same network (guarded by the 128-bit key embedded in the link).
Settings
Everything is configured in one interactive menu with hints in both languages:
mz config # all settings: player and modules
mz config ymz # a specific module right away
From scripts or for a quick change:
mz set mz preload_tracks 3 # how many tracks to fetch ahead (0–8)
mz set mz tray_enabled off
mz set local path ~/Music
mz set icecast url https://radio.example:8443/stream
mz settings local # see current values
Settings live in ~/.config (Linux) or %APPDATA% (Windows): mz/settings.json
for the player, ymz/token, youmz/session, mz-spotify/, mz-local/,
mz-icecast/ for the modules. Secrets are written with 0600 permissions.
Downloaded audio lives only in the temporary directory and cleans up after itself.
Useful environment variables: RUST_LOG (log level, default warn,mz=info),
TMPDIR (where preloaded audio goes), MZ_MODULES_DIR (module dir for development).
Writing your own module
A module is a plain executable speaking a JSON protocol over stdin/stdout.
The template with a ready 440 Hz tone sits in
examples/module-template: build it, drop it next to
mz in modules/<id>/ with a manifest — and it appears in the list.
The full protocol description is in AGENTS.md.
Development
cargo test --workspace --locked # unit tests
cargo build --workspace --release --locked
python3 tests/smoke_seek.py # integration runs (see AGENTS.md)
./scripts/build-android.sh # Android APK (needs the NDK)
Repository layout: mz/ — the player, mcz/ — shared library, modules/ —
providers, android/ — the app, tests/ — integration tests.
Build details, the protocol and internal constraints are in AGENTS.md.
Common problems
| Symptom | Cause and fix |
|---|---|
mz: command not found |
~/.local/bin is not in PATH |
| No sound on Linux | ALSA or a PipeWire/PulseAudio bridge is required (libasound2-dev to build) |
| YouMZ does not play | yt-dlp missing from PATH: sudo apt install yt-dlp or pkg install yt-dlp |
| Local tracks not found | mz set local path "/path with spaces"; check mz settings local |
| Yandex token expired | mz login ymz — get a new one and paste it |
| Radio keeps dropping | a direct stream is required (not an HTML page); check mz set icecast url … |