Adding captions and subtitles

Working with HTML5 Video

Adding captions and subtitles

Working with HTML5 Video

  1. A basic HTML5 video
  2. Adding subtitles
  3. WebVTT syntax basics
  4. Building a custom menu with JavaScript
  5. Captions versus subtitles
  6. Cue settings
  7. Styling text cues
  8. Tags available to cues

A basic HTML5 video

A solid basis to start from

HTML5 video example

		  <video controls preload="metadata">
		      <source src="../video/sintel-short.mp4" type="video/mp4">
		      <source src="../video/sintel-short.webm" type="video/webm">

		      <p>It appears that your browser doesn't support HTML5 video.
		      Here's a <a href="../video/sintel-short.mp4">direct link to
		      the video instead</a>.</p>
		  </video>
		

Code time: tutorial start

Adding subtitles

<track> elements

		  <track label="English" kind="subtitles" srclang="en"
		    src="vtt/sintel-subtitles-en.vtt" default>
          <track label="Deutsch" kind="subtitles" srclang="de"
            src="vtt/sintel-subtitles-de.vtt">
          <track label="Español" kind="subtitles" srclang="es"
            src="vtt/sintel-subtitles-es.vtt">
		

<track> attributes

Code time: tutorial step 2

Cross browser UX not very good for track

You should therefore...

Implement a custom UI for <track> elements using JavaScript!

WebVTT syntax basics

WebVTT looks like so

		  WEBVTT
		   
          0
          00:00:00.000 --> 00:00:12.000
          [Test]
           
          1
          00:00:18.700 --> 00:00:21.500
          This blade has a dark past.
		

WebVTT syntax explanation

Implementing a custom subtitle menu

You can use whatever UI you want

We are using a select menu:

		  <form>
		    <select name="select">
		   
		    </select>
	      </form>
		

Basic WebVTT API information

Code time: tutorial step 3

Set variables then hide all tracks

		  var video = document.querySelector('video');
          var select = document.querySelector('select');
          function hideTracks() {
            for (var i = 0; i < video.textTracks.length; i++) {
              video.textTracks[i].mode = 'hidden';
            }
          }
           
          hideTracks();
		

Build the select menu

		  var tracksOff = document.createElement('option');
          tracksOff.setAttribute('value','off');
          tracksOff.textContent = 'Tracks off';
          select.appendChild(tracksOff);
		

Build the select menu

          for (var i = 0; i < video.textTracks.length; i++) {
            var curTrack = video.textTracks[i];
            var addTrackOpt = document.createElement('option');
            addTrackOpt.setAttribute('value',curTrack.kind + '-' + curTrack.language);
            addTrackOpt.textContent = curTrack.label + ' ' + curTrack.kind;
            select.appendChild(addTrackOpt);
          }
		

The select menu

Add an event listener

This runs the trackChange() function whenever the a new select value is selected

          select.addEventListener('change',function() {
            trackChange(select.value);
          });
		

The trackChange() function

          function trackChange(value) {
            if(value === 'off') {
              hideTracks();
            } else {
              hideTracks();
              var splitValue = value.split('-');
    
              for (var i = 0; i < video.textTracks.length; i++) {
                if(video.textTracks[i].kind === splitValue[0]) {
                  if(video.textTracks[i].language === splitValue[1]) {
                    video.textTracks[i].mode = 'showing';
                  }
                }
              }
            }
          }
		

How trackChange() works

Subtitles versus captions

Subtitles versus captions

Caption <track> example

          <track label="English" kind="captions" srclang="en"
            src="vtt/sintel-captions-en.vtt">        
		

Code time: tutorial step 4

Cue settings, tags and styling captions

WebVTT gets more complex

          1
          00:00:18.700 --> 00:00:21.500 line:20% align:end
          <c.man><b>Man</b>: This blade has a dark past.  </c>
		

Cue settings

Styling captions

Caption text cues have some special tags marking them up, stylable via CSS Extensions.

          <c.man><b>Man</b>: This blade has a dark past.  </c>
		

Styling captions

The ::cue pseudo-element is the key to targetting text track cues for styling.

          video::cue { whitespace: pre; }
          video::cue(.man) { color:yellow }
		

What properties can be applied to text cues?

Available text cue tags

Adding a default selection

if(curTrack.language === 'en' && curTrack.kind === 'subtitles') {
  addTrackOpt.setAttribute('selected','selected');
    trackChange(select.value);
  }

Finished!

Further resources

Getting involved with the MDN community

Credits

Fork me on Github