Subtitles

This player uses a HTML5 <track> element to display subtitles and a subtitle selection menu in all browsers.

#with-subtitles {
  background-image: url(/{{ config.flowplayer7.media }}img/demos/functional.jpg");
}
#with-subtitles.cue6 .fp-captions p {
/* one huge custom subtitle */
  font-size: 40px;
}

[View standalone demo]({{ config.flowplayer7.standalonedemos }}/basics/subtitles)

Setting up

As for video sources we discern 2 installation categories:

Video tag based

In a VIDEO tag based installation subtitles are loaded from TRACK elements as follows:

<div id="with-subtitles" class="flowplayer"
     data-share="false"
     data-ratio="0.4167">

   <video>
      <source type="application/x-mpegurl"
              src="//edge.flowplayer.org/functional.m3u8">
      <source type="video/mp4"
              src="//edge.flowplayer.org/functional.mp4">

      <track kind="subtitles" default srclang="en" label="English"
             src="//edge.flowplayer.org/subtitles/subtitles-en.vtt">
      <track kind="subtitles" srclang="de" label="Deutsch"
             src="//edge.flowplayer.org/subtitles/subtitles-de.vtt"></video>

</div>

Pure JavaScript

The same setup looks like this in a pure JavaScript installation:

flowplayer("#with-subtitles", {
    clip: {
        subtitles: [
            { "default": true, // note the quotes around "default"!
              kind: "subtitles", srclang: "en", label: "English",
              src:  "//edge.flowplayer.org/subtitles/subtitles-en.vtt" },
            { kind: "subtitles", srclang: "de", label: "Deutsch",
              src:  "//edge.flowplayer.org/subtitles/subtitles-de.vtt" }
        ],
        sources: [
            { type: "video/webm",
              src:  "//edge.flowplayer.org/functional.webm" },
            { type: "video/mp4",
              src:  "//edge.flowplayer.org/functional.mp4" },
            { type: "video/flash", src: "mp4:functional" }
        ]
    },
    share: false,
    ratio: 5/12
});

The subtitles array is the representation the attributes of one or more subtitle TRACK elements of a HTML5 VIDEO tag in JavaScript Object Notation in a similar fashion as the sources array is for video SOURCE elements in a clip object.

VTT file format

A WEBVTT file referenced in the TRACK element has the following structure:

WEBVTT FILE

1
00:00:01.000 --> 00:00:04.000
The first subtitle from 1 seconds to 4 seconds
This is a second line
And a third one

2
00:00:05.000 --> 00:00:06.000
<b>Bold</b>, <i>italic</i> and <u>underlines</u> are supported

...

Make sure to save your WebVTT files in UTF-8 format.

Server side

VTT files must be served on a loose cross-origin policy (CORS) with an appropriate Access-Control-Allow-Origin header if they are loaded from a different domain, even a different sub domain.

For instance, in an Apache configuration:

Header set Access-Control-Allow-Origin "*"

Setting the CORS policy for the VTT files is always mandatory when you offer the player for sharing

For more details look up cross-orgin resource sharing.

It is recommended to serve VTT files with a mime type of text/vtt. If you have native subtitles configured this is mandatory.

Configuration

Player options

On the player configuration level the subtitle extension offers these options:

    • option
    • description
    • subtitleParser function (txt)
    • The default subtitle parser can be overridden without the need for a plugin with this option. That way specific subtitle parsers can be implemented not only globally, but for individual players on the page.
      It also allows for custom support of non-VTT caption formats.
      The function takes one argument which is the complete text of all subtitles.
      By definition this option cannot be set as HTML data attribute.
      See below for further details.

Support for loading VTT files from a different domain for native subtitle display is broken in most browsers.

Clip options

The subtitles extension provides the following clip configuration option.

Video tag based cross origin

In VIDEO tag based installations the crossorigin attribute must be added to the VIDEO tag if (and only if) the VTT file is loaded from a different main domain - here is a demo.

<video crossorigin="anonymous">
   <track kind="subtitles" srclang="en" label="English"
          src="//other-domain.com/subtitles.vtt">
   <!-- sources go here -->
</video>

Contrary to the the server side CORS requirement this is not required when the VTT file is loaded from a different sub domain.

Subtitle options

Each member of the subtitles array accepts the following properties:

    • property
    • description
    • "default" quoted string
    • If set, this track is enabled initially. Only one track can be the "default" track.
      Important: This option must be quoted when a track is specified in JSON syntax because default is a reserved word in JavaScript.
      Mandatory if a subtitle track should be shown from the start without being selected via the subtitle menu. Default: false / empty
    • kind string
    • The kind of this track. Usually subtitle.
    • label string
    • Label of this track displayed in the subtitle menu. Default: srclang
    • src string (url / path)
    • Location of the VTT file for this track.
      Specifying src is mandatory.

All properties can be set as attributes of the same name to a TRACK element in a VIDEO tag based installation.

Custom looks

The first subtitle above would generate the following HTML code:

<div class='fp-captions'>
   <p>The first subtitle from 1 seconds to 4 seconds</p><br>
   <p>This is a second line</p><br>
   <p>And a third one</p><br>
</div>

Flowplayer comes with a default look for the subtitles, but are completely customizable via CSS:

/* override default looks */
.flowplayer .fp-captions p {
   font-size: 18px;
}

/* visible subtitle looks (.fp-shown class) */
.flowplayer .fp-captions.fp-shown { 
   opacity: 0.8;
}

/* custom looks for 7:th subtitle */
.flowplayer.cue6 .fp-captions p {
   font-size: 40px;
}

Native subtitles

Currently the TRACK element is supported natively by the following browsers:

  • IE 10 (since November 2011)
  • Google Chrome 18 (since November 2011)
  • Safari 6 (July 2012)
  • Opera 12.5 (August 2012)

Native HTML5 subtitles can only be displayed by the html5 engine.

You can enable native support with nativesubtitles configuration variable and by adding default attribute to the TRACK element. For example:

<div class="flowplayer" data-nativesubtitles="true" data-share="false">
   <video>
      <source type="application/x-mpegurl" src="//mydomain.com/my-video.m3u8">
      <source type="video/mp4" src="//mydomain.com/my-video.mp4">
      <track src="/path/to/my-subtitles-en.vtt" default>
   </video>
</div>

Note that we disable sharing because cross domain loading of VTT files generically is broken in most browsers.

After this the subtitle looks are browser dependent and you lose the CSS customization possibilities. Neither will the Flowplayer subtitle menu be shown because native subtitles cannot be governed externally.

Native support is present when flowplayer.support.subtitles is true. For example:

if (flowplayer.support.subtitles) {
   // do your thing
}

JavaScript API

Properties

The subtitles extension provides the following property for the player API:

    • property
    • description
    • subtitles array
    • The complete list of all currently loaded subtitleobjects. Not to be mistaken for the configured array ofsubtitle track objects.

Like all API properties the subtitles property can be inspected in the browser console:

console.info(flowplayer().subtitles);

Video object

The current video's subtitle track objects are available as video object properties.

    • property
    • description
    • subtitles array
    • The list of subtitle tracks for the current clip, in object notation.

To verify whether the subtitle configuration for the current clip works as intended, inspect video.subtitles in the browser console:

console.info(flowplayer().video.subtitles);

Subtitle object

Each member of the subtitles array has the following properties:

    • property
    • description
    • endTime integer
    • The cuepoint time value when this subtitle ends.
    • startTime integer
    • The cuepoint time value when this subtitle is displayed.
    • text string
    • The text of this subtitle.
    • title string
    • The so-called title of this subtitle, usually an integer, incremented by 1 for each subtitle.

Methods

The subtitles extension provides the following methods for the player API:

    • method
    • description
    • disableSubtitles()
    • Disable subtitle display. Like choosing 'No subtitles' from the subtitle menu.
    • loadSubtitles(index)
    • Loads subtitle track at given index in the configured array of subtitles. Like choosing the track from the subtitle menu at index top down.

| loadSubtitles(index) | Loads subtitle track at given index in the configured array of subtitles. Like choosing the track from the subtitle menu at index top down. |

Events

There is no "subtitle" event, but for each subtitle 2 cuepoints are generated which mark the time when the subtitle is displayed at the startTime of the subtitle, and the time when the subtitle ends at the endTime of the subtitle.

All subtitle cuepoints at startTime have these properties:

    • property
    • description
    • subtitle
    • The subtitle object of this subtitle.
    • time
    • The time value of this cuepoint which is equal to the startTime value of the subtitle object for this subtitle.

All subtitle cuepoints at endTime have these properties:

    • property
    • description
    • subtitleEnd
    • A string referencing the title property of the subtitle object for this subtitle
    • time
    • The time value of this cuepoint which is equal to the endTime value of the subtitle object for this subtitle.

This results in the following outline for handling subtitles in the JavaScript API:

player.on("cuepoint", function(e, api, cuepoint) {

   // start of a subtitle
   if (cuepoint.subtitle) {

   }

   // end of a subtitle
   if (cuepoint.subtitleEnd) {

   }

});

CSS classes

The has-menu class is added to the container element if the current clip features subtitles.

As subtitles use the cuepoints mechanism internally cue{index} classes are used here as well. An even cue index indicates that a subtitle is shown, an odd index that currently no subtitle is shown.

<div class="flowplayer cue0 has-menu">
  <!-- the first subtitle is currently displayed -->
</div>
<div class="flowplayer cue7 has-menu">
  <!-- the forth subtitle has ended -->
</div>

If used in conjunction with cuepoints the cue index includes user configured cuepoints as well and is hardly useable as indicator.

Subtitle parser

An abstract implemenation of a custome subtitleParser option looks like this:

flowplayer("#container", {
  clip: {
    // clip configuration goes here
  },
  subtitleParser: function (txt) {
    // process complete text of a subtitle track
  }
});

The shipped subtitleParser implementation can be used as guidance. Its code can be found on Github.

If you decide to write a parser for a non-VTT format, be aware that these captions will not be shown on devices which cannot play video inline. Consider batch converting the caption files to VTT instead.

Known issues and limitations

Flowplayer does not support VTT extra definitions such as text alignment and line position. Style is completely controlled with CSS for full cross browser support.

When using the default attribute on the track element some browsers may show their native controlbar for a short glimpse of time.

Resources

Resources about the WebVTT format:

Resources for caption creation / conversion

WebVTT validator

Results