@stremio/stremio-video 0.0.58 → 0.0.60

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.58",
3
+ "version": "0.0.60",
4
4
  "description": "Abstraction layer on top of different media players",
5
5
  "author": "Smart Code OOD",
6
6
  "main": "src/index.js",
@@ -103,6 +103,7 @@ function HTMLVideo(options) {
103
103
  var destroyed = false;
104
104
  var stream = null;
105
105
  var subtitlesOffset = 0;
106
+ var subtitlesOpacity = 1;
106
107
  var observedProps = {
107
108
  stream: false,
108
109
  loaded: false,
@@ -244,6 +245,13 @@ function HTMLVideo(options) {
244
245
 
245
246
  return styleElement.sheet.cssRules[0].style.textShadow.slice(0, styleElement.sheet.cssRules[0].style.textShadow.indexOf(')') + 1);
246
247
  }
248
+ case 'subtitlesOpacity': {
249
+ if (destroyed) {
250
+ return null;
251
+ }
252
+
253
+ return Math.round(subtitlesOpacity * 100);
254
+ }
247
255
  case 'audioTracks': {
248
256
  if (hls === null || !Array.isArray(hls.audioTracks)) {
249
257
  return [];
@@ -460,6 +468,21 @@ function HTMLVideo(options) {
460
468
 
461
469
  break;
462
470
  }
471
+ case 'subtitlesOpacity': {
472
+ if (typeof propValue === 'number') {
473
+ try {
474
+ subtitlesOpacity = Math.min(Math.max(propValue / 100, 0), 1);
475
+ styleElement.sheet.cssRules[0].style.opacity = subtitlesOpacity + '';
476
+ } catch (error) {
477
+ // eslint-disable-next-line no-console
478
+ console.error('VVideo with HTML Subtitles', error);
479
+ }
480
+
481
+ onPropChanged('subtitlesOpacity');
482
+ }
483
+
484
+ break;
485
+ }
463
486
  case 'selectedAudioTrackId': {
464
487
  if (hls !== null) {
465
488
  var selecterdAudioTrack = getProp('audioTracks')
@@ -591,6 +614,7 @@ function HTMLVideo(options) {
591
614
  onPropChanged('subtitlesTextColor');
592
615
  onPropChanged('subtitlesBackgroundColor');
593
616
  onPropChanged('subtitlesOutlineColor');
617
+ onPropChanged('subtitlesOpacity');
594
618
  onPropChanged('volume');
595
619
  onPropChanged('muted');
596
620
  onPropChanged('playbackSpeed');
@@ -671,7 +695,7 @@ HTMLVideo.canPlayStream = function(stream) {
671
695
  HTMLVideo.manifest = {
672
696
  name: 'HTMLVideo',
673
697
  external: false,
674
- props: ['stream', 'loaded', 'paused', 'time', 'duration', 'buffering', 'buffered', 'audioTracks', 'selectedAudioTrackId', 'subtitlesTracks', 'selectedSubtitlesTrackId', 'subtitlesOffset', 'subtitlesSize', 'subtitlesTextColor', 'subtitlesBackgroundColor', 'subtitlesOutlineColor', 'volume', 'muted', 'playbackSpeed'],
698
+ props: ['stream', 'loaded', 'paused', 'time', 'duration', 'buffering', 'buffered', 'audioTracks', 'selectedAudioTrackId', 'subtitlesTracks', 'selectedSubtitlesTrackId', 'subtitlesOffset', 'subtitlesSize', 'subtitlesTextColor', 'subtitlesBackgroundColor', 'subtitlesOutlineColor', 'subtitlesOpacity', 'volume', 'muted', 'playbackSpeed'],
675
699
  commands: ['load', 'unload', 'destroy'],
676
700
  events: ['propValue', 'propChanged', 'ended', 'error', 'subtitlesTrackLoaded', 'audioTrackLoaded']
677
701
  };
@@ -161,6 +161,13 @@ function ShellVideo(options) {
161
161
  props[args.name] = Math.round(args.data*1000);
162
162
  break;
163
163
  }
164
+ case 'volume': {
165
+ if (typeof args.data === 'number' && isFinite(args.data)) {
166
+ props[args.name] = args.data;
167
+ onPropChanged('volume');
168
+ }
169
+ break;
170
+ }
164
171
  case 'paused-for-cache':
165
172
  case 'seeking':
166
173
  {
@@ -391,7 +398,6 @@ function ShellVideo(options) {
391
398
  onPropChanged('time');
392
399
  onPropChanged('duration');
393
400
  onPropChanged('buffering');
394
- onPropChanged('volume');
395
401
  onPropChanged('muted');
396
402
  onPropChanged('subtitlesTracks');
397
403
  onPropChanged('selectedSubtitlesTrackId');
@@ -424,7 +430,6 @@ function ShellVideo(options) {
424
430
  onPropChanged('time');
425
431
  onPropChanged('duration');
426
432
  onPropChanged('buffering');
427
- onPropChanged('volume');
428
433
  onPropChanged('muted');
429
434
  onPropChanged('subtitlesTracks');
430
435
  onPropChanged('selectedSubtitlesTrackId');
@@ -3,6 +3,7 @@ var ShellVideo = require('../ShellVideo');
3
3
  var HTMLVideo = require('../HTMLVideo');
4
4
  var TizenVideo = require('../TizenVideo');
5
5
  var TitanVideo = require('../TitanVideo');
6
+ var VidaaVideo = require('../VidaaVideo');
6
7
  var WebOsVideo = require('../WebOsVideo');
7
8
  var IFrameVideo = require('../IFrameVideo');
8
9
  var YouTubeVideo = require('../YouTubeVideo');
@@ -38,9 +39,12 @@ function selectVideoImplementation(commandArgs, options) {
38
39
  if (commandArgs.platform === 'webOS') {
39
40
  return withStreamingServer(withHTMLSubtitles(WebOsVideo));
40
41
  }
41
- if (commandArgs.platform === 'Titan' || commandArgs.platform === 'NetTV' || commandArgs.platform === 'Vidaa') {
42
+ if (commandArgs.platform === 'Titan' || commandArgs.platform === 'NetTV') {
42
43
  return withStreamingServer(withHTMLSubtitles(TitanVideo));
43
44
  }
45
+ if (commandArgs.platform === 'Vidaa') {
46
+ return withStreamingServer(withHTMLSubtitles(VidaaVideo));
47
+ }
44
48
  return withStreamingServer(withHTMLSubtitles(HTMLVideo));
45
49
  }
46
50
 
@@ -51,9 +55,12 @@ function selectVideoImplementation(commandArgs, options) {
51
55
  if (commandArgs.platform === 'webOS') {
52
56
  return withVideoParams(withHTMLSubtitles(WebOsVideo));
53
57
  }
54
- if (commandArgs.platform === 'Titan' || commandArgs.platform === 'NetTV' || commandArgs.platform === 'Vidaa') {
58
+ if (commandArgs.platform === 'Titan' || commandArgs.platform === 'NetTV') {
55
59
  return withVideoParams(withHTMLSubtitles(TitanVideo));
56
60
  }
61
+ if (commandArgs.platform === 'Vidaa') {
62
+ return withVideoParams(withHTMLSubtitles(VidaaVideo));
63
+ }
57
64
  return withVideoParams(withHTMLSubtitles(HTMLVideo));
58
65
  }
59
66
 
@@ -157,8 +157,7 @@ function TitanVideo(options) {
157
157
  cueNode.innerHTML = text;
158
158
  cueNode.style.display = 'inline-block';
159
159
  cueNode.style.padding = '0.2em';
160
- var fontSizeMultiplier = window.screen720p ? 1.538 : 1;
161
- cueNode.style.fontSize = Math.floor((size / 25) * fontSizeMultiplier) + 'vmin';
160
+ cueNode.style.fontSize = Math.floor(size / 25) + 'vmin';
162
161
  cueNode.style.color = textColor;
163
162
  cueNode.style.backgroundColor = backgroundColor;
164
163
  cueNode.style.textShadow = '1px 1px 0.1em ' + outlineColor;
@@ -0,0 +1,533 @@
1
+ var EventEmitter = require('eventemitter3');
2
+ var cloneDeep = require('lodash.clonedeep');
3
+ var deepFreeze = require('deep-freeze');
4
+ var ERROR = require('../error');
5
+
6
+ var SSA_DESCRIPTORS_REGEX = /^\{(\\an[1-8])+\}/i;
7
+
8
+ function VidaaVideo(options) {
9
+ options = options || {};
10
+
11
+ var containerElement = options.containerElement;
12
+ if (!(containerElement instanceof HTMLElement)) {
13
+ throw new Error('Container element required to be instance of HTMLElement');
14
+ }
15
+
16
+ var videoElement = document.createElement('video');
17
+ videoElement.style.width = '100%';
18
+ videoElement.style.height = '100%';
19
+ videoElement.style.backgroundColor = 'black';
20
+ videoElement.controls = false;
21
+ videoElement.playsInline = true;
22
+ videoElement.onerror = function() {
23
+ onVideoError();
24
+ };
25
+ videoElement.onended = function() {
26
+ onEnded();
27
+ };
28
+ videoElement.onpause = function() {
29
+ onPropChanged('paused');
30
+ };
31
+ videoElement.onplay = function() {
32
+ onPropChanged('paused');
33
+ };
34
+ videoElement.ontimeupdate = function() {
35
+ onPropChanged('time');
36
+ };
37
+ videoElement.ondurationchange = function() {
38
+ onPropChanged('duration');
39
+ };
40
+ videoElement.onwaiting = function() {
41
+ onPropChanged('buffering');
42
+ };
43
+ videoElement.onseeking = function() {
44
+ onPropChanged('time');
45
+ onPropChanged('buffering');
46
+ };
47
+ videoElement.onseeked = function() {
48
+ onPropChanged('time');
49
+ onPropChanged('buffering');
50
+ };
51
+ videoElement.onstalled = function() {
52
+ onPropChanged('buffering');
53
+ };
54
+ videoElement.onplaying = function() {
55
+ onPropChanged('time');
56
+ onPropChanged('buffering');
57
+ };
58
+ videoElement.oncanplay = function() {
59
+ onPropChanged('buffering');
60
+ };
61
+ videoElement.canplaythrough = function() {
62
+ onPropChanged('buffering');
63
+ };
64
+ videoElement.onloadedmetadata = function() {
65
+ onPropChanged('loaded');
66
+ };
67
+ videoElement.onloadeddata = function() {
68
+ onPropChanged('buffering');
69
+ };
70
+ videoElement.onvolumechange = function() {
71
+ onPropChanged('volume');
72
+ onPropChanged('muted');
73
+ };
74
+ videoElement.onratechange = function() {
75
+ onPropChanged('playbackSpeed');
76
+ };
77
+ videoElement.textTracks.onchange = function() {
78
+ onPropChanged('subtitlesTracks');
79
+ onPropChanged('selectedSubtitlesTrackId');
80
+ onCueChange();
81
+ Array.from(videoElement.textTracks).forEach(function(track) {
82
+ track.oncuechange = onCueChange;
83
+ });
84
+ };
85
+ containerElement.appendChild(videoElement);
86
+
87
+ var subtitlesElement = document.createElement('div');
88
+ subtitlesElement.style.position = 'absolute';
89
+ subtitlesElement.style.right = '0';
90
+ subtitlesElement.style.bottom = '0';
91
+ subtitlesElement.style.left = '0';
92
+ subtitlesElement.style.zIndex = '1';
93
+ subtitlesElement.style.textAlign = 'center';
94
+ containerElement.style.position = 'relative';
95
+ containerElement.style.zIndex = '0';
96
+ containerElement.appendChild(subtitlesElement);
97
+
98
+ var events = new EventEmitter();
99
+ var destroyed = false;
100
+ var stream = null;
101
+ var observedProps = {
102
+ stream: false,
103
+ loaded: false,
104
+ paused: false,
105
+ time: false,
106
+ duration: false,
107
+ buffering: false,
108
+ subtitlesTracks: false,
109
+ selectedSubtitlesTrackId: false,
110
+ audioTracks: false,
111
+ selectedAudioTrackId: false,
112
+ volume: false,
113
+ muted: false,
114
+ playbackSpeed: false
115
+ };
116
+
117
+ function getProp(propName) {
118
+ switch (propName) {
119
+ case 'stream': {
120
+ return stream;
121
+ }
122
+ case 'loaded': {
123
+ if (stream === null) {
124
+ return null;
125
+ }
126
+
127
+ return videoElement.readyState >= videoElement.HAVE_METADATA;
128
+ }
129
+ case 'paused': {
130
+ if (stream === null) {
131
+ return null;
132
+ }
133
+
134
+ return !!videoElement.paused;
135
+ }
136
+ case 'time': {
137
+ if (stream === null || videoElement.currentTime === null || !isFinite(videoElement.currentTime)) {
138
+ return null;
139
+ }
140
+
141
+ return Math.floor(videoElement.currentTime * 1000);
142
+ }
143
+ case 'duration': {
144
+ if (stream === null || videoElement.duration === null || !isFinite(videoElement.duration)) {
145
+ return null;
146
+ }
147
+
148
+ return Math.floor(videoElement.duration * 1000);
149
+ }
150
+ case 'buffering': {
151
+ if (stream === null) {
152
+ return null;
153
+ }
154
+
155
+ return videoElement.readyState < videoElement.HAVE_FUTURE_DATA;
156
+ }
157
+ case 'subtitlesTracks': {
158
+ if (stream === null) {
159
+ return [];
160
+ }
161
+
162
+ return Array.from(videoElement.textTracks)
163
+ .map(function(track, index) {
164
+ return Object.freeze({
165
+ id: 'EMBEDDED_' + String(index),
166
+ lang: track.language,
167
+ label: track.label || null,
168
+ origin: 'EMBEDDED',
169
+ embedded: true
170
+ });
171
+ });
172
+ }
173
+ case 'selectedSubtitlesTrackId': {
174
+ if (stream === null) {
175
+ return null;
176
+ }
177
+
178
+ return Array.from(videoElement.textTracks)
179
+ .reduce(function(result, track, index) {
180
+ if (result === null && track.mode === 'showing') {
181
+ return 'EMBEDDED_' + String(index);
182
+ }
183
+
184
+ return result;
185
+ }, null);
186
+ }
187
+ case 'audioTracks': {
188
+ if (stream === null) {
189
+ return [];
190
+ }
191
+
192
+ if (!videoElement.audioTracks || !Array.from(videoElement.audioTracks).length) {
193
+ return [];
194
+ }
195
+
196
+ return Array.from(videoElement.audioTracks)
197
+ .map(function(track, index) {
198
+ return Object.freeze({
199
+ id: 'EMBEDDED_' + String(index),
200
+ lang: track.language,
201
+ label: track.label || null,
202
+ origin: 'EMBEDDED',
203
+ embedded: true
204
+ });
205
+ });
206
+ }
207
+ case 'selectedAudioTrackId': {
208
+
209
+ if (stream === null) {
210
+ return null;
211
+ }
212
+
213
+ if (!videoElement.audioTracks || !Array.from(videoElement.audioTracks).length) {
214
+ return null;
215
+ }
216
+
217
+ return Array.from(videoElement.audioTracks)
218
+ .reduce(function(result, track, index) {
219
+ if (result === null && track.enabled) {
220
+ return 'EMBEDDED_' + String(index);
221
+ }
222
+
223
+ return result;
224
+ }, null);
225
+ }
226
+ case 'volume': {
227
+ if (destroyed || videoElement.volume === null || !isFinite(videoElement.volume)) {
228
+ return null;
229
+ }
230
+
231
+ return Math.floor(videoElement.volume * 100);
232
+ }
233
+ case 'muted': {
234
+ if (destroyed) {
235
+ return null;
236
+ }
237
+
238
+ return !!videoElement.muted;
239
+ }
240
+ case 'playbackSpeed': {
241
+ if (destroyed || videoElement.playbackRate === null || !isFinite(videoElement.playbackRate)) {
242
+ return null;
243
+ }
244
+
245
+ return videoElement.playbackRate;
246
+ }
247
+ default: {
248
+ return null;
249
+ }
250
+ }
251
+ }
252
+ function onCueChange() {
253
+ Array.from(videoElement.textTracks).forEach(function(track) {
254
+ Array.from(track.cues || []).forEach(function(cue) {
255
+ cue.snapToLines = false;
256
+ cue.line = 100;
257
+ });
258
+ });
259
+ }
260
+ function onVideoError() {
261
+ if (destroyed) {
262
+ return;
263
+ }
264
+
265
+ var error;
266
+ switch (videoElement.error.code) {
267
+ case 1: {
268
+ error = ERROR.HTML_VIDEO.MEDIA_ERR_ABORTED;
269
+ break;
270
+ }
271
+ case 2: {
272
+ error = ERROR.HTML_VIDEO.MEDIA_ERR_NETWORK;
273
+ break;
274
+ }
275
+ case 3: {
276
+ error = ERROR.HTML_VIDEO.MEDIA_ERR_DECODE;
277
+ break;
278
+ }
279
+ case 4: {
280
+ error = ERROR.HTML_VIDEO.MEDIA_ERR_SRC_NOT_SUPPORTED;
281
+ break;
282
+ }
283
+ default: {
284
+ error = ERROR.UNKNOWN_ERROR;
285
+ }
286
+ }
287
+ onError(Object.assign({}, error, {
288
+ critical: true,
289
+ error: videoElement.error
290
+ }));
291
+ }
292
+ function onError(error) {
293
+ events.emit('error', error);
294
+ if (error.critical) {
295
+ command('unload');
296
+ }
297
+ }
298
+ function onEnded() {
299
+ events.emit('ended');
300
+ }
301
+ function onPropChanged(propName) {
302
+ if (observedProps[propName]) {
303
+ events.emit('propChanged', propName, getProp(propName));
304
+ }
305
+ }
306
+ function observeProp(propName) {
307
+ if (observedProps.hasOwnProperty(propName)) {
308
+ events.emit('propValue', propName, getProp(propName));
309
+ observedProps[propName] = true;
310
+ }
311
+ }
312
+ function setProp(propName, propValue) {
313
+ switch (propName) {
314
+ case 'paused': {
315
+ if (stream !== null) {
316
+ propValue ? videoElement.pause() : videoElement.play();
317
+ onPropChanged('paused');
318
+ }
319
+
320
+ break;
321
+ }
322
+ case 'time': {
323
+ if (stream !== null && propValue !== null && isFinite(propValue)) {
324
+ videoElement.currentTime = parseInt(propValue, 10) / 1000;
325
+ onPropChanged('time');
326
+ }
327
+
328
+ break;
329
+ }
330
+ case 'selectedSubtitlesTrackId': {
331
+ if (stream !== null) {
332
+ Array.from(videoElement.textTracks)
333
+ .forEach(function(track, index) {
334
+ track.mode = 'EMBEDDED_' + String(index) === propValue ? 'showing' : 'disabled';
335
+ });
336
+ var selecterdSubtitlesTrack = getProp('subtitlesTracks')
337
+ .find(function(track) {
338
+ return track.id === propValue;
339
+ });
340
+ if (selecterdSubtitlesTrack) {
341
+ onPropChanged('selectedSubtitlesTrackId');
342
+ events.emit('subtitlesTrackLoaded', selecterdSubtitlesTrack);
343
+ }
344
+ }
345
+
346
+ break;
347
+ }
348
+ case 'selectedAudioTrackId': {
349
+ if (stream !== null) {
350
+ for (var index = 0; index < videoElement.audioTracks.length; index++) {
351
+ videoElement.audioTracks[index].enabled = !!('EMBEDDED_' + String(index) === propValue);
352
+ }
353
+ }
354
+
355
+ var selectedAudioTrack = getProp('audioTracks')
356
+ .find(function(track) {
357
+ return track.id === propValue;
358
+ });
359
+
360
+ if (selectedAudioTrack) {
361
+ onPropChanged('selectedAudioTrackId');
362
+ events.emit('audioTrackLoaded', selectedAudioTrack);
363
+ }
364
+
365
+ break;
366
+ }
367
+ case 'volume': {
368
+ if (propValue !== null && isFinite(propValue)) {
369
+ videoElement.muted = false;
370
+ videoElement.volume = Math.max(0, Math.min(100, parseInt(propValue, 10))) / 100;
371
+ onPropChanged('muted');
372
+ onPropChanged('volume');
373
+ }
374
+
375
+ break;
376
+ }
377
+ case 'muted': {
378
+ videoElement.muted = !!propValue;
379
+ onPropChanged('muted');
380
+ break;
381
+ }
382
+ case 'playbackSpeed': {
383
+ if (propValue !== null && isFinite(propValue)) {
384
+ videoElement.playbackRate = parseFloat(propValue);
385
+ onPropChanged('playbackSpeed');
386
+ }
387
+
388
+ break;
389
+ }
390
+ }
391
+ }
392
+ function command(commandName, commandArgs) {
393
+ switch (commandName) {
394
+ case 'load': {
395
+ command('unload');
396
+ if (commandArgs && commandArgs.stream && typeof commandArgs.stream.url === 'string') {
397
+ stream = commandArgs.stream;
398
+ onPropChanged('stream');
399
+ onPropChanged('loaded');
400
+ videoElement.autoplay = typeof commandArgs.autoplay === 'boolean' ? commandArgs.autoplay : true;
401
+ videoElement.currentTime = commandArgs.time !== null && isFinite(commandArgs.time) ? parseInt(commandArgs.time, 10) / 1000 : 0;
402
+ onPropChanged('paused');
403
+ onPropChanged('time');
404
+ onPropChanged('duration');
405
+ onPropChanged('buffering');
406
+ if (videoElement.textTracks) {
407
+ videoElement.textTracks.onaddtrack = function() {
408
+ videoElement.textTracks.onaddtrack = null;
409
+ setTimeout(function() {
410
+ onPropChanged('subtitlesTracks');
411
+ onPropChanged('selectedSubtitlesTrackId');
412
+ });
413
+ };
414
+ }
415
+ if (videoElement.audioTracks) {
416
+ videoElement.audioTracks.onaddtrack = function() {
417
+ videoElement.audioTracks.onaddtrack = null;
418
+ setTimeout(function() {
419
+ onPropChanged('audioTracks');
420
+ onPropChanged('selectedAudioTrackId');
421
+ });
422
+ };
423
+ }
424
+ videoElement.src = stream.url;
425
+ } else {
426
+ onError(Object.assign({}, ERROR.UNSUPPORTED_STREAM, {
427
+ critical: true,
428
+ stream: commandArgs ? commandArgs.stream : null
429
+ }));
430
+ }
431
+ break;
432
+ }
433
+ case 'unload': {
434
+ stream = null;
435
+ Array.from(videoElement.textTracks).forEach(function(track) {
436
+ track.oncuechange = null;
437
+ });
438
+ videoElement.removeAttribute('src');
439
+ videoElement.load();
440
+ videoElement.currentTime = 0;
441
+ onPropChanged('stream');
442
+ onPropChanged('loaded');
443
+ onPropChanged('paused');
444
+ onPropChanged('time');
445
+ onPropChanged('duration');
446
+ onPropChanged('buffering');
447
+ onPropChanged('subtitlesTracks');
448
+ onPropChanged('selectedSubtitlesTrackId');
449
+ onPropChanged('audioTracks');
450
+ onPropChanged('selectedAudioTrackId');
451
+ break;
452
+ }
453
+ case 'destroy': {
454
+ command('unload');
455
+ destroyed = true;
456
+ onPropChanged('volume');
457
+ onPropChanged('muted');
458
+ onPropChanged('playbackSpeed');
459
+ events.removeAllListeners();
460
+ videoElement.onerror = null;
461
+ videoElement.onended = null;
462
+ videoElement.onpause = null;
463
+ videoElement.onplay = null;
464
+ videoElement.ontimeupdate = null;
465
+ videoElement.ondurationchange = null;
466
+ videoElement.onwaiting = null;
467
+ videoElement.onseeking = null;
468
+ videoElement.onseeked = null;
469
+ videoElement.onstalled = null;
470
+ videoElement.onplaying = null;
471
+ videoElement.oncanplay = null;
472
+ videoElement.canplaythrough = null;
473
+ videoElement.onloadeddata = null;
474
+ videoElement.onvolumechange = null;
475
+ videoElement.onratechange = null;
476
+ videoElement.textTracks.onchange = null;
477
+ containerElement.removeChild(videoElement);
478
+ break;
479
+ }
480
+ }
481
+ }
482
+
483
+ this.on = function(eventName, listener) {
484
+ if (destroyed) {
485
+ throw new Error('Video is destroyed');
486
+ }
487
+
488
+ events.on(eventName, listener);
489
+ };
490
+ this.dispatch = function(action) {
491
+ if (destroyed) {
492
+ throw new Error('Video is destroyed');
493
+ }
494
+
495
+ if (action) {
496
+ action = deepFreeze(cloneDeep(action));
497
+ switch (action.type) {
498
+ case 'observeProp': {
499
+ observeProp(action.propName);
500
+ return;
501
+ }
502
+ case 'setProp': {
503
+ setProp(action.propName, action.propValue);
504
+ return;
505
+ }
506
+ case 'command': {
507
+ command(action.commandName, action.commandArgs);
508
+ return;
509
+ }
510
+ }
511
+ }
512
+
513
+ throw new Error('Invalid action dispatched: ' + JSON.stringify(action));
514
+ };
515
+ }
516
+
517
+ VidaaVideo.canPlayStream = function(stream) {
518
+ if (!stream) {
519
+ return Promise.resolve(false);
520
+ }
521
+
522
+ return Promise.resolve(true);
523
+ };
524
+
525
+ VidaaVideo.manifest = {
526
+ name: 'VidaaVideo',
527
+ external: false,
528
+ props: ['stream', 'loaded', 'paused', 'time', 'duration', 'buffering', 'audioTracks', 'selectedAudioTrackId', 'subtitlesTracks', 'selectedSubtitlesTrackId', 'volume', 'muted', 'playbackSpeed'],
529
+ commands: ['load', 'unload', 'destroy'],
530
+ events: ['propValue', 'propChanged', 'ended', 'error', 'subtitlesTrackLoaded', 'audioTrackLoaded']
531
+ };
532
+
533
+ module.exports = VidaaVideo;
@@ -0,0 +1,3 @@
1
+ var VidaaVideo = require('./VidaaVideo');
2
+
3
+ module.exports = VidaaVideo;