Add and customize captions (iOS)
Add embedded or sidecar captions to your iOS or tvOS app.
Suppose you have captions or subtitles for your video content. In that case, you can use the following sections to add embedded or sidecar captions to your app.
Although there are differences between the intended purposes of captions and subtitles, you use the same processes to add or customize either type of synchronized text to your app. For simplicity, captions and subtitles are referred to as captions in our documentation.
Add captions to your app
Captions can either be embedded in the video (embedded captions) or loaded from a separate file (side-loaded or sidecar captions). The iOS SDK support both types of captions.
You can add embedded captions, sidecar captions, or both.
When the list of available caption tracks is retrieved from the player, the captions appear in the following order:
- None track, denoting that no captions are available.
- Embedded captions
- Side-loaded captions
This is also the order in which the captions are listed in the player menu.
Recipes
Use one of the following recipes to add captions to your app.
iOS settings mapping
The following tables map the specific iOS Settings > Accessibility > Subtitles & Captioning settings to the iOS SDK property.
Remember that viewers must enable Video Override in each of these areas for your customizations to render when they use your app.
Text
iOS Setting | JWCaptionStyle Property |
---|---|
Color | fontColor (UIColor) |
Font | font (UIFont) |
Size | font (UIFont) |
Background
iOS Setting | JWCaptionStyle Property |
---|---|
Color | backgroundColor (UIColor) |
Opacity | backgroundColor (UIColor:alpha) |
Advanced
iOS Setting | JWCaptionStyle Property |
---|---|
Text Edge Style | edgeStyle (JWCaptionEdgeStyle) |
Text Highlight | highlightColor (UIColor) |
Text Opacity | color (UIColor:alpha) |
Listening for caption events
The following table describes the JWAVDelegate
methods that correspond to captions events.
Method | Description |
---|---|
jwplayer(_ player: JWPlayer, updatedCaptionList options: [JWMediaSelectionOption]) | When captions are loaded for the content reports what captions are available. |
jwplayer(_ player: JWPlayer, captionTrackChanged index: Int) | Reports what caption was selected, represented as an index into the list of available captions. |
jwplayer(_ player: JWPlayer, captionPresented caption: [String], at time: JWTimeData) | Reports what strings were displayed and what time they are being presented on screen. |
override func jwplayer(_ player: JWPlayer, updatedCaptionList options: [JWMediaSelectionOption]) {
super.jwplayer(player, updatedCaptionList: options)
}
override func jwplayer(_ player: JWPlayer, captionTrackChanged index: Int) {
super.jwplayer(player, captionTrackChanged: index)
}
override func jwplayer(_ player: JWPlayer, captionPresented caption: [String], at time: JWTimeData) {
super.jwplayer(player, updatedCues: cues)
}
- (void)jwplayer:(id<JWPlayer> _Nonnull)player updatedCaptionList:(NSArray<JWMediaSelectionOption *> * _Nonnull)options {
}
- (void)jwplayer:(id<JWPlayer> _Nonnull)player captionTrackChanged:(NSInteger)index
{
}
- (void)jwplayer:(id<JWPlayer> _Nonnull)player captionPresented:(NSArray<NSString *> * _Nonnull)caption at:(JWTimeData * _Nonnull)time
{
}
Setting a caption track programmatically
Setting a caption track programmatically has many benefits, including
- Knowing and setting the language your user prefers
- Mirroring a user’s language selection outside of the UI in
JWPlayerViewController
orJWCinematicViewController
- Use in conjunction with your UI implementation when the user selects a language if you are only using
JWPlayerView
To set the captions track programmatically, use the index of the captions according to the captions list or with the locale that was set for the captions.
Method | Description |
---|---|
func setCaptionTrack(index: Int) throws | Set the caption by using a valid index into the list of available captions. Using -1 will set to no captions. |
func setCaptionTrack(locale: String?) throws | Set captions using an RFC-5646 language tag—e.g, “en”. |
try {
player.setCaptionTrack(index: 2)
} catch {
// handle error
}
try {
player.setCaptionTrack(locale: “en”)
} catch {
// handle error
}
NSError *setWithIndexError;
[player setCaptionTrackWithIndex:1 error: &setWithIndexError];
if (setWithIndexError) {
// handle error if not null
}
NSError *setWithLocaleError;
[player setCaptionTrackWithLocale:@"en" error: &setWithLocaleError];
if (setWithLocaleError) {
// handle error if not null
}
Caption Rendering
Our SDK renders all side-loaded captions. For embedded captions, such as in an HLS stream, AVPlayer renders the captions. Specifying values within JWCaptionStyle
will only affect side-loaded captions.
Disabling Rendering
For some uses of our player, it may be desired that the player not render the captions. Instead, perhaps you wish to render the captions into a different view, elsewhere on the screen.
In JWPlayer, there is a property called suppressesCaptionRendering
. If true
, the player will not render captions on the screen if a caption track is selected, however, you will still receive caption events, including func jwplayer(_ player: JWPlayer, captionPresented caption: [String], at time: JWTimeData)
. By default, this flag is false
.
class CustomPlayerViewController: JWPlayerViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Suppress caption rendering
player.suppressesCaptionRendering = true
// Initialize configuration and the player below.
}
}
Setting Caption Insets
We can set the amount of space from the edges of the player to the captions container using the JWPlayerView.captionInsets
API. This property is a UIEdgeInsets
, which lets us specify the top, bottom, left, and right distance from the player edges you require.
// The new insets that will be used
let newInsets = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
// Set them to the JWPlayerView instance
playerView.captionInsets = newInsets
// The new insets that will be used
UIEdgeInsets newInsets = UIEdgeInsetsMake(0, 0, 0, 0);
// Set them to your JWPlayerView instance
self.playerView.captionInsets = newInsets;
Accessibility
On iOS devices, users can permit the SDK to select captions based on their device settings. When the caption tracks have been loaded for a video, the SDK chooses the initial caption track based on the following considerations in order:
- User's Chosen Track: If a user chooses a caption locale while watching videos in a playlist, the SDK will choose a caption in the same locale for subsequent videos in the playlist during the playback session.
- User's Language if User has Disability: If a user has enabled the Close Caption & Subtitles for the Deaf and Hard of Hearing (CC+SDH) on the device, the SDK will query the user's native language on the device and choose a caption with the same locale.
- Default Caption Track: The SDK chooses the default captions track as specified in the player configuration.
- No Captions: The SDK will turn off captions if the previous steps cannot determine a starting caption track
Updated 2 months ago