2016-08-03 21:27:03 +02:00
|
|
|
/* eslint-env qunit */
|
2015-04-14 22:08:32 +02:00
|
|
|
import ChaptersButton from '../../../src/js/control-bar/text-track-controls/chapters-button.js';
|
2016-03-25 20:16:56 +02:00
|
|
|
import DescriptionsButton from '../../../src/js/control-bar/text-track-controls/descriptions-button.js';
|
2015-04-14 22:08:32 +02:00
|
|
|
import SubtitlesButton from '../../../src/js/control-bar/text-track-controls/subtitles-button.js';
|
|
|
|
import CaptionsButton from '../../../src/js/control-bar/text-track-controls/captions-button.js';
|
2017-03-02 22:23:41 +02:00
|
|
|
import SubsCapsButton from '../../../src/js/control-bar/text-track-controls/subs-caps-button.js';
|
2015-04-14 22:08:32 +02:00
|
|
|
|
2015-11-24 09:39:58 +02:00
|
|
|
import TextTrack from '../../../src/js/tracks/text-track.js';
|
2015-04-14 22:08:32 +02:00
|
|
|
import TextTrackDisplay from '../../../src/js/tracks/text-track-display.js';
|
|
|
|
import Html5 from '../../../src/js/tech/html5.js';
|
|
|
|
import Tech from '../../../src/js/tech/tech.js';
|
2015-02-14 01:18:07 +02:00
|
|
|
|
2015-05-04 01:12:38 +02:00
|
|
|
import * as browser from '../../../src/js/utils/browser.js';
|
2015-03-26 06:43:41 +02:00
|
|
|
import TestHelpers from '../test-helpers.js';
|
|
|
|
import document from 'global/document';
|
2016-08-03 21:27:03 +02:00
|
|
|
import sinon from 'sinon';
|
2015-03-26 06:43:41 +02:00
|
|
|
|
2017-03-02 22:22:59 +02:00
|
|
|
QUnit.module('Text Tracks', {
|
2016-08-12 19:51:31 +02:00
|
|
|
beforeEach(assert) {
|
2015-12-08 18:24:51 +02:00
|
|
|
this.clock = sinon.useFakeTimers();
|
|
|
|
},
|
2016-08-12 19:51:31 +02:00
|
|
|
afterEach(assert) {
|
2015-12-08 18:24:51 +02:00
|
|
|
this.clock.restore();
|
|
|
|
}
|
|
|
|
});
|
2015-03-11 03:01:11 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should place title list item into ul', function(assert) {
|
2016-08-03 21:27:03 +02:00
|
|
|
const player = TestHelpers.makePlayer();
|
|
|
|
const chaptersButton = new ChaptersButton(player);
|
2015-02-14 01:18:07 +02:00
|
|
|
|
2016-08-03 21:27:03 +02:00
|
|
|
const menuContentElement = chaptersButton.el().getElementsByTagName('UL')[0];
|
|
|
|
const titleElement = menuContentElement.children[0];
|
2015-02-14 01:18:07 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(titleElement.innerHTML === 'Chapters', 'title element placed in ul');
|
2015-02-14 01:18:07 +02:00
|
|
|
|
|
|
|
player.dispose();
|
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('Player track methods call the tech', function(assert) {
|
2016-08-03 21:27:03 +02:00
|
|
|
const player = TestHelpers.makePlayer();
|
2016-03-07 21:54:32 +02:00
|
|
|
let calls = 0;
|
2015-02-14 01:18:07 +02:00
|
|
|
|
2015-09-15 02:45:14 +02:00
|
|
|
player.tech_.textTracks = function() {
|
2015-02-14 01:18:07 +02:00
|
|
|
calls++;
|
|
|
|
};
|
2015-09-15 02:45:14 +02:00
|
|
|
player.tech_.addTextTrack = function() {
|
2015-02-14 01:18:07 +02:00
|
|
|
calls++;
|
|
|
|
};
|
|
|
|
|
|
|
|
player.addTextTrack();
|
|
|
|
player.textTracks();
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(calls, 2, 'both textTrack and addTextTrack defer to the tech');
|
2015-08-25 02:46:54 +02:00
|
|
|
|
|
|
|
player.dispose();
|
2015-02-14 01:18:07 +02:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('TextTrackDisplay initializes tracks on player ready', function(assert) {
|
2016-03-07 21:54:32 +02:00
|
|
|
let calls = 0;
|
2016-08-03 21:27:03 +02:00
|
|
|
/* eslint-disable no-unused-vars */
|
|
|
|
const ttd = new TextTrackDisplay({
|
2016-03-07 21:54:32 +02:00
|
|
|
on() {},
|
|
|
|
addTextTracks() {
|
|
|
|
calls--;
|
|
|
|
},
|
|
|
|
getChild() {
|
|
|
|
calls--;
|
|
|
|
},
|
|
|
|
ready() {
|
|
|
|
calls++;
|
|
|
|
}
|
|
|
|
}, {});
|
2016-08-03 21:27:03 +02:00
|
|
|
/* eslint-enable no-unused-vars */
|
2015-02-14 01:18:07 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(calls, 1, 'only a player.ready call was made');
|
2015-02-14 01:18:07 +02:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('listen to remove and add track events in native text tracks', function(assert) {
|
2016-08-03 21:27:03 +02:00
|
|
|
const oldTestVid = Html5.TEST_VID;
|
|
|
|
const oldTextTracks = Html5.prototype.textTracks;
|
|
|
|
const events = {};
|
2016-03-07 21:54:32 +02:00
|
|
|
|
2015-03-26 06:43:41 +02:00
|
|
|
Html5.prototype.textTracks = function() {
|
2015-02-14 01:18:07 +02:00
|
|
|
return {
|
2018-01-30 20:26:21 +02:00
|
|
|
removeEventListener() {},
|
2016-03-07 21:54:32 +02:00
|
|
|
addEventListener(type, handler) {
|
2015-02-14 01:18:07 +02:00
|
|
|
events[type] = true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2015-05-04 01:12:38 +02:00
|
|
|
Html5.TEST_VID = {
|
2015-02-14 01:18:07 +02:00
|
|
|
textTracks: []
|
|
|
|
};
|
|
|
|
|
2016-08-03 21:27:03 +02:00
|
|
|
const player = {
|
2015-02-14 01:18:07 +02:00
|
|
|
// Function.prototype is a built-in no-op function.
|
2016-03-07 21:54:32 +02:00
|
|
|
controls() {},
|
|
|
|
ready() {},
|
|
|
|
options() {
|
2015-02-14 01:18:07 +02:00
|
|
|
return {};
|
|
|
|
},
|
2016-03-07 21:54:32 +02:00
|
|
|
addChild() {},
|
|
|
|
id() {},
|
|
|
|
el() {
|
2015-02-14 01:18:07 +02:00
|
|
|
return {
|
2016-03-07 21:54:32 +02:00
|
|
|
insertBefore() {},
|
|
|
|
appendChild() {}
|
2015-02-14 01:18:07 +02:00
|
|
|
};
|
|
|
|
}
|
|
|
|
};
|
2016-08-03 21:27:03 +02:00
|
|
|
|
2015-02-14 01:18:07 +02:00
|
|
|
player.player_ = player;
|
2016-08-03 21:27:03 +02:00
|
|
|
player.options_ = {};
|
2015-02-14 01:18:07 +02:00
|
|
|
|
2016-08-03 21:27:03 +02:00
|
|
|
/* eslint-disable no-unused-vars */
|
|
|
|
const html = new Html5({});
|
|
|
|
/* eslint-enable no-unused-vars */
|
2015-02-14 01:18:07 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(events.removetrack, 'removetrack listener was added');
|
|
|
|
assert.ok(events.addtrack, 'addtrack listener was added');
|
2015-02-14 01:18:07 +02:00
|
|
|
|
2015-05-04 01:12:38 +02:00
|
|
|
Html5.TEST_VID = oldTestVid;
|
2015-03-26 06:43:41 +02:00
|
|
|
Html5.prototype.textTracks = oldTextTracks;
|
2018-01-30 20:26:21 +02:00
|
|
|
|
|
|
|
html.dispose();
|
2015-02-14 01:18:07 +02:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('update texttrack buttons on removetrack or addtrack', function(assert) {
|
2016-03-07 21:54:32 +02:00
|
|
|
let update = 0;
|
2016-08-03 21:27:03 +02:00
|
|
|
const events = {};
|
|
|
|
const oldCaptionsUpdate = CaptionsButton.prototype.update;
|
|
|
|
const oldSubsUpdate = SubtitlesButton.prototype.update;
|
|
|
|
const oldDescriptionsUpdate = DescriptionsButton.prototype.update;
|
|
|
|
const oldChaptersUpdate = ChaptersButton.prototype.update;
|
2017-03-02 22:23:41 +02:00
|
|
|
const oldSubsCapsUpdate = SubsCapsButton.prototype.update;
|
2016-08-03 21:27:03 +02:00
|
|
|
|
2015-03-26 06:43:41 +02:00
|
|
|
CaptionsButton.prototype.update = function() {
|
2015-02-14 01:18:07 +02:00
|
|
|
update++;
|
|
|
|
oldCaptionsUpdate.call(this);
|
|
|
|
};
|
2015-03-26 06:43:41 +02:00
|
|
|
SubtitlesButton.prototype.update = function() {
|
2015-02-14 01:18:07 +02:00
|
|
|
update++;
|
|
|
|
oldSubsUpdate.call(this);
|
|
|
|
};
|
2016-03-25 20:16:56 +02:00
|
|
|
DescriptionsButton.prototype.update = function() {
|
|
|
|
update++;
|
|
|
|
oldDescriptionsUpdate.call(this);
|
|
|
|
};
|
2015-03-26 06:43:41 +02:00
|
|
|
ChaptersButton.prototype.update = function() {
|
2015-02-14 01:18:07 +02:00
|
|
|
update++;
|
|
|
|
oldChaptersUpdate.call(this);
|
|
|
|
};
|
2017-03-02 22:23:41 +02:00
|
|
|
SubsCapsButton.prototype.update = function() {
|
|
|
|
update++;
|
|
|
|
oldSubsCapsUpdate.call(this);
|
|
|
|
};
|
2015-02-14 01:18:07 +02:00
|
|
|
|
2016-03-07 21:54:32 +02:00
|
|
|
Tech.prototype.featuresNativeTextTracks = true;
|
2016-08-03 21:27:03 +02:00
|
|
|
|
|
|
|
const oldTextTracks = Tech.prototype.textTracks;
|
|
|
|
|
2015-04-14 22:08:32 +02:00
|
|
|
Tech.prototype.textTracks = function() {
|
2015-02-14 01:18:07 +02:00
|
|
|
return {
|
|
|
|
length: 0,
|
2016-03-07 21:54:32 +02:00
|
|
|
addEventListener(type, handler) {
|
2015-02-14 01:18:07 +02:00
|
|
|
if (!events[type]) {
|
|
|
|
events[type] = [];
|
|
|
|
}
|
|
|
|
events[type].push(handler);
|
2015-08-25 02:46:54 +02:00
|
|
|
},
|
|
|
|
// Requrired in player.dispose()
|
2016-03-07 21:54:32 +02:00
|
|
|
removeEventListener() {}
|
2015-02-14 01:18:07 +02:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2016-08-03 21:27:03 +02:00
|
|
|
const tag = document.createElement('video');
|
|
|
|
const track1 = document.createElement('track');
|
|
|
|
const track2 = document.createElement('track');
|
|
|
|
|
|
|
|
track1.kind = 'captions';
|
|
|
|
track1.label = 'en';
|
|
|
|
track1.language = 'English';
|
|
|
|
track1.src = '#en.vtt';
|
|
|
|
tag.appendChild(track1);
|
|
|
|
|
|
|
|
track2.kind = 'captions';
|
|
|
|
track2.label = 'es';
|
|
|
|
track2.language = 'Spanish';
|
|
|
|
track2.src = '#es.vtt';
|
|
|
|
tag.appendChild(track2);
|
|
|
|
|
2017-03-02 22:23:41 +02:00
|
|
|
const player = TestHelpers.makePlayer({
|
|
|
|
controlBar: {
|
|
|
|
captionsButton: true,
|
|
|
|
subtitlesButton: true
|
|
|
|
}
|
|
|
|
}, tag);
|
2015-02-14 01:18:07 +02:00
|
|
|
|
|
|
|
player.player_ = player;
|
|
|
|
|
2017-03-02 22:23:41 +02:00
|
|
|
assert.equal(update, 5, 'update was called on the five buttons during init');
|
2015-02-14 01:18:07 +02:00
|
|
|
|
2016-08-03 21:27:03 +02:00
|
|
|
for (let i = 0; i < events.removetrack.length; i++) {
|
2016-03-07 21:54:32 +02:00
|
|
|
events.removetrack[i]();
|
2015-02-14 01:18:07 +02:00
|
|
|
}
|
|
|
|
|
2017-03-02 22:23:41 +02:00
|
|
|
assert.equal(update, 10, 'update was called on the five buttons for remove track');
|
2015-02-14 01:18:07 +02:00
|
|
|
|
2016-08-03 21:27:03 +02:00
|
|
|
for (let i = 0; i < events.addtrack.length; i++) {
|
2016-03-07 21:54:32 +02:00
|
|
|
events.addtrack[i]();
|
2015-02-14 01:18:07 +02:00
|
|
|
}
|
|
|
|
|
2017-03-02 22:23:41 +02:00
|
|
|
assert.equal(update, 15, 'update was called on the five buttons for remove track');
|
2015-02-14 01:18:07 +02:00
|
|
|
|
2015-04-14 22:08:32 +02:00
|
|
|
Tech.prototype.textTracks = oldTextTracks;
|
2016-03-07 21:54:32 +02:00
|
|
|
Tech.prototype.featuresNativeTextTracks = false;
|
2015-03-26 06:43:41 +02:00
|
|
|
CaptionsButton.prototype.update = oldCaptionsUpdate;
|
|
|
|
SubtitlesButton.prototype.update = oldSubsUpdate;
|
|
|
|
ChaptersButton.prototype.update = oldChaptersUpdate;
|
2017-03-02 22:23:41 +02:00
|
|
|
SubsCapsButton.prototype.update = oldSubsCapsUpdate;
|
2015-08-25 02:46:54 +02:00
|
|
|
|
|
|
|
player.dispose();
|
2015-02-14 01:18:07 +02:00
|
|
|
});
|
|
|
|
|
2016-12-02 23:13:33 +02:00
|
|
|
QUnit.test('emulated tracks are always used, except in safari', function(assert) {
|
2016-08-03 21:27:03 +02:00
|
|
|
const oldTestVid = Html5.TEST_VID;
|
2016-12-02 23:13:33 +02:00
|
|
|
const oldIsAnySafari = browser.IS_ANY_SAFARI;
|
2015-02-14 01:18:07 +02:00
|
|
|
|
2015-05-04 01:12:38 +02:00
|
|
|
Html5.TEST_VID = {
|
2016-12-02 23:13:33 +02:00
|
|
|
textTracks: []
|
2015-02-14 01:18:07 +02:00
|
|
|
};
|
|
|
|
|
2016-12-02 23:13:33 +02:00
|
|
|
browser.IS_ANY_SAFARI = false;
|
2015-02-14 01:18:07 +02:00
|
|
|
|
2016-12-02 23:13:33 +02:00
|
|
|
assert.ok(!Html5.supportsNativeTextTracks(), 'Html5 does not support native text tracks, in non-safari');
|
2015-02-14 01:18:07 +02:00
|
|
|
|
2016-12-02 23:13:33 +02:00
|
|
|
browser.IS_ANY_SAFARI = true;
|
2015-02-14 01:18:07 +02:00
|
|
|
|
2016-12-02 23:13:33 +02:00
|
|
|
assert.ok(Html5.supportsNativeTextTracks(), 'Html5 does support native text tracks in safari');
|
2015-02-14 01:18:07 +02:00
|
|
|
|
2015-05-04 01:12:38 +02:00
|
|
|
Html5.TEST_VID = oldTestVid;
|
2016-12-02 23:13:33 +02:00
|
|
|
browser.IS_ANY_SAFARI = oldIsAnySafari;
|
2015-02-14 01:18:07 +02:00
|
|
|
});
|
2015-02-18 00:19:21 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('when switching techs, we should not get a new text track', function(assert) {
|
2016-08-03 21:27:03 +02:00
|
|
|
const player = TestHelpers.makePlayer();
|
2015-02-18 00:19:21 +02:00
|
|
|
|
2015-09-15 02:45:14 +02:00
|
|
|
player.loadTech_('TechFaker');
|
2016-08-03 21:27:03 +02:00
|
|
|
const firstTracks = player.textTracks();
|
2015-02-18 00:19:21 +02:00
|
|
|
|
2015-09-15 02:45:14 +02:00
|
|
|
player.loadTech_('TechFaker');
|
2016-08-03 21:27:03 +02:00
|
|
|
const secondTracks = player.textTracks();
|
2015-02-18 00:19:21 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.ok(firstTracks === secondTracks, 'the tracks are equal');
|
2016-08-25 16:58:42 +02:00
|
|
|
|
|
|
|
player.dispose();
|
2015-02-18 00:19:21 +02:00
|
|
|
});
|
2015-08-03 21:19:36 +02:00
|
|
|
|
|
|
|
if (Html5.supportsNativeTextTracks()) {
|
2016-08-03 21:27:03 +02:00
|
|
|
QUnit.test('listen to native remove and add track events in native text tracks', function(assert) {
|
|
|
|
const done = assert.async();
|
2015-08-03 21:19:36 +02:00
|
|
|
|
2016-08-03 21:27:03 +02:00
|
|
|
const el = document.createElement('video');
|
|
|
|
const html = new Html5({el});
|
|
|
|
const tt = el.textTracks;
|
|
|
|
const emulatedTt = html.textTracks();
|
|
|
|
const track = document.createElement('track');
|
2016-03-07 21:54:32 +02:00
|
|
|
|
2015-08-03 21:19:36 +02:00
|
|
|
el.appendChild(track);
|
|
|
|
|
2016-08-03 21:27:03 +02:00
|
|
|
const addtrack = function() {
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(emulatedTt.length, tt.length, 'we have matching tracks length');
|
|
|
|
assert.equal(emulatedTt.length, 1, 'we have one text track');
|
2015-08-03 21:19:36 +02:00
|
|
|
|
|
|
|
emulatedTt.off('addtrack', addtrack);
|
|
|
|
el.removeChild(track);
|
|
|
|
};
|
2016-03-07 21:54:32 +02:00
|
|
|
|
2015-08-03 21:19:36 +02:00
|
|
|
emulatedTt.on('addtrack', addtrack);
|
|
|
|
emulatedTt.on('removetrack', function() {
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(emulatedTt.length, tt.length, 'we have matching tracks length');
|
|
|
|
assert.equal(emulatedTt.length, 0, 'we have no more text tracks');
|
2018-01-30 20:26:21 +02:00
|
|
|
|
|
|
|
html.dispose();
|
2015-08-03 21:19:36 +02:00
|
|
|
done();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2016-08-03 21:27:03 +02:00
|
|
|
QUnit.test('should have removed tracks on dispose', function(assert) {
|
|
|
|
const done = assert.async();
|
2015-08-03 21:19:36 +02:00
|
|
|
|
2016-08-03 21:27:03 +02:00
|
|
|
const el = document.createElement('video');
|
|
|
|
const html = new Html5({el});
|
|
|
|
const tt = el.textTracks;
|
|
|
|
const emulatedTt = html.textTracks();
|
|
|
|
const track = document.createElement('track');
|
2016-03-07 21:54:32 +02:00
|
|
|
|
2015-08-03 21:19:36 +02:00
|
|
|
el.appendChild(track);
|
|
|
|
|
2016-08-03 21:27:03 +02:00
|
|
|
const addtrack = function() {
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(emulatedTt.length, tt.length, 'we have matching tracks length');
|
|
|
|
assert.equal(emulatedTt.length, 1, 'we have one text track');
|
2015-08-03 21:19:36 +02:00
|
|
|
|
|
|
|
emulatedTt.off('addtrack', addtrack);
|
|
|
|
html.dispose();
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(emulatedTt.length, tt.length, 'we have matching tracks length');
|
|
|
|
assert.equal(emulatedTt.length, 0, 'we have no more text tracks');
|
2015-08-03 21:19:36 +02:00
|
|
|
|
|
|
|
done();
|
|
|
|
};
|
2016-03-07 21:54:32 +02:00
|
|
|
|
2015-08-03 21:19:36 +02:00
|
|
|
emulatedTt.on('addtrack', addtrack);
|
|
|
|
});
|
|
|
|
}
|
2015-11-25 23:00:49 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should check for text track changes when emulating text tracks', function(assert) {
|
2016-08-03 21:27:03 +02:00
|
|
|
const tech = new Tech();
|
2015-11-25 23:00:49 +02:00
|
|
|
let numTextTrackChanges = 0;
|
2016-03-07 21:54:32 +02:00
|
|
|
|
2015-11-25 23:00:49 +02:00
|
|
|
tech.on('texttrackchange', function() {
|
|
|
|
numTextTrackChanges++;
|
|
|
|
});
|
|
|
|
tech.emulateTextTracks();
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(numTextTrackChanges, 1, 'we got a texttrackchange event');
|
2018-01-30 20:26:21 +02:00
|
|
|
|
|
|
|
tech.dispose();
|
2015-11-25 23:00:49 +02:00
|
|
|
});
|
2015-11-24 09:39:58 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('removes cuechange event when text track is hidden for emulated tracks', function(assert) {
|
2016-08-03 21:27:03 +02:00
|
|
|
const player = TestHelpers.makePlayer();
|
|
|
|
const tt = new TextTrack({
|
2015-11-24 09:39:58 +02:00
|
|
|
tech: player.tech_,
|
|
|
|
mode: 'showing'
|
|
|
|
});
|
2016-03-07 21:54:32 +02:00
|
|
|
|
2015-11-24 09:39:58 +02:00
|
|
|
tt.addCue({
|
|
|
|
id: '1',
|
|
|
|
startTime: 2,
|
|
|
|
endTime: 5
|
|
|
|
});
|
2017-01-19 22:16:28 +02:00
|
|
|
player.tech_.textTracks().addTrack(tt);
|
2015-11-24 09:39:58 +02:00
|
|
|
|
|
|
|
let numTextTrackChanges = 0;
|
2016-03-07 21:54:32 +02:00
|
|
|
|
2015-11-24 09:39:58 +02:00
|
|
|
player.tech_.on('texttrackchange', function() {
|
|
|
|
numTextTrackChanges++;
|
|
|
|
});
|
|
|
|
|
|
|
|
tt.mode = 'showing';
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(numTextTrackChanges, 1,
|
2015-11-24 09:39:58 +02:00
|
|
|
'texttrackchange should be called once for mode change');
|
|
|
|
tt.mode = 'showing';
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(numTextTrackChanges, 2,
|
2015-11-24 09:39:58 +02:00
|
|
|
'texttrackchange should be called once for mode change');
|
|
|
|
|
|
|
|
player.tech_.currentTime = function() {
|
|
|
|
return 3;
|
|
|
|
};
|
|
|
|
player.tech_.trigger('timeupdate');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(numTextTrackChanges, 3,
|
2015-11-24 09:39:58 +02:00
|
|
|
'texttrackchange should be triggered once for the cuechange');
|
|
|
|
|
|
|
|
tt.mode = 'hidden';
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(numTextTrackChanges, 4,
|
2015-11-24 09:39:58 +02:00
|
|
|
'texttrackchange should be called once for the mode change');
|
|
|
|
|
|
|
|
player.tech_.currentTime = function() {
|
|
|
|
return 7;
|
|
|
|
};
|
|
|
|
player.tech_.trigger('timeupdate');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(numTextTrackChanges, 4,
|
2015-11-24 09:39:58 +02:00
|
|
|
'texttrackchange should be not be called since mode is hidden');
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2015-11-24 09:39:58 +02:00
|
|
|
});
|
2015-12-08 18:24:51 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should return correct remote text track values', function(assert) {
|
2016-08-03 21:27:03 +02:00
|
|
|
const fixture = document.getElementById('qunit-fixture');
|
|
|
|
const html = `
|
2016-03-07 21:54:32 +02:00
|
|
|
<video id="example_1" class="video-js" autoplay preload="none">
|
|
|
|
<source src="http://google.com" type="video/mp4">
|
|
|
|
<source src="http://google.com" type="video/webm">
|
|
|
|
<track kind="captions" label="label">
|
|
|
|
</video>
|
|
|
|
`;
|
2015-12-08 18:24:51 +02:00
|
|
|
|
|
|
|
fixture.innerHTML += html;
|
2016-08-03 21:27:03 +02:00
|
|
|
const tag = document.getElementById('example_1');
|
|
|
|
const player = TestHelpers.makePlayer({}, tag);
|
2015-12-08 18:24:51 +02:00
|
|
|
|
feat: middleware (#3788)
Add middleware support. Middleware can function as go-between between the player and the tech. For example, it can modify the duration that the tech returns to the player. In addition, middleware allow for supporting custom video sources and types.
Currently, middleware can only intercept timeline methods like duration, currentTime, and setCurrentTime.
For example,
```js
videojs.use('video/foo', {
setSource(src, next) {
next(null, {
src: 'http://example.com/video.mp4',
type: 'video/mp4'
});
}
});
```
Will allow you to set a source with type `video/foo` which will play back `video.mp4`.
This makes setting the source asynchronous, which aligns it with the spec a bit more. Methods like play can still be called synchronously on the player after setting the source and the player will play once the source has loaded.
`sourceOrder` option was removed as well and it will now always use source ordering.
BREAKING CHANGE: setting the source is now asynchronous. `sourceOrder` option removed and made the default.
2017-01-20 00:29:09 +02:00
|
|
|
this.clock.tick(10);
|
2015-12-08 18:24:51 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.remoteTextTracks().length, 1, 'add text track via html');
|
|
|
|
assert.equal(player.remoteTextTrackEls().length, 1, 'add html track element via html');
|
2015-12-08 18:24:51 +02:00
|
|
|
|
2016-08-03 21:27:03 +02:00
|
|
|
const htmlTrackElement = player.addRemoteTextTrack({
|
2015-12-08 18:24:51 +02:00
|
|
|
kind: 'captions',
|
|
|
|
label: 'label'
|
2016-12-15 22:48:19 +02:00
|
|
|
}, true);
|
2015-12-08 18:24:51 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.remoteTextTracks().length, 2, 'add text track via method');
|
|
|
|
assert.equal(player.remoteTextTrackEls().length, 2, 'add html track element via method');
|
2015-12-08 18:24:51 +02:00
|
|
|
|
|
|
|
player.removeRemoteTextTrack(htmlTrackElement.track);
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.remoteTextTracks().length, 1, 'remove text track via method');
|
|
|
|
assert.equal(player.remoteTextTrackEls().length,
|
2016-08-03 21:27:03 +02:00
|
|
|
1,
|
|
|
|
'remove html track element via method');
|
2015-12-08 18:24:51 +02:00
|
|
|
|
|
|
|
player.dispose();
|
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('should uniformly create html track element when adding text track', function(assert) {
|
2016-08-03 21:27:03 +02:00
|
|
|
const player = TestHelpers.makePlayer();
|
|
|
|
const track = {
|
2015-12-08 18:24:51 +02:00
|
|
|
kind: 'kind',
|
|
|
|
src: 'src',
|
|
|
|
language: 'language',
|
|
|
|
label: 'label',
|
|
|
|
default: 'default'
|
|
|
|
};
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.remoteTextTrackEls().length, 0, 'no html text tracks');
|
2016-08-03 21:27:03 +02:00
|
|
|
|
2016-12-15 22:48:19 +02:00
|
|
|
const htmlTrackElement = player.addRemoteTextTrack(track, true);
|
2016-08-03 21:27:03 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(htmlTrackElement.kind,
|
2016-08-03 21:27:03 +02:00
|
|
|
htmlTrackElement.track.kind,
|
|
|
|
'verify html track element kind');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(htmlTrackElement.src,
|
2016-08-03 21:27:03 +02:00
|
|
|
htmlTrackElement.track.src,
|
|
|
|
'verify html track element src');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(htmlTrackElement.srclang,
|
2016-08-03 21:27:03 +02:00
|
|
|
htmlTrackElement.track.language,
|
|
|
|
'verify html track element language');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(htmlTrackElement.label,
|
2016-08-03 21:27:03 +02:00
|
|
|
htmlTrackElement.track.label,
|
|
|
|
'verify html track element label');
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(htmlTrackElement.default,
|
2016-08-03 21:27:03 +02:00
|
|
|
htmlTrackElement.track.default,
|
|
|
|
'verify html track element default');
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.remoteTextTrackEls().length, 1, 'html track element exist');
|
|
|
|
assert.equal(player.remoteTextTrackEls().getTrackElementByTrack_(htmlTrackElement.track),
|
2016-08-03 21:27:03 +02:00
|
|
|
htmlTrackElement,
|
|
|
|
'verify same html track element');
|
2015-12-08 18:24:51 +02:00
|
|
|
|
|
|
|
player.dispose();
|
|
|
|
});
|
2016-04-19 21:18:21 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('default text tracks should show by default', function(assert) {
|
2016-08-03 21:27:03 +02:00
|
|
|
const tag = TestHelpers.makeTag();
|
|
|
|
const capt = document.createElement('track');
|
2016-04-19 21:18:21 +02:00
|
|
|
|
2016-04-19 23:09:53 +02:00
|
|
|
capt.setAttribute('kind', 'captions');
|
2016-04-19 21:18:21 +02:00
|
|
|
capt.setAttribute('default', 'default');
|
|
|
|
|
|
|
|
tag.appendChild(capt);
|
|
|
|
|
2016-08-03 21:27:03 +02:00
|
|
|
const player = TestHelpers.makePlayer({
|
2016-04-19 21:18:21 +02:00
|
|
|
html5: {
|
|
|
|
nativeTextTracks: false
|
|
|
|
}
|
|
|
|
}, tag);
|
|
|
|
|
|
|
|
// native tracks are initialized after the player is ready
|
|
|
|
this.clock.tick(1);
|
|
|
|
|
2016-08-03 21:27:03 +02:00
|
|
|
const tracks = player.textTracks();
|
2016-04-19 21:18:21 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(tracks[0].kind, 'captions', 'the captions track is present');
|
|
|
|
assert.equal(tracks[0].mode, 'showing', 'the captions track is showing');
|
2016-08-25 16:58:42 +02:00
|
|
|
|
|
|
|
player.dispose();
|
2016-04-19 21:18:21 +02:00
|
|
|
});
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('default captions take precedence over default descriptions', function(assert) {
|
2016-08-03 21:27:03 +02:00
|
|
|
const tag = TestHelpers.makeTag();
|
|
|
|
const desc = document.createElement('track');
|
|
|
|
const capt = document.createElement('track');
|
2016-04-19 21:18:21 +02:00
|
|
|
|
2016-04-19 23:09:53 +02:00
|
|
|
desc.setAttribute('kind', 'descriptions');
|
2016-04-19 21:18:21 +02:00
|
|
|
desc.setAttribute('default', 'default');
|
2016-04-19 23:09:53 +02:00
|
|
|
capt.setAttribute('kind', 'captions');
|
2016-04-19 21:18:21 +02:00
|
|
|
capt.setAttribute('default', 'default');
|
|
|
|
|
|
|
|
tag.appendChild(desc);
|
|
|
|
tag.appendChild(capt);
|
|
|
|
|
2016-08-03 21:27:03 +02:00
|
|
|
const player = TestHelpers.makePlayer({
|
2016-04-19 21:18:21 +02:00
|
|
|
html5: {
|
|
|
|
nativeTextTracks: false
|
|
|
|
}
|
|
|
|
}, tag);
|
|
|
|
|
|
|
|
// native tracks are initialized after the player is ready
|
|
|
|
this.clock.tick(1);
|
|
|
|
|
2016-08-03 21:27:03 +02:00
|
|
|
const tracks = player.textTracks();
|
2016-04-19 21:18:21 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(tracks[0].kind, 'descriptions', 'the descriptions track is first');
|
|
|
|
assert.equal(tracks[0].mode, 'disabled', 'the descriptions track is disabled');
|
|
|
|
assert.equal(tracks[1].kind, 'captions', 'the captions track is second');
|
|
|
|
assert.equal(tracks[1].mode, 'showing', 'the captions track is showing');
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2016-04-19 21:18:21 +02:00
|
|
|
});
|
2016-04-19 21:46:33 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
QUnit.test('removeRemoteTextTrack should be able to take both a track and the response from addRemoteTextTrack', function(assert) {
|
2016-08-03 21:27:03 +02:00
|
|
|
const player = TestHelpers.makePlayer();
|
|
|
|
const track = {
|
2016-04-19 21:46:33 +02:00
|
|
|
kind: 'kind',
|
|
|
|
src: 'src',
|
|
|
|
language: 'language',
|
|
|
|
label: 'label',
|
|
|
|
default: 'default'
|
|
|
|
};
|
2016-12-15 22:48:19 +02:00
|
|
|
let htmlTrackElement = player.addRemoteTextTrack(track, true);
|
2016-04-19 21:46:33 +02:00
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.remoteTextTrackEls().length, 1, 'html track element exist');
|
2016-04-19 21:46:33 +02:00
|
|
|
|
|
|
|
player.removeRemoteTextTrack(htmlTrackElement);
|
|
|
|
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.remoteTextTrackEls().length,
|
2016-08-03 21:27:03 +02:00
|
|
|
0,
|
|
|
|
'the track element was removed correctly');
|
2016-04-19 21:46:33 +02:00
|
|
|
|
2016-12-15 22:48:19 +02:00
|
|
|
htmlTrackElement = player.addRemoteTextTrack(track, true);
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.remoteTextTrackEls().length, 1, 'html track element exist');
|
2016-04-19 21:46:33 +02:00
|
|
|
|
|
|
|
player.removeRemoteTextTrack(htmlTrackElement.track);
|
2016-08-12 19:51:31 +02:00
|
|
|
assert.equal(player.remoteTextTrackEls().length,
|
2016-08-03 21:27:03 +02:00
|
|
|
0,
|
|
|
|
'the track element was removed correctly');
|
2016-08-25 16:58:42 +02:00
|
|
|
player.dispose();
|
2016-04-19 21:46:33 +02:00
|
|
|
});
|
2017-06-28 08:38:29 +02:00
|
|
|
|
|
|
|
if (Html5.isSupported()) {
|
|
|
|
QUnit.test('auto remove tracks should not clean up tracks added while source is being added', function(assert) {
|
|
|
|
const player = TestHelpers.makePlayer({
|
|
|
|
techOrder: ['html5'],
|
|
|
|
html5: {
|
|
|
|
nativeTextTracks: false
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
const track = {
|
|
|
|
kind: 'kind',
|
|
|
|
src: 'src',
|
|
|
|
language: 'language',
|
|
|
|
label: 'label',
|
|
|
|
default: 'default'
|
|
|
|
};
|
|
|
|
|
|
|
|
player.src({src: 'example.mp4', type: 'video/mp4'});
|
|
|
|
player.addRemoteTextTrack(track, false);
|
|
|
|
|
|
|
|
this.clock.tick(1);
|
|
|
|
assert.equal(player.textTracks().length, 1, 'we have one text track');
|
|
|
|
|
|
|
|
player.dispose();
|
|
|
|
});
|
|
|
|
|
|
|
|
QUnit.test('auto remove tracks added right before a source change will be cleaned up', function(assert) {
|
|
|
|
const player = TestHelpers.makePlayer({
|
|
|
|
techOrder: ['html5'],
|
|
|
|
html5: {
|
|
|
|
nativeTextTracks: false
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
const track = {
|
|
|
|
kind: 'kind',
|
|
|
|
src: 'src',
|
|
|
|
language: 'language',
|
|
|
|
label: 'label',
|
|
|
|
default: 'default'
|
|
|
|
};
|
|
|
|
|
|
|
|
player.addRemoteTextTrack(track, false);
|
|
|
|
player.src({src: 'example.mp4', type: 'video/mp4'});
|
|
|
|
|
|
|
|
this.clock.tick(1);
|
|
|
|
assert.equal(player.textTracks().length, 0, 'we do not have any tracks left');
|
|
|
|
|
|
|
|
player.dispose();
|
|
|
|
});
|
|
|
|
}
|