Selecting Captions Programmatically with the Native SDK for Android

In this topic, you will learn how to programmatically select captions when using the Brightcove Native SDK for Android.


The Native SDK for Android receives captions from either of the following:

  • Brightcove catalog response (Playback API) : Sidecar WebVTT
  • Video manifest (HLS or DASH) : In-manifest WebVTT

For more information about captions, see the Using Captions with the Brightcove Native SDKs document.

Event sequence

The Native SDK follows this event sequence associated with captions:

  1. Retrieve a video from the Brightcove catalog (ie. catalog.findVideoByID()).

  2. Sidecar captions are parsed from the catalog response and added to the video properties.

  3. At this point, you can retrieve caption sources as follows:

  4. Set the video view. The video is added to ExoPlayer.

  5. The Native SDK gets caption sources and emits the following event:

  6. After the video is added to ExoPlayer, the Native SDK looks for in-manifest captions. Any captions not already present in the video caption sources are added. If there are new caption sources, the following event is sent to update the Brightcove media controller.


Select captions

Follow these steps to select captions programmatically:

  1. Create a method to find an specific caption source with the language code. For example:

    private Pair<Uri, BrightcoveCaptionFormat> getCaptionsForLanguageCode(Video video, String languageCode) {
     Object payload = video == null ? null : video.getProperties().get(Video.Fields.CAPTION_SOURCES);
    if (payload instanceof List) {
     List<Pair<Uri, BrightcoveCaptionFormat>> pairs =
        (List<Pair<Uri, BrightcoveCaptionFormat>>) payload;
     for (Pair<Uri, BrightcoveCaptionFormat> pair : pairs) {
       if (pair.second.language().equals(languageCode)) {
         return pair;
    return null;
  2. Notice that caption sources are in Pair<Uri, BrightcoveCaptionFormat>. The Uri in the pair indicates the type closed captions:

    • Sidecar: The full URL is present
    • In-manifest: The BrightcoveCaptionFormat.BRIGHTCOVE_SCHEME is used
  3. Create a method responsible for selecting closed captions from a video with a given language code, by emitting the EventType.SELECT_CLOSED_CAPTION_TRACK event.

    private void selectCaption(Video video, String language) {
     Pair<Uri, BrightcoveCaptionFormat> pair = getCaptionsForLanguageCode(video, language);
    if (pair != null && !pair.first.equals(Uri.EMPTY)) {
     // BrightcoveCaptionFormat.BRIGHTCOVE_SCHEME indicates that is not a URL we need to load with the LoadCaptionsService, but instead we'll be enabled through a different component.
     if (!pair.first.toString().startsWith(BrightcoveCaptionFormat.BRIGHTCOVE_SCHEME)) {
       brightcoveVideoView.getClosedCaptioningController().getLoadCaptionsService().loadCaptions(pair.first, pair.second.type());
     Map<String, Object> properties = new HashMap<>();
     properties.put(Event.CAPTION_FORMAT, pair.second);
     properties.put(Event.CAPTION_URI, pair.first);
     brightcoveVideoView.getEventEmitter().emit(EventType.SELECT_CLOSED_CAPTION_TRACK, properties);
  4. Listen to the EventType.CAPTIONS_LANGUAGES event and select the desired language by the language code.

    brightcoveVideoView.getEventEmitter().once(EventType.CAPTIONS_LANGUAGES, new EventListener() {
    public void processEvent(Event event) {
      // You could find the desired language in the LANGUAGES list.
      // List<String> languages = event.getProperty(Event.LANGUAGES, List.class);
     selectCaption(brightcoveVideoView.getCurrentVideo(), "ja");