High-Performance Native Android Audio Streaming & Discovery Platform
Decentralized Keyless Audius Streaming Β· AndroidX Media3 (ExoPlayer) Β· Universal 28-Band Hardware FFT Β· MediaStore Offline Library
π Official Website Β β’Β π¦ Release Assets (v0.8.0) Β β’Β π₯ 1-Click APK Download Β β’Β π‘οΈ Checksums Β β’Β π€ Contributor Roadmap
Captured directly from an active Android device running Vynora v0.8.0:
- 100% Keyless Protocol: Eliminates developer API keys, third-party video player dependencies, and Google Cloud credentials. All discovery queries execute directly against the decentralized Audius network.
- Dynamic Validator Host Resolution: Implements automated discovery by querying
https://api.audius.coto retrieve a list of live validator host nodes. The client runs health checks, connection pooling, and transparent failover across nodes. - Direct 320kbps Stream Endpoints: Queries the
/v1/tracks/{track_id}/streamendpoint, parsing HTTP 302 redirects to locate the fastest content delivery edge node for unthrottled audio playback. - Phonetic & Typo-Tolerant Search Index: The built-in search engine utilizes phonetic token matching and Levenshtein distance calculations, ensuring fast and accurate results even with imperfect user queries.
- Dedicated Background Service:
VynoraPlaybackServiceextendsMediaSessionService, ensuring resilient background playback during application minimization, screen-off states, and system memory pressure. - 256MB Resilient LRU Disk Cache: Engineered with
SimpleCacheandLeastRecentlyUsedCacheEvictorusingCacheDataSource.Factory. Frequently played tracks and pre-buffered chunks are stored locally to prevent redundant network consumption. - Queue Pre-Buffering: Seamless track transitions with zero audible gap between subsequent songs by prefetching initial audio chunks of the next track in the queue.
- Audio Focus & Headset Disconnect Management: Implements
AudioManager.OnAudioFocusChangeListenerwith automatic ducking on notifications, temporary pause on incoming calls, and instant halt when headphones are disconnected (ACTION_AUDIO_BECOMING_NOISY).
-
Native AudioSession Attachment: Hooks directly into ExoPlayerβs low-level
audioSessionIdusingandroid.media.audiofx.Visualizer, capturing raw uncompressed frequency spectrum byte arrays with zero microphone latency. -
Mathematical Frequency Mapping:
$$\text{Magnitude } |X_k| = \sqrt{R_k^2 + I_k^2}$$ Transforms discrete Fourier transform complex pairs into 28 logarithmically spaced frequency bins spanning$20\text{ Hz}$ to$20\text{ kHz}$ . Sub-bass ($20\text{--}80\text{ Hz}$ ) and punch-bass ($80\text{--}250\text{ Hz}$ ) receive non-linear acoustic weighting for accurate rhythmic response. -
Peak-Hold Gravitational Decay: Features floating peak indicators governed by physics-based velocity falloff:
$$v_{t+1} = v_t + g, \quad y_{\text{peak}} = \max(y_{\text{bar}}, y_{\text{peak}} - v_{t+1})$$ -
Dynamic Ambient Color Extraction: Interrogates active album cover art using
androidx.palette.graphics.Paletteto render a synchronized, real-time background glow behind the visualizer bars.
- Automated ContentResolver Indexing: Scans
MediaStore.Audio.Media.EXTERNAL_CONTENT_URIon a dedicated background coroutine (Dispatchers.IO) without impacting UI thread frame rates. - Broad Format Decoding: Plays MP3, FLAC (including 24-bit studio quality), WAV, M4A, OGG, and AAC files directly from local flash storage.
- Persistent Room SQLite Storage: Manages custom playlists, user favorites, play counts, and playback queue states with reactive Kotlin Flow DAOs.
- Unidirectional Data Flow (UDF): ViewModels emit immutable
UiStateobjects consumed by pure, testable composable functions. - Persistent Docked Miniplayer: Floating miniplayer anchored above navigation bars across all screens with tap-to-expand gesture support.
- Custom Sleep Timer: Modal bottom sheet providing auto-stop timer options (15m, 30m, 45m, 60m, or end of track).
flowchart TD
subgraph UI_Layer ["Presentation Layer (Jetpack Compose + Material 3)"]
A[Home / Explore Screen] --> B[Now Playing Fullscreen]
A --> C[Local Library Screen]
B --> D[28-Band FFT Visualizer Canvas]
B --> E[Docked Floating Miniplayer]
end
subgraph VM_Layer ["State & ViewModel Layer (Kotlin Coroutines & Flow)"]
F[AudiusViewModel]
G[LocalAudioViewModel]
H[PlaybackController]
end
subgraph Domain_Layer ["Domain / Repository Layer"]
I[AudiusRepository]
J[MediaStoreAudioRepository]
K[Room Database Playlists/Favorites]
end
subgraph Engine_Layer ["Audio Engine (AndroidX Media3 ExoPlayer)"]
L[VynoraPlaybackService]
M[SimpleCache 256MB LRU]
N[VisualizerController Hardware FFT]
end
subgraph Data_Layer ["Data Sources"]
O[Audius Decentralized Validator Nodes]
P[Device Storage MediaStore Provider]
end
A --> F
C --> G
B --> H
F --> I
G --> J
I --> O
J --> P
H --> L
L --> M
L --> N
N --> D
| Component | Technology | Version | Purpose |
|---|---|---|---|
| Language | Kotlin | 2.1.0 |
Primary language with Coroutines, Flow, and strict type safety |
| UI Framework | Jetpack Compose | BOM 2024.12.01 |
Declarative reactive UI, edge-to-edge layout, 120Hz animations |
| Design System | Material 3 | 1.3.1 |
Dark theme surfaces, dynamic color extraction, components |
| Audio Engine | AndroidX Media3 (ExoPlayer) | 1.5.1 |
Audio streaming, chunk buffering, 256MB LRU disk cache, queue |
| Background Service | Media3 MediaSessionService | 1.5.1 |
VynoraPlaybackService handling lockscreen, audio focus, notifications |
| Online Provider | Audius REST API | v1 Decentralized |
100% keyless online music discovery, trending charts, and streams |
| Offline Provider | Android MediaStore | API 26β36 |
Local audio discovery and ID3 tag resolution |
| Database | Room SQLite | 2.6.1 |
Playlists, favorite tracks, playback history |
| Networking | Retrofit & OkHttp | 2.11.0 / 4.12.0 |
Dynamic host selection, stream redirects, and connection pooling |
| Serialization | Kotlinx Serialization | 1.7.3 |
JSON parsing for Audius node responses |
| Image Loading | Coil Compose | 2.7.0 |
Asynchronous artwork loading and memory caching |
| Target SDK | Android 16 (VanillaIceCream) | API 36 |
Latest Android platform capabilities |
| Min SDK | Android 8.0 (Oreo) | API 26 |
Broad device compatibility |
- JDK: Java Development Kit 17 (OpenJDK or Oracle)
- Android SDK: Build Tools
36.0.0, Platformandroid-36 - IDE: Android Studio Ladybug (2024.2+) or Meerkat
# 1. Clone the repository
git clone https://github.com/CodeByArnob/Vynora.git
cd Vynora
# 2. Run unit tests
./gradlew testDebugUnitTest
# 3. Run Android Lint verification
./gradlew lintDebug
# 4. Assemble debug APK
./gradlew assembleDebug
# Output APK: app/build/outputs/apk/debug/app-debug.apkVynora is designed to be easily extensible. Developers looking to contribute are invited to explore the following architectural extension points:
-
Current State: Visualizer captures audio data passively via
VisualizerController. -
Extension Opportunity: Implement an active audio processing pipeline using
android.media.audiofx.Equalizer,BassBoost, andVirtualizer. -
Implementation Path:
- In
VynoraPlaybackService.kt, instantiateEqualizer(0, player.audioSessionId). - Expose band frequency ranges (
$60\text{Hz}, 230\text{Hz}, 910\text{Hz}, 3.6\text{kHz}, 14\text{kHz}$ ) and gain controls ($\pm 12\text{dB}$ ) via a newEqualizerController. - Store user presets (Rock, Electronic, Bass Boost, Vocal, Custom) in Room SQLite.
- In
- Current State: Audio is streamed on-demand and cached up to 256MB in
SimpleCache. - Extension Opportunity: Add a persistent background download manager allowing users to save Audius tracks for permanent offline listening.
- Implementation Path:
- Integrate
androidx.media3.exoplayer.offline.DownloadManagerandDownloadService. - Store downloaded tracks in the app's external scoped storage directory (
context.getExternalFilesDir(Environment.DIRECTORY_MUSIC)). - Update
Roomschema to track download status, progress, and file path.
- Integrate
- Current State: Now Playing screen displays track title, artist, album art, and visualizer.
- Extension Opportunity: Add synchronized lyrics display with auto-scroll.
- Implementation Path:
- Create a parser for standard
.lrctimestamp files ([mm:ss.xx] Lyric text). - Integrate a keyless lyrics provider (e.g. LRCLIB API:
https://lrclib.net/api/get). - Use
LaunchedEffectinNowPlayingScreen.ktto monitorplayerViewModel.currentPositionand smoothly animate the active lyric line into view.
- Create a parser for standard
- Current State: Read-only public streaming and local playlists.
- Extension Opportunity: Integrate Audius OAuth2 authentication so users can log in with their Audius account and synchronize their remote favorites and playlists.
- Implementation Path:
- Implement Custom Tabs OAuth redirect for
https://audius.co/oauth/auth. - Add authenticated endpoints in
AudiusApiClient.ktto fetch user profile, followed artists, and favorited tracks.
- Implement Custom Tabs OAuth redirect for
- Current State: Phone and tablet edge-to-edge Compose interface.
- Extension Opportunity: Support vehicle head units via Android Auto.
- Implementation Path:
- Update
VynoraPlaybackServiceto implementMediaLibraryService.MediaLibrarySessionCallback. - Build a
MediaItemtree for root browsing (Trending, Playlists, Local Library).
- Update
| Permission | Manifest Level | Purpose |
|---|---|---|
READ_MEDIA_AUDIO |
Runtime (API 33+) | Grants read access to audio files on device storage |
READ_EXTERNAL_STORAGE |
Runtime (API 26β32) | Legacy read access to storage for Android 8.0β12 |
INTERNET |
Install-time | Communicating with decentralized Audius validator nodes |
ACCESS_NETWORK_STATE |
Install-time | Dynamically adjusts caching policies based on WiFi vs. Cellular |
FOREGROUND_SERVICE |
Install-time | Keeps VynoraPlaybackService active in the background |
FOREGROUND_SERVICE_MEDIA_PLAYBACK |
Install-time (API 34+) | Required Android 14 foreground service declaration for audio |
POST_NOTIFICATIONS |
Runtime (API 33+) | Displays media playback controls in the system notification shade |
RECORD_AUDIO |
Optional Runtime | Fallback for microphone FFT analysis when audio session is unavailable |
The latest verified Android build is published under GitHub Releases (v0.8.0):
| Asset | Direct Download Link | Size | Signature Status |
|---|---|---|---|
Vynora-v0.8.0-debug.apk |
β¬οΈ Download APK (v0.8.0) | 26.9 MB |
Android Signature Scheme v2 Verified |
Vynora-latest.apk |
β¬οΈ Download Latest APK | 26.9 MB |
Android Signature Scheme v2 Verified |
SHA256SUMS.txt |
π View Checksums | 175 B |
Verified Match |
# Verify the integrity of the downloaded APK
sha256sum -c SHA256SUMS.txt
# Output:
# Vynora-v0.8.0-debug.apk: OK
# Vynora-latest.apk: OKSHA-256 Digest:
25B4482756FF86C8DE498236BD6E48C6887A1540BA7D45E2EBB84227183BB89B
- Fork the repository and create your branch from
main. - Follow standard Kotlin conventions (
./gradlew lintDebug). - Ensure all unit tests pass (
./gradlew testDebugUnitTest). - Write clear, conventional commit messages (
feat:,fix:,perf:,refactor:,test:,docs:). - Open a Pull Request referencing the related issue or architectural capability.
Vynora is open-source software licensed under the Apache License 2.0. See the LICENSE file for complete details.