Accessible Video Player

What makes a video accessible is widely misunderstood. Many web professionals know about closed captions. What many don't know is that they absolutely need audio descriptions in order to be WCAG AA compliant.

WCAG video compliance guidelines
Requirement A AA AAA
Closed Captions required required required
Audio Descriptions One or the other required required
Transcripts Not required required

For a lot of companies and organizations, re-cutting a alternative cut of each video on their website is cost prohibitive:

  1. It requires a voice-actor to recite the audio descriptions.
  2. It requires a video editor to re-edit the video.
  3. Sometimes, other footage needs to be shot to accomodate the amount of time needed to insert the audio descriptions into the video.

Because of this, I have recommended using Able Player and have the browser insert the audio descriptions. It requires a separate caption file (in WebVTT format) so the player knows at what time the captions should be read out. In many instances, I also set the player to pause the video when the audio descriptions are recited, so the browser doesn't talk over the existing audio in the video.

One of the great side-effects is that if you implement audio-descriptions this way, the caption file + the audio descriptions file will produce a transcript for free, so your video player will meet a WCAG AAA guideline.

Video Player With Text-To-Speech Audio Descriptions

This is the best solution to use, especially when building from scratch.
This solution described below is available as an NPM module. (Module installation instructions)

Example code explanation

Below is the HTML of the above example. Use the dropdown to highlight each of the individual steps that makes the example accessible.

☜ Scroll to read full source ☞


Installation Instructions

You can load this JavaScript library into your application in serveral ways:

If you haven't done so already, choosing which you should use is obviously a major architectural decision. Here are a few articles that will help you decide:

Using NPM/Webpack to load ES6 Modules:

  1. Install the enable-a11y NPM project. Developers who are using webpack should know how to configure webpack to import the enable modules correctly.
  2. You can use the module like this:
    ☜ Scroll to read full source ☞
    // import the JS module import ablePlayerCustomizations from '~enable-a11y/js/modules/ablePlayerCustomizations'; // AblePlayer uses this module, available via NPM
    import Cookies from 'js-cookie'; // import the CSS for the module import '~enable-a11y/css/ablePlayerCustomizations'; // There is no .init() function to call.
  3. Alternatively, if you are using LESS you can include the styles in your project's CSS using:
    ☜ Scroll to read full source ☞
    @import '~enable-a11y/css/ablePlayerCustomizations';
    (If you are using it in your CSS, you will have to add the .css suffix)

Using ES6 modules natively.

This is the method that this page you are reading now loads the scripts.

  1. Grab the source by either using NPM, grabbing a ZIP file or cloning the enable source code from github.
  2. If you want to load the module as a native ES6 module, copy js/modules/ablePlayerCustomizations.js, and css/ablePlayerCustomizations.css from the repo and put them in the appropriate directories in your project (all JS files must be in the same directory).
  3. Load the CSS in the head of you document:
    ☜ Scroll to read full source ☞
    <html> <head> ... <link rel="stylesheet" href="path-to/css/ablePlayerCustomizations.css" > ... </head> <body> ... </body> </html>
  4. Load your scripts using:
    ☜ Scroll to read full source ☞
    <script type="module"> import ablePlayerCustomizations from "path-to/ablePlayerCustomizations.js" ablePlayerCustomizations.init(); </script>

Using ES4

Just do the same as the ES6 method, except you should get the JavaScript files from the js/modules/es4 directory instead of the js/modules/:
☜ Scroll to read full source ☞
<script src="path-to/es4/ablePlayerCustomizations.js"></script>