Orchard Mobile
The standalone native Android client: on-device analysis, Android Auto, Orchard Connect pairing, and its bundled models.
Orchard Mobile is a standalone native Android client. It plays music on its own, keeps its own library, and signs in to YouTube Music directly. It can pair with Orchard desktop, but it does not depend on one.
Source lives in mobile/.
Requirements
Android 12 (API 31) or newer.
Installing
Prebuilt APKs are published at sfg545.dev/orchard once Orchard Mobile releases.
Build a debug APK yourself with JDK 17 and Android SDK 36:
cd mobile/android
./gradlew assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk
Launch Orchard from the app drawer. Search and playback work immediately. Sign in from Profile → Account to load your own library.
Release builds are signed from ANDROID_KEYSTORE_FILE, ANDROID_KEYSTORE_PASSWORD,
ANDROID_KEY_ALIAS, and ANDROID_KEY_PASSWORD:
./gradlew assembleRelease
Features
Playback
- Smart Crossfade with beat-matched, phrase-aligned transitions, or a fixed crossfade of 1 to 12 seconds
- Gapless playback for albums played in order
- Queue with reordering, removal, history, and restore after the app is killed
- Media notification, lock-screen controls, headset and Bluetooth buttons, audio focus
- Android Auto browsing and voice search
- Playback history
- Age-restricted tracks play when signed in, which most YouTube Music clients cannot do. Android got this working first and desktop was ported from it. See Explicit and Age-Restricted Tracks.
On-device analysis
Orchard Mobile measures the audio rather than trusting a catalog. Beat and downbeat tracking runs a quantized Beat This! model, vocal presence comes from open-unmix, and tempo, key, and energy come from a native C++ analyzer shared in spirit with the desktop one.
Everything feeds the transition planner, which decides where a mix belongs and how ambitious it can afford to be. When the evidence is not there, it falls back to a normal fade. The architecture matches the desktop’s; see Smart Crossfade.
Library and browsing
- Home, search, library, playlists, albums, and artists
- Native YouTube Music sign-in through a dedicated Compose screen. Sign in for your library, or skip it and browse as a guest.
- Offline metadata cache and a configurable audio cache
- Synced and unsynced lyrics from Orchard’s resolver chain
Connected listening
- Orchard Connect to hand playback to a paired Orchard desktop and take it back
- Discord Rich Presence, with animated artwork where available
- Shareable Orchard Song Links
Pairing with Orchard desktop
The phone is always its own playback destination. Adding a desktop:
- Open Orchard desktop and its Orchard Connect pairing view.
- On the phone, open the device picker from Now Playing or Profile → Connected devices.
- Scan the QR code, or paste its
orchard-connect://pairlink. - Approve the phone on the desktop.
- Pick the desktop to send playback there, or the phone to bring it home.
Both devices need to be on the same network. The pairing token is AES/GCM encrypted with an AndroidKeyStore key, bound to the remembered host, and kept out of backups.
Full detail in Orchard Connect.
Development
cd mobile/android
./gradlew testDebugUnitTest assembleDebug lintDebug
The unit suite covers auth signing, queue edits and restoration, playback state, artwork matching, transition filtering and planning, pairing, reconnect policy, and device transfers. Instrumented tests cover the analysis models and need a real device.
Project map
android/app/src/main/java/dev/sfg/orchard/
mobile/playback/ Media3 service, stream resolution, queue rules
mobile/playback/smart/ Analysis, transition planning, rendering
mobile/catalog/ YouTube Music API boundary
mobile/artwork/ Static and animated cover art providers
mobile/auth/ Cookie-session auth and Keystore storage
mobile/lyrics/ Lyrics resolver chain
mobile/connect/ Orchard Connect target selection and transfer
mobile/ui/ Compose theme, navigation, screens
connect/ Typed Socket.IO protocol and pairing client
android/app/src/main/cpp/
analyzer/ Log-mel front end and tempo analysis
transition/ Time-stretch and transition rendering
Model provenance notes live in
mobile/docs/BEAT_MODEL.md.
Bundled models
Both shipped models were chosen because their weights carry a permissive license. Most published music-information-retrieval weights, Essentia’s included, are CC BY-NC-SA and cannot be distributed inside an application.
| Component | Use | License |
|---|---|---|
| Beat This! | Beat and downbeat tracking | MIT, code and weights. Ships the official small0 checkpoint converted to ONNX and quantized to int8. |
| open-unmix | Measuring vocal content at an instant | MIT, code and umxhq weights. Only the vocals target ships. Meta’s htdemucs separates better but its weights are CC-BY-NC-4.0. |
| ONNX Runtime | Inference | MIT |
| Rubber Band | Time-stretching for beat-matched transitions | GPL-2.0-or-later |
License
AGPL-3.0-or-later, the same as Orchard desktop, so code can move freely between the two. The native analysis front end is already shared source and more of it is expected to be. It is also what allows Rubber Band to be linked into the transition renderer. See License and Legal.