MD3Music ships its own music API server inside the APK, and the build matrix does not match the feature list
Third-party music player modeled on Kugou's concept edition, built with Flutter + Rust.
At a glance
- What is it?
- A Flutter and Rust Android client for the Kugou music API, with the API layer compiled into a committed .so and bound to localhost. The packaging, the ABI matrix and the LAN cast server are where the interesting details sit.
- Who is it for?
- Settle the service terms before the code. MD3Music is a Flutter and Rust Android client built on the Kugou music API, and the first question for any reader is whether their own account and their own listening sit inside those terms, because the project's own notice limits it to study, points at a DISCLAIMER file, and rules out casting in public places or for group viewing.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Dart, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 14, 2026, and from our analysis. They are not legal advice.
Star history
- zzyoxml/md3Music1,426 ★ · +861
| Repository | 2026-09-21 | 2026-11-14 |
|---|---|---|
| zzyoxml/md3Music | 565 | 1.4k |
861 Stars in the last 54 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
The default branch is rust-local-force, a script-pushed copy of a private tree
The repository's default branch is not `master` and not `main`. It is `rust-local-force`, and the reason is stated plainly in the overview: development happens in a private repository, that synchronisation overwrites the public code, and the public branch is therefore pushed in full by a script rather than edited by hand. For a reader this means the default branch is a mirror, and the mirror is what release tags point at.
Versioning is driven by tags rather than branches. Pushing a `v*` tag triggers the workflow, which builds the APKs, opens a GitHub Release, increments versionCode and generates a changelog, preferring the matching section of `CHANGELOG.md` when one exists. The three most recent releases sit thirteen days apart: v5.6.5 on 2026-09-17, v5.7.0 on 2026-09-22 and v5.8.0 on 2026-09-30. The last push to the repository is dated 2026-10-02. Alongside that cadence sits a warning that every version and branch before V5 has been deprecated and permanently deleted, so an older checkout found elsewhere is not a fallback.
The server binary is committed, which is why Rust is optional and the API layer is never compiled by default
`libkugou_server.so` is committed to the repository, and that one fact explains the whole build path. At app start the Dart side loads it through a MethodChannel, and the Rust code inside brings up a `tiny_http` server bound to `127.0.0.1`, which is how every Kugou API request ends up handled on the device instead of on a server the user has to run.
Rebuilding it is conditional. The notes say the binary only needs to be built again when files under `kugou_api_server/rust/src/` change:
cd kugou_api_server/rust
cargo build --releaseThe cross-compile path needs more:
./build_android.shFour ABIs, and the Android NDK. The stated prerequisites are Flutter 3.47.0 or newer, Dart 3.12.0 or newer, Rust 1.70 or newer, Android Studio or VS Code, and NDK 28, with Flutter 3.47.5, Dart 3.12.x and NDK 28 named as the verified combination. Keeping the toolchain optional also means a default build never compiles the part of the project that actually talks to the music service.
The CI matrix publishes three ABIs while the feature list claims four
The build matrix and the feature list disagree about 32-bit x86. The feature list names four architectures: armeabi-v7a, arm64-v8a, x86 and x86_64, with x86_64 labelled for emulators. The cross-compile script agrees with the feature list, and its comment names four ABIs. The GitHub Actions workflow, which is what produces the published releases, builds three: arm64-v8a, armeabi-v7a and x86_64. The architecture the overview advertises is the one that never reaches a release page, while the emulator build does.
That gap matters for anyone testing against an older 32-bit emulator image, because the only route to a 32-bit x86 APK is a local `./build_android.sh` run with NDK 28 installed rather than a download. The 64-bit arm build is described as the default download for ordinary devices, and the 32-bit arm APK as the one for older hardware. The same workflow also increments versionCode and writes the changelog from the tag, so an artifact you compile yourself has no versionCode history behind it at all.
Chinese release filenames sit on top of the English names Gradle produces
The packaging step renames artifacts after the build, which is why the download list in the overview is written in Chinese while the internal names are not. The script's own note says Flutter and Gradle still produce `app-<abi>-<flavor>-<type>.apk` inside the build directory, and that calling the Flutter build command directly gives the English native names instead:
flutter build apk --release --flavor standard --split-per-abiThe one-line packaging entry point is a PowerShell script, not a shell one:
.\scripts\md3.ps1 androidIts comment claims a default of release mode, two flavors and all ABIs, then names five outputs in the same block, three of them for 64-bit alone: the standard build, a 3D cover edition carrying a built-in depth cover, and a compatibility edition for Vivo's atomic player, which uses the package name `com.apple.android.music`. Whether the standard build is one of the two flavors or a third variant is not settled anywhere in the overview. That package identifier belongs to Apple's own Android app, and the only reason offered for it is compatibility with the named device.
The cast server is a plain LAN HTTP server, and no authentication step is described
Casting is built into the app rather than delegated to the system. A local HTTP server with Range request support is started on the network so that files in the local music folder can be sent to a DLNA device, which is a separate job from the `127.0.0.1` server that handles API traffic. The overview describes that LAN server in one line and does not say whether a token, a pairing step or a network allowlist is involved, so the sensible reading is that whatever network the phone sits on should be treated as one where the local library is reachable.
The project draws its own boundary around the feature. Casting is described as using the general-purpose DLNA and AirPlay transports, intended for streaming to playback devices the user legally owns inside a personal home network, with no re-storage, redistribution or public transmission of the music files involved. The same notice rules out public venues and multi-person synchronized viewing. A separate disclaimer file and a study-only statement cover the rest: the app presents itself as built on the Kugou music API, carries an AGPL-3.0 license, and is explicitly not for commercial use.
Two features reach past the Dart layer, one through a vendor flag and one through usbdevfs
The technology table is most revealing where it leaves Dart behind. The status bar lyric ticker is described as a Flyme ticker built on a private Meizu flag, with an adjustable lead time, which is a vendor-private mechanism: it does what the overview says on Flyme devices, and nothing is described for any other ROM. The USB exclusive output path runs through native JNI plus CMake C++ over usbdevfs, and the overview gives no permission path, root requirement or device list for it. Song recognition is lighter: the `record` package for capture plus Rust preprocessing of the PCM.
The rest of the stack is conventional, and naming it explains the feature list. State is Provider, animation is `m3e_core` for M3 Expressive Motion, playback is `just_audio` with `just_audio_background` and `audio_session` for focus, networking is Dio, storage is SharedPreferences plus SQLite, casting is `dlna_dart`, and metadata for MP3, FLAC and M4A goes through `audio_metadata_reader` and JAudioTagger. `core/services/` is where these live, and the tree lists nine of them: audio, USB exclusive output, equalizer, DLNA casting, spectrum, desktop lyrics, word curtain and the home widget.
Chinese-only documentation, and two diagrams that stop before they finish
The repository ships one README, written in Chinese with an English tagline, and its language switch offers 简体中文. The root listing contains no English README file, no `README_CN.md` counterpart and no docs directory to fall back on, so an English reader works from the Chinese text or not at all.
The two structural listings do not finish. The architecture diagram shows the Flutter UI on one side and the embedded Rust API server on `127.0.0.1` on the other, joined by a JNI and FFI line, and then stops at a downward arrow with no box beneath it, so the layer receiving the call is never drawn. The project tree lists `lib/main.dart`, `lib/app.dart`, `core/` with `layout/`, `services/`, `theme/` and `utils/`, `data/` with `models/` and `repositories/`, and `modules/` with `home/` and `launch`, and stops there. Everything under `modules/` past those two directories is undescribed, which covers most of the feature list: search, daily recommendations, charts, private FM, cloud drive, audiobooks, MV playback, listening history and multi-account management all live in the part of the tree the documentation never reaches.
Editorial conclusion
Settle the service terms before the code. MD3Music is a Flutter and Rust Android client built on the Kugou music API, and the first question for any reader is whether their own account and their own listening sit inside those terms, because the project's own notice limits it to study, points at a DISCLAIMER file, and rules out casting in public places or for group viewing. Assuming that is answered, the engineering is legible and honest about its edges. The embedded Rust server replaced an earlier Node.js approach, the toolchain floor stays low because the prebuilt server binary is committed, and the packaging script names every artifact it emits. Three specifics deserve checking before you build on it. The release workflow produces three ABIs while the feature list and the cross-compile script both name four, so 32-bit x86 has no published artifact. The cast server is a plain LAN HTTP server with Range support and no authentication step described anywhere, so treat its network as trusted. And the documentation is Chinese only, with the architecture diagram and the module tree both stopping before they finish. Anyone expecting English docs and a 32-bit x86 download will find neither here.
Frequently asked questions
What is the MD3Music app built on?
It is a Flutter and Rust Android music player built on the Kugou music API. An embedded Rust API server bound to 127.0.0.1 handles the requests on the device, replacing an earlier Node.js approach with lower memory use and a faster start.
Do I need Rust installed to build MD3Music?
Not for a default build. The server binary libkugou_server.so is committed to the repository and only needs rebuilding when files under kugou_api_server/rust/src/ change. That path needs Rust 1.70 or newer and Android NDK 28 for the four-ABI cross-compile.
Which CPU architectures does the published MD3Music build include?
The GitHub Actions workflow builds arm64-v8a, armeabi-v7a and x86_64. The feature list and the cross-compile script both name four architectures including 32-bit x86, which does not appear in a release artifact.
What is the default branch of the MD3Music repository?
It is rust-local-force. The overview states that synchronisation from the private development repository overwrites the public code, and that the public branch is now pushed in full by a script.
Does MD3Music need an external server to run?
No. A Rust tiny_http server on 127.0.0.1 starts when the app launches, and all Kugou API requests are processed locally, so there is no backend for the user to host.
Under what conditions does the project permit casting?
Casting uses the standard DLNA and AirPlay transports to reach playback devices the user legally owns inside a personal home network, with no re-storage or redistribution of the files. The overview rules out public venues and multi-person synchronized viewing, states the project is for study rather than commercial use, and links a separate disclaimer file.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/zzyoxml-md3music)Star history chart for your README
[](https://hysenlabs.com/projects/zzyoxml-md3music)Was this useful?