shaka-player 4.9.1 → 4.9.2

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.
@@ -393,7 +393,6 @@ shaka.media.DrmEngine = class {
393
393
  this.config_.keySystemsMapping);
394
394
  }
395
395
 
396
-
397
396
  /** @type {!Map.<string, MediaKeySystemConfiguration>} */
398
397
  let configsByKeySystem;
399
398
 
@@ -402,6 +401,7 @@ shaka.media.DrmEngine = class {
402
401
  await shaka.util.StreamUtils.getDecodingInfosForVariants(variants,
403
402
  this.usePersistentLicenses_, this.srcEquals_,
404
403
  this.config_.preferredKeySystems);
404
+ this.destroyer_.ensureNotDestroyed();
405
405
 
406
406
  const hasDrmInfo = hadDrmInfo || Object.keys(this.config_.servers).length;
407
407
  // An unencrypted content is initialized.
@@ -132,19 +132,7 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
132
132
  this.stats_ = new shaka.util.Stats();
133
133
 
134
134
  /** @private {!shaka.util.PublicPromise} */
135
- this.manifestPromise_ = new shaka.util.PublicPromise();
136
-
137
- /** @private {!shaka.util.PublicPromise} */
138
- this.drmPromise_ = new shaka.util.PublicPromise();
139
-
140
- /** @private {!shaka.util.PublicPromise} */
141
- this.chooseInitialVariantPromise_ = new shaka.util.PublicPromise();
142
-
143
- /** @private {!shaka.util.PublicPromise} */
144
- this.destroyPromise_ = new shaka.util.PublicPromise();
145
-
146
- // Silence promise failures, in case nobody is catching this.destroyPromise_
147
- this.destroyPromise_.catch((error) => {});
135
+ this.successPromise_ = new shaka.util.PublicPromise();
148
136
 
149
137
  /** @private {?shaka.util.FakeEventTarget} */
150
138
  this.eventHandoffTarget_ = null;
@@ -353,21 +341,6 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
353
341
  return this.segmentPrefetchById_;
354
342
  }
355
343
 
356
- /** @return {!Promise} */
357
- waitForManifest() {
358
- return this.manifestPromise_;
359
- }
360
-
361
- /** @return {!Promise} */
362
- waitForDrm() {
363
- return this.drmPromise_;
364
- }
365
-
366
- /** @return {!Promise} */
367
- waitForChooseInitialVariant() {
368
- return this.chooseInitialVariantPromise_;
369
- }
370
-
371
344
  /**
372
345
  * @param {?shaka.extern.AbrManager} abrManager
373
346
  * @param {?shaka.extern.AbrManager.Factory} abrFactory
@@ -397,34 +370,30 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
397
370
 
398
371
  /**
399
372
  * Starts the process of loading the asset.
400
- * @return {!Promise}
373
+ * Success or failure will be measured through waitForFinish()
401
374
  */
402
- async start() {
403
- // Force a context switch, to give the player a chance to hook up events
404
- // immediately if desired.
405
- await Promise.resolve();
406
-
407
- // Perform the preloading process.
408
- try {
409
- await this.parseManifestInner_();
410
- if (this.isDestroyed()) {
411
- return;
412
- }
413
- this.manifestPromise_.resolve();
414
- await this.initializeDrmInner_();
415
- if (this.isDestroyed()) {
416
- return;
417
- }
418
- this.drmPromise_.resolve();
419
- await this.chooseInitialVariantInner_();
420
- if (this.isDestroyed()) {
421
- return;
375
+ start() {
376
+ (async () => {
377
+ // Force a context switch, to give the player a chance to hook up events
378
+ // immediately if desired.
379
+ await Promise.resolve();
380
+
381
+ // Perform the preloading process.
382
+ try {
383
+ await this.parseManifestInner_();
384
+ this.throwIfDestroyed_();
385
+
386
+ await this.initializeDrmInner_();
387
+ this.throwIfDestroyed_();
388
+
389
+ await this.chooseInitialVariantInner_();
390
+ this.throwIfDestroyed_();
391
+
392
+ this.successPromise_.resolve();
393
+ } catch (error) {
394
+ this.successPromise_.reject(error);
422
395
  }
423
- this.chooseInitialVariantPromise_.resolve();
424
- } catch (error) {
425
- this.destroyPromise_.reject(error);
426
- throw error;
427
- }
396
+ })();
428
397
  }
429
398
 
430
399
  /**
@@ -446,7 +415,7 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
446
415
  onError(error) {
447
416
  if (error.severity === shaka.util.Error.Severity.CRITICAL) {
448
417
  // Cancel the loading process.
449
- this.destroyPromise_.reject(error);
418
+ this.successPromise_.reject(error);
450
419
  this.destroy();
451
420
  }
452
421
 
@@ -458,6 +427,20 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
458
427
  }
459
428
  }
460
429
 
430
+ /**
431
+ * Throw if destroyed, to interrupt processes with a recognizable error.
432
+ *
433
+ * @private
434
+ */
435
+ throwIfDestroyed_() {
436
+ if (this.isDestroyed()) {
437
+ throw new shaka.util.Error(
438
+ shaka.util.Error.Severity.CRITICAL,
439
+ shaka.util.Error.Category.PLAYER,
440
+ shaka.util.Error.Code.OBJECT_DESTROYED);
441
+ }
442
+ }
443
+
461
444
  /**
462
445
  * Makes a fires an event corresponding to entering a state of the loading
463
446
  * process.
@@ -553,12 +536,11 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
553
536
 
554
537
  const tracksChangedInitial = this.manifestFilterer_.applyRestrictions(
555
538
  this.manifest_);
556
- const tracksChangedBefore = await this.manifestFilterer_.filterManifest(
557
- this.manifest_);
558
- if (tracksChangedInitial || tracksChangedBefore) {
539
+ if (tracksChangedInitial) {
559
540
  const event = this.makeEvent_(
560
541
  shaka.util.FakeEvent.EventName.TracksChanged);
561
542
  await Promise.resolve();
543
+ this.throwIfDestroyed_();
562
544
  this.dispatchEvent(event);
563
545
  }
564
546
 
@@ -567,6 +549,7 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
567
549
  await this.drmEngine_.initForPlayback(
568
550
  playableVariants,
569
551
  this.manifest_.offlineSessionIds);
552
+ this.throwIfDestroyed_();
570
553
 
571
554
  // Now that we have drm information, filter the manifest (again) so that
572
555
  // we can ensure we only use variants with the selected key system.
@@ -717,10 +700,7 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
717
700
  * @export
718
701
  */
719
702
  waitForFinish() {
720
- return Promise.race([
721
- this.chooseInitialVariantPromise_,
722
- this.destroyPromise_,
723
- ]);
703
+ return this.successPromise_;
724
704
  }
725
705
 
726
706
  /**
package/lib/player.js CHANGED
@@ -1607,7 +1607,12 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
1607
1607
  if (preloadManager) {
1608
1608
  preloadManager.setEventHandoffTarget(this);
1609
1609
  this.stats_ = preloadManager.getStats();
1610
- await mutexWrapOperation(() => preloadManager.start(), 'preload');
1610
+ preloadManager.start();
1611
+ // Silence "uncaught error" warnings from this. Unless we are
1612
+ // interrupted, we will check the result of this process and respond
1613
+ // appropriately. If we are interrupted, we can ignore any error
1614
+ // there.
1615
+ preloadManager.waitForFinish().catch(() => {});
1611
1616
  } else {
1612
1617
  this.stats_ = new shaka.util.Stats();
1613
1618
  }
@@ -1648,9 +1653,12 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
1648
1653
  }, 'initializeMediaSourceEngineInner_');
1649
1654
  }
1650
1655
 
1656
+ // Wait for the preload manager to do all of the loading it can do.
1657
+ await mutexWrapOperation(async () => {
1658
+ await preloadManager.waitForFinish();
1659
+ }, 'waitForFinish');
1660
+
1651
1661
  // Get manifest and associated values from preloader.
1652
- await mutexWrapOperation(
1653
- () => preloadManager.waitForManifest(), 'waitForManifest');
1654
1662
  this.config_ = preloadManager.getConfiguration();
1655
1663
  this.manifestFilterer_ = preloadManager.getManifestFilterer();
1656
1664
  this.parserFactory_ = preloadManager.getParserFactory();
@@ -1674,18 +1682,11 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
1674
1682
  }
1675
1683
 
1676
1684
  // Get drm engine from preloader, then finalize it.
1677
- await mutexWrapOperation(
1678
- () => preloadManager.waitForDrm(), 'waitForDrm');
1679
1685
  this.drmEngine_ = preloadManager.receiveDrmEngine();
1680
1686
  await mutexWrapOperation(async () => {
1681
1687
  await this.drmEngine_.attach(this.video_);
1682
1688
  }, 'drmEngine_.attach');
1683
1689
 
1684
- // Choose an initial variant.
1685
- await mutexWrapOperation(
1686
- () => preloadManager.waitForChooseInitialVariant(),
1687
- 'waitForChooseInitialVariant');
1688
-
1689
1690
  // Also get the ABR manager, which has special logic related to being
1690
1691
  // received.
1691
1692
  const abrManagerFactory = preloadManager.getAbrManagerFactory();
@@ -1873,7 +1874,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
1873
1874
  shaka.util.Error.Category.PLAYER,
1874
1875
  shaka.util.Error.Code.SRC_EQUALS_PRELOAD_NOT_SUPPORTED));
1875
1876
  } else {
1876
- preloadManager.start().catch((error) => {}); // Catch errors.
1877
+ preloadManager.start();
1877
1878
  }
1878
1879
  return preloadManager;
1879
1880
  }
@@ -7103,7 +7104,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
7103
7104
  shaka.util.FakeEvent.EventName.KeyStatusChanged);
7104
7105
  this.dispatchEvent(event);
7105
7106
 
7106
- const keyIds = Object.keys(keyStatusMap);
7107
+ let keyIds = Object.keys(keyStatusMap);
7107
7108
  if (keyIds.length == 0) {
7108
7109
  shaka.log.warning(
7109
7110
  'Got a key status event without any key statuses, so we don\'t ' +
@@ -7111,6 +7112,13 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
7111
7112
  'you\'ll need to set restrictions so we don\'t select those tracks.');
7112
7113
  }
7113
7114
 
7115
+ // Non-standard version of global key status. Modify it to match standard
7116
+ // behavior.
7117
+ if (keyIds.length == 1 && keyIds[0] == '') {
7118
+ keyIds = ['00'];
7119
+ keyStatusMap = {'00': keyStatusMap['']};
7120
+ }
7121
+
7114
7122
  // If EME is using a synthetic key ID, the only key ID is '00' (a single 0
7115
7123
  // byte). In this case, it is only used to report global success/failure.
7116
7124
  // See note about old platforms in: https://bit.ly/2tpez5Z
@@ -7446,7 +7454,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
7446
7454
  * @export
7447
7455
  */
7448
7456
  // eslint-disable-next-line no-useless-concat
7449
- shaka.Player.version = 'v4.9.1' + '-uncompiled'; // x-release-please-version
7457
+ shaka.Player.version = 'v4.9.2' + '-uncompiled'; // x-release-please-version
7450
7458
 
7451
7459
  // Initialize the deprecation system using the version string we just set
7452
7460
  // on the player.
@@ -67,6 +67,18 @@ shaka.polyfill.MediaSource = class {
67
67
  // Bug filed: https://bugs.webkit.org/show_bug.cgi?id=165342
68
68
  shaka.polyfill.MediaSource.stubAbort_();
69
69
  }
70
+ } else if (shaka.util.Platform.isZenterio()) {
71
+ // Zenterio uses WPE based on Webkit 607.x.x which do not correctly
72
+ // implement abort() on SourceBuffer.
73
+ // Calling abort() before appending a segment causes that segment to be
74
+ // incomplete in the buffer.
75
+ // Bug filed: https://bugs.webkit.org/show_bug.cgi?id=165342
76
+ shaka.polyfill.MediaSource.stubAbort_();
77
+ // If you remove up to a keyframe, Webkit 607.x.x incorrectly will also
78
+ // remove that keyframe and the content up to the next.
79
+ // Offsetting the end of the removal range seems to help.
80
+ // Bug filed: https://bugs.webkit.org/show_bug.cgi?id=177884
81
+ shaka.polyfill.MediaSource.patchRemovalRange_();
70
82
  } else if (shaka.util.Platform.isTizen2() ||
71
83
  shaka.util.Platform.isTizen3() ||
72
84
  shaka.util.Platform.isTizen4()) {
@@ -211,6 +211,8 @@ shaka.util.ConfigUtils = class {
211
211
  delete obj[key];
212
212
  } else if (isArrayEmpty(obj[key])) {
213
213
  delete obj[key];
214
+ } else if (typeof obj[key] == 'function') {
215
+ delete obj[key];
214
216
  } else if (isObject(obj[key])) {
215
217
  removeEmpty(obj[key]);
216
218
  }
@@ -299,7 +299,8 @@ shaka.util.Platform = class {
299
299
  !shaka.util.Platform.isOrange() &&
300
300
  !shaka.util.Platform.isPS4() &&
301
301
  !shaka.util.Platform.isAmazonFireTV() &&
302
- !shaka.util.Platform.isWPE();
302
+ !shaka.util.Platform.isWPE() &&
303
+ !shaka.util.Platform.isZenterio();
303
304
  }
304
305
 
305
306
  /**
@@ -362,6 +363,14 @@ shaka.util.Platform = class {
362
363
  return shaka.util.Platform.userAgentContains_('WPE');
363
364
  }
364
365
 
366
+ /**
367
+ * Check if the current platform is Deutsche Telecom Zenterio STB.
368
+ * @return {boolean}
369
+ */
370
+ static isZenterio() {
371
+ return shaka.util.Platform.userAgentContains_('DT_STB_BCM');
372
+ }
373
+
365
374
  /**
366
375
  * Returns a major version number for Safari, or Safari-based iOS browsers.
367
376
  *
@@ -519,7 +528,7 @@ shaka.util.Platform = class {
519
528
  Platform.isEOS() || Platform.isAPL() ||
520
529
  Platform.isVirginMedia() || Platform.isOrange() ||
521
530
  Platform.isWPE() || Platform.isChromecast() ||
522
- Platform.isHisense()) {
531
+ Platform.isHisense() || Platform.isZenterio()) {
523
532
  return true;
524
533
  }
525
534
  return false;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "shaka-player",
3
3
  "description": "DASH/EME video player library",
4
- "version": "4.9.1",
4
+ "version": "4.9.2",
5
5
  "homepage": "https://github.com/shaka-project/shaka-player",
6
6
  "author": "Google",
7
7
  "maintainers": [
@@ -7,6 +7,7 @@
7
7
 
8
8
  goog.provide('shaka.ui.PresentationTimeTracker');
9
9
 
10
+ goog.require('shaka.ads.AdManager');
10
11
  goog.require('shaka.ui.Controls');
11
12
  goog.require('shaka.ui.Element');
12
13
  goog.require('shaka.ui.Locales');
@@ -40,6 +41,10 @@ shaka.ui.PresentationTimeTracker = class extends shaka.ui.Element {
40
41
  }
41
42
  });
42
43
 
44
+ this.eventManager.listen(this.player, 'loading', () => {
45
+ shaka.ui.Utils.setDisplay(this.currentTime_, true);
46
+ });
47
+
43
48
  this.eventManager.listen(this.controls, 'timeandseekrangeupdated', () => {
44
49
  this.updateTime_();
45
50
  });
@@ -47,6 +52,16 @@ shaka.ui.PresentationTimeTracker = class extends shaka.ui.Element {
47
52
  this.eventManager.listen(this.player, 'trackschanged', () => {
48
53
  this.onTracksChanged_();
49
54
  });
55
+
56
+ this.eventManager.listen(
57
+ this.adManager, shaka.ads.AdManager.AD_STARTED, () => {
58
+ shaka.ui.Utils.setDisplay(this.currentTime_, false);
59
+ });
60
+
61
+ this.eventManager.listen(
62
+ this.adManager, shaka.ads.AdManager.AD_STOPPED, () => {
63
+ shaka.ui.Utils.setDisplay(this.currentTime_, true);
64
+ });
50
65
  }
51
66
 
52
67
  /** @private */
@@ -140,6 +140,9 @@ shaka.ui.ResolutionSelection = class extends shaka.ui.SettingsMenu {
140
140
  tracks.sort((t1, t2) => {
141
141
  goog.asserts.assert(t1.height != null, 'Null height');
142
142
  goog.asserts.assert(t2.height != null, 'Null height');
143
+ if (t2.height == t1.height) {
144
+ return t2.bandwidth - t1.bandwidth;
145
+ }
143
146
  return t2.height - t1.height;
144
147
  });
145
148
  }