Chromecast
Chromecast on Quickplay platform qualifies as a device on its own and can perform device registration, content authorization and playback similar to any other conventional devices. The client sender facilitates sharing required information for device registration and content authorization to the receiver and the receiver processes the same for playback.
Cast Initialization
Application should complete this setup and setup theme for entire google cast session.
iOS Implementation
To integrate internal quick play casting, we need to explicitly include a patch file that contains the changes in the rn-qp-nxg-player.podspec, ensuring that default_subspecs includes both 'Release' and 'Casting'.
s.default_subspecs = 'Release', 'Casting'
The reason for this change is that Casting is a subspec that cannot be directly added to the React Native application's Podfile due to limitations with the react_native_pods module.
NOTE:
If internal quickplay casting integration is not required, avoid using its APIs, as doing so may result in warnings.Possible unhandled promise rejection(id: 1).
NOTE:
Internal quickplay casting is not integrated also you may encounter warnings for Casting APIs during app launch.Possible unhandled promise rejection(id: 1).
Next step to integrate the code change in appDelegate.swift file
NSString *receiverAppID = [RNCConfig envFor:@"CHROMECAST_APP_ID"];
GCKDiscoveryCriteria *criteria = [[GCKDiscoveryCriteria alloc] initWithApplicationID:receiverAppID];
GCKCastOptions* options = [[GCKCastOptions alloc] initWithDiscoveryCriteria:criteria];
[GCKCastContext setSharedInstanceWithOptions:options];
options.physicalVolumeButtonsWillControlDeviceVolume = YES;
[GCKCastContext sharedInstance].useDefaultExpandedMediaControls = YES;
//Cast Dialogs UI Customization
GCKUIStyle *castStyle = [GCKUIStyle sharedInstance];
castStyle.castViews.backgroundColor = [UIColor colorWithRed: 0.07 green: 0.07 blue: 0.07 alpha: 1.00];
castStyle.castViews.headingTextColor = [UIColor whiteColor];
castStyle.castViews.headingTextFont = [UIFont fontWithName:@"Mulish-SemiBold" size:24.0];
castStyle.castViews.bodyTextColor = [UIColor whiteColor];
castStyle.castViews.bodyTextFont = [UIFont fontWithName:@"Mulish-Regular" size:14.0];
castStyle.castViews.iconTintColor = [UIColor whiteColor];
castStyle.castViews.buttonTextFont = [UIFont fontWithName:@"Mulish-SemiBold" size:14.0];
[castStyle applyStyle];
Note: Setting GCKCastContext instance should be done via main thread only.
For more details: https://developers.google.com/cast/docs/ios_sender/integrate#initialize_the_cast_context
Android Implementation
Integrate the code change in androidManifest.xml file
<activity android:name=".views.CastControlActivity" android:screenOrientation="portrait" android:exported="true" android:theme="@style/SplashTheme"/>
<activity
android:name=".views.ExpandedControlsActivity"
android:launchMode="singleTask"
android:theme="@style/SplashTheme"
android:exported="true"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
</activity>
<meta-data android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME" android:value="com.univision.univisionnow.CastOptionsProvider"/>
import com.univision.univisionnow.views.ExpandedControlsActivity
import android.content.Context
import com.google.android.gms.cast.framework.CastOptions
import com.google.android.gms.cast.framework.OptionsProvider
import com.google.android.gms.cast.framework.SessionProvider
import com.google.android.gms.cast.framework.media.CastMediaOptions
import com.google.android.gms.cast.framework.media.MediaIntentReceiver;
import com.google.android.gms.cast.framework.media.NotificationOptions
class CastOptionsProvider : OptionsProvider {
private val TAG = "CastOptionsProvider"
override fun getCastOptions(context: Context): CastOptions {
val buttonActions: MutableList<String> = ArrayList()
buttonActions.add(MediaIntentReceiver.ACTION_REWIND)
buttonActions.add(MediaIntentReceiver.ACTION_TOGGLE_PLAYBACK)
buttonActions.add(MediaIntentReceiver.ACTION_FORWARD)
buttonActions.add(MediaIntentReceiver.ACTION_STOP_CASTING)
val compatButtonActionsIndices = intArrayOf(1, 3)
// Tapping on the notification opens an ExpandedControllerActivity with class ExpandedControlsActivity.
val notificationOptions = NotificationOptions.Builder()
.setActions(buttonActions, compatButtonActionsIndices)
.setTargetActivityClassName(ExpandedControlsActivity::class.java.name)
.build()
val mediaOptions = CastMediaOptions.Builder()
.setNotificationOptions(notificationOptions)
.setExpandedControllerActivityClassName(
ExpandedControlsActivity::class.java.name
)
.build()
val receiverAppId = BuildConfig.CHROMECAST_APP_ID
return CastOptions.Builder()
.setReceiverApplicationId(receiverAppId)
.setCastMediaOptions(mediaOptions)
.build()
}
override fun getAdditionalSessionProviders(context: Context): List<SessionProvider>? {
return null
}
}
For more details: https://developers.google.com/cast/docs/android_sender/integrate#initialize_the_cast_context
Supported Interfaces for Casting
CastAuthUserConfig
Use this interface to register user data to the receiver:
| Name | Type | Description |
|---|---|---|
| castDeviceID | string | cast device Id for the content |
| platformClient | PlatformClient | Override PlatformClient if any. Otherwise, default Platform Client will be used |
CastConfig Interface
Use this interface to load media to the receiver:
| Name | Type | Description |
|---|---|---|
| mediaID | string | Media Id for the content |
| title | string | title of the content |
| consumptionType | string | ConsumptionType of the content |
| catalogType | string | Catalog of the content |
| imageURI | string | url for image |
| initialPlaybackPositionMs | number | initial time for player |
| playbackMode | PlaybackMode | playbackmode for player, required for any live playback content |
| customBookmarkData | EpisodeBookmarkRecord | customBookmarkData for Bookmark record |
| mediaType | MediaTypeValue | default value DASH for both the platform android or iOS |
| drmType | DrmTypeValue | default value WIDEVINE for both the platform android or iOS |
| startTime | string | Live playback mode restart or catch up required to provide the value |
| endTime | string | Live playback mode restart or catch up required to provide the value |
| eventId | string | eventId |
| urlParameters | string | url Parameters |
| seasonNumber | number | Season number of the cast playback content |
| episodeNumber | number | Episode number of the cast playback content |
| seriesTitle | string | Series title of the cast playback content |
| subtitle | string | Description or subtitle for the cast playback content |
| metadataMediaType | MetadataMediaType | Metadata type for setting up media metadata on the cast device |
MetadataMediaType
The metadataMediaType property supports the following content types:
| Type | Description | Supported Fields |
|---|---|---|
MEDIA_TYPE_GENERIC | Generic content (Default type) | title, subtitle |
MEDIA_TYPE_MOVIE | Movie content | title, subtitle |
MEDIA_TYPE_TV_SHOW | TV show content | title, season, episode, series title |
MEDIA_TYPE_MUSIC_TRACK | Music track (unsupported in current version) | title |
MEDIA_TYPE_PHOTO | Photo content (unsupported in current version) | title |
MEDIA_TYPE_AUDIOBOOK_CHAPTER | Audiobook chapter (unsupported in current version) | - |
MEDIA_TYPE_USER | User-defined content (unsupported in current version) | - |
Note: The cast metadata properties (
seasonNumber,episodeNumber,seriesTitle,subtitle,metadataMediaType) enhance the media information display on cast devices, providing a richer user experience during casting sessions.
CastMediaMetadata
The CastMediaMetadata represents the metadata related to casted content detals.
| Name | Type | Description |
|---|---|---|
mediaType | number | Type/category of the media being cast (implementation-specific numeric value). |
title | string | Primary display title for the current item. |
subtitle | string | Secondary text (e.g., episode title, tagline, additional context). |
artist | string | Track artist name (typically for music content). |
albumArtist | string | Album-level artist (may differ from artist for compilations). |
albumTitle | string | Album name (music). |
composer | string | Composer name (if available). |
trackNumber | number | Track number within the album (music). |
discNumber | number | Disc number within a multi-disc album (music). |
images | string[] | Image URLs associated with the content (thumbnails/posters). |
seasonNumber | number | Season number (TV/series content). |
episodeNumber | number | Episode number (TV/series content). |
seriesTitle | string | Series title (TV/series content). |
studio | string | Studio / publisher name (if provided). |
duration | number | Total duration of the item. |
liveStartTimeEpoch | number | Live stream start time as an epoch timestamp (if the content is live). |
liveOffset | number | Live offset / delay from the live edge (units are implementation-specific; often seconds). |
CastAuthorizer APIs
Configuration API
/**
* Provides an API to add a GCKStateListener at the SDK layer
*/
initWithConfig(): Promise<void>;
Note: After initializing the
GCKCastContextsingleton instance, you must call this API to check ifisConfigured()returns true. Until then, theGCKCastContextinstance is not considered fully initialized.
Cleanup API
/**
* Provides an API to end the casting session and deregister the GCKStateListener at the SDK layer.
*/
dispose: () => Promise<void>;
Media Control APIs
/**
* API responsible for loading media content onto the receiver (casting device).
*
* @param asset The media asset to be loaded; this parameter is required.
*/
castMedia(
asset: CastConfig,
headers?: { [key: string]: string },
metadata?: { [key: string]: any },
flAnalyticsData?: { [key: string]: string },
videoAnalyticsData?: { [key: string]: string}
): Promise<void>;
Input Arguments for castMedia
| Name | Type | Description |
|---|---|---|
| asset | CastConfig | The asset that must be loaded and played |
| headers | { [key: string]: string } | HTTP Headers to be added to auth request |
| metadata | { [key: string]: any } | TVOD data to be shared with chromecast receiver (optional) |
| flAnalyticsData | { [key: string]: string } | The analytics attributes that has to be shared with chromecast receiver (optional) |
| videoAnalyticsData | { [key: string]: string } | Custom video analytics metadata to be shared with chromecast receiver (optional) |
Playback Control APIs
/**
* API responsible to get the cast player current playback state
*/
getCastPlaybackState: () => Promise<string>;
/**
* API responsible to get the current cast session state
*/
getCastState: () => Promise<string>;
/**
* API responsible for executing the play action sent from the sender to the receiver device.
*/
playCast(): Promise<void>;
/**
* API responsible for executing the pause action sent from the sender to the receiver device.
*/
pauseCast: () => Promise<void>;
/**
* API responsible for executing the stop action sent from the sender to the receiver device.
*/
stopCast: () => Promise<void>;
/**
* API responsible for register user device information in the receiver.
*/
authorizeUserData(config: CastAuthUserConfig): Promise<void>;
/**
* API responsible for get the GCKContext is initialized or not.
*/
isConfigured: () => Promise<boolean>;
/**
* API responsible for register cast player listeners.
*/
attachListener(): Promise<void>;
/**
* API responsible for unregister cast player listeners.
*/
detachListener(): Promise<void>;
/**
* API responsible for setting track variant for the current casting content.
*/
setCastPreferredTrackVariant(type: TrackVariantTypeValue, trackVariantInfo: TrackVariantInfo): Promise<void>;
/**
* Handles seek actions for the active cast content initiated from the sender.
*/
seek(seekPosition: number): Promise<void>;
/**
* Explicit API call required to launch the Cast expandable player screen.
*/
showExpandedControls(disableLiveProgressbar?: boolean): Promise<void>
Note:
showExpandedControlsAPI is implemented in the iOS Platform only.
Retrieve currently playing content metadata
getCurrentItem() to read the metadata of the item that is currently playing on the Cast receiver. Example usage for this is to display “Now Casting” details in your UI. Returns the cast metadata.
let currentItem = await castAuthorizer.getCurrentItem();
Jump to next item
jumpToNextItem() to advance playback to the next item in the Cast queue (similar to a “Next” / “Skip” action). Call this when your app offers a “Play Next” control, or when you want to programmatically move through a playlist/episode queue on the receiver.
await castAuthorizer.jumpToNextItem();
Cast Session Listeners
Use the CastEventListener and the following listener APIs to monitor the status of requested CastSession actions.
/**
* The callback is invoked when a cast session begins.
*/
castSessionStarted(param: any): void;
/**
* The callback is invoked when a cast session begins with error.
*/
castSessionStartFailed(param: any): void;
/**
* The callback is invoked when a cast session ended.
*/
castSessionEnded(): void;
/**
* The callback is invoked when a cast session ended with error.
*/
castSessionEndedError(param: any): void;
/**
* The callback is invoked when a cast session device registration.
*/
castSessionDeviceRegSuccess(): void;
/**
* The callback is invoked when a cast session device registration failed.
*/
castSessionDeviceRegErr(param: any): void;
/**
* The callback is invoked when a casting content playback error.
*/
castError(param: any): void;
/**
* The callback is invoked when a casting content current player playback state.
*/
castStateChange(param: any): void;
/**
* The callback is invoked when a casting content current player playback progress.
*/
castProgressUpdate(param: any): void;
/**
* The callback is invoked when a casting content current player playback of track variant updated.
* Note: this operation right now not supported.
*/
castTrackVariantChanged(param: any): void;
/**
* The callback is invoked when a casting content current player playback of all available tracks.
* Note: this operation right now not supported
*/
castTrackAvailabilityChanged(param: any): void;
/**
* This callback is invoked when any new content is pre-loaded. Publishes the content details of
* pre-loaded content.
*/
castPreloadStatusUpdated(param?: CastMediaMetadata): void;
Managing Listeners
Use cast Authorizer addListener api to register these listeners and removeListener api to unregister these listeners.
/**
* Adds a CastAuthorizer Listener
* @param listener
*/
addListener(
listener: CastSessionStartListeners | CastSessionEndListeners | CastSessionDeviceRegistrationListeners | CastSessionPlaybackListeners | CastEventListener,
): void;
/**
* Remove a CastAuthorizer Listener
* @param listener
*/
removeListener(
listener: CastSessionStartListeners | CastSessionEndListeners | CastSessionDeviceRegistrationListeners | CastSessionPlaybackListeners | CastEventListener,
): void;