A local-first, FOSS Android music player built with Kotlin, Jetpack Compose, and Material 3.
PixelPlayerOSS is an Android music player maintained by @lostf1sh. It focuses on local playback, self-hosted music libraries, expressive Material 3 UI, and user-controlled online lookups.
The app works offline by default. Optional online services are disabled until you enable them in setup or settings.
Package name: com.lostf1sh.pixelplayeross
PixelPlayerOSS keeps the player FOSS-oriented and removes integrations that are not part of that direction.
Removed integrations include Telegram, NetEase, QQ Music, Google Drive, Gemini, Cast, Wear OS, Play Store billing, Firebase, Crashlytics, and Google Play Services runtime dependencies.
Cloud playback is limited to self-hosted sources: Navidrome/Subsonic and Jellyfin.
| Area | Highlights |
|---|---|
| Playback | Media3 playback engine, FFmpeg support, gapless playback, crossfade, custom transitions, queue controls, shuffle, repeat, sleep timer, external file playback |
| Library | Local scanning for MP3, FLAC, AAC, OGG, WAV, M4A, albums, artists, genres, folders, favorites, playlists, stats, metadata editing |
| Self-hosted | Navidrome/Subsonic login, sync, streaming, artwork, Jellyfin login, sync, streaming, artwork |
| Lyrics | Embedded lyrics, local .lrc files, lyrics import/editing, optional LRCLIB lookup |
| Artwork | Local artwork, album-art palette extraction, optional Deezer artist image lookup |
| UI | Jetpack Compose, Material 3, dynamic color, light/dark themes, Glance widgets, animated player surfaces |
| Backup | Preferences, playlists, favorites, lyrics, stats, and app state backup/restore |
PixelPlayerOSS separates offline playback from network lookups.
| Service | Purpose | Default |
|---|---|---|
| Navidrome/Subsonic | Self-hosted library sync and streaming | User login required |
| Jellyfin | Self-hosted library sync and streaming | User login required |
| LRCLIB | Search online lyrics when local or embedded lyrics are missing | Off |
| Deezer | Fetch missing artist artwork and cache it locally | Off |
LRCLIB and Deezer can be enabled during first-run setup or later from Settings > Music Management > Optional online services.
| Requirement | Version |
|---|---|
| Android | 11 or newer, API 30+ |
| JDK | 21 |
| Android SDK | compile/target 37 |
Clone the repository:
git clone https://github.com/lostf1sh/PixelPlayerOSS.git
cd PixelPlayerOSSBuild the debug APK:
JAVA_HOME=/usr/lib/jvm/java-21-openjdk ./gradlew :app:assembleDebugBuild one universal debug APK for local installation:
JAVA_HOME=/usr/lib/jvm/java-21-openjdk ./gradlew :app:assembleDebug -Ppixelplayer.enableAbiSplits=falseBuild a universal unsigned release APK suitable for F-Droid verification:
JAVA_HOME=/usr/lib/jvm/java-21-openjdk ./gradlew :app:assembleRelease -Ppixelplayer.enableAbiSplits=false -Ppixelplayer.disableReleaseSigning=trueRun unit tests:
JAVA_HOME=/usr/lib/jvm/java-21-openjdk ./gradlew :app:testDebugUnitTestGenerate the baseline profile with a connected device or emulator:
JAVA_HOME=/usr/lib/jvm/java-21-openjdk ./gradlew :baselineprofile:generateBaselineProfilePixelPlayerOSS is available on F-Droid:
GitHub releases are available at:
https://github.com/lostf1sh/PixelPlayerOSS/releases
Obtainium app id:
com.lostf1sh.pixelplayeross
Public releases are planned on a regular weekly cadence when main passes the release checklist.
F-Droid listing metadata lives in fastlane/metadata/android/en-US; build/release notes for F-Droid are in docs/FDROID.md.
Note: F-Droid builds and signs its own APKs from source, so they may lag behind GitHub releases while the new version works through the F-Droid build cycle. F-Droid and GitHub APK signatures differ — switching between the two requires an uninstall/reinstall.
app/src/main/java/com/lostf1sh/pixelplayeross/
- data/ Room, repositories, preferences, services, workers
- di/ Hilt modules and qualifiers
- presentation/ Compose screens, components, navigation, ViewModels
- ui/ Theme and Glance widgets
- utils/ Shared utilities
baselineprofile/ Macrobenchmark and baseline profile generation
| Area | Technology |
|---|---|
| Language | Kotlin |
| UI | Jetpack Compose |
| Design | Material 3 |
| Playback | AndroidX Media3, ExoPlayer, FFmpeg |
| Database | Room |
| Dependency Injection | Hilt |
| Preferences | DataStore |
| Background Work | WorkManager |
| Networking | Retrofit, OkHttp |
| Images | Coil |
| Metadata | TagLib |
Contributions are welcome. Open an issue or pull request with a focused change and include test/build results when possible.
Useful local checks:
JAVA_HOME=/usr/lib/jvm/java-21-openjdk ./gradlew :app:compileDebugKotlin
JAVA_HOME=/usr/lib/jvm/java-21-openjdk ./gradlew :app:lintDebug
JAVA_HOME=/usr/lib/jvm/java-21-openjdk ./gradlew :app:testDebugUnitTestRelease process: docs/RELEASE.md
F-Droid notes: docs/FDROID.md
Privacy policy: PRIVACY.md
Security policy: SECURITY.md
PixelPlayerOSS is licensed under the MIT License.
Distributed APKs include third-party components under their own licenses. In particular, the optional FFmpeg decoder dependency org.jellyfin.media3:media3-ffmpeg-decoder is GPL-3.0; see THIRD_PARTY_NOTICES.md.
Maintained by lostf1sh