Implementing Chromecast Streaming from a Mobile Application
Chromecast works through Google Cast SDK: the phone (Sender) controls a playback device (Receiver — Chromecast, Android TV, Google Nest). The phone doesn't stream media data through itself — it sends a URL, and the Receiver fetches the stream directly from the server.
Connecting Google Cast SDK
Android. com.google.android.gms:play-services-cast-framework:latest in build.gradle. Initialization in Application:
class App : Application() {
override fun onCreate() {
super.onCreate()
val options = CastOptions.Builder()
.setReceiverApplicationId(CastMediaControlIntent.DEFAULT_MEDIA_RECEIVER_APPLICATION_ID)
.build()
CastContext.getSharedInstance(this, executor).addOnSuccessListener { castContext ->
// Cast context is ready
}
}
}
DEFAULT_MEDIA_RECEIVER_APPLICATION_ID is the standard Default Media Receiver that plays HLS, DASH, MP4, MP3. For a custom Receiver (your own web application on Chromecast) — register in Google Cast Developer Console and use your own App ID.
iOS. pod 'google-cast-sdk' (CocoaPods) or GoogleCast via SPM (unofficial). API is similar to Android.
Cast Button in UI
Google Cast SDK automatically provides UICastButton (iOS) / MediaRouteButton (Android) — standard Cast icon that displays the list of available devices and changes appearance when connected:
// In menu toolbar
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.menu_player, menu)
CastButtonFactory.setUpMediaRouteButton(this, menu, R.id.media_route_menu_item)
return true
}
For Jetpack Compose — AndroidView with MediaRouteButton.
Starting Playback on Receiver
val castSession = CastContext.getSharedInstance(context).sessionManager.currentCastSession
val remoteClient = castSession?.remoteMediaClient ?: return
val mediaMetadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE).apply {
putString(MediaMetadata.KEY_TITLE, "Movie Title")
putString(MediaMetadata.KEY_SUBTITLE, "Description")
addImage(WebImage(Uri.parse(thumbnailUrl)))
}
val mediaInfo = MediaInfo.Builder(streamUrl)
.setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
.setContentType("application/x-mpegURL") // HLS, or video/mp4 for MP4
.setMetadata(mediaMetadata)
.build()
val loadOptions = MediaLoadRequestData.Builder()
.setMediaInfo(mediaInfo)
.setAutoplay(true)
.setCurrentTime(startPositionMs.toLong())
.build()
remoteClient.load(loadOptions)
Playback Control
RemoteMediaClient is the central object for all commands: play(), pause(), seek(position), setStreamVolume(volume). State is accessed through RemoteMediaClient.Callback:
remoteClient.registerCallback(object : RemoteMediaClient.Callback() {
override fun onStatusUpdated() {
val status = remoteClient.mediaStatus ?: return
val position = status.streamPosition
val isPlaying = status.playerState == MediaStatus.PLAYER_STATE_PLAYING
updateUI(isPlaying, position)
}
})
Mini Controller and Expanded Controller
Google Cast SDK provides ready-made UI components: MiniControllerFragment — a control bar at the bottom of the screen (similar to a mini-player), ExpandedControllerActivity — a fullscreen Cast player. Connected declaratively — minimal code required.
Cast Session and Reconnection
When Wi-Fi connection is lost, CastSession transitions to TEMPORARILY_DISCONNECTED state. After 3 minutes — DISCONNECTED. SessionManagerListener.onSessionSuspended / onSessionResumed — handle reconnection, resume playback from saved position.
If the user closed the application and returned — Cast SDK automatically restores the session through CastContext.sessionManager.currentCastSession. Check on app startup and show the Cast mini-controller if a session is active.
Chromecast on React Native and Flutter
React Native: react-native-google-cast (github.com/react-native-google-cast) — unofficial wrapper. Stable for basic scenarios (starting video, pause, seeking), but extended functionality (queue, custom data) requires native code through bridge.
Flutter: no official package. flutter_google_cast (pub.dev) — community package with unstable support. For production, we recommend native implementation through MethodChannel.
Timeline
Basic Chromecast streaming with Cast button, playback launch and mini-controller — 2–3 days. Custom Receiver (web application) — a separate task, plus 2–3 days.







