A test APK is available for download via the GitHub Releases section. π You can find the latest build under Releases on this repository to try out the app without building it locally.
F-Player is a modern, modularized media player built with Kotlin and Jetpack Compose, focused on local audio and video playback with a polished offline-first experience.
Designed with Clean Architecture principles, it features a robust playback engine powered by Media3 (ExoPlayer), Google Cast support for both audio and video, seamless modular navigation, and advanced features like audio trimming and tag editing. This project serves as a showcase for modern Android development best practices.
F-Player is an offline-first media player focused on a clean, modular architecture. It showcases:
- Feature-first modularization (each feature lives in its own Gradle module).
- Clean Architecture (data, domain, presentation layers per feature).
- Modern Android libraries: Jetpack Compose, Hilt, Media3 (ExoPlayer successor), Room, DataStore, KSP.
- Offline audio and video scanning/playback with Media3 + local metadata handling.
- Google Cast playback for local audio files and video files, including receiver artwork/metadata support.
- External playback entry points for opening supported local or streamed media from other apps.
The project uses Gradle modularization. Key modules included in settings.gradle.kts:
rootProject.name = "MusicPlayer"
include(":app")
include(":core")
// Feature modules are organized under the 'features' directory
include(":features:library")
include(":features:player")
include(":features:playlist")
include(":features:settings")
include(":features:trim")
include(":features:edit")
include(":features:video")The project uses a centralized version catalog. Selected versions used in the project:
- Kotlin
- Android Gradle Plugin (AGP)
- Jetpack Compose BOM
- Hilt
- Media3
- Room
- Coroutines
- Coil
- Google Cast SDK
- KSP
- accompanist-systemuicontroller
Refer to the libs.versions.toml for the full catalog.
- Each feature module (
:features:player,:features:library, etc.) containsdata,domain, andpresentationpackages to enforce separation of concerns. coremodule holds cross-cutting concerns (DI setup, common models, utilities, theme, and UI components).
- Hilt is used for DI across modules. Modules expose bindings through interfaces and rely on
@Module+@InstallInincore/feature modules.
- Media3 (the modern successor to ExoPlayer) is used for playback and session management.
- Audio playback logic lives primarily in the
:features:playermodule. - Video playback is separated into the
:features:videomodule, keeping video library, player screen, and video playback state isolated from the audio player.
- Google Cast support allows audio files and video files to be sent to Cast receivers such as Android TV.
- Audio casting includes queue playback, receiver metadata, album artwork, and default artwork fallback when a track has no embedded album art.
- Video casting supports local and externally opened video media, with receiver metadata/artwork handling kept separate from the local player UI.
- Room stores user playlists and cached metadata.
- DataStore (preferences) stores persistent settings (theme, playback preferences).
- KSP is used for code generation where needed (e.g., Room, other annotation processors) β ensure KSP version is compatible with the Kotlin version.
app/
core/
ββ di/
ββ ui/
ββ utils/
features/
ββ library/
β ββ data/
β ββ domain/
β ββ presentation/
ββ player/
β ββ data/
β ββ domain/
β ββ presentation/
ββ playlist/
ββ settings/
ββ video/
ββ edit/
ββ trim/Each feature follows the same data/domain/presentation pattern. Keeping public interfaces in domain and implementation details in data.











