@stremio/stremio-video 0.0.73 → 0.0.75
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,15 @@ function withHTMLSubtitles(Video) {
|
|
|
40
41
|
containerElement.appendChild(subtitlesElement);
|
|
41
42
|
|
|
42
43
|
var videoState = {
|
|
43
|
-
time: null
|
|
44
|
+
time: null,
|
|
45
|
+
paused: false,
|
|
46
|
+
buffering: false,
|
|
47
|
+
lastSyncAt: null,
|
|
48
|
+
playbackSpeed: 1
|
|
44
49
|
};
|
|
50
|
+
var rafId = null;
|
|
51
|
+
var lastTimeIndex = null;
|
|
52
|
+
var forceRender = false;
|
|
45
53
|
var cuesByTime = null;
|
|
46
54
|
var events = new EventEmitter();
|
|
47
55
|
var destroyed = false;
|
|
@@ -67,18 +75,62 @@ function withHTMLSubtitles(Video) {
|
|
|
67
75
|
extraSubtitlesOpacity: false
|
|
68
76
|
};
|
|
69
77
|
|
|
78
|
+
function getCurrentTime() {
|
|
79
|
+
if (videoState.time === null || !isFinite(videoState.time)) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
if (videoState.paused || videoState.buffering || videoState.lastSyncAt === null) {
|
|
83
|
+
return videoState.time;
|
|
84
|
+
}
|
|
85
|
+
return videoState.time + (Date.now() - videoState.lastSyncAt) * videoState.playbackSpeed;
|
|
86
|
+
}
|
|
87
|
+
function startRenderLoop() {
|
|
88
|
+
if (rafId !== null) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
(function loop() {
|
|
92
|
+
renderSubtitles();
|
|
93
|
+
rafId = requestAnimationFrame(loop);
|
|
94
|
+
})();
|
|
95
|
+
}
|
|
96
|
+
function stopRenderLoop() {
|
|
97
|
+
if (rafId !== null) {
|
|
98
|
+
cancelAnimationFrame(rafId);
|
|
99
|
+
rafId = null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
70
102
|
function renderSubtitles() {
|
|
103
|
+
var time = getCurrentTime();
|
|
104
|
+
|
|
105
|
+
if (cuesByTime === null || time === null) {
|
|
106
|
+
if (lastTimeIndex !== null) {
|
|
107
|
+
while (subtitlesElement.hasChildNodes()) {
|
|
108
|
+
subtitlesElement.removeChild(subtitlesElement.lastChild);
|
|
109
|
+
}
|
|
110
|
+
lastTimeIndex = null;
|
|
111
|
+
}
|
|
112
|
+
forceRender = false;
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
var timeIndex = binarySearchUpperBound(cuesByTime.times, time - delay);
|
|
117
|
+
if (timeIndex === lastTimeIndex && !forceRender) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
lastTimeIndex = timeIndex;
|
|
121
|
+
forceRender = false;
|
|
122
|
+
|
|
71
123
|
while (subtitlesElement.hasChildNodes()) {
|
|
72
124
|
subtitlesElement.removeChild(subtitlesElement.lastChild);
|
|
73
125
|
}
|
|
74
126
|
|
|
75
|
-
if (
|
|
127
|
+
if (timeIndex === -1) {
|
|
76
128
|
return;
|
|
77
129
|
}
|
|
78
130
|
|
|
79
131
|
subtitlesElement.style.bottom = offset + '%';
|
|
80
132
|
subtitlesElement.style.opacity = opacity;
|
|
81
|
-
subtitlesRenderer.render(cuesByTime,
|
|
133
|
+
subtitlesRenderer.render(cuesByTime, timeIndex).forEach(function(cueNode) {
|
|
82
134
|
cueNode.style.display = 'inline-block';
|
|
83
135
|
cueNode.style.padding = '0.2em';
|
|
84
136
|
cueNode.style.whiteSpace = 'pre-wrap';
|
|
@@ -101,7 +153,37 @@ function withHTMLSubtitles(Video) {
|
|
|
101
153
|
switch (propName) {
|
|
102
154
|
case 'time': {
|
|
103
155
|
videoState.time = propValue;
|
|
104
|
-
|
|
156
|
+
videoState.lastSyncAt = Date.now();
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
case 'paused': {
|
|
160
|
+
if (propValue && !videoState.paused && !videoState.buffering && videoState.lastSyncAt !== null && videoState.time !== null) {
|
|
161
|
+
videoState.time = videoState.time + (Date.now() - videoState.lastSyncAt) * videoState.playbackSpeed;
|
|
162
|
+
videoState.lastSyncAt = Date.now();
|
|
163
|
+
} else if (!propValue && videoState.paused) {
|
|
164
|
+
videoState.lastSyncAt = Date.now();
|
|
165
|
+
}
|
|
166
|
+
videoState.paused = propValue;
|
|
167
|
+
break;
|
|
168
|
+
}
|
|
169
|
+
case 'buffering': {
|
|
170
|
+
if (propValue && !videoState.buffering && !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
|
+
} else if (!propValue && videoState.buffering) {
|
|
174
|
+
videoState.lastSyncAt = Date.now();
|
|
175
|
+
}
|
|
176
|
+
videoState.buffering = propValue;
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
case 'playbackSpeed': {
|
|
180
|
+
if (propValue !== null && isFinite(propValue)) {
|
|
181
|
+
if (!videoState.paused && !videoState.buffering && videoState.lastSyncAt !== null && videoState.time !== null) {
|
|
182
|
+
videoState.time = videoState.time + (Date.now() - videoState.lastSyncAt) * videoState.playbackSpeed;
|
|
183
|
+
videoState.lastSyncAt = Date.now();
|
|
184
|
+
}
|
|
185
|
+
videoState.playbackSpeed = propValue;
|
|
186
|
+
}
|
|
105
187
|
break;
|
|
106
188
|
}
|
|
107
189
|
}
|
|
@@ -218,12 +300,18 @@ function withHTMLSubtitles(Video) {
|
|
|
218
300
|
function setProp(propName, propValue) {
|
|
219
301
|
switch (propName) {
|
|
220
302
|
case 'selectedExtraSubtitlesTrackId': {
|
|
303
|
+
if (propValue !== null && selectedTrackId === propValue) {
|
|
304
|
+
return true;
|
|
305
|
+
}
|
|
221
306
|
cuesByTime = null;
|
|
222
307
|
selectedTrackId = null;
|
|
223
308
|
delay = null;
|
|
224
309
|
var selectedTrack = tracks.find(function(track) {
|
|
225
310
|
return track.id === propValue;
|
|
226
311
|
});
|
|
312
|
+
if (!selectedTrack) {
|
|
313
|
+
stopRenderLoop();
|
|
314
|
+
}
|
|
227
315
|
if (selectedTrack) {
|
|
228
316
|
selectedTrackId = selectedTrack.id;
|
|
229
317
|
delay = 0;
|
|
@@ -269,7 +357,7 @@ function withHTMLSubtitles(Video) {
|
|
|
269
357
|
}
|
|
270
358
|
|
|
271
359
|
cuesByTime = result;
|
|
272
|
-
|
|
360
|
+
startRenderLoop();
|
|
273
361
|
events.emit('extraSubtitlesTrackLoaded', selectedTrack);
|
|
274
362
|
})
|
|
275
363
|
.catch(function(error) {
|
|
@@ -299,6 +387,7 @@ function withHTMLSubtitles(Video) {
|
|
|
299
387
|
case 'extraSubtitlesDelay': {
|
|
300
388
|
if (selectedTrackId !== null && propValue !== null && isFinite(propValue)) {
|
|
301
389
|
delay = parseInt(propValue, 10);
|
|
390
|
+
forceRender = true;
|
|
302
391
|
renderSubtitles();
|
|
303
392
|
onPropChanged('extraSubtitlesDelay');
|
|
304
393
|
}
|
|
@@ -308,6 +397,7 @@ function withHTMLSubtitles(Video) {
|
|
|
308
397
|
case 'extraSubtitlesSize': {
|
|
309
398
|
if (propValue !== null && isFinite(propValue)) {
|
|
310
399
|
size = Math.max(0, parseInt(propValue, 10));
|
|
400
|
+
forceRender = true;
|
|
311
401
|
renderSubtitles();
|
|
312
402
|
onPropChanged('extraSubtitlesSize');
|
|
313
403
|
}
|
|
@@ -317,6 +407,7 @@ function withHTMLSubtitles(Video) {
|
|
|
317
407
|
case 'extraSubtitlesOffset': {
|
|
318
408
|
if (propValue !== null && isFinite(propValue)) {
|
|
319
409
|
offset = Math.max(0, Math.min(100, parseInt(propValue, 10)));
|
|
410
|
+
forceRender = true;
|
|
320
411
|
renderSubtitles();
|
|
321
412
|
onPropChanged('extraSubtitlesOffset');
|
|
322
413
|
}
|
|
@@ -332,6 +423,7 @@ function withHTMLSubtitles(Video) {
|
|
|
332
423
|
console.error('withHTMLSubtitles', error);
|
|
333
424
|
}
|
|
334
425
|
|
|
426
|
+
forceRender = true;
|
|
335
427
|
renderSubtitles();
|
|
336
428
|
onPropChanged('extraSubtitlesTextColor');
|
|
337
429
|
}
|
|
@@ -347,6 +439,7 @@ function withHTMLSubtitles(Video) {
|
|
|
347
439
|
console.error('withHTMLSubtitles', error);
|
|
348
440
|
}
|
|
349
441
|
|
|
442
|
+
forceRender = true;
|
|
350
443
|
renderSubtitles();
|
|
351
444
|
onPropChanged('extraSubtitlesBackgroundColor');
|
|
352
445
|
}
|
|
@@ -362,6 +455,7 @@ function withHTMLSubtitles(Video) {
|
|
|
362
455
|
console.error('withHTMLSubtitles', error);
|
|
363
456
|
}
|
|
364
457
|
|
|
458
|
+
forceRender = true;
|
|
365
459
|
renderSubtitles();
|
|
366
460
|
onPropChanged('extraSubtitlesOutlineColor');
|
|
367
461
|
}
|
|
@@ -377,6 +471,7 @@ function withHTMLSubtitles(Video) {
|
|
|
377
471
|
console.error('withHTMLSubtitles', error);
|
|
378
472
|
}
|
|
379
473
|
|
|
474
|
+
forceRender = true;
|
|
380
475
|
renderSubtitles();
|
|
381
476
|
onPropChanged('extraSubtitlesOpacity');
|
|
382
477
|
}
|
|
@@ -450,6 +545,8 @@ function withHTMLSubtitles(Video) {
|
|
|
450
545
|
return false;
|
|
451
546
|
}
|
|
452
547
|
case 'unload': {
|
|
548
|
+
stopRenderLoop();
|
|
549
|
+
lastTimeIndex = null;
|
|
453
550
|
cuesByTime = null;
|
|
454
551
|
tracks = [];
|
|
455
552
|
selectedTrackId = null;
|