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"
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. This textTracks property is a TextTrackList. This TextTrackList dispatches the events from the TextTrackListEventTypes. The TextTrackListEventTypes contains the ADD_TRACK 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 event through the TextTrack interface. Then, in the callback of your ADD_CUE event, you want to track the ENTER and EXIT events through the 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 property.
Alternatively, in the callback of your ADD_TRACK event, you could track the CUE_CHANGE 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.
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.
-
You do not necessarily use the
enterevent. For cues that span a period of time, for exampleEXT-X-DATERANGEcues, you might want to perform your action when the cue ends, so on theexitevent instead. -
You might need to set the
modeof the relevant text track tohidden, as documented in how to programmatically enable or disable text tracks. Some types of timed metadata, for exampleEXT-X-DATERANGEand EventStream, aredisabledby default. You should add a condition to youraddtrackcallback to decide whether you want to set your track tohidden. -
You should set
hlsDateRangetotruein your player configuration or stream configuration, if you want to detectEXT-X-DATERANGEtags in an HLS stream.
The article on how to track ID3 cues might be useful to learn more about detecting ID3 tags specifically.