How nikhilvishwakarma00/velune works
1. What this repo is
- Velune is an Android music player/client for YouTube Music, built as a modular Kotlin app.
- The architecture is centered on a local-first Android app with a background playback service, a Room database, and several network-backed feature modules.
2. Top-level module boundaries
- app/ is the main Android application and contains most of the runtime code: UI, ViewModels, database, playback, settings, and feature orchestration.
- innertube/ is the core YouTube Music API client and page/model layer.
- lrclib/, kugou/, simpmusic/, and betterlyrics/ are lyrics-provider modules.
- lastfm/ and kizzy/ are integration modules for external services.
- canvas/ is a small rendering module used for custom visual output.
3. Presentation layer
- The app UI is built with Jetpack Compose and Material 3.
- Screens are split by domain: home, browse, library, search, playlists, artist, settings, stats, history, and player.
- Reusable composables live under ui/component, player-specific UI under ui/player, and screen-level navigation under ui/screens.
4. State and orchestration
- The app follows MVVM/UDF: UI screens observe ViewModels and render state, while actions flow back to ViewModels.
- ViewModels live in viewmodels/ and correspond closely to visible features such as Home, Browse, Library, Search, Lyrics, Stats, and Account.
- This makes the UI layer mostly declarative; feature logic is not embedded in composables.
5. Playback subsystem
- Playback is handled outside the UI by playback/MusicService, which acts as the long-lived audio engine.
- MediaLibrarySessionCallback and PlayerConnection bridge UI commands to the service and expose playback state back to the app.
- The playback stack includes queue management, crossfade, sleep timer, download support, and equalizer-related models.
- This is the main boundary between foreground UI and background media execution.
6. Local persistence layer
- The app uses Room (db/) for persistent state such as songs, albums, artists, playlists, lyrics, play counts, search history, tags, skips, and event/stat tracking.
- The many schema files under app/schemas/com.nikhil.yt.db.InternalDatabase/ show a mature, versioned database with frequent migrations.
- DataStore is also used for preference-style settings, while Room stores the structured library and playback history data.
7. YouTube Music data source
- innertube/ encapsulates the YouTube Music private API surface: browse, search, player, next, queue, transcript, playlist, and related content.
- Its page classes transform raw API responses into app-friendly page/domain models like albums, artists, home, charts, explore, library, playlists, and related tracks.
- In architectural terms, this module is the main remote data adapter between Velune and YouTube Music.
8. Lyrics subsystem
- Lyrics are aggregated from multiple providers rather than a single source.
- app/lyrics/ coordinates providers such as BetterLyrics, KuGou, LrcLib, SimpMusic, YouTube lyrics, and YouTube subtitle/transcript lyrics.
- The app also contains preload/helper logic so lyrics can be fetched, cached, and synchronized around playback time.
- This is a distinct integration boundary: playback metadata drives lyrics lookup, which then feeds the player UI.
9. External integrations
- lastfm/ likely supports scrobbling/authentication for listening stats.
- kizzy/ provides Discord RPC/websocket presence plumbing; the app-side utilities and settings screens expose Discord presence controls.
- The app also contains dedicated settings and manager classes for sync and third-party account integrations.
10. Social / collaborative playback
- The together/ package is a separate feature subsystem for synchronized listening.
- It includes client/server/online host pieces plus message, link, model, and playback-planning classes.
- From an architecture standpoint, this behaves like an overlay service on top of the normal player state, enabling shared playback coordination.
11. Discovery, search, and library flows
- Search and browse screens consume YouTube data from innertube and local library data from Room.
- Library screens are backed by local entities and filtering/sorting constants, while online screens surface YouTube Music content and recommendations.
- Home, explore, charts, new releases, and mood/genres are remote-content entry points, whereas library/history/playlists are local persistence entry points.
12. Supporting infrastructure
- Dependency injection is provided by Hilt via di/AppModule.kt and di/NetworkModule.kt.
- The app uses coroutines and Flow for async state, Media3/ExoPlayer for audio, and encrypted offline caching as part of the player/storage experience.
- Utilities under utils/, extensions/, and constants/ hold cross-cutting concerns such as connectivity, artwork, updates, scrobbling, playlist suggestions, and formatting.
13. How data typically moves
- User action in Compose UI → ViewModel → repository/helper/service layer → local Room/DataStore and/or remote modules (innertube, lyrics providers, integrations) → state updated back into the UI.
- Playback is a parallel path: UI controls → PlayerConnection/media session → MusicService/ExoPlayer → playback state, notifications, widget, history, and stats updates.
- Lyrics and social presence are secondary consumers of playback state.
14. Important architectural diagram boundaries
- Separate the app into: UI, state management, playback engine, local persistence, YouTube Music API adapter, lyrics providers, external integrations, and collaboration features.
- Show app/ as the orchestrator, with the other Gradle modules acting as specialized adapters/services.
- The clearest external systems to draw are YouTube Music, lyrics services, Last.fm, Discord, and the Android media platform.
Main entry points: HomeViewModel.kt ViewModels · MusicService.kt Playback engine · IntegrationScreen.kt Settings integrations · HomeScreen.kt UI layer
Components 19
App
Android application runtime and orchestration
- App shell · Process entry, activity hosting, and top-level app setup
app/src/main/kotlin/com/nikhil/yt/App.kt - UI layer · Declarative screens, reusable components, and navigation
app/src/main/kotlin/com/nikhil/yt/ui/screens/HomeScreen.kt - ViewModels · Screen state holders and action coordinators
app/src/main/kotlin/com/nikhil/yt/viewmodels/HomeViewModel.kt - Playback engine · Background audio service, session callback, queue, and controls
app/src/main/kotlin/com/nikhil/yt/playback/MusicService.kt - Player bridge · Connects UI and app logic to the media session and service
app/src/main/kotlin/com/nikhil/yt/playback/PlayerConnection.kt - Local store · Room entities, DAO, and structured playback/library history
app/src/main/kotlin/com/nikhil/yt/db/MusicDatabase.kt - Preferences · App settings and lightweight persisted configuration
app/src/main/kotlin/com/nikhil/yt/utils/DataStore.kt - Lyrics coord · Provider selection, preload, and playback-synced lyrics lookup
app/src/main/kotlin/com/nikhil/yt/lyrics/LyricsHelper.kt - Together · Synchronized listening client, host, and guest planning
app/src/main/kotlin/com/nikhil/yt/together/TogetherClient.kt - Settings integrations · Account, Discord, Last.fm, and sync settings surfaces
app/src/main/kotlin/com/nikhil/yt/ui/screens/settings/IntegrationScreen.kt
Core modules
Remote API, lyrics, and integration modules
- InnerTube · YouTube Music API client plus page/model adapters
innertube/src/main/kotlin/com/nikhil/yt/innertube/InnerTube.kt - Lyrics providers · Provider implementations aggregated by the app lyrics layer
lrclib/src/main/kotlin/com/nikhil/yt/lrclib/LrcLib.kt - BetterLyrics · Parser and model module for lyric text formats
betterlyrics/src/main/kotlin/com/nikhil/yt/betterlyrics/BetterLyrics.kt - Last.fm · Listening-scrobble integration and authentication support
lastfm/src/main/kotlin/com/nikhil/yt/lastfm/LastFM.kt - Discord RPC · Discord presence gateway and RPC plumbing
kizzy/src/main/kotlin/com/my/kizzy/rpc/KizzyRPC.kt - Canvas · Custom visual rendering for app artwork or output
canvas/src/main/kotlin/com/nikhil/yt/canvas/VeluneCanvas.kt
External systems
Outside services and platform boundaries
- YouTube Music · Primary remote music catalog, playback, and metadata source
- Lyrics services · Third-party lyrics backends used by the app
- Android media · Media3/ExoPlayer, notifications, widgets, and OS media session
Connections 25
- App shell → UI layer: hosts · Application bootstraps the Compose UI
- UI layer → ViewModels: observes · Screens render state from ViewModels
- ViewModels → Local store: reads/writes · Persistent library, history, stats, and playlists
- ViewModels → Preferences: reads/writes · Preference state and settings persistence
- ViewModels → InnerTube: loads remote data · Browse, search, page, and playback metadata
- ViewModels → Lyrics coord: requests lyrics · Lyrics state and menu actions
- ViewModels → Together: coordinates · Shared-listening controls and status
- UI layer → Player bridge: sends controls · Player UI invokes playback actions
- Player bridge → Playback engine: controls · Media session commands reach the service
- Playback engine → Android media: uses · Audio engine, session, notifications, and downloads
- Playback engine → Local store: updates history · Playback events feed history, stats, and queue state
- Playback engine → Lyrics coord: publishes timing · Current track position drives lyric sync
- Lyrics coord → Lyrics providers: queries · Aggregates multiple lyrics backends
- Lyrics coord → BetterLyrics: parses · Handles lyric format parsing and transformation
- Lyrics providers → Lyrics services: fetches from · Remote lyrics backends and subtitle/transcript sources
- InnerTube → YouTube Music: calls · Primary remote API boundary for YouTube Music
- Together → Android media: hooks playback · Shared playback overlay follows media state
- Settings integrations → Last.fm: configures · Last.fm account and scrobble settings
- Settings integrations → Discord RPC: configures · Discord presence controls and login flow
- Settings integrations → Together: configures · Music Together settings and session management
- Settings integrations → Local store: manages · Backup, restore, and local content settings
- UI layer → Canvas: renders with · Custom visual output used by app UI
- Playback engine → Canvas: feeds visuals · Playback state can drive rendered artwork
- ViewModels → Last.fm: scrobbles · Listening activity updates external stats
- ViewModels → Discord RPC: updates presence · Discord rich presence reflects current playback