Android Music • Movies • TV • Plugins
Native Android music & media streaming app built with Kotlin and Jetpack Compose.
- YouTube Music streaming with multi-client Innertube waterfall resolution
- 🎤 Lyrics display
- 💾 Offline downloads with ExoPlayer cache
- 🎚️ Equalizer / audio effects
- Youtube login
- Spotify login
- Spotify canvas media screen
- 🎬 Movie & TV playback
- 📡 Chromecast support
- 🔊 Sonos speaker support
- 🧲 Torrent streaming via TorrServer
StreamCloud supports CloudStream 3 plugins with improved compatibility:
- ✅ MainAPI Providers — Content providers (movies, TV, anime, etc.)
- ✅ ExtractorAPI — Custom video stream extractors
⚠️ Status: Actively improved with better error reporting and multi-strategy class loading- 📝 Compatibility: Compatible with CloudStream 3 plugins compiled for recent SDK versions
What Works:
- Loading and executing CloudStream 3 plugins (.cs3 files)
- Multi-strategy class loading with fallback mechanisms
- Plugin API registration (both MainAPI and ExtractorAPI)
- Plugin settings callbacks
- Context delegation for plugin resource access
Known Limitations:
- Some older plugins may require updates to work with StreamCloud's classloader setup
- Plugins with undeclared dependencies may fail to load
- Plugin extractors are registered but integration with the player is in progress
Troubleshooting Plugin Issues: If a plugin fails to load, check the app logs for specific error messages. Common issues:
NoClassDefFoundError— Plugin references missing dependenciesClassCastException— Classloader mismatch (improved with fallback strategies)NoSuchMethodError— API incompatibility (check CloudStream SDK version)
See PLUGIN_DEVELOPMENT.md for guidelines on:
- Building compatible plugins
- Using MainAPI and ExtractorAPI
- Testing against StreamCloud
- Debugging plugin loading issues
- Android Auto support
- Android Automotive OS support with full browse tree
- coming soon
- 💜 Language: Kotlin
- 🎨 UI: Jetpack Compose
▶️ Player: Media3 / ExoPlayer- 🌐 Networking: OkHttp
- 🗄️ Local DB: Room
- ⚡ Architecture: ServiceLocator singletons, coroutines + Flow
Audio streams are resolved via a multi-client Innertube waterfall:
ANDROID_MUSIC— YT Music client, best audio metadataANDROID— Standard YouTube Android clientANDROID_TESTSUITE— YouTube-whitelisted internal test clientANDROID_VR(x2) — Oculus Quest clientsIOS— iPhone clientIPADOS— iPad clientANDROID_CREATOR— YouTube Studio Android client
All clients return plain stream URLs. No cipher deobfuscation required.
./gradlew assembleDebugRequires Android Studio Hedgehog or later, minSdk 26, targetSdk 35.
- Plugin Development Guide — How to build plugins for StreamCloud
- Plugin Runtime Architecture — Technical details on plugin loading
This section summarises improvements made to bring StreamCloud's CloudStream 3
compatibility closer to the reference recloudstream/cloudstream
implementation.
| Area | recloudstream/cloudstream | StreamCloud (before) | Gap |
|---|---|---|---|
SubtitleHelper language DB |
170 languages, 4 lookup indexes | ~25 hardcoded entries, 1 index | Plugins calling fromTwoLettersToLanguage() got null |
SubtitleHelper API |
fromTwoLettersToLanguage, fromThreeLettersToLanguage, fromTagToEnglishLanguageName, fromTagToLanguageName |
fromCodeToLangTagIETF, fromLanguageToTagIETF only |
Missing methods = broken subtitle track names |
getQualityFromName |
"4k" only | "4k" only | "uhd", "fhd", "hd", "sd", "qhd" → Unknown |
| Plugin error messages | — | Covered ~7 error patterns | ~500xx, timeout, no-results patterns missing |
-
SubtitleHelper.kt— Comprehensive language database (170 entries)- Replaced the 25-entry hardcoded map with the full 170-language database from
recloudstream/cloudstream, indexed on IETF tag, ISO 639-1, ISO 639-2/B, ISO 639-3, and OpenSubtitles codes. - Added
fromTwoLettersToLanguage(input)— deprecated in the canonical library but still called by many existing plugins; without it subtitle track names werenull. - Added
fromThreeLettersToLanguage(input)— same compat reason. - Added
fromTagToEnglishLanguageName(languageCode)— returns the English name for any recognized code, used by the player's subtitle track picker. - Added
fromTagToLanguageName(languageCode, localizedTo)— returns a JVM-localised name with English fallback. - Improved
fromCodeToLangTagIETFandfromLanguageToTagIETFto use the database rather than a small fixedwhenblock, so all 170 languages resolve correctly.
- Replaced the 25-entry hardcoded map with the full 170-language database from
-
ExtractorApi.kt—getQualityFromNamequality-string aliases- Added aliases:
uhd→2160p,fhd/full hd/fullhd→1080p,hd→720p,sd→480p,qhd/2k→1440p, interlaced suffixes (1080i,720i, …). - Improves quality-based source sorting for plugins that label streams with these strings instead of numeric values.
- Added aliases:
-
CloudStreamDetailScreen.kt— ExpandedfriendlyPluginErrorpatterns- Added recognition for:
MalformedJsonException,JsonParseException,NoSuchMethodError,Connection refused,CertPathValidatorException, HTTP 5xx status codes, timeout strings, and "no links found" / "0 results" diagnostics. - Users see concise, actionable messages instead of raw stack-trace excerpts.
- Added recognition for:
- 34 new
SubtitleHelperTestunit tests — all pass. - 26 new
QualityFromNameTestunit tests — all pass. - Existing
NuvioCompatTest,NuvioTmdbSanitizerTest, andPluginCompatibilityTestare unaffected.
SubtitleHelper.getFlagFromIso()(flag-emoji helper) is not yet ported; requires thelang2countrymapping table (~200 entries). Low priority for functionality.SubtitleHelper.fromLanguageToTagIETFdoes not yet perform Levenshtein fuzzy matching (used by cloudstream for partial names like "English Subtitle"). Can be added if plugins need it.- DRM (
DrmExtractorLink) key-rotation and licence-URL fallback logic from cloudstream has not been ported as StreamCloud does not yet expose a DRM licence-request flow.
Join our Discord community for support, feature requests and updates.