docs.rodeo

MDN Web Docs mirror

IMSC basics

IMSC allows you to add subtitles or captions to your online video. In this article we’ll take you through what you need to get started, including basic document structure, and the basics of how to style, time, and position subtitles.

[!NOTE] IMSC can be used for any kind of timed text you might want to include on a web document, not just for subtitles and captions. But because subtitles and captions represent the most common use cases for IMSC, we will focus on those. For readability we only use the term subtitles. In the technical context we describe, the term “subtitles” is interchangeable with “captions”.

So what is IMSC?

IMSC is a markup language you can use to define timed text for adding subtitles to digital media. It defines the structure of your subtitle content in an XML document. It consists of a series of elements, which you can use to enclose, or wrap, different parts of your subtitle content to make it appear in a certain way or appear at a certain time. Many of these are similar or the same as HTML features.

If you are not already familiar with XML or HTML, read up on them first and then come back here:

[!NOTE] If you want to know what you can do with IMSC in real-world scenarios have a look at the expanded example at the end of this tutorial.

Minimal IMSC document

IMSC is always specified as a complete XML document. As a file it should have the extension “ttml”.

[!NOTE] IMSC does not have native support in browsers at this current moment, but the imscJS polyfill can be used to bridge this gap. All the examples below are rendered by using imscJS. It creates dynamically HTML and CSS from an IMSC XML document.

Let’s look at a minimal IMSC document and how it is rendered:

{{EmbedGHLiveSample("imsc-examples/minimal_ttml/minimal.html", '100%', 560)}} 

The most important features are as follows:

Timing

The minimal IMSC document from the previous example had no timing. That means that the subtitle content will be shown during the complete duration of the video. Usually this is not what you want. Instead you want subtitles to show up at a certain time and then disappear. You can use a combination of the timing attributes begin, end, and dur to make this happen.

Consider the following editable example:

{{EmbedGHLiveSample("imsc-examples/minimal-timing/minimal-timing-player.html", '100%', 590)}} 

This includes the following new attributes:

Play around with the second values in the code sample and push the reload button when you are ready.

[!NOTE] The end times in IMSC are not “inclusive”. The subtitle “Hello, I am Mork from Ork.” is not shown anymore when it reaches the second value in time.

You can also use the dur attribute for timing:

{{EmbedGHLiveSample("imsc-examples/minimal-timing/minimal-timing-player-dur.html", '100%', 590)}} 

This attribute can be used as an alternative to the end attribute. It defines “how long” the subtitle is shown after the begin time has elapsed. In the example the second paragraph shall be displayed for 2s. As it starts at second 2 it shall disappear at second 4.

Note what has changed at second 2 compared to the previous example.

Colors

Often subtitles are shown on an opaque or semi-opaque background to improve readability. You can use the backgroundColor and color attributes to change the colors, as demonstrated in this editable example:

{{EmbedGHLiveSample("imsc-examples/minimal-colors/minimal-colors.html", '100%', 620)}} 

Here we’ve introduced the following:

Try setting some other colors for the text and background colors:

[!NOTE] Don’t worry for now about namespaces. We will explain the meaning of xmlns:tts and tts:backgroundColor in a separate guide.

As explained in the IMSC Styling guide, it is possible to define a collection of styling properties that can be used any number of times. The style s1 below is applied three times:

<tt xmlns="http://www.w3.org/ns/ttml"
    xmlns:tts="http://www.w3.org/ns/ttml#styling"
    xml:lang="en">
  <head>
   <styling>
     <style xml:id="s1" tts:color="yellow" tts:fontStyle="italic"/>
   </styling>
  </head>
  <body>
    <div>
      <p>
        Hello, I am <span style="s1">Mork</span> from <span style="s1">Ork</span>.<br/>
        I come from another <span style="s1">planet</span>.
      </p>
    </div>
  </body>
  </tt>

Position, width, and length

If you do not specify a position explicitly, the subtitle shows up by default in the top-left-hand corner of the video. Commonly however you will want to position your subtitle somewhere else, like the bottom center of the video. You need to specify a region to position a subtitle.

See below for a minimal document that uses regions for positioning.

<tt xmlns="http://www.w3.org/ns/ttml"
 xmlns:tts="http://www.w3.org/ns/ttml#styling"
 xml:lang="en">
  <head>
    <layout>
      <region tts:origin="10% 80%"
              tts:extent="80% 20%"
              xml:id="bottom"/>
      <region tts:origin="10% 10%"
              tts:extent="80% 20%"
              xml:id="top"/>
    </layout>
</head>
<body>
    <div>
      <p region="bottom"
          tts:backgroundColor="black">
          Hello, I am Mork from Ork.
      </p>
    </div>
  </body>
</tt>

This includes the following new features:

This sample will be rendered as shown below. Give it a try and play around with the code in the two boxes. You could for example set the tts:origin attribute to “0% 0%”. Or see what happens when you change the value of the region attribute of the <p> element to “top”.

{{EmbedGHLiveSample("imsc-examples/minimal-region/minimal-region.html", '100%', 650)}} 

Expanded example

The more expanded example below gives you an idea what you can do with IMSC after you worked through our tutorials.

{{EmbedGHLiveSample("imsc-examples/basic-expanded/basics-expanded.html", '100%', 300)}} 

<?xml version="1.0" encoding="UTF-8"?>
<tt
  xmlns="http://www.w3.org/ns/ttml" xmlns:tts="http://www.w3.org/ns/ttml#styling"
  xmlns:ttp="http://www.w3.org/ns/ttml#parameter" xml:lang="en" ttp:timeBase="media">
  <head>
    <styling>
      <style xml:id="defaultStyle" tts:fontFamily="Verdana, Arial" tts:fontSize="100%"
        tts:textAlign="center"/>
      <style xml:id="alignStart" tts:textAlign="start"/>
      <style xml:id="alignCenter" tts:textAlign="center"/>
      <style xml:id="alignEnd" tts:textAlign="end"/>
      <style xml:id="textWhite" tts:color="#FFFFFF"/>
      <style xml:id="titleHeading" tts:fontSize="300%"/>
      <style xml:id="spanDefaultStyle" tts:backgroundColor="#000000" tts:color="#FFFFFF"/>
      <style xml:id="monoFont" tts:fontFamily="Lucida Console, Monaco, monospace"/>
      <style xml:id="sansserifFont" tts:fontFamily="Impact, Charcoal, sans-serif"/>
      <style xml:id="comicFont" tts:fontFamily="Comic Sans MS, cursive, sans-serif"/>
      <style xml:id="blueText" tts:color="#00FFFF" tts:backgroundColor="#000000"/>
      <style xml:id="limeText" tts:color="#00FF00" tts:backgroundColor="#000000"/>
      <style xml:id="fuchsiaText" tts:color="#FF00FF" tts:backgroundColor="#000000"/>
      <style xml:id="yellowText" tts:color="#FFFF00" tts:backgroundColor="#000000"/>
    </styling>
    <layout>
      <region xml:id="rTop" tts:origin="10% 10%" tts:extent="80% 80%" tts:displayAlign="before"/>
      <region xml:id="rCenter" tts:origin="10% 10%" tts:extent="80% 80%" tts:displayAlign="center"/>
      <region xml:id="rBottom" tts:origin="10% 10%" tts:extent="80% 80%" tts:displayAlign="after"/>
    </layout>
  </head>
  <body style="defaultStyle">
    <div>
      <p xml:id="p1" begin="00:00:01" end="00:00:03" region="rCenter" style="alignCenter">
        <span style="titleHeading">IMSC Demo</span>
      </p>
      <p xml:id="p2" begin="00:00:03" end="00:00:05" region="rBottom" style="alignCenter">
        <span style="spanDefaultStyle">You </span><span style="blueText">can</span><span
          style="yellowText"> apply</span><span style="fuchsiaText"> different</span><span
          style="limeText"> colors, </span>
      </p>
      <p xml:id="p3" begin="00:00:05" end="00:00:07" region="rBottom" style="alignCenter">
        <span style="monoFont">use</span><span style="sansserifFont"> different</span><span
          style="comicFont"> fonts,</span>
      </p>
      <p xml:id="p4" begin="00:00:07" end="00:00:09" region="rBottom" style="alignCenter">
        <span>set </span><span tts:fontSize="150%">the</span><span tts:fontSize="200%"> font
          size.</span>
      </p>
      <p xml:id="p5" begin="00:00:09" end="00:00:11" region="rBottom" style="alignStart">
        <span style="spanDefaultStyle">Align at the start, </span><br/>
      </p>
      <p xml:id="p6" begin="00:00:11" end="00:00:13" region="rBottom" style="alignCenter">
        <span style="spanDefaultStyle">center and</span>
      </p>
      <p xml:id="p7" begin="00:00:13" end="00:00:15" region="rBottom" style="alignEnd">
        <span style="spanDefaultStyle">end</span><br/>
      </p>
      <p xml:id="p8" begin="00:00:15" end="00:00:17" region="rTop" style="alignCenter">
        <span style="spanDefaultStyle">or vertically at the top, </span><br/>
      </p>
      <p xml:id="p9" begin="00:00:17" end="00:00:19" region="rCenter" style="alignCenter">
        <span style="spanDefaultStyle">center and </span>
      </p>
      <p xml:id="p10" begin="00:00:19" end="00:00:21" region="rBottom" style="alignCenter">
        <span style="spanDefaultStyle">bottom.</span>
      </p>
    </div>
  </body>
</tt>

Summary

That’s it for your crash course in IMSC code basics! We’ve only really scratched the surface here, and you’ll go much deeper into the above topics in subsequent articles.

In this article

View on MDN