A Kotlin Multiplatform media hub for the Stremio addon ecosystem β browse catalogs, discover metadata, and play streams from your own addons. No built-in content, no bundled scrapers. You choose the sources.
MovieHub is a neutral, privacy-oriented client for the Stremio protocol. All content, metadata, and streams come exclusively from user-installed third-party addons and JS plugins.
- Dynamic Home Screen β Hero carousel with auto-scroll, continue watching with progress bars, category filter chips with emoji labels, shimmer skeleton loading, pull-to-refresh, infinite scroll pagination
- Multi-Addon Catalogs β Items from multiple addons are round-robin interleaved within each catalog section for fair source visibility
- Cache-First Loading β Room DB cache displayed instantly, network refresh runs in background. Background catalog prefetch while profile screen shows β instant HomeScreen on login
- Powerful Search β Cross-addon search with debounced suggestions, persistent search history, discover section with genre/type/sort filters
- Cross-Platform Video β ExoPlayer (Android) + MPV (iOS) with consistent custom overlay controls
- Silent Auto-Switch β Stream fails β next source loads automatically. No error dialogs, no user interaction. Cycles through all available sources. Player auto-closes only when every source is exhausted
- YouTube-Style Swipe Seek β Drag anywhere on screen for real-time Β±MM:SS seeking with centered indicator. Seek executes on finger lift. 30 seconds per full-screen swipe
- Pinch Zoom β Centroid-based zoom (1xβ5x) with pan when zoomed in.
graphicsLayer(clip = false)for smooth overflow rendering - Full Controls β Play/Pause, speed (0.5xβ2x), audio track, subtitle track, video quality, brightness/volume gesture zones, screen lock, sleep timer, debug overlay, PiP
- Proxy Stream Support β Preconnect with proxy headers, two-hop DNS/TCP/TLS warmup (extractor β CDN), HTTP/2 preferred, 30s read timeout for extractor chains
- ExoPlayer Tuning β 1.5s initial buffer (was 50s), 2s rebuffer recovery, OkHttp 10-conn pool, time-prioritized load control
- Widescreen Subtitle Styling Center β Real-time WYSIWYG preview, typography controls, color palette, outline/shadow effects, 5 built-in presets (Netflix, Prime, Disney+, High Contrast), Room DB persistence
- Watch Progress β Auto-saves every 15s, on pause, and at 90% completion (marks watched). Resume with saved position and track preferences (audio/subtitle/video quality)
- DRM β Widevine/ClearKey via Media3 on Android
- 5 Themes Γ 10 Accents β Nuvio Dark (default), Dark, AMOLED Dark, Light, Ocean Dark Γ 10 accent colors. Theme-aware status bar across all screens
- Design System β All colors via
MaterialTheme.colorScheme.*, all dimensions viaMovieHubDimens.*, string resources for localization-ready text - Smart TopAppBar β Consistent across all screens with automatic back navigation
- Multi-Profile β Create, clone, and switch profiles. Addons, favorites, watch history, and settings isolated per profile. Cinemeta auto-seeded on new profiles
- Offline Downloads β Queue, pause, resume, cancel per profile. Configurable concurrent downloads and storage location
- Parallel Fan-Out β All 95+ HTTP addons and JS scrapers queried simultaneously via
supervisorScope+async/awaitAllwith semaphore-controlled concurrency - Real-Time Status Pills β Per-addon loading/completion/failure indicators. Auto-dismiss when all providers complete
- Direct-Play + Torrent β Direct URLs skip validation, torrent streams pass through content verification (title, season/episode, year)
- Offline-First β Cached streams displayed instantly. Network refresh merges new results without flicker
- Provider Filtering β Filter displayed streams by addon source
- 96%+ Common Code β Business logic, networking, UI, and database are entirely in
commonMain. Platform code limited to video rendering and file I/O - Strict MVI β Every feature follows
State + Action + ViewModelwithMutableStateFlow+asStateFlow(). SingleonAction()entry point.@Immutabledata classes - Clean Module Hierarchy β
core/*βfeature/*βnavigationβdiβcomposeApp. Core never depends on feature - Offline-First β Room-backed cache with TTL-based eviction (10min catalogs, 1hr metadata, 20min streams)
- Reactive β Koin DI with
StateFlow-driven ViewModels. Compose recombines on state changes automatically
| Layer | Technology |
|---|---|
| Language | Kotlin 2.3.21 β Multiplatform, 96%+ commonMain |
| UI | Compose Multiplatform 1.11.0 β Material 3, shared across Android & iOS |
| Navigation | Navigation Compose 2.9.2 β Type-safe routes with @Serializable sealed interfaces |
| DI | Koin 4.2.1 β Multiplatform DI with compose integration |
| Networking | Ktor 3.5.0 β Content negotiation, retry with exponential backoff, gzip/deflate |
| Database | Room3 β KMP SQLite ORM, 9 entities, WAL mode |
| Image Loading | Kamel 1.0.9 β Async loading, 50-image memory cache, 50MB disk cache |
| Video (Android) | Media3 / ExoPlayer 1.10.1 β HLS, DASH, SmoothStreaming, Cast, Widevine |
| Video (iOS) | MPV via mpv-shim + MpvPlayerBridge.swift β Full codec support including MKV, H.265, AV1 |
| JS Runtime | QuickJS-KT 1.0.5 β Sandboxed JavaScript, 10s per-plugin timeout, crash protection |
| HTML Parsing | Ksoup 0.2.6 β JVM cheerio-compatible HTML parser |
| Backend/Auth | Supabase 3.6.0 β PostgREST + Auth SDK |
| Logging | Kermit 2.1.0 β Multiplatform structured logging |
| Serialization | Kotlinx Serialization 1.11.0 β JSON with ignoreUnknownKeys, coerceInputValues |
| Build | AGP 9.2.1 β Gradle configuration cache, parallel builds, KSP 2.3.7 |
MovieHub/
βββ composeApp/ # App entry point & Compose root
β βββ commonMain/ # App.kt, Kamel config
β βββ androidMain/ # MainActivity (edge-to-edge, 120Hz, PiP)
β βββ iosMain/ # MainViewController (ComposeUIViewController)
β
βββ di/ # Koin DI β appModules() wires everything
βββ navigation/ # RootNavGraph + Screen sealed interface
β
βββ core/
β βββ model/ # Domain models (pure Kotlin, zero deps)
β βββ network/ # Ktor client, Stremio API, AddonManager,
β β # ScraperManager + PluginRuntime (QuickJS),
β β # TMDB, YouTube resolver, debrid clients
β βββ database/ # Room3 β 9 entities, version 11
β βββ ui/ # Design system, components, theme engine
β βββ player-api/ # MoviePlayerController abstraction
β βββ utils/ # PerformanceMonitor, CrashReporter, Analytics
β
βββ feature/
β βββ home/ # Hero carousel, catalogs, continue watching
β βββ search/ # Cross-addon search, history, discover
β βββ details/ # Metadata, cast, streams, trailers, series
β βββ player/ # Video player (ExoPlayer / MPV)
β βββ addon/ # Addon install, update check, management
β βββ auth/ # Supabase + debrid authentication
β βββ profile/ # Profiles, settings, appearance, library
β βββ sync/ # Cloud sync via Supabase
β
βββ gradle/
β βββ libs.versions.toml # Centralized version catalog (120+ deps)
β
βββ iosApp/ # iOS Xcode project + CBridge (MPV)
β
βββ graphify-out/ # Knowledge graph (code relationships)
- Android Studio Koala+ or IntelliJ IDEA with KMP plugin
- JDK 17+
- Xcode 15+ (for iOS)
- A Stremio addon manifest URL to get started
git clone https://github.com/Sumit123rox/MovieHub.git
cd MovieHub
# Android debug APK
./gradlew :composeApp:assembleDebug
# iOS β compile shared Kotlin, then open in Xcode
./gradlew :composeApp:iosSimulatorArm64MainKotlinNativeCompile
open iosApp/iosApp.xcodeproj- Launch the app β create a profile
- Open External Providers β paste a Stremio addon URL β Install
- Home tab shows catalogs from your addons
- Tap any title β pick a stream β play
MovieHub ships with zero built-in content. You must install addons to see anything.
- TMDB API Key β Settings β Advanced for enriched metadata
- Real-Debrid / AllDebrid / Premiumize β Settings β Sync & Accounts
- Trakt β Settings β Sync & Accounts for watchlist sync
- Appearance β Settings β General β Theme & Accent (5Γ10 combinations)
| Aspect | Android | iOS |
|---|---|---|
| Engine | ExoPlayer (Media3) | MPV (libmpv via mpv-shim) |
| Rendering | AndroidView + PlayerView |
UIKitView + MpvPlayerBridge |
| Position | 1s polling via Player.Listener |
Frame callback via MpvPlayerBridge |
| Formats | HLS, DASH, SmoothStreaming, progressive | All MPV formats β MKV, H.265, AV1, VP9, HLS, DASH |
| DRM | Widevine / ClearKey via Media3 | N/A |
| Cast | Google Cast (Chromecast) | N/A |
| Subtitle Styling | Media3 CaptionStyleCompat |
MPV's libass renderer |
| Data Source | OkHttp with proxy headers + HTTP/2 | MPV's internal HTTP client |
| Orientation | requestedOrientation + restore on exit |
OrientationLockCoordinator.swift |
| Optimization | Detail |
|---|---|
| Image Cache | Kamel 50 decoded bitmaps in memory (~25MB), 50MB disk cache |
| Stream Cap | Bounded accumulation, early exit when sufficient streams found |
| Concurrency | Semaphore-controlled parallel addon queries |
| Recomposition | StreamsUpdated throttled to 250ms, pointerInput(Unit) stable keys |
| ExoPlayer | 1.5s initial buffer, 2s rebuffer, time-prioritized load control |
| Heap | largeHeap=true for headroom on large video buffers |
PRs and ideas welcome β open an issue first to discuss.
MIT β see LICENSE.
Made with β€οΈ in India
β MovieHub