Subtitles
This player uses a HTML5 <track>
element to display subtitles and a subtitle selection menu in all browsers.
Table of contents
#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
...
- A sample file.
- Understanding the VTT file format.
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 "*"
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
-
- nativesubtitles boolean
- HTML5 only. Whether subtitle display is delegated to the native subtitle implementation of the browser or device.
See below for further details. Default:false
-
- 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.
-
- property
- description
-
- subtitles array
- An array of subtitle track objects. Not to be mistaken for the API property holding the array of the currently loaded subtitles.
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 becausedefault
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.
Specifyingsrc
is mandatory.
-
- srclang string
- Language of this subtitle track in 2 letter language code. Default:
en
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)
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 atindex
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 thestartTime
value of thesubtitle
object for this subtitle.
-
- visible
- This is always
false
to discern subtitle cuepoints from generated cuepoints.
All subtitle cuepoints at endTime
have these properties:
-
- property
- description
-
- subtitleEnd
- A string referencing the
title
property of thesubtitle
object for this subtitle
-
- time
- The
time
value of this cuepoint which is equal to theendTime
value of thesubtitle
object for this subtitle.
-
- visible
- This is always
false
to discern subtitle cuepoints from generated cuepoints.
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>
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:
- http://www.w3.org/TR/ruby/
- http://dev.w3.org/html5/webvtt/
- http://edutechwiki.unige.ch/en/WebVTT
- http://html5doctor.com/video-subtitling-and-webvtt/
- https://fileinfo.com/extension/vtt
- http://subtitle-horse.com/specifications
Resources for caption creation / conversion
- https://dcmp.org/ai/ciy/#CiY_resources
- https://github.com/nwoltman/srt-to-vtt-converter
- https://atelier.u-sub.net/srt2vtt/ - online converter
- http://www.nikse.dk/SubtitleEdit/