mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-04-20 06:32:11 +00:00
html subtitles refactored
This commit is contained in:
parent
e8a5e86ab5
commit
78b7cd7f16
2 changed files with 49 additions and 42 deletions
|
|
@ -1,16 +1,16 @@
|
|||
var EventEmitter = require('events');
|
||||
var subtitleUtils = require('./utils/subtitles');
|
||||
|
||||
var HTMLSubtitles = function(containerElement) {
|
||||
function HTMLSubtitles(containerElement) {
|
||||
if (!(containerElement instanceof HTMLElement)) {
|
||||
throw new Error('Instance of HTMLElement required as a first argument');
|
||||
}
|
||||
|
||||
var self = this;
|
||||
var events = new EventEmitter();
|
||||
var destroyed = false;
|
||||
var events = new EventEmitter();
|
||||
var tracks = Object.freeze([]);
|
||||
var cues = Object.freeze({});
|
||||
var cuesByTime = null;
|
||||
var selectedTrackId = null;
|
||||
var delay = 0;
|
||||
var stylesElement = document.createElement('style');
|
||||
|
|
@ -51,10 +51,10 @@ var HTMLSubtitles = function(containerElement) {
|
|||
return Object.freeze(tracks.slice());
|
||||
case 'selectedTrackId':
|
||||
return selectedTrackId;
|
||||
case 'delay':
|
||||
return delay;
|
||||
case 'size':
|
||||
return parseFloat(stylesElement.sheet.cssRules[subtitleStylesIndex].style.fontSize);
|
||||
case 'delay':
|
||||
return delay;
|
||||
case 'darkBackground':
|
||||
return subtitlesElement.classList.contains('dark-background');
|
||||
default:
|
||||
|
|
@ -63,7 +63,7 @@ var HTMLSubtitles = function(containerElement) {
|
|||
case 'setProp':
|
||||
switch (arguments[1]) {
|
||||
case 'selectedTrackId':
|
||||
cues = Object.freeze({});
|
||||
cuesByTime = null;
|
||||
selectedTrackId = null;
|
||||
delay = 0;
|
||||
for (var i = 0; i < tracks.length; i++) {
|
||||
|
|
@ -82,7 +82,7 @@ var HTMLSubtitles = function(containerElement) {
|
|||
})
|
||||
.then(function(text) {
|
||||
if (typeof text === 'string' && selectedTrackId === track.id) {
|
||||
cues = subtitleUtils.parse(text);
|
||||
cuesByTime = subtitleUtils.parse(text);
|
||||
events.emit('load', Object.freeze({
|
||||
track: track
|
||||
}));
|
||||
|
|
@ -98,16 +98,16 @@ var HTMLSubtitles = function(containerElement) {
|
|||
}
|
||||
}
|
||||
return;
|
||||
case 'delay':
|
||||
if (!isNaN(arguments[2])) {
|
||||
delay = parseFloat(arguments[2]);
|
||||
}
|
||||
return;
|
||||
case 'size':
|
||||
if (!isNaN(arguments[2])) {
|
||||
stylesElement.sheet.cssRules[subtitleStylesIndex].style.fontSize = parseFloat(arguments[2]) + 'pt';
|
||||
}
|
||||
return;
|
||||
case 'delay':
|
||||
if (!isNaN(arguments[2])) {
|
||||
delay = parseFloat(arguments[2]);
|
||||
}
|
||||
return;
|
||||
case 'darkBackground':
|
||||
if (arguments[2]) {
|
||||
subtitlesElement.classList.add('dark-background');
|
||||
|
|
@ -149,7 +149,7 @@ var HTMLSubtitles = function(containerElement) {
|
|||
return;
|
||||
case 'clearTracks':
|
||||
tracks = Object.freeze([]);
|
||||
cues = Object.freeze({});
|
||||
cuesByTime = null;
|
||||
selectedTrackId = null;
|
||||
delay = 0;
|
||||
return;
|
||||
|
|
@ -158,14 +158,14 @@ var HTMLSubtitles = function(containerElement) {
|
|||
subtitlesElement.removeChild(subtitlesElement.lastChild);
|
||||
}
|
||||
|
||||
if (isNaN(arguments[2]) || !Array.isArray(cues.times)) {
|
||||
if (isNaN(arguments[2]) || cuesByTime === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
var time = arguments[2] + delay;
|
||||
var cuesForTime = subtitleUtils.cuesForTime(cues, time);
|
||||
var cuesForTime = subtitleUtils.cuesForTime(cuesByTime, time);
|
||||
for (var i = 0; i < cuesForTime.length; i++) {
|
||||
var cueNode = subtitleUtils.render(cuesForTime[i]);
|
||||
var cueNode = subtitleUtils.render(cuesForTime[i].text);
|
||||
cueNode.classList.add('cue');
|
||||
subtitlesElement.append(cueNode, document.createElement('br'));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,60 +26,67 @@ function binarySearchUpperBound(array, value) {
|
|||
function parse(text) {
|
||||
var nativeVTTCue = VTTCue;
|
||||
global.VTTCue = VTTJS.VTTCue;
|
||||
var cues = [];
|
||||
var cuesForTime = {};
|
||||
var parser = new VTTJS.WebVTT.Parser(window, VTTJS.WebVTT.StringDecoder());
|
||||
global.VTTCue = nativeVTTCue;
|
||||
var cues = [];
|
||||
var cuesByTime = {};
|
||||
parser.oncue = function(c) {
|
||||
var cue = {
|
||||
var cue = Object.freeze({
|
||||
startTime: (c.startTime * 1000) | 0,
|
||||
endTime: (c.endTime * 1000) | 0,
|
||||
text: c.text
|
||||
};
|
||||
});
|
||||
cues.push(cue);
|
||||
cuesForTime[cue.startTime] = cuesForTime[cue.startTime] || [];
|
||||
cuesForTime[cue.endTime] = cuesForTime[cue.endTime] || [];
|
||||
cuesByTime[cue.startTime] = cuesByTime[cue.startTime] || [];
|
||||
cuesByTime[cue.endTime] = cuesByTime[cue.endTime] || [];
|
||||
};
|
||||
parser.parse(text);
|
||||
parser.flush();
|
||||
cuesForTime.times = Object.keys(cuesForTime)
|
||||
cuesByTime.times = Object.keys(cuesByTime)
|
||||
.map(function(time) {
|
||||
return parseInt(time);
|
||||
})
|
||||
.sort(function(t1, t2) {
|
||||
return t1 - t2;
|
||||
});
|
||||
Object.freeze(cues);
|
||||
Object.freeze(cuesByTime);
|
||||
Object.freeze(cuesByTime.times);
|
||||
for (var i = 0; i < cues.length; i++) {
|
||||
cuesForTime[cues[i].startTime].push(cues[i]);
|
||||
var startTimeIndex = binarySearchUpperBound(cuesForTime.times, cues[i].startTime);
|
||||
for (var j = startTimeIndex + 1; j < cuesForTime.times.length; j++) {
|
||||
if (cues[i].endTime <= cuesForTime.times[j]) {
|
||||
cuesByTime[cues[i].startTime].push(cues[i]);
|
||||
var startTimeIndex = binarySearchUpperBound(cuesByTime.times, cues[i].startTime);
|
||||
for (var j = startTimeIndex + 1; j < cuesByTime.times.length; j++) {
|
||||
if (cues[i].endTime <= cuesByTime.times[j]) {
|
||||
break;
|
||||
}
|
||||
|
||||
cuesForTime[cuesForTime.times[j]].push(cues[i]);
|
||||
cuesByTime[cuesByTime.times[j]].push(cues[i]);
|
||||
}
|
||||
}
|
||||
for (var i = 0; i < cuesForTime.times.length; i++) {
|
||||
cuesForTime[cuesForTime.times[i]].sort(function(c1, c2) {
|
||||
|
||||
for (var i = 0; i < cuesByTime.times.length; i++) {
|
||||
cuesByTime[cuesByTime.times[i]].sort(function(c1, c2) {
|
||||
return c1.startTime - c2.startTime ||
|
||||
c1.endTime - c2.endTime;
|
||||
});
|
||||
|
||||
Object.freeze(cuesByTime[cuesByTime.times[i]]);
|
||||
}
|
||||
global.VTTCue = nativeVTTCue;
|
||||
return Object.freeze(cuesForTime);
|
||||
|
||||
return cuesByTime;
|
||||
}
|
||||
|
||||
function cuesForTime(cues, time) {
|
||||
var index = binarySearchUpperBound(cues.times, time);
|
||||
return index !== -1 ? cues[cues.times[index]] : [];
|
||||
function cuesForTime(cuesByTime, time) {
|
||||
var index = binarySearchUpperBound(cuesByTime.times, time);
|
||||
return index !== -1 ? cuesByTime[cuesByTime.times[index]] : Object.freeze([]);
|
||||
}
|
||||
|
||||
function render(cue) {
|
||||
return VTTJS.WebVTT.convertCueToDOMTree(window, cue.text);
|
||||
function render(text) {
|
||||
return VTTJS.WebVTT.convertCueToDOMTree(window, text);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
parse,
|
||||
cuesForTime,
|
||||
render
|
||||
};
|
||||
module.exports = Object.freeze({
|
||||
parse: parse,
|
||||
cuesForTime: cuesForTime,
|
||||
render: render
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue