@stremio/stremio-video 0.0.76 → 0.0.78

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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stremio/stremio-video",
3
- "version": "0.0.76",
3
+ "version": "0.0.78",
4
4
  "description": "Abstraction layer on top of different media players",
5
5
  "author": "Smart Code OOD",
6
6
  "main": "src/index.js",
@@ -22,6 +22,7 @@ function HTMLVideo(options) {
22
22
  videoElement.style.width = '100%';
23
23
  videoElement.style.height = '100%';
24
24
  videoElement.style.backgroundColor = 'black';
25
+ videoElement.style.objectFit = 'contain';
25
26
  videoElement.controls = false;
26
27
  videoElement.playsInline = true;
27
28
  videoElement.onerror = function() {
@@ -123,7 +124,8 @@ function HTMLVideo(options) {
123
124
  selectedAudioTrackId: false,
124
125
  volume: false,
125
126
  muted: false,
126
- playbackSpeed: false
127
+ playbackSpeed: false,
128
+ videoScale: false
127
129
  };
128
130
 
129
131
  function getProp(propName) {
@@ -253,39 +255,49 @@ function HTMLVideo(options) {
253
255
  return Math.round(subtitlesOpacity * 100);
254
256
  }
255
257
  case 'audioTracks': {
256
- if (hls === null || !Array.isArray(hls.audioTracks)) {
258
+ if (hls === null || !Array.isArray(hls.allAudioTracks)) {
257
259
  return [];
258
260
  }
259
261
 
260
- return hls.audioTracks
261
- .map(function(track) {
262
+ return hls.allAudioTracks
263
+ .map(function(track, index) {
262
264
  return Object.freeze({
263
- id: 'EMBEDDED_' + String(track.id),
265
+ id: 'EMBEDDED_' + String(index),
264
266
  lang: typeof track.lang === 'string' && track.lang.length > 0 ?
265
267
  track.lang
266
268
  :
267
269
  typeof track.name === 'string' && track.name.length > 0 ?
268
270
  track.name
269
271
  :
270
- String(track.id),
272
+ String(index),
271
273
  label: typeof track.name === 'string' && track.name.length > 0 ?
272
274
  track.name
273
275
  :
274
276
  typeof track.lang === 'string' && track.lang.length > 0 ?
275
277
  track.lang
276
278
  :
277
- String(track.id),
279
+ String(index),
278
280
  origin: 'EMBEDDED',
279
281
  embedded: true
280
282
  });
281
283
  });
282
284
  }
283
285
  case 'selectedAudioTrackId': {
284
- if (hls === null || hls.audioTrack === null || !isFinite(hls.audioTrack) || hls.audioTrack === -1) {
286
+ if (hls === null || hls.audioTrack === -1) {
287
+ return null;
288
+ }
289
+
290
+ var currentGroupTrack = hls.audioTracks[hls.audioTrack];
291
+ if (!currentGroupTrack) {
292
+ return null;
293
+ }
294
+
295
+ var allTracksIndex = hls.allAudioTracks.indexOf(currentGroupTrack);
296
+ if (allTracksIndex === -1) {
285
297
  return null;
286
298
  }
287
299
 
288
- return 'EMBEDDED_' + String(hls.audioTrack);
300
+ return 'EMBEDDED_' + String(allTracksIndex);
289
301
  }
290
302
  case 'volume': {
291
303
  if (destroyed || videoElement.volume === null || !isFinite(videoElement.volume)) {
@@ -308,6 +320,9 @@ function HTMLVideo(options) {
308
320
 
309
321
  return videoElement.playbackRate;
310
322
  }
323
+ case 'videoScale': {
324
+ return videoElement.style.objectFit || 'contain';
325
+ }
311
326
  default: {
312
327
  return null;
313
328
  }
@@ -486,14 +501,18 @@ function HTMLVideo(options) {
486
501
  }
487
502
  case 'selectedAudioTrackId': {
488
503
  if (hls !== null) {
489
- var selecterdAudioTrack = getProp('audioTracks')
504
+ var selectedAudioTrack = getProp('audioTracks')
490
505
  .find(function(track) {
491
506
  return track.id === propValue;
492
507
  });
493
- hls.audioTrack = selecterdAudioTrack ? parseInt(selecterdAudioTrack.id.split('_').pop(), 10) : -1;
494
- if (selecterdAudioTrack) {
508
+ if (selectedAudioTrack) {
509
+ var trackIndex = parseInt(selectedAudioTrack.id.split('_').pop(), 10);
510
+ var allTracks = hls.allAudioTracks;
511
+ if (trackIndex >= 0 && trackIndex < allTracks.length) {
512
+ hls.setAudioOption(allTracks[trackIndex]);
513
+ }
495
514
  onPropChanged('selectedAudioTrackId');
496
- events.emit('audioTrackLoaded', selecterdAudioTrack);
515
+ events.emit('audioTrackLoaded', selectedAudioTrack);
497
516
  }
498
517
  }
499
518
 
@@ -520,6 +539,15 @@ function HTMLVideo(options) {
520
539
  onPropChanged('playbackSpeed');
521
540
  }
522
541
 
542
+ break;
543
+ }
544
+ case 'videoScale': {
545
+ var validValues = ['contain', 'cover', 'fill'];
546
+ if (validValues.indexOf(propValue) !== -1) {
547
+ videoElement.style.objectFit = propValue;
548
+ onPropChanged('videoScale');
549
+ }
550
+
523
551
  break;
524
552
  }
525
553
  }
@@ -559,6 +587,9 @@ function HTMLVideo(options) {
559
587
  onPropChanged('audioTracks');
560
588
  onPropChanged('selectedAudioTrackId');
561
589
  });
590
+ hls.on(Hls.Events.MANIFEST_LOADING, function() {
591
+ hls.subtitleTrack = -1;
592
+ });
562
593
  hls.loadSource(stream.url);
563
594
  hls.attachMedia(videoElement);
564
595
  } else {
@@ -696,7 +727,7 @@ HTMLVideo.canPlayStream = function(stream) {
696
727
  HTMLVideo.manifest = {
697
728
  name: 'HTMLVideo',
698
729
  external: false,
699
- props: ['stream', 'loaded', 'paused', 'time', 'duration', 'buffering', 'buffered', 'audioTracks', 'selectedAudioTrackId', 'subtitlesTracks', 'selectedSubtitlesTrackId', 'subtitlesOffset', 'subtitlesSize', 'subtitlesTextColor', 'subtitlesBackgroundColor', 'subtitlesOutlineColor', 'subtitlesOpacity', 'volume', 'muted', 'playbackSpeed'],
730
+ props: ['stream', 'loaded', 'paused', 'time', 'duration', 'buffering', 'buffered', 'audioTracks', 'selectedAudioTrackId', 'subtitlesTracks', 'selectedSubtitlesTrackId', 'subtitlesOffset', 'subtitlesSize', 'subtitlesTextColor', 'subtitlesBackgroundColor', 'subtitlesOutlineColor', 'subtitlesOpacity', 'volume', 'muted', 'playbackSpeed', 'videoScale'],
700
731
  commands: ['load', 'unload', 'destroy'],
701
732
  events: ['propValue', 'propChanged', 'ended', 'error', 'subtitlesTrackLoaded', 'audioTrackLoaded']
702
733
  };
@@ -27,6 +27,7 @@ var stremioToMPVProps = {
27
27
  'subtitlesBackgroundColor': 'sub-back-color',
28
28
  'subtitlesOutlineColor': 'sub-border-color',
29
29
  'hdrInfo': null,
30
+ 'videoScale': null,
30
31
  };
31
32
 
32
33
  function parseVersion(version) {
@@ -262,6 +263,7 @@ function ShellVideo(options) {
262
263
 
263
264
  function getProp(propName) {
264
265
  if (propName === 'hdrInfo') return props.hdrInfo || null;
266
+ if (propName === 'videoScale') return props.videoScale || 'contain';
265
267
  if(stremioToMPVProps[propName]) return props[stremioToMPVProps[propName]];
266
268
  // eslint-disable-next-line no-console
267
269
  console.log('Unsupported prop requested', propName);
@@ -307,6 +309,27 @@ function ShellVideo(options) {
307
309
  }
308
310
  break;
309
311
  }
312
+ case 'videoScale': {
313
+ if (stream !== null) {
314
+ switch (propValue) {
315
+ case 'cover':
316
+ ipc.send('mpv-set-prop', ['keepaspect', true]);
317
+ ipc.send('mpv-set-prop', ['panscan', 1.0]);
318
+ break;
319
+ case 'fill':
320
+ ipc.send('mpv-set-prop', ['keepaspect', false]);
321
+ ipc.send('mpv-set-prop', ['panscan', 0.0]);
322
+ break;
323
+ default:
324
+ ipc.send('mpv-set-prop', ['keepaspect', true]);
325
+ ipc.send('mpv-set-prop', ['panscan', 0.0]);
326
+ break;
327
+ }
328
+ props.videoScale = propValue;
329
+ onPropChanged('videoScale');
330
+ }
331
+ break;
332
+ }
310
333
  case 'volume': {
311
334
  if (stream !== null && propValue !== null && isFinite(propValue)) {
312
335
  props.mute = false;
@@ -390,14 +413,9 @@ function ShellVideo(options) {
390
413
  var hwdecValue = commandArgs.hardwareDecoding ? 'auto-copy' : 'no';
391
414
  ipc.send('mpv-set-prop', ['hwdec', hwdecValue]);
392
415
 
393
- // On macOS the shell manages vo and HDR/EDR configuration
394
- // directly do not override vo here.
395
- var platformLower = String(commandArgs.platform || '').toLowerCase();
396
- var isMac = platformLower.indexOf('mac') !== -1;
397
- if (!isMac) {
398
- var videoOutput = platformLower === 'windows' ? (commandArgs.videoMode === null ? 'gpu-next' : 'gpu') : 'libmpv';
399
- ipc.send('mpv-set-prop', ['vo', videoOutput]);
400
- }
416
+ // Video output
417
+ var videoOutput = commandArgs.platform === 'windows' ? (commandArgs.videoMode === null ? 'gpu-next' : 'gpu') : 'libmpv';
418
+ ipc.send('mpv-set-prop', ['vo', videoOutput]);
401
419
 
402
420
  var separateWindow = options.mpvSeparateWindow ? 'yes' : 'no';
403
421
  ipc.send('mpv-set-prop', ['osc', separateWindow]);
@@ -352,7 +352,9 @@ function WebOsVideo(options) {
352
352
  mode: audioTrackId === currentAudioTrack ? 'showing' : 'disabled',
353
353
  });
354
354
  });
355
- currentAudioTrack = 'EMBEDDED_0';
355
+ if (!currentAudioTrack) {
356
+ currentAudioTrack = 'EMBEDDED_0';
357
+ }
356
358
  onPropChanged('audioTracks');
357
359
  onPropChanged('selectedAudioTrackId');
358
360
  }
@@ -189,6 +189,10 @@ function withHTMLSubtitles(Video) {
189
189
  }
190
190
 
191
191
  events.emit(eventName, propName, getProp(propName, propValue));
192
+
193
+ if (propName === 'selectedSubtitlesTrackId' && propValue !== null && selectedTrackId !== null) {
194
+ setProp('selectedExtraSubtitlesTrackId', null);
195
+ }
192
196
  }
193
197
  function onOtherVideoEvent(eventName) {
194
198
  return function() {
@@ -300,6 +304,13 @@ function withHTMLSubtitles(Video) {
300
304
  function setProp(propName, propValue) {
301
305
  switch (propName) {
302
306
  case 'selectedExtraSubtitlesTrackId': {
307
+ if (propValue !== null) {
308
+ video.dispatch({
309
+ type: 'setProp',
310
+ propName: 'selectedSubtitlesTrackId',
311
+ propValue: null,
312
+ });
313
+ }
303
314
  if (propValue !== null && selectedTrackId === propValue) {
304
315
  return true;
305
316
  }
@@ -375,7 +375,10 @@ function withStreamingServer(Video) {
375
375
 
376
376
  return true;
377
377
  });
378
- return isFormatSupported && areStreamsSupported;
378
+ var hasEmbeddedSubtitles = probe.streams.some(function(stream) {
379
+ return stream.track === 'subtitle';
380
+ });
381
+ return isFormatSupported && areStreamsSupported && !hasEmbeddedSubtitles;
379
382
  })
380
383
  .catch(function() {
381
384
  // this uses content-type header in HTMLVideo which