@stremio/stremio-video 0.0.52 → 0.0.54
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
|
@@ -351,6 +351,10 @@ function ShellVideo(options) {
|
|
|
351
351
|
|
|
352
352
|
ipc.send('mpv-set-prop', ['no-sub-ass']);
|
|
353
353
|
|
|
354
|
+
// Hardware decoding
|
|
355
|
+
var hwdecValue = commandArgs.hardwareDecoding ? 'auto-copy' : 'no';
|
|
356
|
+
ipc.send('mpv-set-prop', ['hwdec', hwdecValue]);
|
|
357
|
+
|
|
354
358
|
// opengl-cb is an alias for the new name "libmpv", as shown in mpv's video/out/vo.c aliases
|
|
355
359
|
// opengl is an alias for the new name "gpu"
|
|
356
360
|
// When on Windows we use d3d for the rendering in separate window
|
|
@@ -66,6 +66,9 @@ function StremioVideo() {
|
|
|
66
66
|
video.on('extraSubtitlesTrackLoaded', function(track) {
|
|
67
67
|
events.emit('extraSubtitlesTrackLoaded', track);
|
|
68
68
|
});
|
|
69
|
+
video.on('extraSubtitlesTrackAdded', function(track) {
|
|
70
|
+
events.emit('extraSubtitlesTrackAdded', track);
|
|
71
|
+
});
|
|
69
72
|
if (Video.manifest.external) {
|
|
70
73
|
video.on('implementationChanged', function(manifest) {
|
|
71
74
|
events.emit('implementationChanged', manifest);
|
|
@@ -4,17 +4,23 @@ var deepFreeze = require('deep-freeze');
|
|
|
4
4
|
var Color = require('color');
|
|
5
5
|
var ERROR = require('../error');
|
|
6
6
|
|
|
7
|
+
var SSA_DESCRIPTORS_REGEX = /^\{(\\an[1-8])+\}/i;
|
|
8
|
+
|
|
7
9
|
function TitanVideo(options) {
|
|
8
10
|
options = options || {};
|
|
9
11
|
|
|
12
|
+
var size = 100;
|
|
13
|
+
var offset = 0;
|
|
14
|
+
var textColor = 'rgb(255, 255, 255)';
|
|
15
|
+
var backgroundColor = 'rgba(0, 0, 0, 0)';
|
|
16
|
+
var outlineColor = 'rgb(34, 34, 34)';
|
|
17
|
+
var subtitlesOpacity = 1;
|
|
18
|
+
|
|
10
19
|
var containerElement = options.containerElement;
|
|
11
20
|
if (!(containerElement instanceof HTMLElement)) {
|
|
12
21
|
throw new Error('Container element required to be instance of HTMLElement');
|
|
13
22
|
}
|
|
14
23
|
|
|
15
|
-
var styleElement = document.createElement('style');
|
|
16
|
-
containerElement.appendChild(styleElement);
|
|
17
|
-
styleElement.sheet.insertRule('video::cue { font-size: 4vmin; color: rgb(255, 255, 255); background-color: rgba(0, 0, 0, 0); text-shadow: rgb(34, 34, 34) 1px 1px 0.1em; }');
|
|
18
24
|
var videoElement = document.createElement('video');
|
|
19
25
|
videoElement.style.width = '100%';
|
|
20
26
|
videoElement.style.height = '100%';
|
|
@@ -35,48 +41,39 @@ function TitanVideo(options) {
|
|
|
35
41
|
};
|
|
36
42
|
videoElement.ontimeupdate = function() {
|
|
37
43
|
onPropChanged('time');
|
|
38
|
-
onPropChanged('buffered');
|
|
39
44
|
};
|
|
40
45
|
videoElement.ondurationchange = function() {
|
|
41
46
|
onPropChanged('duration');
|
|
42
47
|
};
|
|
43
48
|
videoElement.onwaiting = function() {
|
|
44
49
|
onPropChanged('buffering');
|
|
45
|
-
onPropChanged('buffered');
|
|
46
50
|
};
|
|
47
51
|
videoElement.onseeking = function() {
|
|
48
52
|
onPropChanged('time');
|
|
49
53
|
onPropChanged('buffering');
|
|
50
|
-
onPropChanged('buffered');
|
|
51
54
|
};
|
|
52
55
|
videoElement.onseeked = function() {
|
|
53
56
|
onPropChanged('time');
|
|
54
57
|
onPropChanged('buffering');
|
|
55
|
-
onPropChanged('buffered');
|
|
56
58
|
};
|
|
57
59
|
videoElement.onstalled = function() {
|
|
58
60
|
onPropChanged('buffering');
|
|
59
|
-
onPropChanged('buffered');
|
|
60
61
|
};
|
|
61
62
|
videoElement.onplaying = function() {
|
|
62
63
|
onPropChanged('time');
|
|
63
64
|
onPropChanged('buffering');
|
|
64
|
-
onPropChanged('buffered');
|
|
65
65
|
};
|
|
66
66
|
videoElement.oncanplay = function() {
|
|
67
67
|
onPropChanged('buffering');
|
|
68
|
-
onPropChanged('buffered');
|
|
69
68
|
};
|
|
70
69
|
videoElement.canplaythrough = function() {
|
|
71
70
|
onPropChanged('buffering');
|
|
72
|
-
onPropChanged('buffered');
|
|
73
71
|
};
|
|
74
72
|
videoElement.onloadedmetadata = function() {
|
|
75
73
|
onPropChanged('loaded');
|
|
76
74
|
};
|
|
77
75
|
videoElement.onloadeddata = function() {
|
|
78
76
|
onPropChanged('buffering');
|
|
79
|
-
onPropChanged('buffered');
|
|
80
77
|
};
|
|
81
78
|
videoElement.onvolumechange = function() {
|
|
82
79
|
onPropChanged('volume');
|
|
@@ -88,17 +85,23 @@ function TitanVideo(options) {
|
|
|
88
85
|
videoElement.textTracks.onchange = function() {
|
|
89
86
|
onPropChanged('subtitlesTracks');
|
|
90
87
|
onPropChanged('selectedSubtitlesTrackId');
|
|
91
|
-
onCueChange();
|
|
92
|
-
Array.from(videoElement.textTracks).forEach(function(track) {
|
|
93
|
-
track.oncuechange = onCueChange;
|
|
94
|
-
});
|
|
95
88
|
};
|
|
96
89
|
containerElement.appendChild(videoElement);
|
|
97
90
|
|
|
91
|
+
var subtitlesElement = document.createElement('div');
|
|
92
|
+
subtitlesElement.style.position = 'absolute';
|
|
93
|
+
subtitlesElement.style.right = '0';
|
|
94
|
+
subtitlesElement.style.bottom = '0';
|
|
95
|
+
subtitlesElement.style.left = '0';
|
|
96
|
+
subtitlesElement.style.zIndex = '1';
|
|
97
|
+
subtitlesElement.style.textAlign = 'center';
|
|
98
|
+
containerElement.style.position = 'relative';
|
|
99
|
+
containerElement.style.zIndex = '0';
|
|
100
|
+
containerElement.appendChild(subtitlesElement);
|
|
101
|
+
|
|
98
102
|
var events = new EventEmitter();
|
|
99
103
|
var destroyed = false;
|
|
100
104
|
var stream = null;
|
|
101
|
-
var subtitlesOffset = 0;
|
|
102
105
|
var observedProps = {
|
|
103
106
|
stream: false,
|
|
104
107
|
loaded: false,
|
|
@@ -106,7 +109,6 @@ function TitanVideo(options) {
|
|
|
106
109
|
time: false,
|
|
107
110
|
duration: false,
|
|
108
111
|
buffering: false,
|
|
109
|
-
buffered: false,
|
|
110
112
|
subtitlesTracks: false,
|
|
111
113
|
selectedSubtitlesTrackId: false,
|
|
112
114
|
subtitlesOffset: false,
|
|
@@ -121,6 +123,74 @@ function TitanVideo(options) {
|
|
|
121
123
|
playbackSpeed: false
|
|
122
124
|
};
|
|
123
125
|
|
|
126
|
+
var lastSub;
|
|
127
|
+
var disabledSubs = false;
|
|
128
|
+
|
|
129
|
+
async function refreshSubtitle() {
|
|
130
|
+
if (lastSub) {
|
|
131
|
+
renderSubtitle(lastSub.text, 'show');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
async function renderSubtitle(text, visibility) {
|
|
136
|
+
if (disabledSubs) return;
|
|
137
|
+
if (visibility === 'hide') {
|
|
138
|
+
while (subtitlesElement.hasChildNodes()) {
|
|
139
|
+
subtitlesElement.removeChild(subtitlesElement.lastChild);
|
|
140
|
+
}
|
|
141
|
+
lastSub = null;
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
lastSub = {
|
|
146
|
+
text: text,
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
while (subtitlesElement.hasChildNodes()) {
|
|
150
|
+
subtitlesElement.removeChild(subtitlesElement.lastChild);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
subtitlesElement.style.bottom = offset + '%';
|
|
154
|
+
subtitlesElement.style.opacity = subtitlesOpacity;
|
|
155
|
+
|
|
156
|
+
var cueNode = document.createElement('span');
|
|
157
|
+
cueNode.innerHTML = text;
|
|
158
|
+
cueNode.style.display = 'inline-block';
|
|
159
|
+
cueNode.style.padding = '0.2em';
|
|
160
|
+
cueNode.style.fontSize = Math.floor(size / 25) + 'vmin';
|
|
161
|
+
cueNode.style.color = textColor;
|
|
162
|
+
cueNode.style.backgroundColor = backgroundColor;
|
|
163
|
+
cueNode.style.textShadow = '1px 1px 0.1em ' + outlineColor;
|
|
164
|
+
cueNode.style.whiteSpace = 'pre-wrap';
|
|
165
|
+
|
|
166
|
+
subtitlesElement.appendChild(cueNode);
|
|
167
|
+
subtitlesElement.appendChild(document.createElement('br'));
|
|
168
|
+
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function renderCue(ev) {
|
|
172
|
+
var cues = (ev.target || {}).activeCues;
|
|
173
|
+
if (!cues.length) {
|
|
174
|
+
renderSubtitle('', 'hide');
|
|
175
|
+
} else {
|
|
176
|
+
if (cues.length > 3) {
|
|
177
|
+
// most probably SSA/ASS subs glitch
|
|
178
|
+
ev.target.removeEventListener('cuechange', renderCue);
|
|
179
|
+
renderSubtitle('', 'hide');
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
var text = '';
|
|
183
|
+
for (var i in cues) {
|
|
184
|
+
var cue = cues[i];
|
|
185
|
+
if (cue.text) {
|
|
186
|
+
var cleanedText = cue.text.replace(SSA_DESCRIPTORS_REGEX, '');
|
|
187
|
+
text += (text ? '\n' : '') + cleanedText;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
renderSubtitle(text, 'show');
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
124
194
|
function getProp(propName) {
|
|
125
195
|
switch (propName) {
|
|
126
196
|
case 'stream': {
|
|
@@ -161,20 +231,6 @@ function TitanVideo(options) {
|
|
|
161
231
|
|
|
162
232
|
return videoElement.readyState < videoElement.HAVE_FUTURE_DATA;
|
|
163
233
|
}
|
|
164
|
-
case 'buffered': {
|
|
165
|
-
if (stream === null) {
|
|
166
|
-
return null;
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
var time = videoElement.currentTime !== null && isFinite(videoElement.currentTime) ? videoElement.currentTime : 0;
|
|
170
|
-
for (var i = 0; i < videoElement.buffered.length; i++) {
|
|
171
|
-
if (videoElement.buffered.start(i) <= time && time <= videoElement.buffered.end(i)) {
|
|
172
|
-
return Math.floor(videoElement.buffered.end(i) * 1000);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
return Math.floor(time * 1000);
|
|
177
|
-
}
|
|
178
234
|
case 'subtitlesTracks': {
|
|
179
235
|
if (stream === null) {
|
|
180
236
|
return [];
|
|
@@ -209,7 +265,7 @@ function TitanVideo(options) {
|
|
|
209
265
|
|
|
210
266
|
return Array.from(videoElement.textTracks)
|
|
211
267
|
.reduce(function(result, track, index) {
|
|
212
|
-
if (result === null && track.mode === '
|
|
268
|
+
if (result === null && track.mode === 'hidden') {
|
|
213
269
|
return 'EMBEDDED_' + String(index);
|
|
214
270
|
}
|
|
215
271
|
|
|
@@ -221,35 +277,42 @@ function TitanVideo(options) {
|
|
|
221
277
|
return null;
|
|
222
278
|
}
|
|
223
279
|
|
|
224
|
-
return
|
|
280
|
+
return offset;
|
|
225
281
|
}
|
|
226
282
|
case 'subtitlesSize': {
|
|
227
283
|
if (destroyed) {
|
|
228
284
|
return null;
|
|
229
285
|
}
|
|
230
286
|
|
|
231
|
-
return
|
|
287
|
+
return size;
|
|
232
288
|
}
|
|
233
289
|
case 'subtitlesTextColor': {
|
|
234
290
|
if (destroyed) {
|
|
235
291
|
return null;
|
|
236
292
|
}
|
|
237
293
|
|
|
238
|
-
return
|
|
294
|
+
return textColor;
|
|
239
295
|
}
|
|
240
296
|
case 'subtitlesBackgroundColor': {
|
|
241
297
|
if (destroyed) {
|
|
242
298
|
return null;
|
|
243
299
|
}
|
|
244
300
|
|
|
245
|
-
return
|
|
301
|
+
return backgroundColor;
|
|
246
302
|
}
|
|
247
303
|
case 'subtitlesOutlineColor': {
|
|
248
304
|
if (destroyed) {
|
|
249
305
|
return null;
|
|
250
306
|
}
|
|
251
307
|
|
|
252
|
-
return
|
|
308
|
+
return outlineColor;
|
|
309
|
+
}
|
|
310
|
+
case 'subtitlesOpacity': {
|
|
311
|
+
if (destroyed) {
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
return subtitlesOpacity;
|
|
253
316
|
}
|
|
254
317
|
case 'audioTracks': {
|
|
255
318
|
if (stream === null) {
|
|
@@ -316,14 +379,6 @@ function TitanVideo(options) {
|
|
|
316
379
|
}
|
|
317
380
|
}
|
|
318
381
|
}
|
|
319
|
-
function onCueChange() {
|
|
320
|
-
Array.from(videoElement.textTracks).forEach(function(track) {
|
|
321
|
-
Array.from(track.cues || []).forEach(function(cue) {
|
|
322
|
-
cue.snapToLines = false;
|
|
323
|
-
cue.line = 100 - subtitlesOffset;
|
|
324
|
-
});
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
382
|
function onVideoError() {
|
|
328
383
|
if (destroyed) {
|
|
329
384
|
return;
|
|
@@ -388,6 +443,7 @@ function TitanVideo(options) {
|
|
|
388
443
|
}
|
|
389
444
|
case 'time': {
|
|
390
445
|
if (stream !== null && propValue !== null && isFinite(propValue)) {
|
|
446
|
+
renderSubtitle('', 'hide');
|
|
391
447
|
videoElement.currentTime = parseInt(propValue, 10) / 1000;
|
|
392
448
|
onPropChanged('time');
|
|
393
449
|
}
|
|
@@ -398,7 +454,13 @@ function TitanVideo(options) {
|
|
|
398
454
|
if (stream !== null) {
|
|
399
455
|
Array.from(videoElement.textTracks)
|
|
400
456
|
.forEach(function(track, index) {
|
|
401
|
-
track.mode
|
|
457
|
+
if (track.mode === 'hidden') {
|
|
458
|
+
track.removeEventListener('cuechange', renderCue);
|
|
459
|
+
}
|
|
460
|
+
track.mode = 'EMBEDDED_' + String(index) === propValue ? 'hidden' : 'disabled';
|
|
461
|
+
if (track.mode === 'hidden') {
|
|
462
|
+
track.addEventListener('cuechange', renderCue);
|
|
463
|
+
}
|
|
402
464
|
});
|
|
403
465
|
var selectedSubtitlesTrack = getProp('subtitlesTracks')
|
|
404
466
|
.find(function(track) {
|
|
@@ -414,8 +476,8 @@ function TitanVideo(options) {
|
|
|
414
476
|
}
|
|
415
477
|
case 'subtitlesOffset': {
|
|
416
478
|
if (propValue !== null && isFinite(propValue)) {
|
|
417
|
-
|
|
418
|
-
|
|
479
|
+
offset = Math.max(0, Math.min(100, parseInt(propValue, 10)));
|
|
480
|
+
refreshSubtitle();
|
|
419
481
|
onPropChanged('subtitlesOffset');
|
|
420
482
|
}
|
|
421
483
|
|
|
@@ -423,7 +485,8 @@ function TitanVideo(options) {
|
|
|
423
485
|
}
|
|
424
486
|
case 'subtitlesSize': {
|
|
425
487
|
if (propValue !== null && isFinite(propValue)) {
|
|
426
|
-
|
|
488
|
+
size = Math.max(0, parseInt(propValue, 10));
|
|
489
|
+
refreshSubtitle();
|
|
427
490
|
onPropChanged('subtitlesSize');
|
|
428
491
|
}
|
|
429
492
|
|
|
@@ -432,12 +495,13 @@ function TitanVideo(options) {
|
|
|
432
495
|
case 'subtitlesTextColor': {
|
|
433
496
|
if (typeof propValue === 'string') {
|
|
434
497
|
try {
|
|
435
|
-
|
|
498
|
+
textColor = Color(propValue).rgb().string();
|
|
436
499
|
} catch (error) {
|
|
437
500
|
// eslint-disable-next-line no-console
|
|
438
|
-
console.error('
|
|
501
|
+
console.error('Tizen player with HTML Subtitles', error);
|
|
439
502
|
}
|
|
440
503
|
|
|
504
|
+
refreshSubtitle();
|
|
441
505
|
onPropChanged('subtitlesTextColor');
|
|
442
506
|
}
|
|
443
507
|
|
|
@@ -446,12 +510,14 @@ function TitanVideo(options) {
|
|
|
446
510
|
case 'subtitlesBackgroundColor': {
|
|
447
511
|
if (typeof propValue === 'string') {
|
|
448
512
|
try {
|
|
449
|
-
|
|
513
|
+
backgroundColor = Color(propValue).rgb().string();
|
|
450
514
|
} catch (error) {
|
|
451
515
|
// eslint-disable-next-line no-console
|
|
452
|
-
console.error('
|
|
516
|
+
console.error('Tizen player with HTML Subtitles', error);
|
|
453
517
|
}
|
|
454
518
|
|
|
519
|
+
refreshSubtitle();
|
|
520
|
+
|
|
455
521
|
onPropChanged('subtitlesBackgroundColor');
|
|
456
522
|
}
|
|
457
523
|
|
|
@@ -460,17 +526,35 @@ function TitanVideo(options) {
|
|
|
460
526
|
case 'subtitlesOutlineColor': {
|
|
461
527
|
if (typeof propValue === 'string') {
|
|
462
528
|
try {
|
|
463
|
-
|
|
529
|
+
outlineColor = Color(propValue).rgb().string();
|
|
464
530
|
} catch (error) {
|
|
465
531
|
// eslint-disable-next-line no-console
|
|
466
|
-
console.error('
|
|
532
|
+
console.error('Tizen player with HTML Subtitles', error);
|
|
467
533
|
}
|
|
468
534
|
|
|
535
|
+
refreshSubtitle();
|
|
536
|
+
|
|
469
537
|
onPropChanged('subtitlesOutlineColor');
|
|
470
538
|
}
|
|
471
539
|
|
|
472
540
|
break;
|
|
473
541
|
}
|
|
542
|
+
case 'subtitlesOpacity': {
|
|
543
|
+
if (typeof propValue === 'number') {
|
|
544
|
+
try {
|
|
545
|
+
subtitlesOpacity = Math.min(Math.max(propValue / 100, 0), 1);
|
|
546
|
+
} catch (error) {
|
|
547
|
+
// eslint-disable-next-line no-console
|
|
548
|
+
console.error('Tizen player with HTML Subtitles', error);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
refreshSubtitle();
|
|
552
|
+
|
|
553
|
+
onPropChanged('subtitlesOpacity');
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
break;
|
|
557
|
+
}
|
|
474
558
|
case 'selectedAudioTrackId': {
|
|
475
559
|
if (stream !== null) {
|
|
476
560
|
for (var index = 0; index < videoElement.audioTracks.length; index++) {
|
|
@@ -529,7 +613,6 @@ function TitanVideo(options) {
|
|
|
529
613
|
onPropChanged('time');
|
|
530
614
|
onPropChanged('duration');
|
|
531
615
|
onPropChanged('buffering');
|
|
532
|
-
onPropChanged('buffered');
|
|
533
616
|
if (videoElement.textTracks) {
|
|
534
617
|
videoElement.textTracks.onaddtrack = function() {
|
|
535
618
|
videoElement.textTracks.onaddtrack = null;
|
|
@@ -571,7 +654,6 @@ function TitanVideo(options) {
|
|
|
571
654
|
onPropChanged('time');
|
|
572
655
|
onPropChanged('duration');
|
|
573
656
|
onPropChanged('buffering');
|
|
574
|
-
onPropChanged('buffered');
|
|
575
657
|
onPropChanged('subtitlesTracks');
|
|
576
658
|
onPropChanged('selectedSubtitlesTrackId');
|
|
577
659
|
onPropChanged('audioTracks');
|
|
@@ -608,7 +690,6 @@ function TitanVideo(options) {
|
|
|
608
690
|
videoElement.onratechange = null;
|
|
609
691
|
videoElement.textTracks.onchange = null;
|
|
610
692
|
containerElement.removeChild(videoElement);
|
|
611
|
-
containerElement.removeChild(styleElement);
|
|
612
693
|
break;
|
|
613
694
|
}
|
|
614
695
|
}
|
|
@@ -659,7 +740,7 @@ TitanVideo.canPlayStream = function(stream) {
|
|
|
659
740
|
TitanVideo.manifest = {
|
|
660
741
|
name: 'TitanVideo',
|
|
661
742
|
external: false,
|
|
662
|
-
props: ['stream', 'loaded', 'paused', 'time', 'duration', 'buffering', '
|
|
743
|
+
props: ['stream', 'loaded', 'paused', 'time', 'duration', 'buffering', 'audioTracks', 'selectedAudioTrackId', 'subtitlesTracks', 'selectedSubtitlesTrackId', 'subtitlesOffset', 'subtitlesSize', 'subtitlesTextColor', 'subtitlesBackgroundColor', 'subtitlesOutlineColor', 'subtitlesOpacity', 'volume', 'muted', 'playbackSpeed'],
|
|
663
744
|
commands: ['load', 'unload', 'destroy'],
|
|
664
745
|
events: ['propValue', 'propChanged', 'ended', 'error', 'subtitlesTrackLoaded', 'audioTrackLoaded']
|
|
665
746
|
};
|
|
@@ -225,15 +225,36 @@ function withHTMLSubtitles(Video) {
|
|
|
225
225
|
if (selectedTrack) {
|
|
226
226
|
selectedTrackId = selectedTrack.id;
|
|
227
227
|
delay = 0;
|
|
228
|
-
function loadSubtitleFromUrl(url, isFallback) {
|
|
229
|
-
fetch(url)
|
|
230
|
-
.then(function(resp) {
|
|
231
|
-
if (resp.ok) {
|
|
232
|
-
return resp.text();
|
|
233
|
-
}
|
|
234
228
|
|
|
235
|
-
|
|
236
|
-
|
|
229
|
+
function getSubtitlesData(track, isFallback) {
|
|
230
|
+
var url = isFallback ? track.fallbackUrl : track.url;
|
|
231
|
+
|
|
232
|
+
if (typeof url === 'string') {
|
|
233
|
+
return fetch(url)
|
|
234
|
+
.then(function(resp) {
|
|
235
|
+
if (resp.ok) {
|
|
236
|
+
return resp.text();
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
throw new Error(resp.status + ' (' + resp.statusText + ')');
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
if (track.buffer instanceof ArrayBuffer) {
|
|
244
|
+
try {
|
|
245
|
+
const uInt8Array = new Uint8Array(track.buffer);
|
|
246
|
+
const text = new TextDecoder().decode(uInt8Array);
|
|
247
|
+
return Promise.resolve(text);
|
|
248
|
+
} catch(e) {
|
|
249
|
+
return Promise.reject(e);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return Promise.reject('No `url` or `buffer` field available for this track');
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
function loadSubtitles(track, isFallback) {
|
|
257
|
+
getSubtitlesData(track, isFallback)
|
|
237
258
|
.then(function(text) {
|
|
238
259
|
return subtitlesConverter.convert(text);
|
|
239
260
|
})
|
|
@@ -255,7 +276,7 @@ function withHTMLSubtitles(Video) {
|
|
|
255
276
|
}
|
|
256
277
|
|
|
257
278
|
if (!isFallback && typeof selectedTrack.fallbackUrl === 'string') {
|
|
258
|
-
|
|
279
|
+
loadSubtitles(selectedTrack, true);
|
|
259
280
|
return;
|
|
260
281
|
}
|
|
261
282
|
|
|
@@ -266,7 +287,7 @@ function withHTMLSubtitles(Video) {
|
|
|
266
287
|
}));
|
|
267
288
|
});
|
|
268
289
|
}
|
|
269
|
-
|
|
290
|
+
loadSubtitles(selectedTrack);
|
|
270
291
|
}
|
|
271
292
|
renderSubtitles();
|
|
272
293
|
onPropChanged('selectedExtraSubtitlesTrackId');
|
|
@@ -374,7 +395,6 @@ function withHTMLSubtitles(Video) {
|
|
|
374
395
|
.filter(function(track, index, tracks) {
|
|
375
396
|
return track &&
|
|
376
397
|
typeof track.id === 'string' &&
|
|
377
|
-
typeof track.url === 'string' &&
|
|
378
398
|
typeof track.lang === 'string' &&
|
|
379
399
|
typeof track.label === 'string' &&
|
|
380
400
|
typeof track.origin === 'string' &&
|
|
@@ -386,6 +406,31 @@ function withHTMLSubtitles(Video) {
|
|
|
386
406
|
|
|
387
407
|
return true;
|
|
388
408
|
}
|
|
409
|
+
case 'addLocalSubtitles': {
|
|
410
|
+
if (commandArgs && typeof commandArgs.filename === 'string' && commandArgs.buffer instanceof ArrayBuffer) {
|
|
411
|
+
var id = 'LOCAL_' + tracks
|
|
412
|
+
.filter(function(track) { return track.local; })
|
|
413
|
+
.length;
|
|
414
|
+
|
|
415
|
+
var track = {
|
|
416
|
+
id: id,
|
|
417
|
+
url: null,
|
|
418
|
+
buffer: commandArgs.buffer,
|
|
419
|
+
lang: 'local',
|
|
420
|
+
label: commandArgs.filename,
|
|
421
|
+
origin: 'LOCAL',
|
|
422
|
+
local: true,
|
|
423
|
+
embedded: false,
|
|
424
|
+
};
|
|
425
|
+
|
|
426
|
+
tracks.push(track);
|
|
427
|
+
|
|
428
|
+
onPropChanged('extraSubtitlesTracks');
|
|
429
|
+
events.emit('extraSubtitlesTrackAdded', track);
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
return true;
|
|
433
|
+
}
|
|
389
434
|
case 'load': {
|
|
390
435
|
command('unload');
|
|
391
436
|
if (commandArgs.stream && Array.isArray(commandArgs.stream.subtitles)) {
|
|
@@ -485,9 +530,9 @@ function withHTMLSubtitles(Video) {
|
|
|
485
530
|
external: Video.manifest.external,
|
|
486
531
|
props: Video.manifest.props.concat(['extraSubtitlesTracks', 'selectedExtraSubtitlesTrackId', 'extraSubtitlesDelay', 'extraSubtitlesSize', 'extraSubtitlesOffset', 'extraSubtitlesTextColor', 'extraSubtitlesBackgroundColor', 'extraSubtitlesOutlineColor', 'extraSubtitlesOpacity'])
|
|
487
532
|
.filter(function(value, index, array) { return array.indexOf(value) === index; }),
|
|
488
|
-
commands: Video.manifest.commands.concat(['load', 'unload', 'destroy', 'addExtraSubtitlesTracks'])
|
|
533
|
+
commands: Video.manifest.commands.concat(['load', 'unload', 'destroy', 'addExtraSubtitlesTracks', 'addLocalSubtitles'])
|
|
489
534
|
.filter(function(value, index, array) { return array.indexOf(value) === index; }),
|
|
490
|
-
events: Video.manifest.events.concat(['propValue', 'propChanged', 'error', 'extraSubtitlesTrackLoaded'])
|
|
535
|
+
events: Video.manifest.events.concat(['propValue', 'propChanged', 'error', 'extraSubtitlesTrackLoaded', 'extraSubtitlesTrackAdded'])
|
|
491
536
|
.filter(function(value, index, array) { return array.indexOf(value) === index; })
|
|
492
537
|
};
|
|
493
538
|
|