[466218] (EASEL) Update script for audio description to support latest
browsers
diff --git a/plugins/org.eclipse.actf.examples.scripteditor/resources/scripts/vd-compat.js b/plugins/org.eclipse.actf.examples.scripteditor/resources/scripts/vd-compat.js
index 203ca1f..22fd2ad 100644
--- a/plugins/org.eclipse.actf.examples.scripteditor/resources/scripts/vd-compat.js
+++ b/plugins/org.eclipse.actf.examples.scripteditor/resources/scripts/vd-compat.js
@@ -1,402 +1,380 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-//
-// Ad-hoc codes to bridge the gap between the HTML5 spec and browser implementations
-//
-if (typeof TextTrack == 'undefined') {
- (function () {
- TextTrack = function (kind, label, language) { // See: http://dev.w3.org/html5/spec/media-elements.html#texttrack
- this.kind = kind;
- this.label = label;
- this.language = language;
- this.mode = TextTrack.HIDDEN;
- this.cues = new TextTrackCueList();
- this.activeCues = new TextTrackCueList();
- };
-
- TextTrack.DISABLED = 0;
- TextTrack.HIDDEN = 1;
- TextTrack.SHOWING = 2;
-
- TextTrack.prototype.addCue = function (cue) {
- cue.track = this;
- this.cues.__addCue__(cue);
- };
-
- TextTrack.prototype.removeCue = function (cue) {
- cue.track = null;
- this.cues.__removeCue__(cue);
- };
-
- TextTrack.prototype.toString = function () {
- return 'TextTrack <' + this.kind + '> ' + this.label + ' (' + this.language + ') : ' + this.cues;
- };
-
- TextTrackList = function () { // See: http://dev.w3.org/html5/spec/media-elements.html#texttracklist
- var list = [];
-
- list.toString = function () {
- return 'TextTrackList [\n\t' + this.join(',\n\t') + '\n]';
- };
-
- return list;
- };
-
-/* TextTrackList = function () {}; // not working on IE
-
- TextTrackList.prototype = [];*/
-
- TextTrackCue = function (id, startTime, endTime, text, settings, pauseOnExit) { // See: http://dev.w3.org/html5/spec/media-elements.html#texttrackcue
- this.id = id;
- this.startTime = startTime;
- this.endTime = endTime;
- this.text = text;
- this.settings = settings || '';
- this.pauseOnExit = pauseOnExit || false;
- };
-
- TextTrackCue.prototype.toString = function () {
- return 'TextTrackCue <' + this.id + '> ' + this.startTime + ' -> ' + this.endTime + ' : ' + this.text + (this.pauseOnExit ? ' * pause-on-exit * ' : ' ');
- };
-
- TextTrackCueList = function () { // See: http://dev.w3.org/html5/spec/media-elements.html#texttrackcuelist
- var list = [];
-
- list.getCueById = function (id) {
- for (var i = 0; i < this.length; ++i) {
- var e = this[i];
-
- if (e.id == id) {
- return e;
- }
- }
-
- return null;
- };
-
- list.__addCue__ = function (cue) {
- this.push(cue);
- };
-
- list.__removeCue__ = function (cue) {
- for (var i = 0; i < this.length; ++i) {
- if (this[i] === cue) {
- this.splice(i--, 1);
- }
- }
- };
-
- list.toString = function () {
- return 'TextTrackCueList [\n\t' + this.join(',\n\t') + '\n]';
- };
-
- return list;
- };
-
-/* TextTrackCueList = function () {}; // not working on IE
-
- TextTrackCueList.prototype = [];
-
- TextTrackCueList.prototype.getCueById = function (id) {
- for (var i = 0; i < this.length; ++i) {
- var e = this[i];
-
- if (e.id == id) {
- return e;
- }
- }
-
- return null;
- };
-
- TextTrackCueList.prototype.__addCue__ = function (cue) {
- this.push(cue);
- };
-
- TextTrackCueList.prototype.__removeCue__ = function (cue) {
- for (var i = 0; i < this.length; ++i) {
- if (this[i] === cue) {
- this.splice(i--, 1);
- }
- }
- };
-
- TextTrackCueList.prototype.toString = function () {
- return 'TextTrackCueList [\n\t' + this.join(',\n\t') + '\n]';
- };*/
-
- var fixMediaElement = function (m) {
- m.textTracks = new TextTrackList();
- m.addTextTrack = addTextTrack;
- m.__lastTime__ = m.currentTime;
- m.addEventListener('timeupdate', updateCues, false);
- m.addEventListener('seeked', updateCues, false);
- };
-
- var fixTrackElement = function (t) {
- t.kind = t.getAttribute('kind');
- t.src = t.getAttribute('src');
- t.srclang = t.getAttribute('srclang');
- t.label = t.getAttribute('label');
- t['default'] = t.getAttribute('default') != null; // .default causes an error in IE
-
- if (!t.dataset) {
- var d = {};
- var a = t.attributes;
-
- for (var i = 0; i < a.length; ++i) {
- if (a[i].name.indexOf('data-') == 0) {
- d[a[i].name.substr(5)] = a[i].value;
- }
- }
-
- t.dataset = d;
- }
- };
-
- var addTextTrack = function (kind, label, language) { // HTMLMediaElement#addTextTrack
- var t = new TextTrack(kind, label, language);
- this.textTracks.push(t);
- return t;
- };
-
- var updateCues = function (e) { // http://dev.w3.org/html5/spec/media-elements.html#media-playback
- var video = e.target;
-
- var currentTime = video.currentTime;
- var lastTime = video.__lastTime__; video.__lastTime__ = currentTime;
- var isMonotonicIncrease = currentTime > lastTime && currentTime <= lastTime + .5; // major browsers fire timeupdate events every 250 ms
-
- var currentCues = [];
- var otherCues = [];
- var conflicted = false;
-
- var tracks = video.textTracks;
-
- for (var i = 0; i < tracks.length; ++i) {
- var t = tracks[i];
-
- if (t.mode != TextTrack.DISABLED) {
- var cues = t.cues;
-
- for (var j = 0; j < cues.length; ++j) {
- var c = cues[j];
-
- if (c.startTime <= currentTime && c.endTime > currentTime) {
- currentCues.push(c);
- c.__missed__ = false;
- conflicted = conflicted || !c.__active__;
- }
- else {
- otherCues.push(c);
- c.__missed__ = isMonotonicIncrease && c.startTime >= lastTime && c.endTime <= currentTime;
- conflicted = conflicted || c.__active__ || c.__missed__;
- }
- }
- }
- }
-
- if (!conflicted) {
- return;
- }
-
- var events = [];
-
- for (var i = 0; i < otherCues.length; ++i) {
- var c = otherCues[i];
-
- if (c.pauseOnExit && (c.__active__ || c.__missed__)) {
- video.pause();
- }
-
- if (c.__missed__) {
- events.push({ type: 'enter', timeStamp: c.startTime, target: c });
- }
-
- if (c.__active__ || c.__missed__) {
- events.push({ type: 'exit', timeStamp: c.endTime, target: c });
- }
-
- c.__active__ = false;
- c.track.activeCues.__removeCue__(c);
- }
-
- for (var i = 0; i < currentCues.length; ++i) {
- var c = currentCues[i];
-
- if (!c.__active__) {
- events.push({ type: 'enter', timeStamp: c.startTime, target: c });
- }
-
- c.__active__ = true;
- c.track.activeCues.__addCue__(c);
- }
-
- events.sort(function (a, b) { return a.timeStamp - b.timeStamp });
-
- for (var i = 0; i < events.length; ++i) {
- var e = events[i];
- var f = e.target['on' + e.type];
-
- if (f) {
- f.call(e.target, e);
- }
- }
- };
-
- var videoElems = document.getElementsByTagName('video');
-
- for (var i = 0; i < videoElems.length; ++i) {
- fixMediaElement(videoElems[i]);
- }
-
- var audioElems = document.getElementsByTagName('audio');
-
- for (var i = 0; i < audioElems.length; ++i) {
- fixMediaElement(audioElems[i]);
- }
-
- var trackElems = document.getElementsByTagName('track');
-
- for (var i = 0; i < trackElems.length; ++i) {
- var t = trackElems[i];
- fixTrackElement(t);
- t.track = t.parentNode.addTextTrack(t.kind, t.label, t.srclang);
- }
- })();
-}
-
-if (typeof MediaController == 'undefined') {
- (function () {
- MediaController = function () {}; // See: http://dev.w3.org/html5/spec/media-elements.html#mediacontroller
-
- MediaController.prototype.__syncTime__ = function (kicker) {
- if (kicker.__seekedForSync__) {
- kicker.__seekedForSync__ = false;
- return;
- }
-
- var slaveElems = getSlaveElementsOf(this);
- var currentTime = kicker.currentTime;
-
- for (var i = 0; i < slaveElems.length; ++i) {
- var s = slaveElems[i];
-
- if (s !== kicker) {
- s.__seekedForSync__ = true;
- s.currentTime = currentTime;
- }
- }
- };
-
- MediaController.prototype.__syncPlayback__ = function (kicker) {
- var slaveElems = getSlaveElementsOf(this);
- var readyState = 0;
- var paused = false;
-
- for (var i = 0; i < slaveElems.length; ++i) {
- var s = slaveElems[i];
- readyState = Math.max(readyState, s.readyState);
- paused = paused || s.ended || (s.paused && !s.__pausedForSync__);
- }
-
- this.readyState = readyState;
- this.paused = paused || readyState < 4; // < HAVE_ENOUGH_DATA
-
- for (var i = 0; i < slaveElems.length; ++i) {
- var s = slaveElems[i];
-
- if (this.paused) {
- if (!s.paused) {
- s.__pausedForSync__ = true;
- s.pause();
- }
- else {
-
- }
- }
- else {
- if (s.paused) {
- s.__pausedForSync__ = false;
- s.play();
- }
- else {
- s.__pausedForSync__ = false;
- }
- }
- }
- };
-
- var getSlaveElementsOf = function (controller) {
- var videoElems = document.getElementsByTagName('video');
- var audioElems = document.getElementsByTagName('audio');
- var slaveElems = [];
-
- for (var i = 0; i < videoElems.length; ++i) {
- var v = videoElems[i];
-
- if (v.controller === controller) {
- slaveElems.push(v);
- }
- }
-
- for (var i = 0; i < audioElems.length; ++i) {
- var a = audioElems[i];
-
- if (a.controller === controller) {
- slaveElems.push(a);
- }
- }
-
- return slaveElems;
- };
-
- var controllers = {};
-
- var fixMediaElement = function (m) {
- m.mediaGroup = m.getAttribute('mediagroup');
-
- if (!m.mediaGroup) {
- return;
- }
-
- m.controller = controllers[m.mediaGroup] || (controllers[m.mediaGroup] = new MediaController());
- m.addEventListener('seeked', syncTime, false);
- m.addEventListener('seeked', syncPlayback, false);
- m.addEventListener('playing', syncPlayback, false);
- m.addEventListener('waiting', syncPlayback, false);
- m.addEventListener('pause', syncPlayback, false);
- m.addEventListener('ended', syncPlayback, false);
- m.__pausedForSync__ = true;
- };
-
- var syncTime = function (e) {
- e.target.controller.__syncTime__(e.target);
- };
-
- var syncPlayback = function (e) {
- e.target.controller.__syncPlayback__(e.target);
- };
-
- var videoElems = document.getElementsByTagName('video');
-
- for (var i = 0; i < videoElems.length; ++i) {
- fixMediaElement(videoElems[i]);
- }
-
- var audioElems = document.getElementsByTagName('audio');
-
- for (var i = 0; i < audioElems.length; ++i) {
- fixMediaElement(audioElems[i]);
- }
- })();
-}
-
+/*******************************************************************************
+ * Copyright (c) 2009, 2015 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+//
+// Ad-hoc codes to bridge the gap between the HTML5 spec and browser implementations
+//
+if (true) { // if (typeof TextTrack == 'undefined') { // As of Mar 2015, no major browser sufficiently supports TextTrack.
+ (function () {
+ TextTrack = function (kind, label, language) { // See: http://www.w3.org/TR/html5/embedded-content-0.html#texttrack
+ this.kind = kind;
+ this.label = label;
+ this.language = language;
+ this.mode = TextTrack.HIDDEN;
+ this.cues = new TextTrackCueList();
+ this.activeCues = new TextTrackCueList();
+ };
+
+ TextTrack.DISABLED = 0;
+ TextTrack.HIDDEN = 1;
+ TextTrack.SHOWING = 2;
+
+ TextTrack.prototype.addCue = function (cue) {
+ cue.track = cue.__track__ = this;
+ this.cues.__addCue__(cue);
+ };
+
+ TextTrack.prototype.removeCue = function (cue) {
+ cue.track = cue.__track__ = null;
+ this.cues.__removeCue__(cue);
+ };
+
+ TextTrack.prototype.toString = function () {
+ return 'TextTrack <' + this.kind + '> ' + this.label + ' (' + this.language + ') : ' + this.cues;
+ };
+
+ TextTrackList = function () { // See: http://www.w3.org/TR/html5/embedded-content-0.html#texttracklist
+ var list = [];
+
+ list.getTrackById = function (id) {
+ for (var i = 0; i < this.length; ++i) {
+ var e = this[i];
+
+ if (e.id == id) {
+ return e;
+ }
+ }
+
+ return null;
+ };
+
+ list.toString = function () {
+ return 'TextTrackList [\n\t' + this.join(',\n\t') + '\n]';
+ };
+
+ return list;
+ };
+
+ TextTrackCue = function (startTime, endTime, text) { // See: http://www.w3.org/TR/html5/embedded-content-0.html#texttrackcue
+ if (typeof VTTCue != 'undefined') {
+ return new VTTCue(startTime, endTime, text);
+ }
+ else {
+ this.startTime = startTime;
+ this.endTime = endTime;
+ this.text = text;
+ }
+ };
+
+ TextTrackCue.prototype.toString = function () {
+ return 'TextTrackCue <' + this.id + '> ' + this.startTime + ' -> ' + this.endTime + ' : ' + this.text + (this.pauseOnExit ? ' * pause-on-exit * ' : ' ');
+ };
+
+ TextTrackCueList = function () { // See: http://www.w3.org/TR/html5/embedded-content-0.html#texttrackcuelist
+ var list = [];
+
+ list.getCueById = function (id) {
+ for (var i = 0; i < this.length; ++i) {
+ var e = this[i];
+
+ if (e.id == id) {
+ return e;
+ }
+ }
+
+ return null;
+ };
+
+ list.__addCue__ = function (cue) {
+ this.push(cue);
+ };
+
+ list.__removeCue__ = function (cue) {
+ for (var i = 0; i < this.length; ++i) {
+ if (this[i] === cue) {
+ this.splice(i--, 1);
+ }
+ }
+ };
+
+ list.toString = function () {
+ return 'TextTrackCueList [\n\t' + this.join(',\n\t') + '\n]';
+ };
+
+ return list;
+ };
+
+ var fixMediaElement = function (m) {
+ m.textTracks = m.__textTracks__ = new TextTrackList();
+ m.addTextTrack = m.__addTextTrack__ = addTextTrack;
+ m.__lastTime__ = m.currentTime;
+ m.addEventListener('timeupdate', updateCues, false);
+ m.addEventListener('seeked', updateCues, false);
+ };
+
+ var fixTrackElement = function (t) {
+ t.kind = t.getAttribute('kind');
+ t.src = t.getAttribute('src');
+ t.srclang = t.getAttribute('srclang');
+ t.label = t.getAttribute('label');
+ t['default'] = t.getAttribute('default') != null; // .default causes an error in IE
+
+ if (!t.dataset) {
+ var d = {};
+ var a = t.attributes;
+
+ for (var i = 0; i < a.length; ++i) {
+ if (a[i].name.indexOf('data-') == 0) {
+ d[a[i].name.substr(5)] = a[i].value;
+ }
+ }
+
+ t.dataset = d;
+ }
+ };
+
+ var addTextTrack = function (kind, label, language) { // HTMLMediaElement#addTextTrack
+ var t = new TextTrack(kind, label, language);
+ this.__textTracks__.push(t);
+ return t;
+ };
+
+ var updateCues = function (e) { // http://dev.w3.org/html5/spec/media-elements.html#media-playback
+ var video = e.target;
+
+ var currentTime = video.currentTime;
+ var lastTime = video.__lastTime__; video.__lastTime__ = currentTime;
+ var isMonotonicIncrease = currentTime > lastTime && currentTime <= lastTime + .5; // major browsers fire timeupdate events every 250 ms
+
+ var currentCues = [];
+ var otherCues = [];
+ var conflicted = false;
+
+ var tracks = video.__textTracks__;
+
+ for (var i = 0; i < tracks.length; ++i) {
+ var t = tracks[i];
+
+ if (t.mode != TextTrack.DISABLED) {
+ var cues = t.cues;
+
+ for (var j = 0; j < cues.length; ++j) {
+ var c = cues[j];
+
+ if (c.startTime <= currentTime && c.endTime > currentTime) {
+ currentCues.push(c);
+ c.__missed__ = false;
+ conflicted = conflicted || !c.__active__;
+ }
+ else {
+ otherCues.push(c);
+ c.__missed__ = isMonotonicIncrease && c.startTime >= lastTime && c.endTime <= currentTime;
+ conflicted = conflicted || c.__active__ || c.__missed__;
+ }
+ }
+ }
+ }
+
+ if (!conflicted) {
+ return;
+ }
+
+ var events = [];
+
+ for (var i = 0; i < otherCues.length; ++i) {
+ var c = otherCues[i];
+
+ if (c.pauseOnExit && (c.__active__ || c.__missed__)) {
+ video.pause();
+ }
+
+ if (c.__missed__) {
+ events.push({ type: 'enter', timeStamp: c.startTime, target: c });
+ }
+
+ if (c.__active__ || c.__missed__) {
+ events.push({ type: 'exit', timeStamp: c.endTime, target: c });
+ }
+
+ c.__active__ = false;
+ c.__track__.activeCues.__removeCue__(c);
+ }
+
+ for (var i = 0; i < currentCues.length; ++i) {
+ var c = currentCues[i];
+
+ if (!c.__active__) {
+ events.push({ type: 'enter', timeStamp: c.startTime, target: c });
+ }
+
+ c.__active__ = true;
+ c.__track__.activeCues.__addCue__(c);
+ }
+
+ events.sort(function (a, b) { return a.timeStamp - b.timeStamp });
+
+ for (var i = 0; i < events.length; ++i) {
+ var e = events[i];
+ var f = e.target['on' + e.type];
+
+ if (f) {
+ f.call(e.target, e);
+ }
+ }
+ };
+
+ var videoElems = document.getElementsByTagName('video');
+
+ for (var i = 0; i < videoElems.length; ++i) {
+ fixMediaElement(videoElems[i]);
+ }
+
+ var audioElems = document.getElementsByTagName('audio');
+
+ for (var i = 0; i < audioElems.length; ++i) {
+ fixMediaElement(audioElems[i]);
+ }
+
+ var trackElems = document.getElementsByTagName('track');
+
+ for (var i = 0; i < trackElems.length; ++i) {
+ var t = trackElems[i];
+ fixTrackElement(t);
+ t.track = t.__track__ = t.parentNode.__addTextTrack__(t.kind, t.label, t.srclang);
+ }
+ })();
+}
+
+if (true) { // if (typeof MediaController == 'undefined') { // As of Mar 2015, no major browser sufficiently supports MediaController.
+ (function () {
+ MediaController = function () {}; // See: http://www.w3.org/TR/html5/embedded-content-0.html#mediacontroller
+
+ MediaController.prototype.__syncTime__ = function (kicker) {
+ if (kicker.__seekedForSync__) {
+ kicker.__seekedForSync__ = false;
+ return;
+ }
+
+ var slaveElems = getSlaveElementsOf(this);
+ var currentTime = kicker.currentTime;
+
+ for (var i = 0; i < slaveElems.length; ++i) {
+ var s = slaveElems[i];
+
+ if (s !== kicker) {
+ s.__seekedForSync__ = true;
+ s.currentTime = currentTime;
+ }
+ }
+ };
+
+ MediaController.prototype.__syncPlayback__ = function (kicker) {
+ var slaveElems = getSlaveElementsOf(this);
+ var readyState = 0;
+ var paused = false;
+
+ for (var i = 0; i < slaveElems.length; ++i) {
+ var s = slaveElems[i];
+ readyState = Math.max(readyState, s.readyState);
+ paused = paused || s.ended || (s.paused && !s.__pausedForSync__);
+ }
+
+ this.readyState = readyState;
+ this.paused = paused || readyState < 4; // < HAVE_ENOUGH_DATA
+
+ for (var i = 0; i < slaveElems.length; ++i) {
+ var s = slaveElems[i];
+
+ if (this.paused) {
+ if (!s.paused) {
+ s.__pausedForSync__ = true;
+ s.pause();
+ }
+ else {
+
+ }
+ }
+ else {
+ if (s.paused) {
+ s.__pausedForSync__ = false;
+ s.play();
+ }
+ else {
+ s.__pausedForSync__ = false;
+ }
+ }
+ }
+ };
+
+ var getSlaveElementsOf = function (controller) {
+ var videoElems = document.getElementsByTagName('video');
+ var audioElems = document.getElementsByTagName('audio');
+ var slaveElems = [];
+
+ for (var i = 0; i < videoElems.length; ++i) {
+ var v = videoElems[i];
+
+ if (v.controller === controller) {
+ slaveElems.push(v);
+ }
+ }
+
+ for (var i = 0; i < audioElems.length; ++i) {
+ var a = audioElems[i];
+
+ if (a.controller === controller) {
+ slaveElems.push(a);
+ }
+ }
+
+ return slaveElems;
+ };
+
+ var controllers = {};
+
+ var fixMediaElement = function (m) {
+ m.mediaGroup = m.getAttribute('mediagroup');
+
+ if (!m.mediaGroup) {
+ return;
+ }
+
+ m.controller = controllers[m.mediaGroup] || (controllers[m.mediaGroup] = new MediaController());
+ m.addEventListener('seeked', syncTime, false);
+ m.addEventListener('seeked', syncPlayback, false);
+ m.addEventListener('playing', syncPlayback, false);
+ m.addEventListener('waiting', syncPlayback, false);
+ m.addEventListener('pause', syncPlayback, false);
+ m.addEventListener('ended', syncPlayback, false);
+ m.__pausedForSync__ = true;
+ };
+
+ var syncTime = function (e) {
+ e.target.controller.__syncTime__(e.target);
+ };
+
+ var syncPlayback = function (e) {
+ e.target.controller.__syncPlayback__(e.target);
+ };
+
+ var videoElems = document.getElementsByTagName('video');
+
+ for (var i = 0; i < videoElems.length; ++i) {
+ fixMediaElement(videoElems[i]);
+ }
+
+ var audioElems = document.getElementsByTagName('audio');
+
+ for (var i = 0; i < audioElems.length; ++i) {
+ fixMediaElement(audioElems[i]);
+ }
+ })();
+}
+
diff --git a/plugins/org.eclipse.actf.examples.scripteditor/resources/scripts/vd-player-en.js b/plugins/org.eclipse.actf.examples.scripteditor/resources/scripts/vd-player-en.js
index 8d7d886..2238da3 100644
--- a/plugins/org.eclipse.actf.examples.scripteditor/resources/scripts/vd-player-en.js
+++ b/plugins/org.eclipse.actf.examples.scripteditor/resources/scripts/vd-player-en.js
@@ -1,436 +1,445 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-//
-// Plays video descriptions (including extended video descriptions and external audio fragments) on the draft HTML5 spec
-//
-(function () {
- var TEXT_RESOURCES = { playLabel: 'Play', pauseLabel: 'Pause', stopLabel: 'Stop', skipLabel: 'Skip 10 s', backLabel: 'Back 10 s', volUpLabel: 'Vol Up', volDnLabel: 'Vol Down', timeFormat: '%m m %s s', showTextLabel: 'Show Text' }; // English
- var FORMAT_REPLACE = { MSIE: 'm4a', AppleWebKit: 'm4a', _: 'oga' }; // formats for .* external audio resources (e.g., 'foo.*' is replaced with 'foo.m4a' on MSIE)
-
- // Parses external text track resources
- //
- var TextTrackParser = [];
-
- TextTrackParser.read = function (xhr) {
- for (var i = 0; i < this.length; ++i) {
- var r = this[i];
- if (r.isReadable(xhr)) {
- return r.readCues(xhr);
- }
- }
-
- return null;
- };
-
- TextTrackParser.register = function (name, isReadable, readCues) {
- this.push({ name: name, isReadable: isReadable, readCues: readCues });
- };
-
- // TTML (ignores layout and styles)
- //
- (function () {
- var TTML_NAMESPACE = 'http://www.w3.org/ns/ttml';
- var XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
- var TVD_NAMESPACE = 'http://www.eclipse.org/actf/ai/tvd';
-
- var frameRate = 30;
- var subFrameRate = 1;
-
- var timeToSecond = function (exp) {
- if (!exp) return null;
- var v = exp.match(/^(\d{2,}):(\d{2}):(\d{2})(?:\.(\d+)|:(\d{2})(?:\.(\d+))?)?$/);
- var h = v[1] * 60 * 60;
- var m = v[2] * 60;
- var s = parseFloat(v[3] + '.' + (v[4] || 0));
- var f = parseInt(v[5] || 0) / frameRate;
- var u = parseInt(v[6] || 0) / frameRate / subFrameRate;
- return h + m + s + f + u;
- };
-
- var wildcardToFormat = function (url) {
- if (!url) return null;
- var v = navigator.userAgent.match(/MSIE|AppleWebKit/) || ['_'];
- var f = FORMAT_REPLACE[v[0]];
- return url.replace('*', f);
- };
-
- var isTTML = function (xhr) {
- var xml = xhr.responseXML;
- if (!xml) return false;
- var tts = xml.getElementsByTagName('tt'); // xml.getElementsByTagNameNS(TTML_NAMESPACE, 'tt'); // for IE
- return tts.length == 1;
- };
-
- var readCues = function (xhr) {
- var xml = xhr.responseXML;
- var ps = xml.getElementsByTagName('p'); // xml.getElementsByTagNameNS(TTML_NAMESPACE, 'p'); // for IE
- var cues = [];
-
- for (var i = 0; i < ps.length; ++i) {
- var p = ps[i];
- var id = p.getAttribute('xml:id'); // p.getAttributeNS(XML_NAMESPACE, 'id'); // for IE
- var begin = timeToSecond(p.getAttribute('begin'));
- var end = timeToSecond(p.getAttribute('end'));
- var dur = timeToSecond(p.getAttribute('dur'));
- var text = p.textContent || p.firstChild.nodeValue;
- var extended = p.getAttribute('tvd:extended') == 'true'; // p.getAttributeNS(TVD_NAMESPACE, 'extended') == 'true'; // for IE
- var external = wildcardToFormat(p.getAttribute('tvd:external')); // p.getAttributeNS(TVD_NAMESPACE, 'external'); // for IE
- end = end || (begin + (extended ? 0 : dur));
- dur = dur || (end - begin);
- var cue = new TextTrackCue(id, begin, end, text, '', extended);
- cue.__duration__ = dur;
- cue.__external__ = external;
- cues.push(cue);
- }
-
- return cues;
- };
-
- TextTrackParser.register('TTML', isTTML, readCues);
- })();
-
- // WebVTT (ignores layout and styles)
- //
- (function () {
- var timeToSecond = function (exp) {
- if (!exp) return null;
- var v = exp.match(/^(?:(\d{2,}):)?(\d{2}):(\d{2}\.\d{3})$/);
- var h = (v[1] || 0) * 60 * 60;
- var m = v[2] * 60;
- var s = parseFloat(v[3]);
- return h + m + s;
- };
-
- var wildcardToFormat = function (url) {
- if (!url) return null;
- var v = navigator.userAgent.match(/MSIE|AppleWebKit/) || ['_'];
- var f = FORMAT_REPLACE[v[0]];
- return url.replace('*', f);
- };
-
- var isWebVTT = function (xhr) {
- var txt = xhr.responseText;
- return txt.match(/^WEBVTT\b/);
- };
-
- var readCues = function (xhr) {
- var txt = xhr.responseText.replace(/\r\n|\r/g, '\n');
- var elems = txt.split(/\n{2,}/);
- var cues = [];
-
- for (var i = 0; i < elems.length; ++i) {
- var e = elems[i];
- var m = e.match(/^(?:(\w+)\n)?((?:\d{2,})?:\d{2}:\d{2}\.\d{3})[ \t]+-->[ \t]+((?:\d{2,})?:\d{2}:\d{2}\.\d{3})(?:[ \t]+([^\n]+))?\n([\w\W]+)$/m);
-
- if (m) {
- var id = m[1] || '';
- var begin = timeToSecond(m[2]);
- var end = timeToSecond(m[3]);
- var settings = m[4] || '';
- var extended = settings.match(/\bextended\b/);
- var text = m[5];
- var m1 = settings.match(/\bduration=((?:\d{2,}:)?\d{2}:\d{2}\.\d{3})/);
- var dur = m1 ? timeToSecond(m1[1]) : 0;
- var m2 = settings.match(/\bexternal=([^,]+)/);
- var external = wildcardToFormat(m2 ? m2[1] : '');
- end = end || (begin + (extended ? 0 : dur));
- dur = dur || (end - begin);
- var cue = new TextTrackCue(id, begin, end, text, '', extended);
- cue.__duration__ = dur;
- cue.__external__ = external;
- cues.push(cue);
- }
- }
-
- return cues;
- };
-
- TextTrackParser.register('WebVTT', isWebVTT, readCues);
- })();
-
- // Shows/reads aloud captions/descriptions
- //
- var initCues = function (track, video) {
- var onenter = function (e) {
- var cue = e.target;
-
- if (cue.track.__kind__ == 'descriptions') {
- if (cue.__audio__) { // external resource exists
- cue.__audio__.currentTime = 0;
- cue.__audio__.play();
- video.__descriptions__.setAttribute('aria-live', 'off');
- showText(cue.text, video.__descriptions__);
- }
- else { // uses screen reader
- video.__descriptions__.setAttribute('aria-live', 'assertive');
- showText(cue.text, video.__descriptions__);
- }
- }
- else if (cue.track.__kind__ == 'captions') {
- showText(cue.text, video.__captions__);
- }
- };
-
- var onexit = function (e) {
- var cue = e.target;
-
- if (cue.track.__kind__ == 'descriptions') {
- var isExtended = cue.pauseOnExit && video.paused;
-
- if (isExtended) {
- if (cue.__audio__) {
- if (cue.__audio__.ended) {
- showText('', video.__descriptions__);
- video.play();
- }
- else {
- cue.__audio__.addEventListener('ended', function () {
- showText('', video.__descriptions__);
- video.play();
- }, false);
- }
- }
- else {
- if (cue.endTime - cue.startTime >= cue.__duration__) {
- showText('', video.__descriptions__);
- video.play();
- }
- else {
- setTimeout(function () {
- showText('', video.__descriptions__);
- video.play();
- }, (cue.__duration__ - cue.endTime + cue.startTime) * 1000);
- }
- }
- }
- else {
- if (cue.__audio__) {
- cue.__audio__.pause();
- showText('', video.__descriptions__);
- }
- else {
- showText('', video.__descriptions__);
- }
- }
- }
- else if (cue.track.__kind__ == 'captions') {
- showText('', video.__captions__);
- }
- };
-
- var showText = function (text, container) {
- var oldText = container.firstChild;
- var newText = document.createElement('span');
- newText.appendChild(document.createTextNode(text));
- container.replaceChild(newText, oldText);
- };
-
- var cues = track.cues;
-
- for (var i = 0; i < cues.length; ++i) {
- var c = cues[i];
-
- if (c.__external__) {
- c.__audio__ = new Audio(c.__external__);
- }
-
- c.onenter = onenter;
- c.onexit = onexit;
- }
- };
-
- var loadCues = function (track, video) {
- var xhr = new XMLHttpRequest();
- xhr.onreadystatechange = function () {
- if (xhr.readyState == 4) {
- switch (xhr.status) {
- case 200:
- case 0: // for local files
- var cues = TextTrackParser.read(xhr);
-
- if (cues) {
- for (var i = 0; i < cues.length; ++i) {
- track.track.addCue(cues[i]);
- }
-
- track.track.mode = track['default'] ? TextTrack.SHOWING : TextTrack.DISABLED; // .default causes an error in IE
- initCues(track.track, video);
- }
-
- break;
- }
- }
- };
-
- xhr.open('GET', track.src, true);
- xhr.send(null);
- };
-
- // Sets up control buttons and caption/description display areas
- //
- var createVDControls = function (video) {
- var paused = video.paused;
-
- var e = document.createElement('div');
- e.className = 'vd-controls';
- video.__controls__ = video.parentNode.appendChild(e);
-
- var toggleButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
- toggleButton.appendChild(document.createTextNode(''));
- toggleButton.accessKey = 'p';
- toggleButton.onclick = function () {
- if (paused) {
- this.__update__(paused = false);
- video.play();
- }
- else {
- this.__update__(paused = true);
- video.pause();
- }
- };
- toggleButton.__update__ = function () {
- this.firstChild.nodeValue = paused ? TEXT_RESOURCES.playLabel : TEXT_RESOURCES.pauseLabel;
- };
- toggleButton.__update__();
-
- var stopButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
- stopButton.appendChild(document.createTextNode(TEXT_RESOURCES.stopLabel));
- stopButton.accessKey = 's';
- stopButton.onclick = function () {
- video.currentTime = 0;
- video.play();
- video.pause();
- toggleButton.__update__(paused = true);
- };
-
- var backButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
- backButton.appendChild(document.createTextNode(TEXT_RESOURCES.backLabel));
- backButton.accessKey = 'b';
- backButton.onclick = function () {
- video.currentTime -= 10;
- video.play();
- toggleButton.__update__(paused = false);
- };
-
- var skipButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
- skipButton.appendChild(document.createTextNode(TEXT_RESOURCES.skipLabel));
- skipButton.accessKey = 'f';
- skipButton.onclick = function () {
- video.currentTime += 10;
- video.play();
- toggleButton.__update__(paused = false);
- };
-
- var volDnButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
- volDnButton.appendChild(document.createTextNode(TEXT_RESOURCES.volDnLabel));
- volDnButton.accessKey = 'n';
- volDnButton.onclick = function () {
- video.volume -= .1;
- };
-
- var volUpButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
- volUpButton.appendChild(document.createTextNode(TEXT_RESOURCES.volUpLabel));
- volUpButton.accessKey = 'u';
- volUpButton.onclick = function () {
- video.volume += .1;
- };
-
- var formatTime = function (t) {
- var m = parseInt(t / 60);
- var s = parseInt(t % 60);
- return TEXT_RESOURCES.timeFormat.replace('%m', m).replace('%s', s);
- };
-
- var timeDisplay = e.appendChild(document.createElement('div')).appendChild(document.createElement('span'));
- timeDisplay.appendChild(document.createTextNode(formatTime(0)));
-
- video.addEventListener('timeupdate', function (e) {
- timeDisplay.firstChild.nodeValue = formatTime(e.target.currentTime);
- }, false);
-
- video.addEventListener('ended', function (e) {
- toggleButton.__update__(paused = true);
- }, false);
-
- video.addEventListener('playing', function (e) {
- toggleButton.disabled = false;
- stopButton.disabled = false;
- backButton.disabled = false;
- skipButton.disabled = false;
- }, false);
-
- video.addEventListener('pause', function (e) {
- if (paused) { // paused by user (not for extended descriptions)
- return;
- }
- toggleButton.disabled = true;
- stopButton.disabled = true;
- backButton.disabled = true;
- skipButton.disabled = true;
- }, false);
- };
-
- var createVDDisplays = function (video) {
- var e1 = document.createElement('div');
- e1.className = 'vd-descriptions';
- e1.appendChild(document.createElement('span'));
- video.__descriptions__ = video.parentNode.appendChild(e1);
-
- var e2 = document.createElement('div');
- e2.className = 'vd-captions';
- e2.appendChild(document.createElement('span'));
- video.__captions__ = video.parentNode.appendChild(e2);
-
- var e1opt = document.createElement('div');
- e1opt.className = 'vd-descriptions-config';
- var l1 = document.createElement('label');
- var c1 = document.createElement('input');
- c1.type = 'checkbox';
- c1.onclick = function () {
- if (this.checked) {
- video.__descriptions__.className = [video.__descriptions__.className, 'vd-show'].join(' ');
- }
- else {
- video.__descriptions__.className = video.__descriptions__.className.replace(/\bvd-show\b/g, '');
- }
- };
- l1.appendChild(c1);
- l1.appendChild(document.createTextNode(TEXT_RESOURCES.showTextLabel));
- e1opt.appendChild(l1);
- video.parentNode.appendChild(e1opt);
- }
-
- var fixVideoElement = function (video) {
- var container = document.createElement('div');
- container.className = 'vd-container';
- container.appendChild(video.parentNode.replaceChild(container, video));
- createVDControls(video);
- createVDDisplays(video);
- };
-
- var videoElems = document.getElementsByTagName('video');
-
- for (var i = 0; i < videoElems.length; ++i) {
- var v = videoElems[i];
- fixVideoElement(v);
- var trackElems = v.getElementsByTagName('track');
-
- for (var j = 0; j < trackElems.length; ++j) {
- var t = trackElems[j];
-
- if (t.kind == 'descriptions' || t.kind == 'captions' || t.kind == 'metadata' && (t.dataset.kind == 'descriptions' || t.dataset.kind == 'captions')) {
- t.track.__kind__ = t.dataset.kind || t.kind;
- loadCues(t, v);
- }
- }
- }
-})();
-
+/*******************************************************************************
+ * Copyright (c) 2009, 2015 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+//
+// Plays video descriptions (including extended video descriptions and external audio fragments) on the draft HTML5 spec
+//
+(function () {
+ var TEXT_RESOURCES = { playLabel: 'Play', pauseLabel: 'Pause', stopLabel: 'Stop', skipLabel: 'Skip 10 s', backLabel: 'Back 10 s', volUpLabel: 'Vol Up', volDnLabel: 'Vol Down', timeFormat: '%m m %s s', showTextLabel: 'Show Text' }; // English
+ var USER_AGENTS_RE = /MSIE|AppleWebKit/;
+ var FORMAT_REPLACE = { MSIE: 'm4a', AppleWebKit: 'm4a', _: 'oga' }; // formats for .* external audio resources (e.g., 'foo.*' is replaced with 'foo.m4a' on MSIE)
+
+ // Ad-hoc codes to bridge the gap between the HTML5 spec and browser implementations
+ //
+ var __track__ = function (e) {
+ return (e.__track__ || e.track);
+ };
+
+ // Parses external text track resources
+ //
+ var TextTrackParser = [];
+
+ TextTrackParser.read = function (xhr) {
+ for (var i = 0; i < this.length; ++i) {
+ var r = this[i];
+ if (r.isReadable(xhr)) {
+ return r.readCues(xhr);
+ }
+ }
+
+ return null;
+ };
+
+ TextTrackParser.register = function (name, isReadable, readCues) {
+ this.push({ name: name, isReadable: isReadable, readCues: readCues });
+ };
+
+ // TTML (ignores layout and styles)
+ //
+ (function () {
+ var TTML_NAMESPACE = 'http://www.w3.org/ns/ttml';
+ var XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
+ var TVD_NAMESPACE = 'http://www.eclipse.org/actf/ai/tvd';
+
+ var frameRate = 30;
+ var subFrameRate = 1;
+
+ var timeToSecond = function (exp) {
+ if (!exp) return null;
+ var v = exp.match(/^(\d{2,}):(\d{2}):(\d{2})(?:\.(\d+)|:(\d{2})(?:\.(\d+))?)?$/);
+ var h = v[1] * 60 * 60;
+ var m = v[2] * 60;
+ var s = parseFloat(v[3] + '.' + (v[4] || 0));
+ var f = parseInt(v[5] || 0) / frameRate;
+ var u = parseInt(v[6] || 0) / frameRate / subFrameRate;
+ return h + m + s + f + u;
+ };
+
+ var wildcardToFormat = function (url) {
+ if (!url) return null;
+ var v = navigator.userAgent.match(USER_AGENTS_RE) || ['_'];
+ var f = FORMAT_REPLACE[v[0]];
+ return url.replace('*', f);
+ };
+
+ var isTTML = function (xhr) {
+ var xml = xhr.responseXML;
+ if (!xml) return false;
+ var tts = xml.getElementsByTagName('tt'); // xml.getElementsByTagNameNS(TTML_NAMESPACE, 'tt'); // for IE
+ return tts.length == 1;
+ };
+
+ var readCues = function (xhr) {
+ var xml = xhr.responseXML;
+ var ps = xml.getElementsByTagName('p'); // xml.getElementsByTagNameNS(TTML_NAMESPACE, 'p'); // for IE
+ var cues = [];
+
+ for (var i = 0; i < ps.length; ++i) {
+ var p = ps[i];
+// var id = p.getAttribute('xml:id'); // p.getAttributeNS(XML_NAMESPACE, 'id'); // for IE
+ var begin = timeToSecond(p.getAttribute('begin'));
+ var end = timeToSecond(p.getAttribute('end'));
+ var dur = timeToSecond(p.getAttribute('dur'));
+ var text = p.textContent || p.firstChild.nodeValue;
+ var extended = p.getAttribute('tvd:extended') == 'true'; // p.getAttributeNS(TVD_NAMESPACE, 'extended') == 'true'; // for IE
+ var external = wildcardToFormat(p.getAttribute('tvd:external')); // p.getAttributeNS(TVD_NAMESPACE, 'external'); // for IE
+ end = end || (begin + (extended ? 0 : dur));
+ dur = dur || (end - begin);
+ var cue = new TextTrackCue(begin, end, text);
+ cue.pauseOnExit = extended;
+ cue.__duration__ = dur;
+ cue.__external__ = external;
+ cues.push(cue);
+ }
+
+ return cues;
+ };
+
+ TextTrackParser.register('TTML', isTTML, readCues);
+ })();
+
+ // WebVTT (ignores layout and styles)
+ //
+ (function () {
+ var timeToSecond = function (exp) {
+ if (!exp) return null;
+ var v = exp.match(/^(?:(\d{2,}):)?(\d{2}):(\d{2}\.\d{3})$/);
+ var h = (v[1] || 0) * 60 * 60;
+ var m = v[2] * 60;
+ var s = parseFloat(v[3]);
+ return h + m + s;
+ };
+
+ var wildcardToFormat = function (url) {
+ if (!url) return null;
+ var v = navigator.userAgent.match(USER_AGENTS_RE) || ['_'];
+ var f = FORMAT_REPLACE[v[0]];
+ return url.replace('*', f);
+ };
+
+ var isWebVTT = function (xhr) {
+ var txt = xhr.responseText;
+ return txt.match(/^WEBVTT\b/);
+ };
+
+ var readCues = function (xhr) {
+ var txt = xhr.responseText.replace(/\r\n|\r/g, '\n');
+ var elems = txt.split(/\n{2,}/);
+ var cues = [];
+
+ for (var i = 0; i < elems.length; ++i) {
+ var e = elems[i];
+ var m = e.match(/^(?:(\w+)\n)?((?:\d{2,})?:\d{2}:\d{2}\.\d{3})[ \t]+-->[ \t]+((?:\d{2,})?:\d{2}:\d{2}\.\d{3})(?:[ \t]+([^\n]+))?\n([\w\W]+)$/m);
+
+ if (m) {
+// var id = m[1] || '';
+ var begin = timeToSecond(m[2]);
+ var end = timeToSecond(m[3]);
+ var settings = m[4] || '';
+ var extended = settings.match(/\bextended\b/);
+ var text = m[5];
+ var m1 = settings.match(/\bduration=((?:\d{2,}:)?\d{2}:\d{2}\.\d{3})/);
+ var dur = m1 ? timeToSecond(m1[1]) : 0;
+ var m2 = settings.match(/\bexternal=([^,]+)/);
+ var external = wildcardToFormat(m2 ? m2[1] : '');
+ end = end || (begin + (extended ? 0 : dur));
+ dur = dur || (end - begin);
+ var cue = new TextTrackCue(begin, end, text);
+ cue.pauseOnExit = extended;
+ cue.__duration__ = dur;
+ cue.__external__ = external;
+ cues.push(cue);
+ }
+ }
+
+ return cues;
+ };
+
+ TextTrackParser.register('WebVTT', isWebVTT, readCues);
+ })();
+
+ // Shows/reads aloud captions/descriptions
+ //
+ var initCues = function (track, video) {
+ var onenter = function (e) {
+ var cue = e.target;
+ if (__track__(cue).__kind__ == 'descriptions') {
+ if (cue.__audio__) { // external resource exists
+ cue.__audio__.currentTime = 0;
+ cue.__audio__.play();
+ video.__descriptions__.setAttribute('aria-live', 'off');
+ showText(cue.text, video.__descriptions__);
+ }
+ else { // uses screen reader
+ video.__descriptions__.setAttribute('aria-live', 'assertive');
+ showText(cue.text, video.__descriptions__);
+ }
+ }
+ else if (__track__(cue).__kind__ == 'captions') {
+ showText(cue.text, video.__captions__);
+ }
+ };
+
+ var onexit = function (e) {
+ var cue = e.target;
+ if (__track__(cue).__kind__ == 'descriptions') {
+ var isExtended = cue.pauseOnExit && video.paused;
+
+ if (isExtended) {
+ if (cue.__audio__) {
+ if (cue.__audio__.ended) {
+ showText('', video.__descriptions__);
+ video.play();
+ }
+ else {
+ cue.__audio__.addEventListener('ended', function () {
+ showText('', video.__descriptions__);
+ video.play();
+ }, false);
+ }
+ }
+ else {
+ if (cue.endTime - cue.startTime >= cue.__duration__) {
+ showText('', video.__descriptions__);
+ video.play();
+ }
+ else {
+ setTimeout(function () {
+ showText('', video.__descriptions__);
+ video.play();
+ }, (cue.__duration__ - cue.endTime + cue.startTime) * 1000);
+ }
+ }
+ }
+ else {
+ if (cue.__audio__) {
+ cue.__audio__.pause();
+ showText('', video.__descriptions__);
+ }
+ else {
+ showText('', video.__descriptions__);
+ }
+ }
+ }
+ else if (__track__(cue).__kind__ == 'captions') {
+ showText('', video.__captions__);
+ }
+ };
+
+ var showText = function (text, container) {
+ var oldText = container.firstChild;
+ var newText = document.createElement('span');
+ newText.appendChild(document.createTextNode(text));
+ container.replaceChild(newText, oldText);
+ };
+
+ var cues = track.cues;
+
+ for (var i = 0; i < cues.length; ++i) {
+ var c = cues[i];
+
+ if (c.__external__) {
+ c.__audio__ = new Audio(c.__external__);
+ }
+
+ c.onenter = onenter;
+ c.onexit = onexit;
+ }
+ };
+
+ var loadCues = function (track, video) {
+ var xhr = new XMLHttpRequest();
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+ switch (xhr.status) {
+ case 200:
+ case 0: // for local files
+ var cues = TextTrackParser.read(xhr);
+
+ if (cues) {
+ var t = __track__(track);
+
+ for (var i = 0; i < cues.length; ++i) {
+ t.addCue(cues[i]);
+ }
+
+ t.mode = track['default'] ? TextTrack.SHOWING : TextTrack.DISABLED; // .default causes an error in IE
+ initCues(t, video);
+ }
+
+ break;
+ }
+ }
+ };
+
+ xhr.open('GET', track.src, true);
+ xhr.send(null);
+ };
+
+ // Sets up control buttons and caption/description display areas
+ //
+ var createVDControls = function (video) {
+ var paused = video.paused;
+
+ var e = document.createElement('div');
+ e.className = 'vd-controls';
+ video.__controls__ = video.parentNode.appendChild(e);
+
+ var toggleButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
+ toggleButton.appendChild(document.createTextNode(''));
+ toggleButton.accessKey = 'p';
+ toggleButton.onclick = function () {
+ if (paused) {
+ this.__update__(paused = false);
+ video.play();
+ }
+ else {
+ this.__update__(paused = true);
+ video.pause();
+ }
+ };
+ toggleButton.__update__ = function () {
+ this.firstChild.nodeValue = paused ? TEXT_RESOURCES.playLabel : TEXT_RESOURCES.pauseLabel;
+ };
+ toggleButton.__update__();
+
+ var stopButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
+ stopButton.appendChild(document.createTextNode(TEXT_RESOURCES.stopLabel));
+ stopButton.accessKey = 's';
+ stopButton.onclick = function () {
+ video.currentTime = 0;
+ video.play();
+ video.pause();
+ toggleButton.__update__(paused = true);
+ };
+
+ var backButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
+ backButton.appendChild(document.createTextNode(TEXT_RESOURCES.backLabel));
+ backButton.accessKey = 'b';
+ backButton.onclick = function () {
+ video.currentTime -= 10;
+ video.play();
+ toggleButton.__update__(paused = false);
+ };
+
+ var skipButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
+ skipButton.appendChild(document.createTextNode(TEXT_RESOURCES.skipLabel));
+ skipButton.accessKey = 'f';
+ skipButton.onclick = function () {
+ video.currentTime += 10;
+ video.play();
+ toggleButton.__update__(paused = false);
+ };
+
+ var volDnButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
+ volDnButton.appendChild(document.createTextNode(TEXT_RESOURCES.volDnLabel));
+ volDnButton.accessKey = 'n';
+ volDnButton.onclick = function () {
+ video.volume -= .1;
+ };
+
+ var volUpButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
+ volUpButton.appendChild(document.createTextNode(TEXT_RESOURCES.volUpLabel));
+ volUpButton.accessKey = 'u';
+ volUpButton.onclick = function () {
+ video.volume += .1;
+ };
+
+ var formatTime = function (t) {
+ var m = parseInt(t / 60);
+ var s = parseInt(t % 60);
+ return TEXT_RESOURCES.timeFormat.replace('%m', m).replace('%s', s);
+ };
+
+ var timeDisplay = e.appendChild(document.createElement('div')).appendChild(document.createElement('span'));
+ timeDisplay.appendChild(document.createTextNode(formatTime(0)));
+
+ video.addEventListener('timeupdate', function (e) {
+ timeDisplay.firstChild.nodeValue = formatTime(e.target.currentTime);
+ }, false);
+
+ video.addEventListener('ended', function (e) {
+ toggleButton.__update__(paused = true);
+ }, false);
+
+ video.addEventListener('play', function (e) {
+ toggleButton.disabled = false;
+ stopButton.disabled = false;
+ backButton.disabled = false;
+ skipButton.disabled = false;
+ }, false);
+
+ video.addEventListener('pause', function (e) {
+ if (paused) { // paused by user (not for extended descriptions)
+ return;
+ }
+ toggleButton.disabled = true;
+ stopButton.disabled = true;
+ backButton.disabled = true;
+ skipButton.disabled = true;
+ }, false);
+ };
+
+ var createVDDisplays = function (video) {
+ var e1 = document.createElement('div');
+ e1.className = 'vd-descriptions';
+ e1.appendChild(document.createElement('span'));
+ video.__descriptions__ = video.parentNode.appendChild(e1);
+
+ var e2 = document.createElement('div');
+ e2.className = 'vd-captions';
+ e2.appendChild(document.createElement('span'));
+ video.__captions__ = video.parentNode.appendChild(e2);
+
+ var e1opt = document.createElement('div');
+ e1opt.className = 'vd-descriptions-config';
+ var l1 = document.createElement('label');
+ var c1 = document.createElement('input');
+ c1.type = 'checkbox';
+ c1.onclick = function () {
+ if (this.checked) {
+ video.__descriptions__.className = [video.__descriptions__.className, 'vd-show'].join(' ');
+ }
+ else {
+ video.__descriptions__.className = video.__descriptions__.className.replace(/\bvd-show\b/g, '');
+ }
+ };
+ l1.appendChild(c1);
+ l1.appendChild(document.createTextNode(TEXT_RESOURCES.showTextLabel));
+ e1opt.appendChild(l1);
+ video.parentNode.appendChild(e1opt);
+ }
+
+ var fixVideoElement = function (video) {
+ var container = document.createElement('div');
+ container.className = 'vd-container';
+ container.appendChild(video.parentNode.replaceChild(container, video));
+ createVDControls(video);
+ createVDDisplays(video);
+ };
+
+ var videoElems = document.getElementsByTagName('video');
+
+ for (var i = 0; i < videoElems.length; ++i) {
+ var v = videoElems[i];
+ fixVideoElement(v);
+ var trackElems = v.getElementsByTagName('track');
+
+ for (var j = 0; j < trackElems.length; ++j) {
+ var t = trackElems[j];
+
+ if (t.kind == 'descriptions' || t.kind == 'captions' || t.kind == 'metadata' && (t.dataset.kind == 'descriptions' || t.dataset.kind == 'captions')) {
+ __track__(t).__kind__ = (t.dataset.kind || t.kind);
+ loadCues(t, v);
+ }
+ }
+ }
+})();
+
diff --git a/plugins/org.eclipse.actf.examples.scripteditor/resources/scripts/vd-player-ja.js b/plugins/org.eclipse.actf.examples.scripteditor/resources/scripts/vd-player-ja.js
index 969c7fc..a391508 100644
--- a/plugins/org.eclipse.actf.examples.scripteditor/resources/scripts/vd-player-ja.js
+++ b/plugins/org.eclipse.actf.examples.scripteditor/resources/scripts/vd-player-ja.js
@@ -1,436 +1,446 @@
-/*******************************************************************************
- * Copyright (c) 2009, 2012 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
-//
-// Plays video descriptions (including extended video descriptions and external audio fragments) on the draft HTML5 spec
-//
-(function () {
- var TEXT_RESOURCES = { playLabel: '\u518d\u751f', pauseLabel: '\u4e00\u6642\u505c\u6b62', stopLabel: '\u505c\u6b62', skipLabel: '10\u79d2\u9032\u3080', backLabel: '10\u79d2\u623b\u308b', volUpLabel: '\u97f3\u91cf\u5927', volDnLabel: '\u97f3\u91cf\u5c0f', timeFormat: '%m\u5206%s\u79d2', showTextLabel: '\u30c6\u30ad\u30b9\u30c8\u3092\u8868\u793a' };
- var FORMAT_REPLACE = { MSIE: 'm4a', AppleWebKit: 'm4a', _: 'oga' }; // formats for .* external audio resources (e.g., 'foo.*' is replaced with 'foo.m4a' on MSIE)
-
- // Parses external text track resources
- //
- var TextTrackParser = [];
-
- TextTrackParser.read = function (xhr) {
- for (var i = 0; i < this.length; ++i) {
- var r = this[i];
- if (r.isReadable(xhr)) {
- return r.readCues(xhr);
- }
- }
-
- return null;
- };
-
- TextTrackParser.register = function (name, isReadable, readCues) {
- this.push({ name: name, isReadable: isReadable, readCues: readCues });
- };
-
- // TTML (ignores layout and styles)
- //
- (function () {
- var TTML_NAMESPACE = 'http://www.w3.org/ns/ttml';
- var XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
- var TVD_NAMESPACE = 'http://www.eclipse.org/actf/ai/tvd';
-
- var frameRate = 30;
- var subFrameRate = 1;
-
- var timeToSecond = function (exp) {
- if (!exp) return null;
- var v = exp.match(/^(\d{2,}):(\d{2}):(\d{2})(?:\.(\d+)|:(\d{2})(?:\.(\d+))?)?$/);
- var h = v[1] * 60 * 60;
- var m = v[2] * 60;
- var s = parseFloat(v[3] + '.' + (v[4] || 0));
- var f = parseInt(v[5] || 0) / frameRate;
- var u = parseInt(v[6] || 0) / frameRate / subFrameRate;
- return h + m + s + f + u;
- };
-
- var wildcardToFormat = function (url) {
- if (!url) return null;
- var v = navigator.userAgent.match(/MSIE|AppleWebKit/) || ['_'];
- var f = FORMAT_REPLACE[v[0]];
- return url.replace('*', f);
- };
-
- var isTTML = function (xhr) {
- var xml = xhr.responseXML;
- if (!xml) return false;
- var tts = xml.getElementsByTagName('tt'); // xml.getElementsByTagNameNS(TTML_NAMESPACE, 'tt'); // for IE
- return tts.length == 1;
- };
-
- var readCues = function (xhr) {
- var xml = xhr.responseXML;
- var ps = xml.getElementsByTagName('p'); // xml.getElementsByTagNameNS(TTML_NAMESPACE, 'p'); // for IE
- var cues = [];
-
- for (var i = 0; i < ps.length; ++i) {
- var p = ps[i];
- var id = p.getAttribute('xml:id'); // p.getAttributeNS(XML_NAMESPACE, 'id'); // for IE
- var begin = timeToSecond(p.getAttribute('begin'));
- var end = timeToSecond(p.getAttribute('end'));
- var dur = timeToSecond(p.getAttribute('dur'));
- var text = p.textContent || p.firstChild.nodeValue;
- var extended = p.getAttribute('tvd:extended') == 'true'; // p.getAttributeNS(TVD_NAMESPACE, 'extended') == 'true'; // for IE
- var external = wildcardToFormat(p.getAttribute('tvd:external')); // p.getAttributeNS(TVD_NAMESPACE, 'external'); // for IE
- end = end || (begin + (extended ? 0 : dur));
- dur = dur || (end - begin);
- var cue = new TextTrackCue(id, begin, end, text, '', extended);
- cue.__duration__ = dur;
- cue.__external__ = external;
- cues.push(cue);
- }
-
- return cues;
- };
-
- TextTrackParser.register('TTML', isTTML, readCues);
- })();
-
- // WebVTT (ignores layout and styles)
- //
- (function () {
- var timeToSecond = function (exp) {
- if (!exp) return null;
- var v = exp.match(/^(?:(\d{2,}):)?(\d{2}):(\d{2}\.\d{3})$/);
- var h = (v[1] || 0) * 60 * 60;
- var m = v[2] * 60;
- var s = parseFloat(v[3]);
- return h + m + s;
- };
-
- var wildcardToFormat = function (url) {
- if (!url) return null;
- var v = navigator.userAgent.match(/MSIE|AppleWebKit/) || ['_'];
- var f = FORMAT_REPLACE[v[0]];
- return url.replace('*', f);
- };
-
- var isWebVTT = function (xhr) {
- var txt = xhr.responseText;
- return txt.match(/^WEBVTT\b/);
- };
-
- var readCues = function (xhr) {
- var txt = xhr.responseText.replace(/\r\n|\r/g, '\n');
- var elems = txt.split(/\n{2,}/);
- var cues = [];
-
- for (var i = 0; i < elems.length; ++i) {
- var e = elems[i];
- var m = e.match(/^(?:(\w+)\n)?((?:\d{2,})?:\d{2}:\d{2}\.\d{3})[ \t]+-->[ \t]+((?:\d{2,})?:\d{2}:\d{2}\.\d{3})(?:[ \t]+([^\n]+))?\n([\w\W]+)$/m);
-
- if (m) {
- var id = m[1] || '';
- var begin = timeToSecond(m[2]);
- var end = timeToSecond(m[3]);
- var settings = m[4] || '';
- var extended = settings.match(/\bextended\b/);
- var text = m[5];
- var m1 = settings.match(/\bduration=((?:\d{2,}:)?\d{2}:\d{2}\.\d{3})/);
- var dur = m1 ? timeToSecond(m1[1]) : 0;
- var m2 = settings.match(/\bexternal=([^,]+)/);
- var external = wildcardToFormat(m2 ? m2[1] : '');
- end = end || (begin + (extended ? 0 : dur));
- dur = dur || (end - begin);
- var cue = new TextTrackCue(id, begin, end, text, '', extended);
- cue.__duration__ = dur;
- cue.__external__ = external;
- cues.push(cue);
- }
- }
-
- return cues;
- };
-
- TextTrackParser.register('WebVTT', isWebVTT, readCues);
- })();
-
- // Shows/reads aloud captions/descriptions
- //
- var initCues = function (track, video) {
- var onenter = function (e) {
- var cue = e.target;
-
- if (cue.track.__kind__ == 'descriptions') {
- if (cue.__audio__) { // external resource exists
- cue.__audio__.currentTime = 0;
- cue.__audio__.play();
- video.__descriptions__.setAttribute('aria-live', 'off');
- showText(cue.text, video.__descriptions__);
- }
- else { // uses screen reader
- video.__descriptions__.setAttribute('aria-live', 'assertive');
- showText(cue.text, video.__descriptions__);
- }
- }
- else if (cue.track.__kind__ == 'captions') {
- showText(cue.text, video.__captions__);
- }
- };
-
- var onexit = function (e) {
- var cue = e.target;
-
- if (cue.track.__kind__ == 'descriptions') {
- var isExtended = cue.pauseOnExit && video.paused;
-
- if (isExtended) {
- if (cue.__audio__) {
- if (cue.__audio__.ended) {
- showText('', video.__descriptions__);
- video.play();
- }
- else {
- cue.__audio__.addEventListener('ended', function () {
- showText('', video.__descriptions__);
- video.play();
- }, false);
- }
- }
- else {
- if (cue.endTime - cue.startTime >= cue.__duration__) {
- showText('', video.__descriptions__);
- video.play();
- }
- else {
- setTimeout(function () {
- showText('', video.__descriptions__);
- video.play();
- }, (cue.__duration__ - cue.endTime + cue.startTime) * 1000);
- }
- }
- }
- else {
- if (cue.__audio__) {
- cue.__audio__.pause();
- showText('', video.__descriptions__);
- }
- else {
- showText('', video.__descriptions__);
- }
- }
- }
- else if (cue.track.__kind__ == 'captions') {
- showText('', video.__captions__);
- }
- };
-
- var showText = function (text, container) {
- var oldText = container.firstChild;
- var newText = document.createElement('span');
- newText.appendChild(document.createTextNode(text));
- container.replaceChild(newText, oldText);
- };
-
- var cues = track.cues;
-
- for (var i = 0; i < cues.length; ++i) {
- var c = cues[i];
-
- if (c.__external__) {
- c.__audio__ = new Audio(c.__external__);
- }
-
- c.onenter = onenter;
- c.onexit = onexit;
- }
- };
-
- var loadCues = function (track, video) {
- var xhr = new XMLHttpRequest();
- xhr.onreadystatechange = function () {
- if (xhr.readyState == 4) {
- switch (xhr.status) {
- case 200:
- case 0: // for local files
- var cues = TextTrackParser.read(xhr);
-
- if (cues) {
- for (var i = 0; i < cues.length; ++i) {
- track.track.addCue(cues[i]);
- }
-
- track.track.mode = track['default'] ? TextTrack.SHOWING : TextTrack.DISABLED; // .default causes an error in IE
- initCues(track.track, video);
- }
-
- break;
- }
- }
- };
-
- xhr.open('GET', track.src, true);
- xhr.send(null);
- };
-
- // Sets up control buttons and caption/description display areas
- //
- var createVDControls = function (video) {
- var paused = video.paused;
-
- var e = document.createElement('div');
- e.className = 'vd-controls';
- video.__controls__ = video.parentNode.appendChild(e);
-
- var toggleButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
- toggleButton.appendChild(document.createTextNode(''));
- toggleButton.accessKey = 'p';
- toggleButton.onclick = function () {
- if (paused) {
- this.__update__(paused = false);
- video.play();
- }
- else {
- this.__update__(paused = true);
- video.pause();
- }
- };
- toggleButton.__update__ = function () {
- this.firstChild.nodeValue = paused ? TEXT_RESOURCES.playLabel : TEXT_RESOURCES.pauseLabel;
- };
- toggleButton.__update__();
-
- var stopButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
- stopButton.appendChild(document.createTextNode(TEXT_RESOURCES.stopLabel));
- stopButton.accessKey = 's';
- stopButton.onclick = function () {
- video.currentTime = 0;
- video.play();
- video.pause();
- toggleButton.__update__(paused = true);
- };
-
- var backButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
- backButton.appendChild(document.createTextNode(TEXT_RESOURCES.backLabel));
- backButton.accessKey = 'b';
- backButton.onclick = function () {
- video.currentTime -= 10;
- video.play();
- toggleButton.__update__(paused = false);
- };
-
- var skipButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
- skipButton.appendChild(document.createTextNode(TEXT_RESOURCES.skipLabel));
- skipButton.accessKey = 'f';
- skipButton.onclick = function () {
- video.currentTime += 10;
- video.play();
- toggleButton.__update__(paused = false);
- };
-
- var volDnButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
- volDnButton.appendChild(document.createTextNode(TEXT_RESOURCES.volDnLabel));
- volDnButton.accessKey = 'n';
- volDnButton.onclick = function () {
- video.volume -= .1;
- };
-
- var volUpButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
- volUpButton.appendChild(document.createTextNode(TEXT_RESOURCES.volUpLabel));
- volUpButton.accessKey = 'u';
- volUpButton.onclick = function () {
- video.volume += .1;
- };
-
- var formatTime = function (t) {
- var m = parseInt(t / 60);
- var s = parseInt(t % 60);
- return TEXT_RESOURCES.timeFormat.replace('%m', m).replace('%s', s);
- };
-
- var timeDisplay = e.appendChild(document.createElement('div')).appendChild(document.createElement('span'));
- timeDisplay.appendChild(document.createTextNode(formatTime(0)));
-
- video.addEventListener('timeupdate', function (e) {
- timeDisplay.firstChild.nodeValue = formatTime(e.target.currentTime);
- }, false);
-
- video.addEventListener('ended', function (e) {
- toggleButton.__update__(paused = true);
- }, false);
-
- video.addEventListener('playing', function (e) {
- toggleButton.disabled = false;
- stopButton.disabled = false;
- backButton.disabled = false;
- skipButton.disabled = false;
- }, false);
-
- video.addEventListener('pause', function (e) {
- if (paused) { // paused by user (not for extended descriptions)
- return;
- }
- toggleButton.disabled = true;
- stopButton.disabled = true;
- backButton.disabled = true;
- skipButton.disabled = true;
- }, false);
- };
-
- var createVDDisplays = function (video) {
- var e1 = document.createElement('div');
- e1.className = 'vd-descriptions';
- e1.appendChild(document.createElement('span'));
- video.__descriptions__ = video.parentNode.appendChild(e1);
-
- var e2 = document.createElement('div');
- e2.className = 'vd-captions';
- e2.appendChild(document.createElement('span'));
- video.__captions__ = video.parentNode.appendChild(e2);
-
- var e1opt = document.createElement('div');
- e1opt.className = 'vd-descriptions-config';
- var l1 = document.createElement('label');
- var c1 = document.createElement('input');
- c1.type = 'checkbox';
- c1.onclick = function () {
- if (this.checked) {
- video.__descriptions__.className = [video.__descriptions__.className, 'vd-show'].join(' ');
- }
- else {
- video.__descriptions__.className = video.__descriptions__.className.replace(/\bvd-show\b/g, '');
- }
- };
- l1.appendChild(c1);
- l1.appendChild(document.createTextNode(TEXT_RESOURCES.showTextLabel));
- e1opt.appendChild(l1);
- video.parentNode.appendChild(e1opt);
- }
-
- var fixVideoElement = function (video) {
- var container = document.createElement('div');
- container.className = 'vd-container';
- container.appendChild(video.parentNode.replaceChild(container, video));
- createVDControls(video);
- createVDDisplays(video);
- };
-
- var videoElems = document.getElementsByTagName('video');
-
- for (var i = 0; i < videoElems.length; ++i) {
- var v = videoElems[i];
- fixVideoElement(v);
- var trackElems = v.getElementsByTagName('track');
-
- for (var j = 0; j < trackElems.length; ++j) {
- var t = trackElems[j];
-
- if (t.kind == 'descriptions' || t.kind == 'captions' || t.kind == 'metadata' && (t.dataset.kind == 'descriptions' || t.dataset.kind == 'captions')) {
- t.track.__kind__ = t.dataset.kind || t.kind;
- loadCues(t, v);
- }
- }
- }
-})();
-
+/*******************************************************************************
+ * Copyright (c) 2009, 2015 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+//
+// Plays video descriptions (including extended video descriptions and external audio fragments) on the draft HTML5 spec
+//
+(function () {
+ var TEXT_RESOURCES = { playLabel: '\u518d\u751f', pauseLabel: '\u4e00\u6642\u505c\u6b62', stopLabel: '\u505c\u6b62', skipLabel: '10\u79d2\u9032\u3080', backLabel: '10\u79d2\u623b\u308b', volUpLabel: '\u97f3\u91cf\u5927', volDnLabel: '\u97f3\u91cf\u5c0f', timeFormat: '%m\u5206%s\u79d2', showTextLabel: '\u30c6\u30ad\u30b9\u30c8\u3092\u8868\u793a' };
+// var TEXT_RESOURCES = { playLabel: 'Play', pauseLabel: 'Pause', stopLabel: 'Stop', skipLabel: 'Skip 10 s', backLabel: 'Back 10 s', volUpLabel: 'Vol Up', volDnLabel: 'Vol Down', timeFormat: '%m m %s s', showTextLabel: 'Show Text' }; // English
+ var USER_AGENTS_RE = /MSIE|AppleWebKit/;
+ var FORMAT_REPLACE = { MSIE: 'm4a', AppleWebKit: 'm4a', _: 'oga' }; // formats for .* external audio resources (e.g., 'foo.*' is replaced with 'foo.m4a' on MSIE)
+
+ // Ad-hoc codes to bridge the gap between the HTML5 spec and browser implementations
+ //
+ var __track__ = function (e) {
+ return (e.__track__ || e.track);
+ };
+
+ // Parses external text track resources
+ //
+ var TextTrackParser = [];
+
+ TextTrackParser.read = function (xhr) {
+ for (var i = 0; i < this.length; ++i) {
+ var r = this[i];
+ if (r.isReadable(xhr)) {
+ return r.readCues(xhr);
+ }
+ }
+
+ return null;
+ };
+
+ TextTrackParser.register = function (name, isReadable, readCues) {
+ this.push({ name: name, isReadable: isReadable, readCues: readCues });
+ };
+
+ // TTML (ignores layout and styles)
+ //
+ (function () {
+ var TTML_NAMESPACE = 'http://www.w3.org/ns/ttml';
+ var XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
+ var TVD_NAMESPACE = 'http://www.eclipse.org/actf/ai/tvd';
+
+ var frameRate = 30;
+ var subFrameRate = 1;
+
+ var timeToSecond = function (exp) {
+ if (!exp) return null;
+ var v = exp.match(/^(\d{2,}):(\d{2}):(\d{2})(?:\.(\d+)|:(\d{2})(?:\.(\d+))?)?$/);
+ var h = v[1] * 60 * 60;
+ var m = v[2] * 60;
+ var s = parseFloat(v[3] + '.' + (v[4] || 0));
+ var f = parseInt(v[5] || 0) / frameRate;
+ var u = parseInt(v[6] || 0) / frameRate / subFrameRate;
+ return h + m + s + f + u;
+ };
+
+ var wildcardToFormat = function (url) {
+ if (!url) return null;
+ var v = navigator.userAgent.match(USER_AGENTS_RE) || ['_'];
+ var f = FORMAT_REPLACE[v[0]];
+ return url.replace('*', f);
+ };
+
+ var isTTML = function (xhr) {
+ var xml = xhr.responseXML;
+ if (!xml) return false;
+ var tts = xml.getElementsByTagName('tt'); // xml.getElementsByTagNameNS(TTML_NAMESPACE, 'tt'); // for IE
+ return tts.length == 1;
+ };
+
+ var readCues = function (xhr) {
+ var xml = xhr.responseXML;
+ var ps = xml.getElementsByTagName('p'); // xml.getElementsByTagNameNS(TTML_NAMESPACE, 'p'); // for IE
+ var cues = [];
+
+ for (var i = 0; i < ps.length; ++i) {
+ var p = ps[i];
+// var id = p.getAttribute('xml:id'); // p.getAttributeNS(XML_NAMESPACE, 'id'); // for IE
+ var begin = timeToSecond(p.getAttribute('begin'));
+ var end = timeToSecond(p.getAttribute('end'));
+ var dur = timeToSecond(p.getAttribute('dur'));
+ var text = p.textContent || p.firstChild.nodeValue;
+ var extended = p.getAttribute('tvd:extended') == 'true'; // p.getAttributeNS(TVD_NAMESPACE, 'extended') == 'true'; // for IE
+ var external = wildcardToFormat(p.getAttribute('tvd:external')); // p.getAttributeNS(TVD_NAMESPACE, 'external'); // for IE
+ end = end || (begin + (extended ? 0 : dur));
+ dur = dur || (end - begin);
+ var cue = new TextTrackCue(begin, end, text);
+ cue.pauseOnExit = extended;
+ cue.__duration__ = dur;
+ cue.__external__ = external;
+ cues.push(cue);
+ }
+
+ return cues;
+ };
+
+ TextTrackParser.register('TTML', isTTML, readCues);
+ })();
+
+ // WebVTT (ignores layout and styles)
+ //
+ (function () {
+ var timeToSecond = function (exp) {
+ if (!exp) return null;
+ var v = exp.match(/^(?:(\d{2,}):)?(\d{2}):(\d{2}\.\d{3})$/);
+ var h = (v[1] || 0) * 60 * 60;
+ var m = v[2] * 60;
+ var s = parseFloat(v[3]);
+ return h + m + s;
+ };
+
+ var wildcardToFormat = function (url) {
+ if (!url) return null;
+ var v = navigator.userAgent.match(USER_AGENTS_RE) || ['_'];
+ var f = FORMAT_REPLACE[v[0]];
+ return url.replace('*', f);
+ };
+
+ var isWebVTT = function (xhr) {
+ var txt = xhr.responseText;
+ return txt.match(/^WEBVTT\b/);
+ };
+
+ var readCues = function (xhr) {
+ var txt = xhr.responseText.replace(/\r\n|\r/g, '\n');
+ var elems = txt.split(/\n{2,}/);
+ var cues = [];
+
+ for (var i = 0; i < elems.length; ++i) {
+ var e = elems[i];
+ var m = e.match(/^(?:(\w+)\n)?((?:\d{2,})?:\d{2}:\d{2}\.\d{3})[ \t]+-->[ \t]+((?:\d{2,})?:\d{2}:\d{2}\.\d{3})(?:[ \t]+([^\n]+))?\n([\w\W]+)$/m);
+
+ if (m) {
+// var id = m[1] || '';
+ var begin = timeToSecond(m[2]);
+ var end = timeToSecond(m[3]);
+ var settings = m[4] || '';
+ var extended = settings.match(/\bextended\b/);
+ var text = m[5];
+ var m1 = settings.match(/\bduration=((?:\d{2,}:)?\d{2}:\d{2}\.\d{3})/);
+ var dur = m1 ? timeToSecond(m1[1]) : 0;
+ var m2 = settings.match(/\bexternal=([^,]+)/);
+ var external = wildcardToFormat(m2 ? m2[1] : '');
+ end = end || (begin + (extended ? 0 : dur));
+ dur = dur || (end - begin);
+ var cue = new TextTrackCue(begin, end, text);
+ cue.pauseOnExit = extended;
+ cue.__duration__ = dur;
+ cue.__external__ = external;
+ cues.push(cue);
+ }
+ }
+
+ return cues;
+ };
+
+ TextTrackParser.register('WebVTT', isWebVTT, readCues);
+ })();
+
+ // Shows/reads aloud captions/descriptions
+ //
+ var initCues = function (track, video) {
+ var onenter = function (e) {
+ var cue = e.target;
+ if (__track__(cue).__kind__ == 'descriptions') {
+ if (cue.__audio__) { // external resource exists
+ cue.__audio__.currentTime = 0;
+ cue.__audio__.play();
+ video.__descriptions__.setAttribute('aria-live', 'off');
+ showText(cue.text, video.__descriptions__);
+ }
+ else { // uses screen reader
+ video.__descriptions__.setAttribute('aria-live', 'assertive');
+ showText(cue.text, video.__descriptions__);
+ }
+ }
+ else if (__track__(cue).__kind__ == 'captions') {
+ showText(cue.text, video.__captions__);
+ }
+ };
+
+ var onexit = function (e) {
+ var cue = e.target;
+ if (__track__(cue).__kind__ == 'descriptions') {
+ var isExtended = cue.pauseOnExit && video.paused;
+
+ if (isExtended) {
+ if (cue.__audio__) {
+ if (cue.__audio__.ended) {
+ showText('', video.__descriptions__);
+ video.play();
+ }
+ else {
+ cue.__audio__.addEventListener('ended', function () {
+ showText('', video.__descriptions__);
+ video.play();
+ }, false);
+ }
+ }
+ else {
+ if (cue.endTime - cue.startTime >= cue.__duration__) {
+ showText('', video.__descriptions__);
+ video.play();
+ }
+ else {
+ setTimeout(function () {
+ showText('', video.__descriptions__);
+ video.play();
+ }, (cue.__duration__ - cue.endTime + cue.startTime) * 1000);
+ }
+ }
+ }
+ else {
+ if (cue.__audio__) {
+ cue.__audio__.pause();
+ showText('', video.__descriptions__);
+ }
+ else {
+ showText('', video.__descriptions__);
+ }
+ }
+ }
+ else if (__track__(cue).__kind__ == 'captions') {
+ showText('', video.__captions__);
+ }
+ };
+
+ var showText = function (text, container) {
+ var oldText = container.firstChild;
+ var newText = document.createElement('span');
+ newText.appendChild(document.createTextNode(text));
+ container.replaceChild(newText, oldText);
+ };
+
+ var cues = track.cues;
+
+ for (var i = 0; i < cues.length; ++i) {
+ var c = cues[i];
+
+ if (c.__external__) {
+ c.__audio__ = new Audio(c.__external__);
+ }
+
+ c.onenter = onenter;
+ c.onexit = onexit;
+ }
+ };
+
+ var loadCues = function (track, video) {
+ var xhr = new XMLHttpRequest();
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState == 4) {
+ switch (xhr.status) {
+ case 200:
+ case 0: // for local files
+ var cues = TextTrackParser.read(xhr);
+
+ if (cues) {
+ var t = __track__(track);
+
+ for (var i = 0; i < cues.length; ++i) {
+ t.addCue(cues[i]);
+ }
+
+ t.mode = track['default'] ? TextTrack.SHOWING : TextTrack.DISABLED; // .default causes an error in IE
+ initCues(t, video);
+ }
+
+ break;
+ }
+ }
+ };
+
+ xhr.open('GET', track.src, true);
+ xhr.send(null);
+ };
+
+ // Sets up control buttons and caption/description display areas
+ //
+ var createVDControls = function (video) {
+ var paused = video.paused;
+
+ var e = document.createElement('div');
+ e.className = 'vd-controls';
+ video.__controls__ = video.parentNode.appendChild(e);
+
+ var toggleButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
+ toggleButton.appendChild(document.createTextNode(''));
+ toggleButton.accessKey = 'p';
+ toggleButton.onclick = function () {
+ if (paused) {
+ this.__update__(paused = false);
+ video.play();
+ }
+ else {
+ this.__update__(paused = true);
+ video.pause();
+ }
+ };
+ toggleButton.__update__ = function () {
+ this.firstChild.nodeValue = paused ? TEXT_RESOURCES.playLabel : TEXT_RESOURCES.pauseLabel;
+ };
+ toggleButton.__update__();
+
+ var stopButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
+ stopButton.appendChild(document.createTextNode(TEXT_RESOURCES.stopLabel));
+ stopButton.accessKey = 's';
+ stopButton.onclick = function () {
+ video.currentTime = 0;
+ video.play();
+ video.pause();
+ toggleButton.__update__(paused = true);
+ };
+
+ var backButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
+ backButton.appendChild(document.createTextNode(TEXT_RESOURCES.backLabel));
+ backButton.accessKey = 'b';
+ backButton.onclick = function () {
+ video.currentTime -= 10;
+ video.play();
+ toggleButton.__update__(paused = false);
+ };
+
+ var skipButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
+ skipButton.appendChild(document.createTextNode(TEXT_RESOURCES.skipLabel));
+ skipButton.accessKey = 'f';
+ skipButton.onclick = function () {
+ video.currentTime += 10;
+ video.play();
+ toggleButton.__update__(paused = false);
+ };
+
+ var volDnButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
+ volDnButton.appendChild(document.createTextNode(TEXT_RESOURCES.volDnLabel));
+ volDnButton.accessKey = 'n';
+ volDnButton.onclick = function () {
+ video.volume -= .1;
+ };
+
+ var volUpButton = e.appendChild(document.createElement('div')).appendChild(document.createElement('button'));
+ volUpButton.appendChild(document.createTextNode(TEXT_RESOURCES.volUpLabel));
+ volUpButton.accessKey = 'u';
+ volUpButton.onclick = function () {
+ video.volume += .1;
+ };
+
+ var formatTime = function (t) {
+ var m = parseInt(t / 60);
+ var s = parseInt(t % 60);
+ return TEXT_RESOURCES.timeFormat.replace('%m', m).replace('%s', s);
+ };
+
+ var timeDisplay = e.appendChild(document.createElement('div')).appendChild(document.createElement('span'));
+ timeDisplay.appendChild(document.createTextNode(formatTime(0)));
+
+ video.addEventListener('timeupdate', function (e) {
+ timeDisplay.firstChild.nodeValue = formatTime(e.target.currentTime);
+ }, false);
+
+ video.addEventListener('ended', function (e) {
+ toggleButton.__update__(paused = true);
+ }, false);
+
+ video.addEventListener('play', function (e) {
+ toggleButton.disabled = false;
+ stopButton.disabled = false;
+ backButton.disabled = false;
+ skipButton.disabled = false;
+ }, false);
+
+ video.addEventListener('pause', function (e) {
+ if (paused) { // paused by user (not for extended descriptions)
+ return;
+ }
+ toggleButton.disabled = true;
+ stopButton.disabled = true;
+ backButton.disabled = true;
+ skipButton.disabled = true;
+ }, false);
+ };
+
+ var createVDDisplays = function (video) {
+ var e1 = document.createElement('div');
+ e1.className = 'vd-descriptions';
+ e1.appendChild(document.createElement('span'));
+ video.__descriptions__ = video.parentNode.appendChild(e1);
+
+ var e2 = document.createElement('div');
+ e2.className = 'vd-captions';
+ e2.appendChild(document.createElement('span'));
+ video.__captions__ = video.parentNode.appendChild(e2);
+
+ var e1opt = document.createElement('div');
+ e1opt.className = 'vd-descriptions-config';
+ var l1 = document.createElement('label');
+ var c1 = document.createElement('input');
+ c1.type = 'checkbox';
+ c1.onclick = function () {
+ if (this.checked) {
+ video.__descriptions__.className = [video.__descriptions__.className, 'vd-show'].join(' ');
+ }
+ else {
+ video.__descriptions__.className = video.__descriptions__.className.replace(/\bvd-show\b/g, '');
+ }
+ };
+ l1.appendChild(c1);
+ l1.appendChild(document.createTextNode(TEXT_RESOURCES.showTextLabel));
+ e1opt.appendChild(l1);
+ video.parentNode.appendChild(e1opt);
+ }
+
+ var fixVideoElement = function (video) {
+ var container = document.createElement('div');
+ container.className = 'vd-container';
+ container.appendChild(video.parentNode.replaceChild(container, video));
+ createVDControls(video);
+ createVDDisplays(video);
+ };
+
+ var videoElems = document.getElementsByTagName('video');
+
+ for (var i = 0; i < videoElems.length; ++i) {
+ var v = videoElems[i];
+ fixVideoElement(v);
+ var trackElems = v.getElementsByTagName('track');
+
+ for (var j = 0; j < trackElems.length; ++j) {
+ var t = trackElems[j];
+
+ if (t.kind == 'descriptions' || t.kind == 'captions' || t.kind == 'metadata' && (t.dataset.kind == 'descriptions' || t.dataset.kind == 'captions')) {
+ __track__(t).__kind__ = (t.dataset.kind || t.kind);
+ loadCues(t, v);
+ }
+ }
+ }
+})();
+