The Dark Old Days of TTML
How to caption the web using TTML and why you might not want to
Brightcove
Video.js
@gkatsev
http://slides.com/gkatsev/ttml/
Gary Katsevman
TTML
Timed Text Markup Language
Originally, DFXP
Distribution Format Exchange Profile
Standardized by W3C
Related Standards
WebVTT
SMPTE-EE
CFF-TT
Common File Format
Uses SMPTE-TT in UltraViolet
SMPTE-TT?
Society of Motion Picture and Television Engineers
Standards, Recommended Practices, Engineering Guidelines
-
TV Production
-
Filmmaking
-
Digital cinema
-
Audio Recording
-
Information Technology
-
Medical Imaging
Superset of TTML
Maintaining Legacy
CEA-706
CEA-608
DVB
FCC's CVAA
21st Century Communications and Video Accessibility Act
Safe Harbor for SMPTE-TT
2012
WHATWG chose WebVTT in 2010
TTML
Industry Standard
Ingestion Systems
-
YouTube
-
Netflix
-
Amazon
Google Cast
Internet Explorer
Microsoft Edge
Like Html, CSS
But worse
Much worse
<tt xml:lang="en"
xmlns="http://www.w3.org/ns/ttml"
xmlns:tts="http://www.w3.org/ns/ttml#styling">
<head>
<metadata xmlns:ttm="http://www.w3.org/ns/ttml#metadata">
<ttm:title>TTML Example</ttm:title>
<ttm:copyright>Thierry Michel 2015</ttm:copyright>
</metadata>
<styling xmlns:tts="http://www.w3.org/ns/ttml#styling">
<style xml:id="s1" tts:color="red" tts:textAlign="center" />
</styling>
</head>
<body>
<div>
<p xml:id="c1" begin="00:00:00" end="00:00:10">
Hello I am your first line.</p>
<p xml:id="c2" begin="00:00:02" end="00:00:10">
I am your second captions<br/>but with two lines.</p>
<p xml:id="c3" xml:lang="fr" begin="00:00:04" end="00:00:10">
Je suis le troisième sous-titre.</p>
<p xml:id="c4" begin="00:00:06" end="00:00:10" >
I am another caption with <span tts:fontWeight="bold">Bold</span> and <span tts:fontStyle="italic">Italic</span> styles.</p>
<p xml:id="c5" begin="00:00:08" end="00:00:10" style="s1">
I am the last caption displayed in red and centered.</p>
</div>
</body>
</tt>
TTML
WEBVTT
title: Web-VTT Example
copyright: Thierry Michel 2015
NOTE to style this document, CSS color font must be the specified in the HTML hosting page in the <style> element.
c1
00:00.000 --> 00:10.000
Hello I am your first line.
c2
00:02.000 --> 00:10.000
I am your second captions
but with two lines.
c3
00:04.000 --> 00:10.000
<lang fr>Je suis le troisième sous-titre.</lang>
c4
00:06.000 --> 00:10.000
I am another caption with <b>Bold</b> and <i>Italic</i> styles.
c5
00:08.000 --> 00:10.000 align:middle
<c.red>I am the last caption displayed in red and centered.</c>
--------------------------------------
In the HTML 5, CSS style:
<style> ::cue(.red) {color:red;} </style>
VTT
<tt xml:lang="en"
xmlns="http://www.w3.org/ns/ttml"
xmlns:tts="http://www.w3.org/ns/ttml#styling">
<head>
<metadata xmlns:ttm="http://www.w3.org/ns/ttml#metadata">
<ttm:title>TTML Example</ttm:title>
<ttm:copyright>Thierry Michel 2015</ttm:copyright>
</metadata>
<styling xmlns:tts="http://www.w3.org/ns/ttml#styling">
<style xml:id="s1" tts:color="red" tts:textAlign="center"/>
</styling>
</head>
<body>
<div>
<p xml:id="c1" begin="00:00:00" end="00:00:10">
Hello I am your first line.</p>
<p xml:id="c2" begin="00:00:02" end="00:00:10">
I am your second captions<br/>but with two lines.</p>
</div>
</body>
<body>
<div>
<p xml:id="c3" xml:lang="fr" begin="00:00:04" end="00:00:10">
Je suis le troisième sous-titre.</p>
<p xml:id="c4" begin="00:00:06" end="00:00:10" >
I am another caption with
<span tts:fontWeight="bold">Bold</span> and
<span tts:fontStyle="italic">Italic</span> styles.</p>
</div>
</body>
<head>
<styling xmlns:tts="http://www.w3.org/ns/ttml#styling">
<style xml:id="s1" tts:color="red" tts:textAlign="center" />
</styling>
</head>
<body>
<div>
<p xml:id="c5" begin="00:00:08" end="00:00:10" style="s1">
I am the last caption displayed in red and centered.</p>
</div>
</body>
videojs-ttml
player.ttml({
src: 'test/fixtures/full.xml',
label: 'English',
srclang: 'en-us'
});
videojs.plugin('ttml', function(options) {
const player = this;
let ttmlDisplay;
const dfxpurl = options.src;
videojs.xhr({
uri: dfxpurl
}, function(err, res, body) {
if (res.statusCode >= 400) {
return videojs.error(err);
}
const styleParser = parseTtml(body, player.currentHeight());
player.ttml.styleParser = styleParser;
ttmlDisplay = player.addChild('ttmlDisplay');
});
document.querySelector('.on-button')
.addEventListener('click', function() {
ttmlDisplay.enable();
});
document.querySelector('.off-button')
.addEventListener('click', function() {
ttmlDisplay.disable();
});
document.querySelector('.en-button')
.addEventListener('click', function() {
ttmlDisplay.setLanguage('en');
ttmlDisplay.enable();
});
document.querySelector('.fr-button')
.addEventListener('click', function() {
ttmlDisplay.setLanguage('fr');
ttmlDisplay.enable();
});
const parseTtml = function(ttml, height) {
const dom = (new DOMParser())
.parseFromString(ttml, 'text/xml');
if (!dom || dom.querySelector('parsererror')) {
videojs.error('failed to parse the TTML');
}
// remove all potential <script> elements
const domScripts = dom.querySelectorAll('script');
for (let i = 0; i < domScripts; i++) {
const domScript = domScripts[i];
domScript.parentNode.removeChild(domScript);
}
const language = dom.documentElement.getAttribute('xml:lang');
const body = dom.querySelector('body');
const styleParser = new TtmlDomParser(dom, {}, height);
return styleParser;
};
const TtmlDomParser = function(dom, styleOptions, height) {
/* various other setup */
this.setNamespaces(dom);
this.parseHead(dom);
this.parseBody(dom);
};
Brightcove
Video.js
@gkatsev
http://slides.com/gkatsev/ttml/
Gary Katsevman
Thanks!
The Dark Old Days of TTML
By Gary Katsevman
The Dark Old Days of TTML
How to caption the web using TTML and why you might not want to
- 658