@stremio/stremio-video 0.0.45 → 0.0.47
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
|
@@ -6,6 +6,7 @@ var ERROR = require('../error');
|
|
|
6
6
|
var SUBS_SCALE_FACTOR = 0.0066;
|
|
7
7
|
|
|
8
8
|
var stremioToMPVProps = {
|
|
9
|
+
'loaded': 'loaded',
|
|
9
10
|
'stream': null,
|
|
10
11
|
'paused': 'pause',
|
|
11
12
|
'time': 'time-pos',
|
|
@@ -24,17 +25,35 @@ var stremioToMPVProps = {
|
|
|
24
25
|
'subtitlesOutlineColor': 'sub-border-color',
|
|
25
26
|
};
|
|
26
27
|
|
|
28
|
+
function parseVersion(version) {
|
|
29
|
+
return version.split('.').slice(0, 2).map(function (v) { return parseInt(v); });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function versionGTE(a, b) {
|
|
33
|
+
var versionA = parseVersion(a);
|
|
34
|
+
var versionB = parseVersion(b);
|
|
35
|
+
if (versionA[0] > versionB[0]) return true;
|
|
36
|
+
if (versionA[0] < versionB[0]) return false;
|
|
37
|
+
return versionA[1] >= versionB[1];
|
|
38
|
+
}
|
|
39
|
+
|
|
27
40
|
function ShellVideo(options) {
|
|
28
41
|
options = options || {};
|
|
29
42
|
|
|
30
43
|
var ipc = options.shellTransport;
|
|
31
|
-
|
|
44
|
+
var observedProps = {};
|
|
45
|
+
var props = {};
|
|
32
46
|
var stremioProps = {};
|
|
33
47
|
Object.keys(stremioToMPVProps).forEach(function(key) {
|
|
34
48
|
if(stremioToMPVProps[key]) {
|
|
35
49
|
stremioProps[stremioToMPVProps[key]] = key;
|
|
36
50
|
}
|
|
37
51
|
});
|
|
52
|
+
var resolveMPVVersion;
|
|
53
|
+
var waitForMPVVersion = new Promise(function (resolve) {
|
|
54
|
+
resolveMPVVersion = resolve;
|
|
55
|
+
});
|
|
56
|
+
command('unload');
|
|
38
57
|
|
|
39
58
|
ipc.send('mpv-command', ['stop']);
|
|
40
59
|
ipc.send('mpv-observe-prop', 'path');
|
|
@@ -66,13 +85,9 @@ function ShellVideo(options) {
|
|
|
66
85
|
var events = new EventEmitter();
|
|
67
86
|
var destroyed = false;
|
|
68
87
|
var stream = null;
|
|
69
|
-
// var selectedSubtitlesTrackId = null;
|
|
70
|
-
var observedProps = {};
|
|
71
|
-
var continueFrom = 0;
|
|
72
88
|
|
|
73
89
|
var avgDuration = 0;
|
|
74
90
|
var minClipDuration = 30;
|
|
75
|
-
var props = { };
|
|
76
91
|
|
|
77
92
|
function setBackground(visible) {
|
|
78
93
|
// This is a bit of a hack but there is no better way so far
|
|
@@ -93,11 +108,15 @@ function ShellVideo(options) {
|
|
|
93
108
|
ipc.on('mpv-prop-change', function(args) {
|
|
94
109
|
switch (args.name) {
|
|
95
110
|
case 'mpv-version':
|
|
111
|
+
resolveMPVVersion(args.data);
|
|
112
|
+
props[args.name] = logProp(args);
|
|
113
|
+
break;
|
|
96
114
|
case 'ffmpeg-version': {
|
|
97
115
|
props[args.name] = logProp(args);
|
|
98
116
|
break;
|
|
99
117
|
}
|
|
100
118
|
case 'duration': {
|
|
119
|
+
setBackground(false);
|
|
101
120
|
var intDuration = args.data | 0;
|
|
102
121
|
// Accumulate average duration over time. if it is greater than minClipDuration
|
|
103
122
|
// and equal to the currently reported duration, it is returned as video length.
|
|
@@ -111,15 +130,12 @@ function ShellVideo(options) {
|
|
|
111
130
|
// for bitwise maths so the maximum supported video duration is 1073741823 (2 ^ 30 - 1)
|
|
112
131
|
// which is around 34 years of playback time.
|
|
113
132
|
avgDuration = avgDuration ? (avgDuration + intDuration) >> 1 : intDuration;
|
|
133
|
+
props.loaded = intDuration > 0;
|
|
134
|
+
if(props.loaded) onPropChanged('loaded');
|
|
114
135
|
break;
|
|
115
136
|
}
|
|
116
137
|
case 'time-pos': {
|
|
117
138
|
props[args.name] = Math.round(args.data*1000);
|
|
118
|
-
if(continueFrom) {
|
|
119
|
-
ipc.send('mpv-set-prop', ['time-pos', continueFrom]);
|
|
120
|
-
props[args.name] = Math.round(continueFrom);
|
|
121
|
-
continueFrom = 0;
|
|
122
|
-
}
|
|
123
139
|
break;
|
|
124
140
|
}
|
|
125
141
|
case 'sub-scale': {
|
|
@@ -306,60 +322,76 @@ function ShellVideo(options) {
|
|
|
306
322
|
case 'load': {
|
|
307
323
|
command('unload');
|
|
308
324
|
if (commandArgs && commandArgs.stream && typeof commandArgs.stream.url === 'string') {
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
325
|
+
waitForMPVVersion.then(function (mpvVersion) {
|
|
326
|
+
stream = commandArgs.stream;
|
|
327
|
+
onPropChanged('stream');
|
|
312
328
|
|
|
313
|
-
|
|
329
|
+
ipc.send('mpv-set-prop', ['no-sub-ass']);
|
|
314
330
|
|
|
315
|
-
|
|
331
|
+
// opengl-cb is an alias for the new name "libmpv", as shown in mpv's video/out/vo.c aliases
|
|
332
|
+
// opengl is an alias for the new name "gpu"
|
|
333
|
+
// When on Windows we use d3d for the rendering in separate window
|
|
334
|
+
var windowRenderer = navigator.platform === 'Win32' ? 'direct3d' : 'opengl';
|
|
335
|
+
var videoOutput = options.mpvSeparateWindow ? windowRenderer : 'opengl-cb';
|
|
336
|
+
var separateWindow = options.mpvSeparateWindow ? 'yes' : 'no';
|
|
337
|
+
ipc.send('mpv-set-prop', ['vo', videoOutput]);
|
|
338
|
+
ipc.send('mpv-set-prop', ['osc', separateWindow]);
|
|
339
|
+
ipc.send('mpv-set-prop', ['input-defalt-bindings', separateWindow]);
|
|
340
|
+
ipc.send('mpv-set-prop', ['input-vo-keyboard', separateWindow]);
|
|
316
341
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
342
|
+
var startAt = Math.floor(parseInt(commandArgs.time, 10) / 1000) || 0;
|
|
343
|
+
if (startAt !== 0) {
|
|
344
|
+
if (versionGTE(mpvVersion, '0.39')) {
|
|
345
|
+
ipc.send('mpv-command', ['loadfile', stream.url, 'replace', '-1', 'start=+' + startAt]);
|
|
346
|
+
} else {
|
|
347
|
+
ipc.send('mpv-command', ['loadfile', stream.url, 'replace', 'start=+' + startAt]);
|
|
348
|
+
}
|
|
349
|
+
} else {
|
|
350
|
+
ipc.send('mpv-command', ['loadfile', stream.url]);
|
|
351
|
+
}
|
|
352
|
+
ipc.send('mpv-set-prop', ['pause', false]);
|
|
353
|
+
ipc.send('mpv-set-prop', ['speed', props.speed]);
|
|
354
|
+
if (props.aid) {
|
|
355
|
+
if (typeof props.aid === 'string' && props.aid.startsWith('EMBEDDED_')) {
|
|
356
|
+
ipc.send('mpv-set-prop', ['aid', props.aid.slice('EMBEDDED_'.length)]);
|
|
357
|
+
} else {
|
|
358
|
+
ipc.send('mpv-set-prop', ['aid', props.aid]);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
ipc.send('mpv-set-prop', ['mute', 'no']);
|
|
327
362
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
onPropChanged('buffering');
|
|
338
|
-
onPropChanged('volume');
|
|
339
|
-
onPropChanged('muted');
|
|
340
|
-
onPropChanged('subtitlesTracks');
|
|
341
|
-
onPropChanged('selectedSubtitlesTrackId');
|
|
363
|
+
onPropChanged('paused');
|
|
364
|
+
onPropChanged('time');
|
|
365
|
+
onPropChanged('duration');
|
|
366
|
+
onPropChanged('buffering');
|
|
367
|
+
onPropChanged('volume');
|
|
368
|
+
onPropChanged('muted');
|
|
369
|
+
onPropChanged('subtitlesTracks');
|
|
370
|
+
onPropChanged('selectedSubtitlesTrackId');
|
|
371
|
+
});
|
|
342
372
|
} else {
|
|
343
373
|
onError(Object.assign({}, ERROR.UNSUPPORTED_STREAM, {
|
|
344
374
|
critical: true,
|
|
345
375
|
stream: commandArgs ? commandArgs.stream : null
|
|
346
376
|
}));
|
|
347
377
|
}
|
|
348
|
-
|
|
349
378
|
break;
|
|
350
379
|
}
|
|
351
380
|
case 'unload': {
|
|
352
381
|
props = {
|
|
382
|
+
loaded: false,
|
|
383
|
+
pause: false,
|
|
353
384
|
mute: false,
|
|
354
385
|
speed: 1,
|
|
355
386
|
subtitlesTracks: [],
|
|
356
|
-
|
|
387
|
+
audioTracks: [],
|
|
388
|
+
buffering: false,
|
|
357
389
|
aid: null,
|
|
358
390
|
sid: null,
|
|
359
391
|
};
|
|
360
|
-
continueFrom = 0;
|
|
361
392
|
avgDuration = 0;
|
|
362
393
|
ipc.send('mpv-command', ['stop']);
|
|
394
|
+
onPropChanged('loaded');
|
|
363
395
|
onPropChanged('stream');
|
|
364
396
|
onPropChanged('paused');
|
|
365
397
|
onPropChanged('time');
|
|
@@ -6,6 +6,8 @@ var ERROR = require('../error');
|
|
|
6
6
|
var getTracksData = require('../tracksData');
|
|
7
7
|
var createAVPlay = require('./AVPlay');
|
|
8
8
|
|
|
9
|
+
var SSA_DESCRIPTORS_REGEX = /^\{(\\an[1-8])+\}/i;
|
|
10
|
+
|
|
9
11
|
function TizenVideo(options) {
|
|
10
12
|
options = options || {};
|
|
11
13
|
|
|
@@ -50,10 +52,12 @@ function TizenVideo(options) {
|
|
|
50
52
|
async function renderSubtitle(duration, text) {
|
|
51
53
|
if (disabledSubs) return;
|
|
52
54
|
var now = await getProp('time');
|
|
55
|
+
var cleanedText = text.replace(SSA_DESCRIPTORS_REGEX, '');
|
|
56
|
+
|
|
53
57
|
// we ignore custom delay here, it's not needed for embedded subs
|
|
54
58
|
lastSub = {
|
|
55
59
|
duration: duration,
|
|
56
|
-
text:
|
|
60
|
+
text: cleanedText,
|
|
57
61
|
now: now,
|
|
58
62
|
};
|
|
59
63
|
if (subtitleTimeout) {
|
|
@@ -69,7 +73,7 @@ function TizenVideo(options) {
|
|
|
69
73
|
subtitlesElement.style.opacity = subtitlesOpacity;
|
|
70
74
|
|
|
71
75
|
var cueNode = document.createElement('span');
|
|
72
|
-
cueNode.innerHTML =
|
|
76
|
+
cueNode.innerHTML = cleanedText;
|
|
73
77
|
cueNode.style.display = 'inline-block';
|
|
74
78
|
cueNode.style.padding = '0.2em';
|
|
75
79
|
cueNode.style.fontSize = Math.floor(size / 25) + 'vmin';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
function supportsTranscoding() {
|
|
2
|
-
if (typeof global.tizen !== 'undefined' || typeof global.webOS !== 'undefined') {
|
|
2
|
+
if (typeof global.tizen !== 'undefined' || typeof global.webOS !== 'undefined' || typeof window.qt !== 'undefined') {
|
|
3
3
|
return Promise.resolve(false);
|
|
4
4
|
}
|
|
5
5
|
return Promise.resolve(true);
|