Subtitles

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

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

OTVTrackInfo[] getOTVTrackInfo()

This returns an array of all tracks in the current stream, including subtitle and audio 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

The following example code is used 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() == OTVTrackType.OTV_TRACK_TYPE_TIMEDTEXT )
     {
       // add to text track list with index ā€˜iā€™
     }
     else if( trackInfo[ i ].getType() == OTVTrackType.OTV_TRACK_TYPE_AUDIO )
     {
       // 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():

    selectTrack(int xIndex)
    
  • To deselect a track at an index of the array returned by getOTVTrackInfo()(optional):

    deselectTrack(int xIndex)
    
  • 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 streams 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 subtitles 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.

    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() == OTVTrackType.OTV_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.