OrchardDocs

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:

  1. Open Orchard desktop and its Orchard Connect pairing view.
  2. On the phone, open the device picker from Now Playing or Profile → Connected devices.
  3. Scan the QR code, or paste its orchard-connect://pair link.
  4. Approve the phone on the desktop.
  5. 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.

ComponentUseLicense
Beat This!Beat and downbeat trackingMIT, code and weights. Ships the official small0 checkpoint converted to ONNX and quantized to int8.
open-unmixMeasuring vocal content at an instantMIT, code and umxhq weights. Only the vocals target ships. Meta’s htdemucs separates better but its weights are CC-BY-NC-4.0.
ONNX RuntimeInferenceMIT
Rubber BandTime-stretching for beat-matched transitionsGPL-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.