Subtitles

To test this feature and view the example code, please see the Example Code Quick Start guide.

Subtitles can be displayed when a stream is playing by calling methods on the OTVVideoView instance.

OTVTrackInfo[] getOTVTrackInfo()

This returns an array of all tracks in the current stream, comprising video, audio and subtitle tracks. The following subtitle track types are supported:

  • WebVTT
  • SMPTE-TT (text)
  • EIA-608 (CC608) - all four services (CC1 - CC4)
  • EIA-708 (CC708) - first service only
  • SRT

Prerequisites

  • A clear stream with subtitles is available for testing.

Example code

Use the following example code to enable subtitles.

  • The subtitle tracks are located by interrogating for tracks of type TIMEDTEXT, for example:

    OTVTrackInfo[] trackInfo = mOTVVideoView.getOTVTrackInfo();
    for (int i = 0; i < trackInfo.length ; i++) {
     if (trackInfo[i].getType() == OTVTrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT) {
       // Add to text track list with index 'i'
     } else if (trackInfo[i].getType() == OTVTrackInfo.MEDIA_TRACK_TYPE_AUDIO) {
       // Ignore track
     } else if (trackInfo[i].getType() == OTVTrackInfo.MEDIA_TRACK_TYPE_VIDEO) {
       // Ignore track
     }
    }
    // Return text track list and indexes to present to the user for selection
    
  • To select a track at an index of the array returned by getOTVTrackInfo().

    mOTVVideoView.selectTrack(index);
    
  • To deselect a track at an index of the array returned by getOTVTrackInfo() (optional).

    mOTVVideoView.deselectTrack(index);
    
  • To implement a listener (ITrackChangedListener) that will be called whenever the track changes (optional).

    mOTVVideoView.registerOnTrackChangedListener(mTrackChangedListener);
    // Create a Track changed listener
    private ITrackChangedListener mTrackChangedListener = new ITrackChangedListener() {
      @Override
      public void onTrackChanged() {
        // handle anything you want to do when a stream's track changes
      }
    }
    

Text style

Text-based subtitles' appearance (size, colour, fonts, background, etc.) is controlled by system settings. Typically those settings are under System > Accessibility > Captions

Additional track information

The OTVTrackInfo class contains additional information about the subtitle track, which can be attained through the class's methods. Typically, that extra information is extracted from the stream's manifest/playlist, so the availability of the information is dependent on the streams:

  • isActive() will return true for the selected track, and false for all other subtitle tracks in the list
  • getName() provides a string describing the track (which may be simply the language)
  • getLanguage() provides the language code string in either way of ISO-639-1 or ISO-639-2
  • getEncodeType() returns an integer representing the subtitles' encoding (see the reference API of OTVTrackInfo for the various values)
  • getCharacteristics() will return a string of track characteristics as advertised in some HLS streams.
  • getVideoTrackInfos() will return null for subtitle tracks

An example demonstrating the use of these methods is shown below.

  OTVTrackInfo[] tracks = mPlayer.getOTVTrackInfo();
  int selectedTrackIndex = -1;
  for (int index = 0; index < tracks.size(); ++index) {
    OTVTrackInfo trackInfo = tracks.valueAt(index);
    if (trackInfo.getType() == OTVTrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT) {
      // Subtitles track
      if (trackInfo.isActive()) {
        selectedTrackIndex = index;
      }
      StringBuilder trackNameBuilder = track.getName().equals("") ?
          String.format(Locale.ENGLISH,"Track %d",index + 1) :
          track.getName();
      trackNameBuilder.append(" <" + trackInfo.getLanguage() + ">");
      String characterisics = track.getCharacteristics().toLowerCase();
      if (!characterisics.isEmpty()) {
        String[] characterisicsArray = characterisics.split(",");
        for (String chrs : characterisicsArray) {
          if (chrs.equalsIgnoreCase("public.accessibility.transcribes-spoken-dialog") ||
              chrs.equalsIgnoreCase("public.accessibility.describes-music-and-sound") ||
              chrs.equalsIgnoreCase("public.easy-to-read")) {
              trackNameBuilder.append(" (Hard of Hearing)");
              break;
          }
        }
      }
      String encodingType;
      int et = track.getEncodeType();
      switch (et) {
      case OTVTrackInfo.SUBTITLE_TRACK_ENCODING_TYPE_DVB_BITMAP:
        trackNameBuilder.append(" [DVB bitmap]");
        break;
      case OTVTrackInfo.SUBTITLE_TRACK_ENCODING_TYPE_EIA_608:
        trackNameBuilder.append(" [CC608]");
        break;
      case OTVTrackInfo.SUBTITLE_TRACK_ENCODING_TYPE_EIA_708:
        trackNameBuilder.append(" [CC708]");
        break;
      case OTVTrackInfo.SUBTITLE_TRACK_ENCODING_TYPE_ID3:
        trackNameBuilder.append(" [ID3]");
        break;
      case OTVTrackInfo.SUBTITLE_TRACK_ENCODING_TYPE_WEBVTT:
        trackNameBuilder.append(" [WebVTT]");
        break;
      case OTVTrackInfo.SUBTITLE_TRACK_ENCODING_TYPE_SRT:
        trackNameBuilder.append(" [SRT]");
        break;
      case OTVTrackInfo.SUBTITLE_TRACK_ENCODING_TYPE_SMPTE:
        trackNameBuilder.append(" [SMPTE]");
        break;
      default:
        break;
      }
      String trackName = trackNameBuilder.toString();
      ...
    }
  }

External subtitles

The following is an example for adding an external subtitle source:

    mOTVVideoView.setVideoPath("https://path/to/video.m3u8");
    mOTVVideoView.addSubtitleSource("https://path/to/subtitles.srt", "MIME type", "Language");

Call this method immediately after you have set the video path, it will return true if you have passed through a valid URI and Mime type. If this method is called after playback has begun, it will restart playback.

This method will still return true if you pass through a valid URI that is not a subtitle address.

Accessibility settings

When using a device that has Captions enabled through its Accessibility caption options, there are specific changes to the default behaviour of subtitles within the application:

  • If Caption language settings are set to default language, the track within the stream marked default will be used if any are marked as such.
  • If language is not set to default, the subtitles will attempt to use a track that matches your chosen language. If a track matching the chosen language cannot be found, the default will be selected.
  • If there is no default track on the stream and default is selected, the captions manager will use the devices current language as the default track.