# How to detect active text track cues on iOS

This article describes how you can use the TextTrack API to detect the active text track cues, by subscribing to the `enter` and `exit` events of a cue, or to the `cuechange` event of a text track.

Implementing this functionality can be a use-case for developers who want to build their own UI, and insert and style their subtitles with maximum freedom. Alternatively, you may need to access the active cues for analytics purposes, or to render them outside of the video player.

Another common use-case is to detect the active text track cue of timed metadata. This article also discusses this use-case.

## Implementation for subtitles and closed captions

Note that this section focuses on detecting active cues for subtitles and closed captions. Go to the section on ["implementation for timed metadata"](#implementation-for-timed-metadata) if you rather want to track timed metadata like ID3, emsg, `EXT-X-DATERANGE` and EventStream.

The iOS SDK exposes the TextTrack API through [`player.textTracks`](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/v11/api-reference/ios/Classes/THEOplayer#/s:13THEOplayerSDK0A0C10textTracksAA13TextTrackList_pvp). This `textTracks` property is a [`TextTrackList`](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/v11/api-reference/ios/Protocols/TextTrackList). This `TextTrackList` dispatches the events from the [`TextTrackListEventTypes`](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/v11/api-reference/ios/Structs/TextTrackListEventTypes). The `TextTrackListEventTypes` contains the [`ADD_TRACK`](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/v11/api-reference/ios/Structs/TextTrackListEventTypes#/s:13THEOplayerSDK23TextTrackListEventTypesV9ADD_TRACKAA0F4TypeCyAA03AdddF0CGvpZ) event, as well as the `CHANGE` and `REMOVE_TRACK` event.

In the callback of your `ADD_TRACK` event, you want to track the [`ADD_CUE`](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/v11/api-reference/ios/Structs/TextTrackEventTypes#/s:13THEOplayerSDK19TextTrackEventTypesV7ADD_CUEAA0E4TypeCyAA06AddCueE0CGvpZ) event through the [`TextTrack`](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/v11/api-reference/ios/Protocols/TextTrack) interface. Then, in the callback of your `ADD_CUE` event, you want to track the [`ENTER`](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/v11/api-reference/ios/Structs/TextTrackCueEventTypes#/s:13THEOplayerSDK22TextTrackCueEventTypesV5ENTERAA0F4TypeCyAA0e5EnterF0CGvpZ) and [`EXIT`](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/v11/api-reference/ios/Structs/TextTrackCueEventTypes#/s:13THEOplayerSDK22TextTrackCueEventTypesV4EXITAA0F4TypeCyAA0e4ExitF0CGvpZ) events through the [`TextTrackCue`](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/v11/api-reference/ios/Protocols/TextTrackCue) interface. The `ENTER` event is dispatched when a cue becomes active and the `EXIT` event is dispatched when a cue becomes inactive. You can fetch the actual content in the callback of your `ENTER` event through its [`content`](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/v11/api-reference/ios/Protocols/TextTrackCue#/s:13THEOplayerSDK12TextTrackCueP7contentypSgvp) property.

Alternatively, in the callback of your `ADD_TRACK` event, you could track the [`CUE_CHANGE`](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/v11/api-reference/ios/Structs/TextTrackEventTypes#/s:13THEOplayerSDK19TextTrackEventTypesV10CUE_CHANGEAA0E4TypeCyAA09CueChangeE0CGvpZ) event through the `TextTrack` interface. Then, in the callback of your `CUE_CHANGE` event, you want to iterate over the active cues. For each active cue, you could also query its `content` property.

The code below allows you to detect the active text track cues.

```swift
player.textTracks.addEventListener(type: TextTrackListEventTypes.ADD_TRACK) { addTrackEvent in
    let track: TextTrack = addTrackEvent.track as! TextTrack
    track.addEventListener(type: TextTrackEventTypes.ADD_CUE) { addCueEvent in
        let cue = addCueEvent.cue
        cue.addEventListener(type: TextTrackCueEventTypes.ENTER) { enterEvent in
            print(enterEvent, enterEvent.cue.content)
        }
        cue.addEventListener(type: TextTrackCueEventTypes.EXIT) { exitEvent in
            print(exitEvent)
        }
    }
    track.addEventListener(type: TextTrackEventTypes.CUE_CHANGE) { cueChangeEvent in
        let textTrack: TextTrack = cueChangeEvent.track as! TextTrack
        textTrack.activeCues.forEach { cue in
            print("cuechange active cue", cue)
        }
    }
}
// ...
// player.source = ...
```

You should invoke these event handlers before you configure your stream, because the player might have already dispatched the event before you were able to subscribe to it.

## Implementation for timed metadata

The implementation for timed metadata is identical to the one for subtitles and closed captions, except for three things.

1. You do not necessarily use the `enter` event. For cues that span a period of time, for example `EXT-X-DATERANGE` cues, you might want to perform your action when the cue ends, so on the `exit` event instead.

2. You might need to set the `mode` of the relevant text track to `hidden`, as documented in [how to programmatically enable or disable text tracks](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/how-to-guides/ios/text-tracks/enable-disable-text-tracks.md). Some types of timed metadata, for example `EXT-X-DATERANGE` and EventStream, are `disabled` by default. You should add a condition to your `addtrack` callback to decide whether you want to set your track to `hidden`.

3. You should set [`hlsDateRange`](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/v11/api-reference/ios/Classes/THEOplayerConfiguration) to `true` in your player configuration or stream configuration, if you want to detect `EXT-X-DATERANGE` tags in an HLS stream.

The article on [how to track ID3 cues](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/how-to-guides/ios/text-tracks/track-id3-cues.md) might be useful to learn more about detecting ID3 tags specifically.

## Related articles

* [How to programmatically detect text track changes](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/how-to-guides/ios/text-tracks/detect-text-track-changes.md)
* [How to programmatically enable or disable text tracks](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/how-to-guides/ios/text-tracks/enable-disable-text-tracks.md)
* [How to track ID3 cues](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/how-to-guides/ios/text-tracks/track-id3-cues.md)
