@stremio/stremio-video 0.0.38 → 0.0.39

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.38",
3
+ "version": "0.0.39",
4
4
  "description": "Abstraction layer on top of different media players",
5
5
  "author": "Smart Code OOD",
6
6
  "main": "src/index.js",
@@ -23,7 +23,7 @@
23
23
  "magnet-uri": "6.2.0",
24
24
  "url": "0.11.0",
25
25
  "video-name-parser": "1.4.6",
26
- "vtt.js": "github:jaruba/vtt.js#e4f5f5603730866bacb174a93f51b734c9f29e6a"
26
+ "vtt.js": "github:jaruba/vtt.js#84d33d157848407d790d78423dacc41a096294f0"
27
27
  },
28
28
  "devDependencies": {
29
29
  "eslint": "7.32.0"
@@ -100,9 +100,6 @@ function TizenVideo(options) {
100
100
  oncurrentplaytime: function() {
101
101
  onPropChanged('time');
102
102
  },
103
- onerror: function() {
104
- onVideoError();
105
- },
106
103
  onsubtitlechange: function(duration, text) {
107
104
  renderSubtitle(duration, text);
108
105
  },
@@ -128,8 +125,12 @@ function TizenVideo(options) {
128
125
  var events = new EventEmitter();
129
126
  var destroyed = false;
130
127
  var stream = null;
128
+ var retries = 0;
129
+ var maxRetries = 5;
130
+ var isLoaded = null;
131
131
  var observedProps = {
132
132
  stream: false,
133
+ loaded: false,
133
134
  paused: false,
134
135
  time: false,
135
136
  duration: false,
@@ -152,6 +153,9 @@ function TizenVideo(options) {
152
153
  case 'stream': {
153
154
  return stream;
154
155
  }
156
+ case 'loaded': {
157
+ return isLoaded;
158
+ }
155
159
  case 'paused': {
156
160
  if (stream === null) {
157
161
  return null;
@@ -350,18 +354,6 @@ function TizenVideo(options) {
350
354
  }
351
355
  }
352
356
  }
353
- function onVideoError() {
354
- if (destroyed) {
355
- return;
356
- }
357
-
358
- var error;
359
- error = ERROR.UNKNOWN_ERROR;
360
- onError(Object.assign({}, error, {
361
- critical: true,
362
- error: error
363
- }));
364
- }
365
357
  function onError(error) {
366
358
  events.emit('error', error);
367
359
  if (error.critical) {
@@ -593,19 +585,35 @@ function TizenVideo(options) {
593
585
  window.webapis.avplay.setDisplayRect(0, 0, window.innerWidth, window.innerHeight);
594
586
  window.webapis.avplay.setDisplayMethod('PLAYER_DISPLAY_MODE_LETTER_BOX');
595
587
  window.webapis.avplay.seekTo(commandArgs.time !== null && isFinite(commandArgs.time) ? parseInt(commandArgs.time, 10) : 0);
596
- window.webapis.avplay.prepare();
597
- onPropChanged('duration');
598
- window.webapis.avplay.play();
599
-
600
- onPropChanged('stream');
601
- onPropChanged('paused');
602
- onPropChanged('time');
603
- onPropChanged('duration');
604
- onPropChanged('subtitlesTracks');
605
- onPropChanged('selectedSubtitlesTrackId');
606
- onPropChanged('audioTracks');
607
- onPropChanged('selectedAudioTrackId');
588
+ window.webapis.avplay.prepareAsync(function() {
589
+ onPropChanged('duration');
590
+ window.webapis.avplay.play();
608
591
 
592
+ isLoaded = true;
593
+ onPropChanged('loaded');
594
+ onPropChanged('stream');
595
+ onPropChanged('paused');
596
+ onPropChanged('time');
597
+ onPropChanged('duration');
598
+ onPropChanged('subtitlesTracks');
599
+ onPropChanged('selectedSubtitlesTrackId');
600
+ onPropChanged('audioTracks');
601
+ onPropChanged('selectedAudioTrackId');
602
+ }, function(error) {
603
+ if (retries < maxRetries) {
604
+ retries++;
605
+ try {
606
+ window.webapis.avplay.stop();
607
+ } catch(e) {}
608
+ command('load', commandArgs);
609
+ } else {
610
+ onError(Object.assign({}, ERROR.STREAM_FAILED_TO_LOAD, {
611
+ critical: true,
612
+ stream: commandArgs ? commandArgs.stream : null,
613
+ error: error,
614
+ }));
615
+ }
616
+ });
609
617
  } else {
610
618
  onError(Object.assign({}, ERROR.UNSUPPORTED_STREAM, {
611
619
  critical: true,
@@ -617,6 +625,8 @@ function TizenVideo(options) {
617
625
  case 'unload': {
618
626
  stream = null;
619
627
  window.webapis.avplay.stop();
628
+ isLoaded = false;
629
+ onPropChanged('loaded');
620
630
  onPropChanged('stream');
621
631
  onPropChanged('paused');
622
632
  onPropChanged('time');
@@ -686,7 +696,7 @@ TizenVideo.canPlayStream = function() {
686
696
  TizenVideo.manifest = {
687
697
  name: 'TizenVideo',
688
698
  external: false,
689
- props: ['stream', 'paused', 'time', 'duration', 'buffering', 'audioTracks', 'selectedAudioTrackId', 'subtitlesTracks', 'selectedSubtitlesTrackId', 'subtitlesOffset', 'subtitlesSize', 'subtitlesTextColor', 'subtitlesBackgroundColor', 'subtitlesOutlineColor', 'subtitlesOpacity', 'playbackSpeed'],
699
+ props: ['stream', 'loaded', 'paused', 'time', 'duration', 'buffering', 'audioTracks', 'selectedAudioTrackId', 'subtitlesTracks', 'selectedSubtitlesTrackId', 'subtitlesOffset', 'subtitlesSize', 'subtitlesTextColor', 'subtitlesBackgroundColor', 'subtitlesOutlineColor', 'subtitlesOpacity', 'playbackSpeed'],
690
700
  commands: ['load', 'unload', 'destroy'],
691
701
  events: ['propValue', 'propChanged', 'ended', 'error', 'subtitlesTrackLoaded', 'audioTrackLoaded']
692
702
  };
@@ -6,8 +6,12 @@ var ERROR = require('../error');
6
6
  function luna(params, call, fail, method) {
7
7
  if (call) params.onSuccess = call || function() {};
8
8
 
9
- params.onFailure = function () { // function(result)
10
- // console.log('WebOS',(params.method || method) + ' [fail][' + result.errorCode + '] ' + result.errorText );
9
+ params.onFailure = function (result) {
10
+ // eslint-disable-next-line no-console
11
+ console.log('WebOS', (params.method || method) + ' [fail][' + result.errorCode + '] ' + result.errorText );
12
+
13
+ // eslint-disable-next-line no-console
14
+ console.log('fail result', JSON.stringify(result));
11
15
 
12
16
  if (fail) fail();
13
17
  };
@@ -61,9 +65,10 @@ function launchVideoApp(params, success, failure) {
61
65
  });
62
66
  }
63
67
 
64
- var webOsColors = ['black', 'white', 'yellow', 'red', 'green', 'blue'];
68
+ var webOsColors = ['none', 'black', 'white', 'yellow', 'red', 'green', 'blue'];
65
69
  var stremioColors = {
66
70
  // rgba
71
+ 'rgba(0, 0, 0, 0)': 'none',
67
72
  'rgba(0, 0, 0, 255)': 'black',
68
73
  'rgba(255, 255, 255, 255)': 'white',
69
74
  'rgba(255, 255, 0, 255)': 'yellow',
@@ -78,12 +83,12 @@ var stremioColors = {
78
83
  'rgba(0, 255, 0, 1)': 'green',
79
84
  'rgba(0, 0, 255, 1)': 'blue',
80
85
  // rgb
81
- 'rgba(0, 0, 0)': 'black',
82
- 'rgba(255, 255, 255)': 'white',
83
- 'rgba(255, 255, 0)': 'yellow',
84
- 'rgba(255, 0, 0)': 'red',
85
- 'rgba(0, 255, 0)': 'green',
86
- 'rgba(0, 0, 255)': 'blue',
86
+ 'rgb(0, 0, 0)': 'black',
87
+ 'rgb(255, 255, 255)': 'white',
88
+ 'rgb(255, 255, 0)': 'yellow',
89
+ 'rgb(255, 0, 0)': 'red',
90
+ 'rgb(0, 255, 0)': 'green',
91
+ 'rgb(0, 0, 255)': 'blue',
87
92
  // 8-digit hex
88
93
  '#000000FF': 'black',
89
94
  '#FFFFFFFF': 'white',
@@ -163,18 +168,18 @@ function WebOsVideo(options) {
163
168
 
164
169
  var count_message = 0;
165
170
 
166
- var subtitleOffset = 5;
171
+ var subStyles = {
172
+ color: 'white',
173
+ font_size: 1,
174
+ bg_color: 'none',
175
+ position: -1,
176
+ bg_opacity: 0,
177
+ char_opacity: 255
178
+ };
167
179
 
168
180
  var setSubs = function (info) {
169
181
  textTracks = [];
170
- // console.log('sub tracks 1, nr of sub tracks: ', info.numSubtitleTracks);
171
182
  if (info.numSubtitleTracks) {
172
-
173
- // console.log('sub tracks 2');
174
-
175
- // try {
176
- // console.log('got sub info', JSON.stringify(info.subtitleTrackInfo));
177
- // } catch(e) {};
178
183
  for (var i = 0; i < info.subtitleTrackInfo.length; i++) {
179
184
  var textTrack = info.subtitleTrackInfo[i];
180
185
  textTrack.index = i;
@@ -196,9 +201,6 @@ function WebOsVideo(options) {
196
201
  });
197
202
 
198
203
  }
199
-
200
- // console.log('sub tracks all', textTracks);
201
-
202
204
  onPropChanged('subtitlesTracks');
203
205
  onPropChanged('selectedSubtitlesTrackId');
204
206
 
@@ -207,14 +209,7 @@ function WebOsVideo(options) {
207
209
 
208
210
  var setTracks = function (info) {
209
211
  audioTracks = [];
210
- // console.log('audio tracks 1, nr of audio tracks: ', info.numAudioTracks);
211
212
  if (info.numAudioTracks) {
212
-
213
- //console.log('audio tracks 2');
214
-
215
- // try {
216
- // console.log('got audio info', JSON.stringify(info.audioTrackInfo));
217
- // } catch(e) {};
218
213
  for (var i = 0; i < info.audioTrackInfo.length; i++) {
219
214
  var audioTrack = info.audioTrackInfo[i];
220
215
  audioTrack.index = i;
@@ -232,7 +227,6 @@ function WebOsVideo(options) {
232
227
  mode: audioTrackId === currentAudioTrack ? 'showing' : 'disabled',
233
228
  });
234
229
  }
235
- // console.log('audio tracks all', audioTracks);
236
230
  onPropChanged('audioTracks');
237
231
  onPropChanged('selectedAudioTrackId');
238
232
 
@@ -243,7 +237,6 @@ function WebOsVideo(options) {
243
237
  if (subscribed) return;
244
238
  subscribed = true;
245
239
  var answered = false;
246
- // console.log('subscribing');
247
240
  luna({
248
241
  method: 'subscribe',
249
242
  parameters: {
@@ -253,9 +246,6 @@ function WebOsVideo(options) {
253
246
  }, function (result) {
254
247
  if (result.sourceInfo && !answered) {
255
248
  answered = true;
256
- // try {
257
- // console.log('got source info', JSON.stringify(result.sourceInfo.programInfo[0]));
258
- // } catch(e) {};
259
249
  var info = result.sourceInfo.programInfo[0];
260
250
 
261
251
  setSubs(info);
@@ -282,7 +272,6 @@ function WebOsVideo(options) {
282
272
  return;
283
273
  }
284
274
 
285
- // console.log('WebOS', 'subscribe', JSON.stringify(result));
286
275
  count_message++;
287
276
 
288
277
  if (count_message === 30 && !answered) {
@@ -323,16 +312,14 @@ function WebOsVideo(options) {
323
312
  // };
324
313
 
325
314
  var toggleSubtitles = function (status) {
326
- if (!knownMediaId) return;
315
+ if (!videoElement.mediaId) return;
327
316
 
328
317
  disabledSubs = !status;
329
318
 
330
- // console.log('enable subs: ' + status);
331
-
332
319
  luna({
333
320
  method: 'setSubtitleEnable',
334
321
  parameters: {
335
- 'mediaId': knownMediaId,
322
+ 'mediaId': videoElement.mediaId,
336
323
  'enable': status
337
324
  }
338
325
  });
@@ -422,7 +409,6 @@ function WebOsVideo(options) {
422
409
 
423
410
  var lastSubColor = null;
424
411
  var lastSubBgColor = null;
425
- var lastSubBgOpacity = 0;
426
412
  var lastPlaybackSpeed = 1;
427
413
 
428
414
  var events = new EventEmitter();
@@ -430,7 +416,7 @@ function WebOsVideo(options) {
430
416
  var stream = null;
431
417
  var startTime = null;
432
418
  var subtitlesOffset = 0;
433
- var subtitlesOpacity = 255;
419
+ var subtitlesOpacity = 100;
434
420
  var observedProps = {
435
421
  stream: false,
436
422
  paused: false,
@@ -532,21 +518,21 @@ function WebOsVideo(options) {
532
518
  return null;
533
519
  }
534
520
 
535
- return lastSubColor || 'rgba(255, 255, 255, 255)';
521
+ return lastSubColor || 'rgb(255, 255, 255)';
536
522
  }
537
523
  case 'subtitlesBackgroundColor': {
538
524
  if (destroyed) {
539
525
  return null;
540
526
  }
541
527
 
542
- return lastSubBgColor || 'rgba(255, 255, 255, 0)';
528
+ return lastSubBgColor || 'rgba(0, 0, 0, 0)';
543
529
  }
544
530
  case 'subtitlesOpacity': {
545
531
  if (destroyed) {
546
532
  return null;
547
533
  }
548
534
 
549
- return subtitlesOpacity || 255;
535
+ return subtitlesOpacity || 100;
550
536
  }
551
537
  case 'audioTracks': {
552
538
  return audioTracks;
@@ -681,62 +667,93 @@ function WebOsVideo(options) {
681
667
  break;
682
668
  }
683
669
  case 'selectedSubtitlesTrackId': {
684
- if (stream !== null) {
670
+ if (videoElement.mediaId && stream !== null) {
685
671
  if ((propValue || '').indexOf('EMBEDDED_') === 0) {
686
- if (disabledSubs) {
687
- toggleSubtitles(true);
688
- }
672
+ toggleSubtitles(true);
673
+
674
+ subStyles.bg_opacity = subStyles.bg_color === 'none' ? 0 : 255;
675
+
676
+ [
677
+ 'setSubtitleCharacterColor',
678
+ 'setSubtitleBackgroundColor',
679
+ 'setSubtitlePosition',
680
+ 'setSubtitleFontSize',
681
+ 'setSubtitleBackgroundOpacity',
682
+ 'setSubtitleCharacterOpacity'
683
+ ].forEach(function(key) {
684
+ luna({
685
+ method: key,
686
+ parameters: {
687
+ mediaId: videoElement.mediaId,
688
+ charColor: subStyles.color,
689
+ bgColor: subStyles.bg_color === 'none' ? 'black' : subStyles.bg_color,
690
+ position: subStyles.position,
691
+ fontSize: subStyles.font_size,
692
+ bgOpacity: subStyles.bg_opacity,
693
+ charOpacity: subStyles.char_opacity
694
+ }
695
+ });
696
+ });
689
697
 
690
- // console.log('WebOS', 'change subtitles for id: ', knownMediaId, ' index:', propValue);
698
+ // eslint-disable-next-line no-console
699
+ console.log('WebOS', 'change subtitles for id: ', videoElement.mediaId, ' index:', propValue);
691
700
 
692
701
  currentSubTrack = propValue;
693
702
  var trackIndex = parseInt(propValue.replace('EMBEDDED_', ''));
694
- // console.log('set subs to track idx: ' + trackIndex);
695
- luna({
696
- method: 'selectTrack',
697
- parameters: {
698
- 'type': 'text',
699
- 'mediaId': knownMediaId,
700
- 'index': trackIndex
701
- }
702
- }, function() {
703
- // console.log('changed subs track successfully');
704
- var selectedSubtitlesTrack = getProp('subtitlesTracks')
705
- .find(function(track) {
706
- return track.id === propValue;
703
+ // eslint-disable-next-line no-console
704
+ console.log('set subs to track idx: ' + trackIndex);
705
+ setTimeout(function() {
706
+ var successCb = function() {
707
+ var selectedSubtitlesTrack = getProp('subtitlesTracks')
708
+ .find(function(track) {
709
+ return track.id === propValue;
710
+ });
711
+ textTracks = textTracks.map(function(track) {
712
+ track.mode = track.id === currentSubTrack ? 'showing' : 'disabled';
713
+ return track;
707
714
  });
708
- textTracks = textTracks.map(function(track) {
709
- track.mode = track.id === currentSubTrack ? 'showing' : 'disabled';
710
- return track;
711
- });
712
- if (selectedSubtitlesTrack) {
713
- events.emit('subtitlesTrackLoaded', selectedSubtitlesTrack);
714
- onPropChanged('selectedSubtitlesTrackId');
715
- }
716
- });
717
- } else if (!propValue) {
718
- toggleSubtitles(false);
715
+ if (selectedSubtitlesTrack) {
716
+ events.emit('subtitlesTrackLoaded', selectedSubtitlesTrack);
717
+ onPropChanged('selectedSubtitlesTrackId');
718
+ }
719
+ };
720
+ luna({
721
+ method: 'selectTrack',
722
+ parameters: {
723
+ 'type': 'text',
724
+ 'mediaId': videoElement.mediaId,
725
+ 'index': trackIndex
726
+ }
727
+ }, successCb, successCb);
728
+ }, 500);
719
729
  }
720
730
  }
721
731
 
732
+ if ((propValue || '').indexOf('EMBEDDED_') === -1) {
733
+ currentSubTrack = null;
734
+ onPropChanged('selectedSubtitlesTrackId');
735
+ toggleSubtitles(false);
736
+ }
737
+
722
738
  break;
723
739
  }
724
740
  case 'subtitlesOffset': {
725
741
  if (propValue !== null && isFinite(propValue)) {
726
- subtitlesOffset = Math.max(0, Math.min(100, parseInt(propValue, 10)));
727
- var nextOffset = stremioSubOffsets(subtitleOffset);
742
+ subtitlesOffset = propValue;
743
+ var nextOffset = stremioSubOffsets(Math.max(0, Math.min(100, parseInt(subtitlesOffset, 10))));
728
744
  if (nextOffset === false) { // use default
729
- nextOffset = 0;
745
+ nextOffset = -1;
746
+ }
747
+ subStyles.position = nextOffset;
748
+ if (videoElement.mediaId) {
749
+ luna({
750
+ method: 'setSubtitlePosition',
751
+ parameters: {
752
+ 'mediaId': videoElement.mediaId,
753
+ 'position': nextOffset,
754
+ }
755
+ });
730
756
  }
731
- luna({
732
- method: 'setSubtitlePosition',
733
- parameters: {
734
- 'mediaId': knownMediaId,
735
- 'position': nextOffset,
736
- }
737
- }, function() {
738
- // console.log('successfully changed sub offset to: ' + nextOffset);
739
- });
740
757
 
741
758
  onPropChanged('subtitlesOffset');
742
759
  }
@@ -745,20 +762,21 @@ function WebOsVideo(options) {
745
762
  }
746
763
  case 'subtitlesSize': {
747
764
  if (propValue !== null && isFinite(propValue)) {
748
- subSize = Math.max(0, parseInt(propValue, 10));
749
- var nextSubSize = stremioSubSizes(subSize);
765
+ subSize = propValue;
766
+ var nextSubSize = stremioSubSizes(Math.max(0, parseInt(subSize, 10)));
750
767
  if (nextSubSize === false) { // use default
751
- nextSubSize = 2;
768
+ nextSubSize = 1;
769
+ }
770
+ subStyles.font_size = nextSubSize;
771
+ if (videoElement.mediaId) {
772
+ luna({
773
+ method: 'setSubtitleFontSize',
774
+ parameters: {
775
+ 'mediaId': videoElement.mediaId,
776
+ 'fontSize': nextSubSize,
777
+ }
778
+ });
752
779
  }
753
- luna({
754
- method: 'setSubtitleFontSize',
755
- parameters: {
756
- 'mediaId': knownMediaId,
757
- 'fontSize': nextSubSize,
758
- }
759
- }, function() {
760
- // console.log('successfully changed sub size to: ' + nextSubSize);
761
- });
762
780
 
763
781
  onPropChanged('subtitlesSize');
764
782
  }
@@ -773,15 +791,16 @@ function WebOsVideo(options) {
773
791
  if (stremioColors[propValue] && webOsColors.indexOf(stremioColors[propValue]) > -1) {
774
792
  nextColor = stremioColors[propValue];
775
793
  }
776
- luna({
777
- method: 'setSubtitleCharacterColor',
778
- parameters: {
779
- 'mediaId': knownMediaId,
780
- 'charColor': nextColor,
781
- }
782
- }, function() {
783
- // console.log('changed subtitle color successfully to: ' + nextColor);
784
- });
794
+ subStyles.color = nextColor;
795
+ if (videoElement.mediaId) {
796
+ luna({
797
+ method: 'setSubtitleCharacterColor',
798
+ parameters: {
799
+ 'mediaId': videoElement.mediaId,
800
+ 'charColor': nextColor,
801
+ }
802
+ });
803
+ }
785
804
  lastSubColor = propValue;
786
805
  onPropChanged('subtitlesTextColor');
787
806
  }
@@ -791,39 +810,33 @@ function WebOsVideo(options) {
791
810
  case 'subtitlesBackgroundColor': {
792
811
  if (typeof propValue === 'string') {
793
812
  if (stremioColors[propValue] && webOsColors.indexOf(stremioColors[propValue]) > -1) {
794
- luna({
795
- method: 'setSubtitleBackgroundColor',
796
- parameters: {
797
- 'mediaId': knownMediaId,
798
- 'color': stremioColors[propValue],
799
- }
800
- }, function() {
801
- // console.log('changed subtitle background color successfully to: ' + stremioColors[propValue]);
802
- if (!lastSubBgOpacity) {
813
+ subStyles.bg_color = stremioColors[propValue];
814
+ if (videoElement.mediaId) {
815
+ luna({
816
+ method: 'setSubtitleBackgroundColor',
817
+ parameters: {
818
+ 'mediaId': videoElement.mediaId,
819
+ 'bgColor': stremioColors[propValue] === 'none' ? 'black' : stremioColors[propValue],
820
+ }
821
+ });
822
+ if (stremioColors[propValue] === 'none') {
823
+ luna({
824
+ method: 'setSubtitleBackgroundOpacity',
825
+ parameters: {
826
+ 'mediaId': videoElement.mediaId,
827
+ 'bgOpacity': 0,
828
+ }
829
+ });
830
+ } else {
803
831
  luna({
804
832
  method: 'setSubtitleBackgroundOpacity',
805
833
  parameters: {
806
- 'mediaId': knownMediaId,
834
+ 'mediaId': videoElement.mediaId,
807
835
  'bgOpacity': 255,
808
836
  }
809
- }, function() {
810
- // console.log('changed subtitle background opacity successfully to: ' + 255);
811
- lastSubBgOpacity = 255;
812
837
  });
813
838
  }
814
- });
815
- } else {
816
- // we don't know this color, set sub background opacity to 0
817
- luna({
818
- method: 'setSubtitleBackgroundOpacity',
819
- parameters: {
820
- 'mediaId': knownMediaId,
821
- 'bgOpacity': 0,
822
- }
823
- }, function() {
824
- // console.log('changed subtitle background opacity successfully to: ' + 0);
825
- lastSubBgOpacity = 0;
826
- });
839
+ }
827
840
  }
828
841
  lastSubBgColor = propValue;
829
842
  onPropChanged('subtitlesBackgroundColor');
@@ -833,13 +846,17 @@ function WebOsVideo(options) {
833
846
  }
834
847
  case 'subtitlesOpacity': {
835
848
  if (typeof propValue === 'number') {
836
- luna({
837
- method: 'setSubtitleBackgroundOpacity',
838
- parameters: {
839
- 'mediaId': knownMediaId,
840
- 'bgOpacity': Math.min(Math.max(propValue / 0.4, 0), 255),
841
- }
842
- });
849
+ var nextSubOpacity = Math.floor(propValue / 100 * 255);
850
+ subStyles.char_opacity = nextSubOpacity;
851
+ if (videoElement.mediaId) {
852
+ luna({
853
+ method: 'setSubtitleCharacterOpacity',
854
+ parameters: {
855
+ 'mediaId': videoElement.mediaId,
856
+ 'charOpacity': nextSubOpacity,
857
+ }
858
+ });
859
+ }
843
860
 
844
861
  subtitlesOpacity = propValue;
845
862
  onPropChanged('subtitlesOpacity');
@@ -848,44 +865,41 @@ function WebOsVideo(options) {
848
865
  break;
849
866
  }
850
867
  case 'selectedAudioTrackId': {
851
- // console.log('WebOS', 'change audio track for id: ', knownMediaId, ' index:', propValue);
852
-
853
868
  if ((propValue || '').indexOf('EMBEDDED_') === 0) {
854
869
  currentAudioTrack = propValue;
855
870
  var trackIndex = parseInt(propValue.replace('EMBEDDED_', ''));
856
- luna({
857
- method: 'selectTrack',
858
- parameters: {
859
- 'type': 'audio',
860
- 'mediaId': knownMediaId,
861
- 'index': trackIndex
862
- }
863
- }, function() {
864
- // console.log('changed audio track successfully');
865
- var selectedAudioTrack = getProp('audioTracks')
866
- .find(function(track) {
867
- return track.id === propValue;
871
+ if (videoElement.mediaId) {
872
+ luna({
873
+ method: 'selectTrack',
874
+ parameters: {
875
+ 'type': 'audio',
876
+ 'mediaId': videoElement.mediaId,
877
+ 'index': trackIndex
878
+ }
879
+ }, function() {
880
+ var selectedAudioTrack = getProp('audioTracks')
881
+ .find(function(track) {
882
+ return track.id === propValue;
883
+ });
884
+
885
+ audioTracks = audioTracks.map(function(track) {
886
+ track.mode = track.id === currentAudioTrack ? 'showing' : 'disabled';
887
+ return track;
868
888
  });
869
889
 
870
- audioTracks = audioTracks.map(function(track) {
871
- track.mode = track.id === currentAudioTrack ? 'showing' : 'disabled';
872
- return track;
890
+ if (selectedAudioTrack) {
891
+ events.emit('audioTrackLoaded', selectedAudioTrack);
892
+ onPropChanged('selectedAudioTrackId');
893
+ }
873
894
  });
874
-
875
- if (selectedAudioTrack) {
876
- events.emit('audioTrackLoaded', selectedAudioTrack);
877
- onPropChanged('selectedAudioTrackId');
878
- }
879
- });
880
- if (videoElement.audioTracks) {
895
+ }
896
+ if (videoElement && videoElement.audioTracks) {
881
897
  for (var i = 0; i < videoElement.audioTracks.length; i++) {
882
898
  videoElement.audioTracks[i].enabled = false;
883
899
  }
884
900
 
885
901
  if(videoElement.audioTracks[trackIndex]) {
886
902
  videoElement.audioTracks[trackIndex].enabled = true;
887
-
888
- // console.log('WebOS', 'change audio two method:', trackIndex);
889
903
  }
890
904
  }
891
905
 
@@ -906,22 +920,18 @@ function WebOsVideo(options) {
906
920
  break;
907
921
  }
908
922
  case 'playbackSpeed': {
909
- // console.log('start change play rate to: ' + propValue);
910
- // console.log(typeof propValue);
911
923
  if (propValue !== null && isFinite(propValue)) {
912
924
  lastPlaybackSpeed = parseFloat(propValue);
913
- luna({
914
- method: 'setPlayRate',
915
- parameters: {
916
- 'mediaId': knownMediaId,
917
- 'playRate': lastPlaybackSpeed,
918
- 'audioOutput': true,
919
- }
920
- }, function() {
921
- // console.log('set playback rate success: ', lastPlaybackSpeed);
922
- }, function() {
923
- // console.log('failed setting playback rate success: ', lastPlaybackSpeed);
924
- });
925
+ if (videoElement.mediaId) {
926
+ luna({
927
+ method: 'setPlayRate',
928
+ parameters: {
929
+ 'mediaId': videoElement.mediaId,
930
+ 'playRate': lastPlaybackSpeed,
931
+ 'audioOutput': true,
932
+ }
933
+ });
934
+ }
925
935
  onPropChanged('playbackSpeed');
926
936
  }
927
937
 
@@ -957,7 +967,6 @@ function WebOsVideo(options) {
957
967
  function retrieveMediaId() {
958
968
  if (videoElement.mediaId) {
959
969
  knownMediaId = videoElement.mediaId;
960
- // console.log('got media id: ', videoElement.mediaId);
961
970
  clearInterval(timer);
962
971
  subscribe(cb);
963
972
  return;
package/src/error.js CHANGED
@@ -68,6 +68,10 @@ var ERROR = {
68
68
  UNSUPPORTED_STREAM: {
69
69
  code: 2,
70
70
  message: 'Stream is not supported'
71
+ },
72
+ STREAM_FAILED_TO_LOAD: {
73
+ code: 3,
74
+ message: 'Stream failed to load'
71
75
  }
72
76
  };
73
77
 
@@ -0,0 +1,24 @@
1
+ function isPlayerLoaded(video, props) {
2
+ if (!props.includes('loaded')) {
3
+ return Promise.resolve(true);
4
+ }
5
+ return new Promise(function(resolve, reject) {
6
+ var isLoaded = null;
7
+ video.on('propChanged', function(propName, propValue) {
8
+ if (propName === 'loaded' && propValue !== null && isLoaded === null) {
9
+ isLoaded = propValue;
10
+ if (propValue === true) {
11
+ resolve(true);
12
+ } else if (propValue === false) {
13
+ reject(Error('Player failed to load, will not retrieve video params'));
14
+ }
15
+ }
16
+ });
17
+ video.dispatch({
18
+ type: 'observeProp',
19
+ propName: 'loaded'
20
+ });
21
+ });
22
+ }
23
+
24
+ module.exports = isPlayerLoaded;
@@ -6,6 +6,7 @@ var deepFreeze = require('deep-freeze');
6
6
  var mediaCapabilities = require('../mediaCapabilities');
7
7
  var convertStream = require('./convertStream');
8
8
  var fetchVideoParams = require('./fetchVideoParams');
9
+ var isPlayerLoaded = require('./isPlayerLoaded');
9
10
  var supportsTranscoding = require('../supportsTranscoding');
10
11
  var ERROR = require('../error');
11
12
 
@@ -203,7 +204,11 @@ function withStreamingServer(Video) {
203
204
  });
204
205
  loaded = true;
205
206
  flushActionsQueue();
206
- fetchVideoParams(commandArgs.streamingServerURL, result.mediaURL, result.infoHash, result.fileIdx, commandArgs.stream.behaviorHints)
207
+
208
+ isPlayerLoaded(video, Video.manifest.props)
209
+ .then(function() {
210
+ return fetchVideoParams(commandArgs.streamingServerURL, result.mediaURL, result.infoHash, result.fileIdx, commandArgs.stream.behaviorHints);
211
+ })
207
212
  .then(function(result) {
208
213
  if (commandArgs !== loadArgs) {
209
214
  return;