中文 | English
FuoEvolve is an open-source music player based on the FeelUOwn ecosystem. Android is usable today. Experimental iOS build support is available, but iOS is not released.
The project uses Kotlin Multiplatform and Compose Multiplatform for shared UI, state, and player contracts. On Android it packages the FeelUOwn Python core and provider plugins with Chaquopy, then plays audio and video through AndroidX Media3.
| Channel | Link | Packages |
|---|---|---|
| Stable | Latest GitHub Release | Signed release APKs for arm64-v8a, x86_64, and universal devices. |
| Canary | Latest master Android APK workflow | Artifacts from the newest successful master build: signed debug APK for development debugging, plus signed release APKs for arm64-v8a, x86_64, and universal devices. |
iOS builds are experimental debug artifacts only. They are not published as GitHub Releases or supported for end-user installation.
- 🎵 FeelUOwn-based online music provider integration on Android.
- 🔎 Search across enabled providers and local music, with provider filtering.
- 🧭 Typed provider search tabs for songs, artists, albums, playlists, and videos where the upstream provider supports those result types.
- 🏠 Provider home sections for recommendations, exploration, user playlists, and favorites.
▶️ Media3 audio playback, video/MV playback, queue management, shuffle, repeat, up-next, multi-part tracks, covers, and LRC lyrics.- 🔁 Smart replacement for unavailable tracks, with configurable provider pool, score threshold, metadata policy, and lyric policy.
- ⬇️ Downloads, app-private lyrics, local music database, local metadata edits, and provider-assisted metadata/lyric lookup.
- 🔗 Direct system sharing with App Link-friendly share URLs.
- ⚙️ Runtime settings for providers, login, quality, playback behavior, local scan filters, cache limits, lyrics, and theme.
Provider packages currently bundled in the Android app:
| Provider | Package | Default | Login modes |
|---|---|---|---|
| NetEase Cloud Music | fuo_netease==1.0.8 |
Enabled | WebView, Cookie |
| QQ Music | fuo-qqmusic==1.0.16 |
Available in Settings | WebView, Cookie |
| Bilibili | feeluown-bilibili==0.5.5 |
Available in Settings | WebView, Cookie |
| YouTube Music | fuo-ytmusic==0.4.18 |
Available in Settings | WebView, Headers |
The app loads NetEase by default. QQ Music, Bilibili, and YouTube Music are packaged and can be enabled, disabled, or reordered from Settings.
Legend: ✅ supported, including features that require login; 🧩 supported only when the upstream provider exposes the required method or result type; ➖ not exposed in the app today.
| Feature | NetEase | QQ Music | Bilibili | YouTube Music |
|---|---|---|---|---|
| Provider login/logout | ✅ | ✅ | ✅ | ✅ |
| Song search | ✅ | ✅ | ✅ | ✅ |
| Artist / album / playlist / video search tabs | 🧩 | 🧩 | 🧩 | 🧩 |
| Daily songs | ✅ | ✅ | ➖ | ✅ |
| Recommended playlists | ✅ | ✅ | ➖ | ✅ |
| Private FM / radio | ✅ | ✅ | ➖ | ➖ |
| Top lists | ✅ | ➖ | ➖ | ✅ |
| User playlists | ✅ | ✅ | ✅ | ✅ |
| Favorite songs | ✅ | ✅ | ➖ | ✅ |
| Favorite playlists | ✅ | ✅ | ✅ | ✅ |
| Favorite artists | ✅ | ✅ | ➖ | ✅ |
| Favorite albums | ✅ | ✅ | ➖ | ✅ |
| Add song to user playlist | 🧩 | 🧩 | 🧩 | 🧩 |
| Remove song from playlist | 🧩 | 🧩 | 🧩 | ➖ |
| Similar songs / hot comments / song MV | 🧩 | 🧩 | 🧩 | 🧩 |
| Video playback | 🧩 | 🧩 | 🧩 | 🧩 |
Provider behavior can still vary with upstream service limits, region, login state, and the exact FeelUOwn provider implementation.
| Area | Current options |
|---|---|
| 🎛️ Providers | Enable or disable packaged providers, reorder provider priority, manage provider login, and switch login mode per provider. |
| 🎧 Audio quality | Separate Wi-Fi and cellular policies: highest, high, standard, or low-data. |
| 🔁 Unavailable tracks | Smart replacement or skip. Smart replacement can choose providers, minimum score, replacement metadata, and replacement lyrics. |
| 🖼️ Playback display | Lyrics font size, system/light/dark mode, dynamic color, and preset color schemes. |
| 💽 Local music | Media permission entry, database-backed refresh, grouping by all/artist/album, directory inclusion, and minimum-duration filter. |
| ✏️ Local metadata | Edit title/artist/album, search provider metadata, and download lyrics into app-private storage. |
| 🧹 Cache | Configurable audio cache and image cache limits. |
| ⬇️ Downloads | Download provider tracks, play downloaded tracks locally, and remove downloaded files. |
| 🐞 Debug builds | Debug log viewer is available only in debug builds. |
shared: shared Compose UI, domain contracts, player state, common tests, and the shared Python bridge.androidApp: Android application, Chaquopy packaging, Media3 playback, assets, resources, and provider bridge wiring.shared/src/commonMain/python/fuo_mobile: Python adapter around the FeelUOwn core and provider plugins.iosApp/FuoEvolve: Swift app shell for experimental iOS builds..github/workflows: Android APK and release workflows, plus the experimental iOS debug workflow.
- JDK 17 or newer.
- Android Studio or Android command-line tools for Android builds.
- Python 3.12 when a local Chaquopy build Python is needed.
- Xcode on macOS for experimental iOS builds.
Build a debug Android APK with the checked-in Gradle wrapper:
./gradlew :androidApp:assembleDebugInstall it on a connected device or emulator:
./gradlew :androidApp:installDebugThe Android build packages FeelUOwn and provider plugins through Chaquopy. The
default FeelUOwn source is the PyPI 5.1.2 sdist, and provider packages are
declared in androidApp/build.gradle.kts.
The iOS project under iosApp/FuoEvolve.xcodeproj has experimental debug-build
support, including shared UI integration and Python runtime preparation. Every
push to master builds a simulator debug artifact in GitHub Actions. iOS is not
released: do not treat its artifacts as production-ready or expect a GitHub
Release, App Store distribution, or end-user installation support.
Prepare the Python runtime locally before building in Xcode:
bash scripts/prepare-ios-python.shProvider and playback integration remain experimental.
Run shared multiplatform tests:
./gradlew :shared:allTestsRun Android lint checks:
./gradlew :androidApp:lint :shared:lintTo add a provider, declare the Python dependency in androidApp/build.gradle.kts,
add it to the Android provider registry, expose it from Settings, and wire any
provider-specific login or feature definitions in the bridge. The default enabled
provider set is NetEase:
{
"enabled": ["netease"]
}FuoEvolve is licensed under the GNU General Public License v3.0. See LICENSE for details.