Shuttle2
Shuttle2 copied to clipboard
Add offline song download feature
…by, Plex)
This implements comprehensive offline download functionality for remote media providers, allowing users to download songs for offline playback similar to Spotify.
Core Features
Database Schema
- Added
DownloadStateenum to track download states (NONE, QUEUED, DOWNLOADING, PAUSED, COMPLETED, FAILED) - Created
DownloadDataentity with Room database support - Added
DownloadDaowith comprehensive query methods - Incremented database version to 41
- Added TypeConverter for DownloadState
Download Repository
- Created
DownloadRepositoryinterface for download operations - Implemented
DownloadRepositoryImplwith full CRUD operations - Supports queuing, progress tracking, pause/resume, and cancellation
- Includes automatic file cleanup when downloads are removed
Download Manager
- Implemented
DownloadManagersingleton for coordinating downloads - Supports concurrent downloads (max 3 simultaneous)
- Automatic queue processing
- Progress tracking and error handling
- File storage in app-specific directories organized by provider
Provider Integration
-
Jellyfin: Added
buildJellyfinDownloadPath()for direct download URLs (no transcoding) -
Emby: Added
buildEmbyDownloadPath()for direct download URLs -
Plex: Added
buildPlexDownloadPath()for direct download URLs - All download URLs use
static=trueto avoid transcoding and get original files
Offline Playback
- Updated
JellyfinMediaInfoProviderto check for offline files first - Updated
EmbyMediaInfoProviderto check for offline files first - Updated
PlexMediaInfoProviderto check for offline files first - Seamless fallback to streaming if file not downloaded
- Returns
file://URIs for downloaded content (isRemote = false)
Dependency Injection
- Added
DownloadRepositorybinding inRepositoryModule - Injected
DownloadRepositoryinto all MediaInfoProviders -
DownloadManageruses constructor injection with Hilt
Architecture
The implementation follows the existing codebase patterns:
- Repository pattern for data access
- Hilt/Dagger for dependency injection
- Room for database operations
- Coroutines for async operations
- Clean separation between data, domain, and presentation layers
Storage Structure
/data/data/com.simplecityapps.shuttle/files/downloads/
├── jellyfin/
│ └── {itemId}.{ext}
├── emby/
│ └── {itemId}.{ext}
└── plex/
└── {itemId}.{ext}
Next Steps (for future PRs)
- Implement
DownloadServicefor background downloads with notifications - Add UI components (download buttons, progress indicators)
- Implement batch download for albums/playlists
- Add download settings (WiFi-only, storage location, quality)
- Implement storage management and cleanup UI
- Add download notifications with progress
- Handle network changes and retry logic
- Add tests for download functionality
Addresses #88