Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

move timeout back into parseCues #3181

Closed
wants to merge 14 commits into from
Closed
4 changes: 4 additions & 0 deletions build/grunt.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,10 @@ module.exports = function(grunt) {
},
dist: {},
watch: {
novtt: {
files: ['build/temp/video.js'],
tasks: ['concat:novtt']
},
minify: {
files: ['build/temp/video.js'],
tasks: ['uglify']
Expand Down
6 changes: 6 additions & 0 deletions src/js/tech/tech.js
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,12 @@ class Tech extends Component {
if (!window['WebVTT'] && this.el().parentNode != null) {
let script = document.createElement('script');
script.src = this.options_['vtt.js'] || '../node_modules/videojs-vtt.js/dist/vtt.js';
script.onload = () => {
this.trigger('vttjsloaded');
};
script.onerror = () => {
this.trigger('vttjserror');
};
this.el().parentNode.appendChild(script);
window['WebVTT'] = true;
}
Expand Down
14 changes: 11 additions & 3 deletions src/js/tracks/text-track.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,22 @@ const loadTrack = function(src, track) {

track.loaded_ = true;

// Make sure that vttjs has loaded, otherwise, wait till it finished loading
// NOTE: this is only used for the alt/video.novtt.js build
if (typeof window.WebVTT !== 'function') {
window.setTimeout(function() {
parseCues(responseBody, track);
}, 100);
if (track.tech_) {
let loadHandler = () => parseCues(responseBody, track);
track.tech_.on('vttjsloaded', loadHandler);
track.tech_.on('vttjserror', () => {
log.error(`vttjs failed to load, stopping trying to process ${track.src}`);
track.tech_.off('vttjsloaded', loadHandler);
});

}
} else {
parseCues(responseBody, track);
}

}));
};

Expand Down
124 changes: 124 additions & 0 deletions test/unit/tracks/text-track.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import window from 'global/window';
import EventTarget from '../../../src/js/event-target.js';
import TextTrack from '../../../src/js/tracks/text-track.js';
import TestHelpers from '../test-helpers.js';
import log from '../../../src/js/utils/log.js';

const defaultTech = {
textTracks() {},
Expand Down Expand Up @@ -254,3 +257,124 @@ test('fires cuechange when cues become active and inactive', function() {

player.dispose();
});

test('tracks are parsed if vttjs is loaded', function() {
const clock = sinon.useFakeTimers();
const oldVTT = window.WebVTT;
let parserCreated = false;

window.WebVTT = () => {};
window.WebVTT.StringDecoder = () => {};
window.WebVTT.Parser = () => {
parserCreated = true;
return {
oncue() {},
onparsingerror() {},
onflush() {},
parse() {},
flush() {}
};
};

let xhr;
window.xhr.onCreate = (newXhr) => xhr = newXhr;

let tt = new TextTrack({
tech: defaultTech,
src: 'http://example.com'
});

xhr.respond(200, {}, 'WebVTT\n');

ok(parserCreated, 'WebVTT is loaded, so we can just parse');

clock.restore();
window.WebVTT = oldVTT;
});

test('tracks are parsed once vttjs is loaded', function() {
const clock = sinon.useFakeTimers();
const oldVTT = window.WebVTT;
let parserCreated = false;

window.WebVTT = true;

let xhr;
window.xhr.onCreate = (newXhr) => xhr = newXhr;

let testTech = new EventTarget();
testTech.textTracks = () => {};
testTech.currentTime = () => {};

let tt = new TextTrack({
tech: testTech,
src: 'http://example.com'
});

xhr.respond(200, {}, 'WebVTT\n');

ok(!parserCreated, 'WebVTT is not loaded, do not try to parse yet');

clock.tick(100);
ok(!parserCreated, 'WebVTT still not loaded, do not try to parse yet');

window.WebVTT = () => {};
window.WebVTT.StringDecoder = () => {};
window.WebVTT.Parser = () => {
parserCreated = true;
return {
oncue() {},
onparsingerror() {},
onflush() {},
parse() {},
flush() {}
};
};

testTech.trigger('vttjsloaded');
ok(parserCreated, 'WebVTT is loaded, so we can parse now');

clock.restore();
window.WebVTT = oldVTT;
});

test('stops processing if vttjs loading errored out', function() {
const clock = sinon.useFakeTimers();
sinon.stub(log, 'error');
const oldVTT = window.WebVTT;
let parserCreated = false;

window.WebVTT = true;

let xhr;
window.xhr.onCreate = (newXhr) => xhr = newXhr;

let testTech = new EventTarget();
testTech.textTracks = () => {};
testTech.currentTime = () => {};

sinon.stub(testTech, 'off');
testTech.off.withArgs('vttjsloaded');

let tt = new TextTrack({
tech: testTech,
src: 'http://example.com'
});

xhr.respond(200, {}, 'WebVTT\n');

ok(!parserCreated, 'WebVTT is not loaded, do not try to parse yet');

testTech.trigger('vttjserror');
let errorSpyCall = log.error.getCall(0);
let offSpyCall = testTech.off.getCall(0);

ok(errorSpyCall.calledWithMatch('vttjs failed to load, stopping trying to process'),
'vttjs failed to load, so, we logged an error');
ok(!parserCreated, 'WebVTT is not loaded, do not try to parse yet');
ok(offSpyCall, 'tech.off was called');

clock.restore();
log.error.restore();
window.WebVTT = oldVTT;
});