A media track can be an audio or video stream object, or a text object (subtitle
or caption).

> [!NOTE]
> **Note:** The [Styled](https://developers.google.com/cast/docs/styled_receiver) and [Default Media](https://developers.google.com/cast/docs/web_receiver#default_media_web_receiver) Receivers allow you to use only the text tracks with the API. To work with the audio and video tracks, you must develop a [Custom Receiver](https://developers.google.com/cast/docs/web_receiver/basic).

A [`GCKMediaTrack`](https://developers.google.com/cast/docs/reference/ios/interface_g_c_k_media_track)
object represents a track. It consists of a unique numeric identifier and other
attributes such as a content ID and title. A `GCKMediaTrack` instance can be
created as follows:
Swift

```swift
let captionsTrack = GCKMediaTrack.init(identifier: 1,
                                       contentIdentifier: "https://some-url/caption_en.vtt",
                                       contentType: "text/vtt",
                                       type: GCKMediaTrackType.text,
                                       textSubtype: GCKMediaTextTrackSubtype.captions,
                                       name: "English Captions",
                                       languageCode: "en",
                                       customData: nil)
```
Objective-C

```objective-c
GCKMediaTrack *captionsTrack =
      [[GCKMediaTrack alloc] initWithIdentifier:1
                              contentIdentifier:@"https://some-url/caption_en.vtt"
                                    contentType:@"text/vtt"
                                           type:GCKMediaTrackTypeText
                                    textSubtype:GCKMediaTextTrackSubtypeCaptions
                                           name:@"English Captions"
                                   languageCode:@"en"
                                     customData:nil];
```

A media item can have multiple tracks; for example, it can have multiple
subtitles (each for a different language) or multiple alternative audio streams
(for different languages).
[`GCKMediaInformation`](https://developers.google.com/cast/docs/reference/ios/interface_g_c_k_media_information)
is the class that represents a media item. To associate a collection of
[`GCKMediaTrack`](https://developers.google.com/cast/docs/reference/ios/interface_g_c_k_media_track) objects
with a media item, your app should update its
`mediaTracks` property. Your app needs to make this association before it loads
the media to the receiver, as in the following code:
Swift

```swift
let tracks = [captionsTrack]

let url = URL.init(string: "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4")
guard let mediaURL = url else {
  print("invalid mediaURL")
  return
}

let mediaInfoBuilder = GCKMediaInformationBuilder.init(contentURL: mediaURL)
mediaInfoBuilder.streamType = GCKMediaStreamType.none;
mediaInfoBuilder.contentType = "video/mp4"
mediaInfoBuilder.metadata = metadata;
mediaInfoBuilder.mediaTracks = tracks;
mediaInformation = mediaInfoBuilder.build()
```
Objective-C

```objective-c
NSArray *tracks = @[captionsTrack];

GCKMediaInformationBuilder *mediaInfoBuilder =
  [[GCKMediaInformationBuilder alloc] initWithContentURL:
   [NSURL URLWithString:@"https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"]];
mediaInfoBuilder.streamType = GCKMediaStreamTypeNone;
mediaInfoBuilder.contentType = @"video/mp4";
mediaInfoBuilder.metadata = metadata;
mediaInfoBuilder.mediaTracks = tracks;
self.mediaInformation = [mediaInfoBuilder build];
```

Activate one or more tracks that were associated with the media item (after the
media is loaded) by calling `-[setActiveTrackIDs:]` on
[`GCKRemoteMediaClient`](https://developers.google.com/cast/docs/reference/ios/interface_g_c_k_remote_media_client)
and passing the IDs of the tracks to be activated. For example, the following
code activates the captions track created above.
Swift

```swift
sessionManager.currentSession?.remoteMediaClient?.setActiveTrackIDs([1])
```
Objective-C

```objective-c
[self.sessionManager.currentSession.remoteMediaClient setActiveTrackIDs:@[@1]];
```

To deactivate a track on the current media item, call
`-[setActiveTrackIDs:]` on
[`GCKRemoteMediaClient`](https://developers.google.com/cast/docs/reference/ios/interface_g_c_k_remote_media_client)
with an empty array or nil. The following code disables the captions track.
Swift

```swift
sessionManager.currentSession?.remoteMediaClient?.setActiveTrackIDs([])
```
Objective-C

```objective-c
[self.sessionManager.currentSession.remoteMediaClient setActiveTrackIDs:@[]];
```

## Style text tracks

The
[`GCKMediaTextTrackStyle`](https://developers.google.com/cast/docs/reference/ios/interface_g_c_k_media_text_track_style)
class encapsulates the style information of a text track. A track style can be
applied to the currently playing media item by calling
[`-[GCKRemoteMediaClient
setTextTrackStyle]`](https://developers.google.com/cast/docs/reference/ios/interface_g_c_k_media_control_channel).
The track style created in the code below turns text red (FF) at 50% opacity
(80) and sets a serif font.
Swift

```swift
let textTrackStyle = GCKMediaTextTrackStyle.createDefault()
textTrackStyle.foregroundColor = GCKColor.init(cssString: "#FF000080")
textTrackStyle.fontFamily = "serif"
styleChangeRequest = sessionManager.currentSession?.remoteMediaClient?.setTextTrackStyle(textTrackStyle)
styleChangeRequest?.delegate = self
```
Objective-C

```objective-c
GCKMediaTextTrackStyle *textTrackStyle = [GCKMediaTextTrackStyle createDefault];
[textTrackStyle setForegroundColor:[[GCKColor alloc] initWithCSSString:@"#FF000080"]];
[textTrackStyle setFontFamily:@"serif"];
self.styleChangeRequest = [self.sessionManager.currentSession.remoteMediaClient setTextTrackStyle:textTrackStyle];
self.styleChangeRequest.delegate = self;
```

You can use the returned
[`GCKRequest`](https://developers.google.com/cast/docs/reference/ios/interface_g_c_k_request) object for
tracking this request.
Swift

```swift
// MARK: - GCKRequestDelegate

func requestDidComplete(_ request: GCKRequest) {
  if request == styleChangeRequest {
    print("Style update completed.")
    styleChangeRequest = nil
  }
}
```
Objective-C

```objective-c
#pragma mark - GCKRequestDelegate

- (void)requestDidComplete:(GCKRequest *)request {
  if (request == self.styleChangeRequest) {
    NSLog(@"Style update completed.");
    self.styleChangeRequest = nil;
  }
}
```

See [Status updates](https://developers.google.com/cast/docs/ios_sender_advanced#receive_status_updates)
below for more information. Apps should allow users to update the style for text
tracks, either using the settings provided by the system or by the app itself.
There is a default style provided, which can be retrieved
via the static method [`+[GCKMediaTextTrackStyle
createDefault]`](https://developers.google.com/cast/docs/reference/ios/interface_g_c_k_media_text_track_style).
The following text track style elements can be changed:

- Foreground (text) color and opacity
- Background color and opacity
- Edge type
- Edge Color
- Font Scale
- Font Family
- Font Style

## Receive status updates

When multiple senders are connected to the same receiver, it is important
for each sender to be aware of the changes on the receiver even if those
changes were initiated from other senders.

> [!NOTE]
> **Note:** This is important for all apps, not only those that explicitly support multiple senders, because some Cast devices have control inputs (remotes, buttons) that behave as virtual senders, affecting the status on the receiver.

To ensure your sender receives status updates from the receiver, your app should
register a
[`GCKRemoteMediaClientListener`](https://developers.google.com/cast/docs/reference/ios/protocol_g_c_k_remote_media_client_listener-p).
If the
[`GCKMediaTextTrackStyle`](https://developers.google.com/cast/docs/reference/ios/interface_g_c_k_media_text_track_style)
of the current media changes, then all of the connected senders will be notified
through both the
`-[remoteMediaClient:didUpdateMediaMetadata:]` and the
`-[remoteMediaClient:didUpdateMediaStatus:]` callbacks. In this case, the
Receiver SDK does not verify whether the new style is different from the
previous one and notifies all the connected senders regardless. If, however,
the list of active tracks is updated, only the
`-[remoteMediaClient:didUpdateMediaStatus:]` in connected senders will be
notified.

> [!NOTE]
> **Note:** The list of tracks associated with the currently loaded media cannot be changed. If needed, you have to update the tracks information on the [`GCKMediaInformation`](https://developers.google.com/cast/docs/reference/ios/interface_g_c_k_media_information) object and reload the media.

## Satisfy CORS requirements

For adaptive media streaming, Google Cast requires the presence of CORS headers,
but even simple mp4 media streams require CORS if they include Tracks. If you
want to enable Tracks for any media, you must enable CORS for both your track
streams and your media streams. So, if you do not have CORS headers available
for your simple mp4 media on your server, and you then add a simple subtitle
track, you will not be able to stream your media unless you update your server
to include the appropriate CORS header. In addition, you need to allow at least
the following headers: Content-Type, Accept-Encoding, and Range. Note that the
last two headers are additional headers that you may not have needed previously.