3 exports.__esModule = true;
5 var _textTrackCueList = require('./text-track-cue-list');
7 var _textTrackCueList2 = _interopRequireDefault(_textTrackCueList);
9 var _fn = require('../utils/fn.js');
11 var Fn = _interopRequireWildcard(_fn);
13 var _trackEnums = require('./track-enums');
15 var _log = require('../utils/log.js');
17 var _log2 = _interopRequireDefault(_log);
19 var _window = require('global/window');
21 var _window2 = _interopRequireDefault(_window);
23 var _track = require('./track.js');
25 var _track2 = _interopRequireDefault(_track);
27 var _url = require('../utils/url.js');
29 var _xhr = require('xhr');
31 var _xhr2 = _interopRequireDefault(_xhr);
33 var _mergeOptions = require('../utils/merge-options');
35 var _mergeOptions2 = _interopRequireDefault(_mergeOptions);
37 var _browser = require('../utils/browser.js');
39 var browser = _interopRequireWildcard(_browser);
41 function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
43 function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
45 function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
47 function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
49 function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
55 * Takes a webvtt file contents and parses it into cues
57 * @param {string} srcContent
58 * webVTT file contents
60 * @param {TextTrack} track
61 * TextTrack to add cues to. Cues come from the srcContent.
65 var parseCues = function parseCues(srcContent, track) {
66 var parser = new _window2['default'].WebVTT.Parser(_window2['default'], _window2['default'].vttjs, _window2['default'].WebVTT.StringDecoder());
69 parser.oncue = function (cue) {
73 parser.onparsingerror = function (error) {
77 parser.onflush = function () {
84 parser.parse(srcContent);
85 if (errors.length > 0) {
86 if (_window2['default'].console && _window2['default'].console.groupCollapsed) {
87 _window2['default'].console.groupCollapsed('Text Track parsing errors for ' + track.src);
89 errors.forEach(function (error) {
90 return _log2['default'].error(error);
92 if (_window2['default'].console && _window2['default'].console.groupEnd) {
93 _window2['default'].console.groupEnd();
101 * Load a `TextTrack` from a specifed url.
103 * @param {string} src
104 * Url to load track from.
106 * @param {TextTrack} track
107 * Track to add cues to. Comes from the content at the end of `url`.
111 var loadTrack = function loadTrack(src, track) {
115 var crossOrigin = (0, _url.isCrossOrigin)(src);
118 opts.cors = crossOrigin;
121 (0, _xhr2['default'])(opts, Fn.bind(this, function (err, response, responseBody) {
123 return _log2['default'].error(err, response);
126 track.loaded_ = true;
128 // Make sure that vttjs has loaded, otherwise, wait till it finished loading
129 // NOTE: this is only used for the alt/video.novtt.js build
130 if (typeof _window2['default'].WebVTT !== 'function') {
132 var loadHandler = function loadHandler() {
133 return parseCues(responseBody, track);
136 track.tech_.on('vttjsloaded', loadHandler);
137 track.tech_.on('vttjserror', function () {
138 _log2['default'].error('vttjs failed to load, stopping trying to process ' + track.src);
139 track.tech_.off('vttjsloaded', loadHandler);
143 parseCues(responseBody, track);
149 * A representation of a single `TextTrack`.
151 * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack}
155 var TextTrack = function (_Track) {
156 _inherits(TextTrack, _Track);
159 * Create an instance of this class.
161 * @param {Object} options={}
162 * Object of option names and values
164 * @param {Tech} options.tech
165 * A reference to the tech that owns this TextTrack.
167 * @param {TextTrack~Kind} [options.kind='subtitles']
168 * A valid text track kind.
170 * @param {TextTrack~Mode} [options.mode='disabled']
171 * A valid text track mode.
173 * @param {string} [options.id='vjs_track_' + Guid.newGUID()]
174 * A unique id for this TextTrack.
176 * @param {string} [options.label='']
177 * The menu label for this track.
179 * @param {string} [options.language='']
180 * A valid two character language code.
182 * @param {string} [options.srclang='']
183 * A valid two character language code. An alternative, but deprioritized
184 * vesion of `options.language`
186 * @param {string} [options.src]
187 * A url to TextTrack cues.
189 * @param {boolean} [options.default]
190 * If this track should default to on or off.
192 function TextTrack() {
195 var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
197 _classCallCheck(this, TextTrack);
200 throw new Error('A tech was not provided.');
203 var settings = (0, _mergeOptions2['default'])(options, {
204 kind: _trackEnums.TextTrackKind[options.kind] || 'subtitles',
205 language: options.language || options.srclang || ''
207 var mode = _trackEnums.TextTrackMode[settings.mode] || 'disabled';
208 var default_ = settings['default'];
210 if (settings.kind === 'metadata' || settings.kind === 'chapters') {
213 // on IE8 this will be a document element
214 // for every other browser this will be a normal object
215 var tt = (_this = _possibleConstructorReturn(this, _Track.call(this, settings)), _this);
217 tt.tech_ = settings.tech;
219 if (browser.IS_IE8) {
220 for (var prop in TextTrack.prototype) {
221 if (prop !== 'constructor') {
222 tt[prop] = TextTrack.prototype[prop];
230 var cues = new _textTrackCueList2['default'](tt.cues_);
231 var activeCues = new _textTrackCueList2['default'](tt.activeCues_);
233 var timeupdateHandler = Fn.bind(tt, function () {
235 // Accessing this.activeCues for the side-effects of updating itself
236 // due to it's nature as a getter function. Do not remove or cues will
238 /* eslint-disable no-unused-expressions */
240 /* eslint-enable no-unused-expressions */
242 this.trigger('cuechange');
247 if (mode !== 'disabled') {
248 tt.tech_.ready(function () {
249 tt.tech_.on('timeupdate', timeupdateHandler);
254 * @member {boolean} default
255 * If this track was set to be on or off by default. Cannot be changed after
260 Object.defineProperty(tt, 'default', {
261 get: function get() {
264 set: function set() {}
268 * @member {string} mode
269 * Set the mode of this TextTrack to a valid {@link TextTrack~Mode}. Will
270 * not be set if setting to an invalid mode.
272 * @fires TextTrack#modechange
274 Object.defineProperty(tt, 'mode', {
275 get: function get() {
278 set: function set(newMode) {
281 if (!_trackEnums.TextTrackMode[newMode]) {
285 if (mode === 'showing') {
286 this.tech_.ready(function () {
287 _this2.tech_.on('timeupdate', timeupdateHandler);
291 * An event that fires when mode changes on this track. This allows
292 * the TextTrackList that holds this track to act accordingly.
294 * > Note: This is not part of the spec!
296 * @event TextTrack#modechange
297 * @type {EventTarget~Event}
299 this.trigger('modechange');
304 * @member {TextTrackCueList} cues
305 * The text track cue list for this TextTrack.
307 Object.defineProperty(tt, 'cues', {
308 get: function get() {
315 set: function set() {}
319 * @member {TextTrackCueList} activeCues
320 * The list text track cues that are currently active for this TextTrack.
322 Object.defineProperty(tt, 'activeCues', {
323 get: function get() {
329 if (this.cues.length === 0) {
333 var ct = this.tech_.currentTime();
336 for (var i = 0, l = this.cues.length; i < l; i++) {
337 var cue = this.cues[i];
339 if (cue.startTime <= ct && cue.endTime >= ct) {
341 } else if (cue.startTime === cue.endTime && cue.startTime <= ct && cue.startTime + 0.5 >= ct) {
348 if (active.length !== this.activeCues_.length) {
351 for (var _i = 0; _i < active.length; _i++) {
352 if (this.activeCues_.indexOf(active[_i]) === -1) {
358 this.activeCues_ = active;
359 activeCues.setCues_(this.activeCues_);
363 set: function set() {}
367 tt.src = settings.src;
368 loadTrack(settings.src, tt);
373 return _ret = tt, _possibleConstructorReturn(_this, _ret);
377 * Add a cue to the internal list of cues.
379 * @param {TextTrack~Cue} cue
380 * The cue to add to our internal list
384 TextTrack.prototype.addCue = function addCue(originalCue) {
385 var cue = originalCue;
387 if (_window2['default'].vttjs && !(originalCue instanceof _window2['default'].vttjs.VTTCue)) {
388 cue = new _window2['default'].vttjs.VTTCue(originalCue.startTime, originalCue.endTime, originalCue.text);
390 for (var prop in originalCue) {
391 if (!(prop in cue)) {
392 cue[prop] = originalCue[prop];
396 // make sure that `id` is copied over
397 cue.id = originalCue.id;
398 cue.originalCue_ = originalCue;
401 var tracks = this.tech_.textTracks();
404 for (var i = 0; i < tracks.length; i++) {
405 if (tracks[i] !== this) {
406 tracks[i].removeCue(cue);
411 this.cues_.push(cue);
412 this.cues.setCues_(this.cues_);
416 * Remove a cue from our internal list
418 * @param {TextTrack~Cue} removeCue
419 * The cue to remove from our internal list
423 TextTrack.prototype.removeCue = function removeCue(_removeCue) {
424 var i = this.cues_.length;
427 var cue = this.cues_[i];
429 if (cue === _removeCue || cue.originalCue_ && cue.originalCue_ === _removeCue) {
430 this.cues_.splice(i, 1);
431 this.cues.setCues_(this.cues_);
438 }(_track2['default']);
441 * cuechange - One or more cues in the track have become active or stopped being active.
445 TextTrack.prototype.allowedEvents_ = {
446 cuechange: 'cuechange'
449 exports['default'] = TextTrack;