feat(cast): Chromecast support for mobile player#258
Conversation
|
Great pull, wanted this for a while too. Do you have screenshots of tests where its working? The main issue is that ARVIO often plays streams that require request headers like User-Agent, Referer, Origin, or proxy headers. Local ExoPlayer applies those headers, but the Chromecast path only sends the raw stream URL to Chromecast. That means many addon/scraper/debrid streams may fail on Chromecast with 403/no playback even though they work locally. So I think this needs one more pass before merge:
Compile checks passed, so this is not a build problem. It is a runtime compatibility problem with real ARVIO stream sources. |
|
Tested with IPTV streams that require a custom User-Agent header — casting works because Chromecast's built-in Chrome browser agent is accepted by the server. Streams where headers are strictly enforced will fail silently on the device (no playback), same as an unsupported format. The majority of debrid and IPTV HLS streams cast correctly. A future improvement could detect Chromecast playback errors and surface a warning — but hiding the cast button preemptively would break working streams. |
|
This is a good feature and I do want Chromecast support, but I don't think this is safe to merge yet. Right now the PR conflicts with current main in PlayerScreen.kt, so it needs to be rebased first. When resolving it, please keep both the new cast logic and the existing subtitle/settings logic. Bigger issue: CastManager currently sends only the stream URL to Chromecast. A lot of ARVIO streams need headers/cookies/referer/user-agent/proxy headers to play. Those headers are used by ExoPlayer locally, but Chromecast will not automatically get them, so many streams may fail when casting. To make it safe, either:
After that we should test direct streams, IPTV streams, and addon/debrid streams before merging. |
- pointerInput key changed from Unit to isCasting so the gesture handler restarts when casting state changes, capturing the updated queueControlsSeek lambda that routes double-tap to castManager.skipForward/Back - track lastCastPositionMs during the 500ms poll loop; use it to seek ExoPlayer on disconnect (remoteMediaClient is null by then so getApproximatePosition() always returned 0) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Chromecast's default receiver fetches stream URLs directly without any custom HTTP headers. Streams that set proxyHeaders.request (e.g. addons requiring Authorization or Referer) would fail silently on the device. Check behaviorHints.proxyHeaders.request and hide the cast button when any per-stream headers are required, keeping it visible for IPTV and debrid streams where auth is embedded in the URL. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Done — rebased onto current main (conflict in PlayerScreen.kt resolved, keeping both the subtitle settings LaunchedEffects/Regexes and all cast logic) and addressed the header safety concern. How the header issue is handled: Added a val streamNeedsHeaders = uiState.selectedStream
?.behaviorHints?.proxyHeaders?.request?.isNotEmpty() == true
// ...
if (isTouchDevice && castAvailable && !streamNeedsHeaders) { /* cast button */ }Why this is safe for IPTV and debrid streams: IPTV streams (Xtream Codes, M3U) and debrid-resolved links (Real-Debrid, AllDebrid) embed their auth as tokens in the URL itself — they don't set The button is only hidden for Stremio addon streams that explicitly set |
Summary
play-services-cast-framework:21.4.0,mediarouter:1.7.0)CastManagersingleton manages session lifecycle and exposescastState: StateFlow<CastState>; all cast control (play/pause/seek/skip) routes throughRemoteMediaClientCastOptionsProviderregistered inAndroidManifest.xmlwith notification actions (rewind, play/pause, forward, stop casting)RemoteMediaClientTheme.ArflixTV.Mobilenow extendsTheme.AppCompat.NoActionBarsoMediaRouteChooserDialogopens without crashingTest plan
CastState.NotAvailable, button hidden, no crash