# How to insert subtitles on iOS

This article describes how you can side-load subtitles or closed captions, i.e. how you can add text tracks which are not part of your HLS or MPEG-DASH manifest.

Every source description has a text tracks property, which accepts an array of side-loaded text tracks. All valid tracks are available for playback as long as the player's source is not set again.

Text track descriptions can also be used for other purposes, e.g. for including preview thumbnails and chapters.

## Prerequisites

On iOS and tvOS, playback goes through AVFoundation, which cannot sideload subtitles by itself. To insert subtitles that are not part of your stream, you need the [Sideloaded Subtitles connector](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/connectors/ios/sideloaded-texttracks/getting-started.md) in addition to the THEOplayer iOS SDK.

Add the connector to your `Podfile` and install it:

```ruby
pod 'THEOplayer-Connector-SideloadedSubtitle'
```

Always use matching THEOplayer and connector versions, because the connector relies on an experimental API of the iOS SDK.

> **Note**
>
> The connector is only needed for subtitle text tracks. Metadata text tracks, such as WebVTT thumbnails, are sideloaded by the THEOplayer iOS SDK itself.

## Usage

Each text track is described by a `TextTrackDescription`.

```swift
var sampleSource: SourceDescription {
    let textTrack1 = TextTrackDescription(src: "https://your.webvtt", srclang: "en", isDefault: true, kind: .subtitles, label: "English", format: .WebVTT)
    let textTrack2 = TextTrackDescription(src: "https://your.webvtt", srclang: "ar", isDefault: false, kind: .subtitles, label: "Arabic", format: .WebVTT)

    return SourceDescription(
        source: TypedSource(
            src: "https://your.m3u8",
            type: "application/x-mpegurl"
        ),
        textTracks: [textTrack1, textTrack2]
    )
}
```

Then set the source on the player through the connector's `setSourceWithSubtitles` method, instead of assigning it to `player.source`:

```swift
import THEOplayerConnectorSideloadedSubtitle

self.theoplayer.setSourceWithSubtitles(source: sampleSource)
```

> **Warning**
>
> Replace every `player.source = source` call in your app with `setSourceWithSubtitles(source:)` if you sideload subtitles on at least one of your sources, even for sources without sideloaded subtitles. Mixing both approaches can lead to unexpected behavior.

Take note of the following limitations of sideloaded subtitles on iOS and tvOS:

* Only WebVTT (iOS-compatible) and SRT subtitles are supported.
* The label of the text track is generated by the operating system based on the language code, so the `label` you configure is disregarded.
* The `isDefault` flag is ignored. To show a sideloaded subtitle track by default, listen for the `ADD_TRACK` event and set the mode of the track to `showing`, as described 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).

The connector documentation covers additional features, such as [shifting the presentation of cues](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/connectors/ios/sideloaded-texttracks/getting-started.md#setting-a-time-offset) and [caching sideloaded subtitles](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/connectors/ios/sideloaded-texttracks/getting-started.md#caching) for offline playback.

## Related articles

* [How to dynamically change the visible captions](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/how-to-guides/ios/text-tracks/change-visible-captions.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 implement preview thumbnails](https://docs-preview.optiview.dolby.com/pr-863/theoplayer/how-to-guides/ios/text-tracks/preview-thumbnails.md)
