A NetEase Cloud Music player for Android, rendered entirely with QML.
Built on qml4j — a pure-Java QML engine (no Qt, no C++).
Home · light (Monet) | Home · dark | Lyrics · per-syllable + romaji/translation | Lyrics · fluid backdrop + wavy progress
- End-to-end playback over the NetEase Cloud Music API — recommendations, search, your playlists, recent, and local files.
- QR login to NetEase; like/unlike, play queue, play modes (list-loop / shuffle / repeat-one).
- Source switching — grey/VIP/trial tracks fall back automatically to alternate audio sources (GD音乐台 / 波点 / 酷我), matched by title + artist before playing (toggleable).
- Material 3 UI — the whole interface is QML (
md3.Core), running on the qml4j engine. - Dynamic color (Monet) — the theme reseeds from the current cover art (toggleable); full dark / light / follow-system modes.
- System media controls & background playback — a foreground
MediaSessionservice drives the lockscreen / notification / bluetooth transport, with auto-advance, position sync and audio-focus handling (pause on calls, duck on transient loss) while the app is backgrounded. - Lyric page — host-drawn with Skija: per-syllable scrolling (AMLL TTML mirror, NetEase fallback), an Apple-Music-style SkSL fluid backdrop tinted from the cover, romaji + translation with wrapping, alignment-aware interlude dots, animated background vocals, a Material wavy progress bar and an icon-button transport.
- Bundled PingFang font drives the whole UI and lyric page (Latin + CJK); the lyric page's font size, weight and line spacing are configurable in settings.
- In-app back navigation — back/gesture pops the open overlay (lyrics → queue → settings → playlist → tab) instead of exiting.
- Edge-to-edge fullscreen, themed system bars, and a startup splash while the QML tree compiles (dexing is cached across launches, invalidated on reinstall).
| Module | What |
|---|---|
player-core/ |
Platform-neutral core (Maven, dev.t1m3.qplayer): the QML-facing PlayerController, NetEase API, lyric parsers (LRC / YRC / TTML), audio + metadata abstractions. |
android-shell/ |
Android app (Gradle, applicationId dev.t1m3.qplayer, minSdk 26). QML UI in app/src/main/assets/*.qml; host integration + the Skija lyric page in …/android/. |
shared-qml/ |
Vendored md3.Core component library + bundled fonts (PingFang / Material Symbols), at the repo root so the Android shell and a future desktop host can share it. |
| qml4j | The QML engine. A published dependency, not part of this repo. |
qml4j-core is pulled from Maven Central; only the in-repo player-core module is built locally.
Requires JDK 21 and the Android SDK.
# player core → Maven Local
cd player-core && mvn -q -DskipTests install
# the APK (qml4j-core resolves from Maven Central)
cd ../android-shell && ./gradlew :app:assembleDebug
# → app/build/outputs/apk/debug/app-debug.apk- qml4j — the pure-Java QML engine that runs the UI.
- Skija — Skia bindings for the JVM; the renderer and the host-drawn lyric page draw through it.
- material-components-qml — the Material 3 QML component library (
md3.Core) the UI is built from (vendored, engine-adapted). - AMLL TTML DB — syllable-level lyrics.
- Lyric rendering adapted from the Haedus renderer; icons are Material Symbols Rounded.
Personal/educational project. NetEase Cloud Music is a trademark of its respective owner; this app is an unofficial client and is not affiliated with NetEase.



