GitHub - cgiffard/Captionator: HTML5 polyfill for closed captioning with the element, and implements the WHATWG Timed Text Track specification. (original) (raw)

Captionator

Simple closed-captioning polyfill for HTML5. Just 8KB when gzipped!

What does Captionator do?

What can I do with Captionator?

You can see a demo of Captionator here: http://captionatorjs.com/demo.html

Using Captionator

After including the library, adding captions to your video is pretty simple:

This will not only caption your video (this example will caption every element on the page with Timed Text Tracks available to it,) but it will also provide a .tracksproperty on your video element(s) - which you can use to dynamically manipulate the track data as per the WHATWG specification.

If you've got specific requirements about which videos get captioned, and in what language(s), there are some extra options:

captionator.captionify(videoElementsToCaption,defaultLanguage,options)

The first parameter can be an array of selectors or DOMElements, or a single selector string or DOMElement. The second parameter is a language string.

You can use the options parameter to specify your own render function for captions, if you don't like captionator's inbuilt renderer:

captionator.captionify(["#yourVideoElement1","#yourVideoElement2"],"de",{ renderer: myFunction });

(More on this below!)

Multiple subtitles and custom render functions

It's pretty straightforward to manage multiple enabled subtitle tracks. Take this set of track elements for example:

In this case, the English subtitles are enabled by default. Unless you specify a custom renderer, Captionator will automatically generate as many separate containers as are required for enabled tracks, set up the relevant events and styles.

Specifying a custom renderer

Should you wish to specify your own renderer, you can use the following syntax when calling captionator.captionify:

captionator.captionify(null,null,{ "renderer": function(yourHTMLVideoElement) { ... } });

The renderer function you define is executed, and passed the HTMLVideoElement whenever it fires atimeupdate event. You can use the TextTrack.activeCues to determine what cues should be displayed at any given time.

The event data for the video timeupdate event is not passed to your function. This is because you are defining a renderer, not an event handler. Should future Captionator updates require caption re-rendering on different events (or in places not triggered by events at all) code which depends on event information will not function correctly.

Enabling and disabling subtitle tracks programatically: A Quick Guide

You can find a demonstration of this feature in the example file.

Getting Tracks

Captionator simply makes a new property (array) available through javascript on the HTMLVideoElement:

var myVideo = document.getElementById("myVideo"); var myTracks = myVideo.tracks;

By extension, getting access to the track you want is as simple as:

var firstSubtitleTrack = myVideo.tracks[0];

Each track defines the following user accessible properties:

Ergo, to access the property language from the third track, you'd use the following code:

var thirdTrackLanguage = myVideo.tracks[2].language;

To enable or disable a track:

myVideo.tracks[2].mode = captionator.TextTrack.SHOWING; // Equivalent to (integer) 2 myVideo.tracks[2].mode = captionator.TextTrack.HIDDEN; // Equivalent to (integer) 1 myVideo.tracks[2].mode = captionator.TextTrack.OFF; // Equivalent to (integer) 0

The track is then enabled/disabled when the video fires a timeupdate event, or when a track mode changes. You can update it immediately (although Captionator handles this itself in nearly every case) like so:

captionator.rebuildCaptions(myVideo);

(Where myVideo is an instance of a captioned HTMLVideoElement)

For a more advanced example, see the subtitle selector in the example file.

Options

The following lists options which you can pass to captionator:

Styling Options

Video and Audio tracks (MediaTrack)

A/V track support has been removed from Captionator as the specification changed.

Building Captionator.js

Captionator.js comes pre-built in both unminified and minified versions, but you can build it yourself.

You'll need node.js, jake, jshint, and uglify-js. You can use this guide to installing node.js if you get stuck.

Once that's done, install the dependencies with npm:

npm install --global jshint npm install --global jake npm install --global uglify-js

All done? Now, do whatever you need to do to Captionator by modifying its various components in the /source directory. When you're ready to build, you can just:

The default jake task builds and lints the file, minifies it, and runs through the test suite. That's it! All files created are placed in the /js directory, ready for production use.

You can also independently run each of the following tasks:

Autobuild

If you use a Mac, and Safari, autobuild.pl is a little script which monitors the source files, and then rebuilds, minifies, and lints captionator.js - and reloads your Safari tab whenever it detects changes. Using it is as simple as running:

Notes about newer browsers

As browers start to implement WebVTT and the TextTrack JS API, Captionator.js will step back and your captions will be delivered by the native capabilities of those browsers. In some cases though, the implementations are buggy or incomplete. Currently, both IE10's and Chrome's WebVTT & JS API implementations are incomplete. Captionator.js will not run in these browsers. Instead, it quietly quits. You can detect whether this is the case by checking for a false return value from the captionator.captionify() function.

Currently, Chrome's implementation of TextTracks breaks Captionator, but doesn't actually work on its own yet. I advise that you turn off TextTrack support in chrome://flags.

IE10's implementation is not complete, but it does work.

If you understand that you'll probably break things but want to try it anyway, you can disable Captionator's TextTrack support checking by setting the forceCaptionify option to true.

New Features

Thanks

Thanks to @silviapfeiffer for her knowledge and assistance with some of the hairier aspects of these specifications! Thanks also to @ourmaninjapan for his welcome assistance with Japanese text/line breaking algorithms!

Licence

Copyright (c) 2012, Christopher Giffard All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.