Skip to content

Productionize cloud-only Jockie-style Music playback #249

Description

@ucguy4u

Problem

Airo now has the foundation for a Jockie-style music experience: provider-aware music tracks, direct licensed sample streams, an audio_service-backed playback path, and explicit guardrails that prevent YouTube/Spotify/Apple from being treated as raw background streams.

This needs to be productionized before release. The production requirement is cloud mode only: this feature must be available only when the user has enabled the cloud toggle / cloud mode. It must not appear or play in local/offline mode.

User Outcome

Users in cloud mode can search/play a safe music catalog, continue listening while using other Airo features, and control playback through the mini player / media controls. Users in local mode see no local music playback surface for this feature.

Current Foundation To Inspect

Relevant code paths:

  • app/lib/features/music/domain/services/music_playback.dart
  • app/lib/features/music/domain/services/music_provider_adapter.dart
  • app/lib/features/music/domain/services/direct_licensed_music_provider.dart
  • app/lib/features/music/domain/services/audio_service_music_service.dart
  • app/lib/features/music/domain/services/music_service.dart
  • app/lib/features/music/domain/services/just_audio_music_service.dart
  • app/lib/features/music/domain/services/beats_audio_handler.dart
  • app/lib/features/music/application/providers/music_provider.dart
  • app/lib/features/music/presentation/screens/music_screen.dart
  • app/lib/features/music/presentation/widgets/mini_player.dart
  • docs/features/music/JOCKIE_STYLE_MUSIC_RESEARCH.md

Related cloud/local pattern to reuse:

  • app/lib/features/coins/application/providers/cloud_mode_provider.dart
  • Coins UI cloud toggle patterns in groups_list_screen.dart and group_detail_screen.dart

Scope

In Scope

  • Gate the entire Music / Beats experience behind cloud mode.
  • Hide or disable /live/music, /beats, MiniPlayer, music search, and playback controls when cloud mode is off.
  • Add a cloud-mode CTA from the music entry point, using existing Airo cloud toggle UX patterns.
  • Ensure local/offline mode cannot start playback through direct streams, search, deep links, agent tools, mini player, or queue restoration.
  • Replace SampleLib demo catalog with a production cloud-backed licensed catalog service or a cloud-configured allowlist.
  • Keep MusicProviderAdapter / ResolvedTrack as the provider boundary for future providers.
  • Add provider status handling for:
    • Direct licensed cloud catalog: playable in background.
    • Spotify: metadata/search only until official SDK playback is implemented.
    • Apple Music: metadata/search only until MusicKit playback is implemented.
    • YouTube: visible-player only, excluded from background queue.
  • Ensure background playback uses audio_service on Android/iOS and degrades gracefully on web/test platforms.
  • Add telemetry for search, play start, play failure, provider unsupported, and cloud-mode blocked actions.
  • Add QA coverage for cloud-mode gating and background playback state transitions.

Out Of Scope

  • No YouTube audio extraction, yt-dlp, InnerTube, Lavalink YouTube source, or hidden audio-only YouTube playback.
  • No raw Spotify/Apple/Tidal audio extraction or transcoding.
  • No local/offline music catalog for this feature.
  • No copyrighted sample tracks unless Airo has explicit playback rights.
  • No Discord bot service in this issue. If needed later, create a separate backend/Discord issue.

Required Architecture

Cloud-Only Gate

Create a music-specific cloud availability provider, for example:

final musicCloudAvailabilityProvider = Provider<MusicCloudAvailability>((ref) {
  // Read the app-level or feature-level cloud mode source.
  // Return enabled only when cloud mode is active and required auth/config exists.
});

The gate must be enforced in all of these layers:

  • Routing: local mode should not enter the full music player silently.
  • UI: music entry point and mini player should not expose playback in local mode.
  • Controller/service: direct calls to playTrack, playQueue, resume, and queue restoration must reject when cloud mode is off.
  • Agent/tooling: natural language commands like “play music” must route to cloud-mode CTA when cloud mode is off.
  • Persistence: local-mode startup must not restore a previous cloud music queue.

Provider Contract

Keep provider resolution explicit:

enum MusicPlaybackKind {
  directStream,
  providerSdk,
  embeddedVisiblePlayer,
  previewOnly,
  unsupported,
}

Only directStream tracks from the cloud licensed catalog can enter the background queue today.

Production Catalog

Move the demo catalog out of production behavior. Use one of:

  • Cloud-hosted licensed catalog endpoint.
  • Firebase Remote Config / Firestore allowlist of licensed stream URLs.
  • A first-party backend endpoint that returns normalized ResolvedTrack records.

Each catalog item must include:

  • provider id
  • canonical source URL
  • playback kind
  • stream URL only when licensed for playback
  • license/rights label
  • artwork URL if available
  • duration if known
  • expiry rules if the stream URL is signed

Acceptance Criteria

  • Music feature is unavailable in local mode except for a clear “Enable cloud mode” CTA.
  • Local mode cannot play music through /live/music, /beats, mini player, agent tools, deep links, queue restoration, or service calls.
  • Cloud mode can play direct licensed catalog streams through audio_service / just_audio.
  • Android/iOS background controls work for play, pause, seek, next, previous, and stop.
  • Web/test fallback does not crash when audio_service is unavailable.
  • SampleLib/demo streams are not the production catalog unless explicitly approved as demo-only and hidden from release builds.
  • YouTube links are recognized only for future visible-player handling and are rejected from the background queue.
  • Spotify and Apple Music items show as official-SDK-required until those integrations are implemented.
  • Unsupported providers show clear UI state and do not attempt stream loading.
  • No copyrighted unofficial direct URLs remain in music code, tests, fixtures, or docs.
  • Unit tests cover cloud-mode allowed/blocked states.
  • Widget tests cover local-mode CTA and cloud-mode playable catalog.
  • Integration/manual QA covers switching tabs while music plays, app background/foreground, and lock-screen controls.
  • flutter analyze lib/features/music test/features/music passes.
  • flutter test test/features/music passes.
  • Release notes or feature docs document cloud-only availability and provider limitations.

Test Plan

  • Unit:
    • provider resolution maps playback kinds correctly
    • local mode blocks all playback entry points
    • cloud mode allows direct licensed tracks
    • YouTube/Spotify/Apple do not enter direct background queue
  • Widget:
    • local mode shows cloud CTA, not playlist controls
    • cloud mode shows catalog and provider badges
    • unsupported rows show lock/unsupported state
  • Integration/manual:
    • start playback in cloud mode, switch to Games/Agent/IPTV, confirm mini player remains active
    • background app and verify Android/iOS media controls
    • turn cloud mode off and verify queue stops/clears and mini player disappears
    • cold start in local mode and verify no music queue restoration

Risks / Notes

  • Provider terms are the main production risk. Do not implement extraction-style behavior from Discord bots.
  • A Discord bot architecture is separate from Aero’s in-app player and should not be bundled into Flutter.
  • Cloud-only gating is both product and compliance scope; do not leave service-level bypasses.
  • If a global cloud toggle does not exist outside Coins yet, add a shared app-level cloud mode provider before wiring Music to it.

Agent / Ownership

Main agent: agent/mobile-ui

Supporting reviewers:

  • agent/security for provider/compliance guardrails
  • agent/core-architecture for shared cloud-mode provider design
  • agent/qa-testing for background playback and mode-gating QA

Estimate

5-8 engineering days, depending on whether a shared app-level cloud toggle already exists and whether the licensed catalog backend is ready.

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent/mobile-uiMobile Platform & UI Agent tasksenhancementNew feature or requestmedia-hubMedia Hub Streaming Surface featurepriority/P1High - Important but not blockingtype/taskImplementation task

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions