FLAC music player + internet radio for Android
Open-source, freemium, built for audiophiles and car/Bluetooth use.
- Browse and play FLAC, MP3, OGG, AAC, WAV, and ALAC files from your device
- Browse by artist, album, or folder
- Full metadata extraction via Media3
- Search and stream thousands of stations via radio-browser.info
- Filter by name, genre, country, or language
- Save favorites (5 free, unlimited with premium)
- Station vote counts and popularity data
- Full AVRCP support for play/pause/skip from steering wheel controls
- Tested with Tesla — track title, artist, and album art display on car screen
- Works with any AVRCP-compatible head unit or Bluetooth device
A "stats for nerds" overlay on the Now Playing screen showing real-time technical details:
| Local Files | Streams |
|---|---|
| Codec (FLAC, MP3, etc.) | Everything from local, plus: |
| Sample rate | Network throughput |
| Bit depth | Buffer health |
| Channel count | Session data used |
| Bitrate | Today's / monthly total |
- Monitor daily and monthly streaming data consumption
- Configurable monthly limit with warnings at 80% and alert at 100%
- Per-session and cumulative tracking stored locally
- Only network-sourced audio counts (local playback excluded)
- Dynamic theming with Material 3
- Follows system color palette
Core features are free. Premium unlocks:
- Unlimited saved radio station favorites
- Equalizer with presets
- Sleep timer
- Custom themes beyond Material You defaults
FOSS builds have all premium features unlocked by default.
| Layer | Technology |
|---|---|
| Language | Kotlin 2.x |
| UI | Jetpack Compose + Material 3 |
| Min SDK | API 31 (Android 12) |
| Audio | AndroidX Media3 (ExoPlayer) |
| Networking | Retrofit 2 + OkHttp + Kotlin Serialization |
| Database | Room |
| DI | Hilt |
| Async | Kotlin Coroutines + Flow |
| Image Loading | Coil 3 |
| Build | Gradle (Kotlin DSL) with version catalogs |
| CI/CD | GitHub Actions + Fastlane |
| Testing | JUnit 5 + MockK + Turbine + Compose Test |
soniflac/
├── app/ # App entry point, navigation, flavors (gplay / foss)
├── core/
│ ├── model/ # Shared data models (Track, Station, Playlist)
│ ├── database/ # Room DB, DAOs, entities, migrations
│ ├── network/ # Retrofit services, radio-browser.info client
│ ├── player/ # Media3 playback service, AVRCP, stream metrics
│ ├── common/ # Extensions and utilities
│ └── testing/ # Shared test fakes and fixtures
├── feature/
│ ├── library/ # Local file browsing UI
│ ├── radio/ # Internet radio search/browse UI
│ ├── nowplaying/ # Now Playing screen and controls
│ ├── streamstats/ # Stream Stats overlay
│ └── settings/ # Settings and premium unlock
├── billing/ # Premium billing abstraction (Play Billing / FOSS)
└── build-logic/ # Convention plugins
Feature modules never depend on each other — all shared state flows through core/ modules.
See ARCHITECTURE.md for the full design document, including module dependency graph, data models, and implementation details.
| Variant | Description |
|---|---|
gplayDebug |
Development with Google Play Billing |
gplayRelease |
Google Play Store release |
fossDebug |
Development, all features unlocked |
fossRelease |
F-Droid / sideload release |
The IS_FOSS BuildConfig flag controls premium feature gating per flavor.
- Android Studio Ladybug or newer
- JDK 17
- Android SDK 35
git clone https://github.com/particlesector/Soniflac.git
cd Soniflac
# FOSS debug build (all features unlocked, recommended for development)
./gradlew assembleFossDebug
# Google Play debug build (requires Play Billing setup)
./gradlew assembleGplayDebug# Lint and static analysis
./gradlew ktlintCheck detekt
# Unit tests
./gradlew testFossDebugUnitTest
./gradlew testGplayDebugUnitTest
# All checks (mirrors CI)
./gradlew ktlintCheck detekt testFossDebugUnitTest testGplayDebugUnitTest assembleFossDebug assembleGplayDebugEvery PR to main runs:
- Lint — ktlint + detekt static analysis
- Unit Tests — both
gplayandfossflavors - Build — debug APKs for both flavors
All checks must pass before merge.
Triggered by pushing a tag matching v* (e.g., v1.0.0):
- Runs full test suite
- Builds signed release APK + AAB (
gplayRelease) - Builds signed release APK (
fossRelease) - Uploads to Google Play (internal track) via Fastlane
- Creates GitHub Release with changelog and APK attachments
Contributions are welcome. Please read CONTRIBUTING.md before submitting a PR.
Key points:
- This project uses Conventional Commits (
feat:,fix:,docs:,test:,ci:,refactor:,chore:) - PRs must include tests for new functionality
- All CI checks must pass
- Feature modules never depend on each other — route shared state through
core/
SoniFlac is licensed under the GNU General Public License v3.0.
By contributing, you agree that your contributions will be licensed under the same license.