@stremio/stremio-video 0.0.73 → 0.0.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -401,8 +401,8 @@ function HTMLVideo(options) {
|
|
|
401
401
|
.find(function(track) {
|
|
402
402
|
return track.id === propValue;
|
|
403
403
|
});
|
|
404
|
+
onPropChanged('selectedSubtitlesTrackId');
|
|
404
405
|
if (selecterdSubtitlesTrack) {
|
|
405
|
-
onPropChanged('selectedSubtitlesTrackId');
|
|
406
406
|
events.emit('subtitlesTrackLoaded', selecterdSubtitlesTrack);
|
|
407
407
|
}
|
|
408
408
|
}
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
var VTTJS = require('vtt.js');
|
|
2
|
-
var binarySearchUpperBound = require('./binarySearchUpperBound');
|
|
3
2
|
|
|
4
|
-
function render(cuesByTime,
|
|
3
|
+
function render(cuesByTime, timeIndex) {
|
|
5
4
|
var nodes = [];
|
|
6
|
-
var timeIndex = binarySearchUpperBound(cuesByTime.times, time);
|
|
7
5
|
if (timeIndex !== -1) {
|
|
8
6
|
var cuesForTime = cuesByTime[cuesByTime.times[timeIndex]];
|
|
9
7
|
for (var i = 0; i < cuesForTime.length; i++) {
|
|
@@ -3,6 +3,7 @@ var cloneDeep = require('lodash.clonedeep');
|
|
|
3
3
|
var deepFreeze = require('deep-freeze');
|
|
4
4
|
var Color = require('color');
|
|
5
5
|
var ERROR = require('../error');
|
|
6
|
+
var binarySearchUpperBound = require('./binarySearchUpperBound');
|
|
6
7
|
var subtitlesParser = require('./subtitlesParser');
|
|
7
8
|
var subtitlesRenderer = require('./subtitlesRenderer');
|
|
8
9
|
var subtitlesConverter = require('./subtitlesConverter');
|
|
@@ -40,8 +41,14 @@ function withHTMLSubtitles(Video) {
|
|
|
40
41
|
containerElement.appendChild(subtitlesElement);
|
|
41
42
|
|
|
42
43
|
var videoState = {
|
|
43
|
-
time: null
|
|
44
|
+
time: null,
|
|
45
|
+
paused: false,
|
|
46
|
+
lastSyncAt: null,
|
|
47
|
+
playbackSpeed: 1
|
|
44
48
|
};
|
|
49
|
+
var rafId = null;
|
|
50
|
+
var lastTimeIndex = null;
|
|
51
|
+
var forceRender = false;
|
|
45
52
|
var cuesByTime = null;
|
|
46
53
|
var events = new EventEmitter();
|
|
47
54
|
var destroyed = false;
|
|
@@ -67,18 +74,62 @@ function withHTMLSubtitles(Video) {
|
|
|
67
74
|
extraSubtitlesOpacity: false
|
|
68
75
|
};
|
|
69
76
|
|
|
77
|
+
function getCurrentTime() {
|
|
78
|
+
if (videoState.time === null || !isFinite(videoState.time)) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
if (videoState.paused || videoState.lastSyncAt === null) {
|
|
82
|
+
return videoState.time;
|
|
83
|
+
}
|
|
84
|
+
return videoState.time + (Date.now() - videoState.lastSyncAt) * videoState.playbackSpeed;
|
|
85
|
+
}
|
|
86
|
+
function startRenderLoop() {
|
|
87
|
+
if (rafId !== null) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
(function loop() {
|
|
91
|
+
renderSubtitles();
|
|
92
|
+
rafId = requestAnimationFrame(loop);
|
|
93
|
+
})();
|
|
94
|
+
}
|
|
95
|
+
function stopRenderLoop() {
|
|
96
|
+
if (rafId !== null) {
|
|
97
|
+
cancelAnimationFrame(rafId);
|
|
98
|
+
rafId = null;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
70
101
|
function renderSubtitles() {
|
|
102
|
+
var time = getCurrentTime();
|
|
103
|
+
|
|
104
|
+
if (cuesByTime === null || time === null) {
|
|
105
|
+
if (lastTimeIndex !== null) {
|
|
106
|
+
while (subtitlesElement.hasChildNodes()) {
|
|
107
|
+
subtitlesElement.removeChild(subtitlesElement.lastChild);
|
|
108
|
+
}
|
|
109
|
+
lastTimeIndex = null;
|
|
110
|
+
}
|
|
111
|
+
forceRender = false;
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
var timeIndex = binarySearchUpperBound(cuesByTime.times, time - delay);
|
|
116
|
+
if (timeIndex === lastTimeIndex && !forceRender) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
lastTimeIndex = timeIndex;
|
|
120
|
+
forceRender = false;
|
|
121
|
+
|
|
71
122
|
while (subtitlesElement.hasChildNodes()) {
|
|
72
123
|
subtitlesElement.removeChild(subtitlesElement.lastChild);
|
|
73
124
|
}
|
|
74
125
|
|
|
75
|
-
if (
|
|
126
|
+
if (timeIndex === -1) {
|
|
76
127
|
return;
|
|
77
128
|
}
|
|
78
129
|
|
|
79
130
|
subtitlesElement.style.bottom = offset + '%';
|
|
80
131
|
subtitlesElement.style.opacity = opacity;
|
|
81
|
-
subtitlesRenderer.render(cuesByTime,
|
|
132
|
+
subtitlesRenderer.render(cuesByTime, timeIndex).forEach(function(cueNode) {
|
|
82
133
|
cueNode.style.display = 'inline-block';
|
|
83
134
|
cueNode.style.padding = '0.2em';
|
|
84
135
|
cueNode.style.whiteSpace = 'pre-wrap';
|
|
@@ -101,7 +152,27 @@ function withHTMLSubtitles(Video) {
|
|
|
101
152
|
switch (propName) {
|
|
102
153
|
case 'time': {
|
|
103
154
|
videoState.time = propValue;
|
|
104
|
-
|
|
155
|
+
videoState.lastSyncAt = Date.now();
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
case 'paused': {
|
|
159
|
+
if (propValue && !videoState.paused && videoState.lastSyncAt !== null && videoState.time !== null) {
|
|
160
|
+
videoState.time = videoState.time + (Date.now() - videoState.lastSyncAt) * videoState.playbackSpeed;
|
|
161
|
+
videoState.lastSyncAt = Date.now();
|
|
162
|
+
} else if (!propValue && videoState.paused) {
|
|
163
|
+
videoState.lastSyncAt = Date.now();
|
|
164
|
+
}
|
|
165
|
+
videoState.paused = propValue;
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
case 'playbackSpeed': {
|
|
169
|
+
if (propValue !== null && isFinite(propValue)) {
|
|
170
|
+
if (!videoState.paused && videoState.lastSyncAt !== null && videoState.time !== null) {
|
|
171
|
+
videoState.time = videoState.time + (Date.now() - videoState.lastSyncAt) * videoState.playbackSpeed;
|
|
172
|
+
videoState.lastSyncAt = Date.now();
|
|
173
|
+
}
|
|
174
|
+
videoState.playbackSpeed = propValue;
|
|
175
|
+
}
|
|
105
176
|
break;
|
|
106
177
|
}
|
|
107
178
|
}
|
|
@@ -224,6 +295,9 @@ function withHTMLSubtitles(Video) {
|
|
|
224
295
|
var selectedTrack = tracks.find(function(track) {
|
|
225
296
|
return track.id === propValue;
|
|
226
297
|
});
|
|
298
|
+
if (!selectedTrack) {
|
|
299
|
+
stopRenderLoop();
|
|
300
|
+
}
|
|
227
301
|
if (selectedTrack) {
|
|
228
302
|
selectedTrackId = selectedTrack.id;
|
|
229
303
|
delay = 0;
|
|
@@ -269,7 +343,7 @@ function withHTMLSubtitles(Video) {
|
|
|
269
343
|
}
|
|
270
344
|
|
|
271
345
|
cuesByTime = result;
|
|
272
|
-
|
|
346
|
+
startRenderLoop();
|
|
273
347
|
events.emit('extraSubtitlesTrackLoaded', selectedTrack);
|
|
274
348
|
})
|
|
275
349
|
.catch(function(error) {
|
|
@@ -299,6 +373,7 @@ function withHTMLSubtitles(Video) {
|
|
|
299
373
|
case 'extraSubtitlesDelay': {
|
|
300
374
|
if (selectedTrackId !== null && propValue !== null && isFinite(propValue)) {
|
|
301
375
|
delay = parseInt(propValue, 10);
|
|
376
|
+
forceRender = true;
|
|
302
377
|
renderSubtitles();
|
|
303
378
|
onPropChanged('extraSubtitlesDelay');
|
|
304
379
|
}
|
|
@@ -308,6 +383,7 @@ function withHTMLSubtitles(Video) {
|
|
|
308
383
|
case 'extraSubtitlesSize': {
|
|
309
384
|
if (propValue !== null && isFinite(propValue)) {
|
|
310
385
|
size = Math.max(0, parseInt(propValue, 10));
|
|
386
|
+
forceRender = true;
|
|
311
387
|
renderSubtitles();
|
|
312
388
|
onPropChanged('extraSubtitlesSize');
|
|
313
389
|
}
|
|
@@ -317,6 +393,7 @@ function withHTMLSubtitles(Video) {
|
|
|
317
393
|
case 'extraSubtitlesOffset': {
|
|
318
394
|
if (propValue !== null && isFinite(propValue)) {
|
|
319
395
|
offset = Math.max(0, Math.min(100, parseInt(propValue, 10)));
|
|
396
|
+
forceRender = true;
|
|
320
397
|
renderSubtitles();
|
|
321
398
|
onPropChanged('extraSubtitlesOffset');
|
|
322
399
|
}
|
|
@@ -332,6 +409,7 @@ function withHTMLSubtitles(Video) {
|
|
|
332
409
|
console.error('withHTMLSubtitles', error);
|
|
333
410
|
}
|
|
334
411
|
|
|
412
|
+
forceRender = true;
|
|
335
413
|
renderSubtitles();
|
|
336
414
|
onPropChanged('extraSubtitlesTextColor');
|
|
337
415
|
}
|
|
@@ -347,6 +425,7 @@ function withHTMLSubtitles(Video) {
|
|
|
347
425
|
console.error('withHTMLSubtitles', error);
|
|
348
426
|
}
|
|
349
427
|
|
|
428
|
+
forceRender = true;
|
|
350
429
|
renderSubtitles();
|
|
351
430
|
onPropChanged('extraSubtitlesBackgroundColor');
|
|
352
431
|
}
|
|
@@ -362,6 +441,7 @@ function withHTMLSubtitles(Video) {
|
|
|
362
441
|
console.error('withHTMLSubtitles', error);
|
|
363
442
|
}
|
|
364
443
|
|
|
444
|
+
forceRender = true;
|
|
365
445
|
renderSubtitles();
|
|
366
446
|
onPropChanged('extraSubtitlesOutlineColor');
|
|
367
447
|
}
|
|
@@ -377,6 +457,7 @@ function withHTMLSubtitles(Video) {
|
|
|
377
457
|
console.error('withHTMLSubtitles', error);
|
|
378
458
|
}
|
|
379
459
|
|
|
460
|
+
forceRender = true;
|
|
380
461
|
renderSubtitles();
|
|
381
462
|
onPropChanged('extraSubtitlesOpacity');
|
|
382
463
|
}
|
|
@@ -450,6 +531,8 @@ function withHTMLSubtitles(Video) {
|
|
|
450
531
|
return false;
|
|
451
532
|
}
|
|
452
533
|
case 'unload': {
|
|
534
|
+
stopRenderLoop();
|
|
535
|
+
lastTimeIndex = null;
|
|
453
536
|
cuesByTime = null;
|
|
454
537
|
tracks = [];
|
|
455
538
|
selectedTrackId = null;
|