rx-player 3.29.0-dev.2022090500 → 3.29.0-dev.2022091600

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.
Files changed (142) hide show
  1. package/CHANGELOG.md +5 -1
  2. package/VERSION +1 -1
  3. package/dist/_esm5.processed/core/api/option_utils.js +7 -11
  4. package/dist/_esm5.processed/core/api/public_api.d.ts +4 -4
  5. package/dist/_esm5.processed/core/api/public_api.js +18 -19
  6. package/dist/_esm5.processed/core/api/{media_element_track_choice_manager.d.ts → tracks_management/media_element_track_choice_manager.d.ts} +2 -2
  7. package/dist/_esm5.processed/core/api/{media_element_track_choice_manager.js → tracks_management/media_element_track_choice_manager.js} +7 -4
  8. package/dist/_esm5.processed/core/api/{track_choice_manager.d.ts → tracks_management/track_choice_manager.d.ts} +2 -2
  9. package/dist/_esm5.processed/core/api/{track_choice_manager.js → tracks_management/track_choice_manager.js} +7 -7
  10. package/dist/_esm5.processed/core/api/{emit_seek_events.d.ts → utils.d.ts} +24 -1
  11. package/dist/_esm5.processed/core/api/{emit_seek_events.js → utils.js} +32 -1
  12. package/dist/_esm5.processed/core/decrypt/content_decryptor.d.ts +26 -0
  13. package/dist/_esm5.processed/core/decrypt/content_decryptor.js +101 -9
  14. package/dist/_esm5.processed/core/decrypt/session_events_listener.d.ts +15 -18
  15. package/dist/_esm5.processed/core/decrypt/session_events_listener.js +9 -7
  16. package/dist/_esm5.processed/core/decrypt/utils/check_key_statuses.d.ts +19 -22
  17. package/dist/_esm5.processed/core/decrypt/utils/check_key_statuses.js +87 -16
  18. package/dist/_esm5.processed/core/decrypt/utils/persistent_sessions_store.d.ts +1 -2
  19. package/dist/_esm5.processed/core/decrypt/utils/persistent_sessions_store.js +1 -2
  20. package/dist/_esm5.processed/core/fetchers/index.d.ts +2 -2
  21. package/dist/_esm5.processed/core/fetchers/segment/index.d.ts +2 -3
  22. package/dist/_esm5.processed/core/fetchers/segment/prioritized_segment_fetcher.d.ts +9 -9
  23. package/dist/_esm5.processed/core/fetchers/segment/prioritized_segment_fetcher.js +17 -15
  24. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.d.ts +33 -40
  25. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher.js +156 -153
  26. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher_creator.d.ts +3 -3
  27. package/dist/_esm5.processed/core/fetchers/segment/segment_fetcher_creator.js +2 -2
  28. package/dist/_esm5.processed/core/fetchers/segment/task_prioritizer.d.ts +145 -0
  29. package/dist/_esm5.processed/core/fetchers/segment/task_prioritizer.js +325 -0
  30. package/dist/_esm5.processed/core/fetchers/utils/try_urls_with_backoff.d.ts +2 -2
  31. package/dist/_esm5.processed/core/fetchers/utils/try_urls_with_backoff.js +3 -3
  32. package/dist/_esm5.processed/core/init/create_media_source.d.ts +10 -0
  33. package/dist/_esm5.processed/core/init/create_media_source.js +1 -1
  34. package/dist/_esm5.processed/core/init/stall_avoider.d.ts +2 -1
  35. package/dist/_esm5.processed/core/init/stall_avoider.js +2 -1
  36. package/dist/_esm5.processed/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.js +1 -1
  37. package/dist/_esm5.processed/core/segment_buffers/implementations/text/html/html_text_segment_buffer.js +3 -3
  38. package/dist/_esm5.processed/core/segment_buffers/implementations/types.d.ts +6 -2
  39. package/dist/_esm5.processed/core/stream/orchestrator/{get_blacklisted_ranges.d.ts → get_time_ranges_for_content.d.ts} +1 -1
  40. package/dist/_esm5.processed/core/stream/orchestrator/{get_blacklisted_ranges.js → get_time_ranges_for_content.js} +1 -1
  41. package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +61 -19
  42. package/dist/_esm5.processed/core/stream/representation/downloading_queue.d.ts +8 -4
  43. package/dist/_esm5.processed/core/stream/representation/downloading_queue.js +200 -83
  44. package/dist/_esm5.processed/core/stream/types.d.ts +3 -1
  45. package/dist/_esm5.processed/errors/encrypted_media_error.d.ts +6 -1
  46. package/dist/_esm5.processed/errors/encrypted_media_error.js +4 -5
  47. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/index.d.ts +1 -1
  48. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/index.js +1 -1
  49. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/load_and_push_segment.d.ts +26 -0
  50. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/load_and_push_segment.js +60 -0
  51. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/prepare_source_buffer.d.ts +6 -5
  52. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/prepare_source_buffer.js +40 -9
  53. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/remove_buffer_around_time.d.ts +3 -2
  54. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/remove_buffer_around_time.js +7 -14
  55. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/types.d.ts +1 -1
  56. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/{thumbnail_loader.d.ts → video_thumbnail_loader.d.ts} +1 -13
  57. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.js +331 -0
  58. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader_error.d.ts +1 -2
  59. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader_error.js +1 -2
  60. package/dist/_esm5.processed/features/initialize_features.js +2 -1
  61. package/dist/_esm5.processed/features/list/directfile.js +1 -1
  62. package/dist/_esm5.processed/features/types.d.ts +1 -1
  63. package/dist/_esm5.processed/manifest/index.d.ts +2 -2
  64. package/dist/_esm5.processed/public_types.d.ts +47 -0
  65. package/dist/_esm5.processed/utils/reference.d.ts +23 -3
  66. package/dist/_esm5.processed/utils/reference.js +23 -2
  67. package/dist/rx-player.js +1253 -1014
  68. package/dist/rx-player.min.js +1 -1
  69. package/package.json +1 -1
  70. package/sonar-project.properties +1 -1
  71. package/src/core/api/README.md +1 -1
  72. package/src/core/api/__tests__/{get_player_state.test.ts → utils.test.ts} +1 -1
  73. package/src/core/api/option_utils.ts +1 -5
  74. package/src/core/api/public_api.ts +15 -13
  75. package/src/core/api/{__tests__ → tracks_management/__tests__}/media_element_track_choice_manager.test.ts +0 -0
  76. package/src/core/api/{media_element_track_choice_manager.ts → tracks_management/media_element_track_choice_manager.ts} +10 -7
  77. package/src/core/api/{track_choice_manager.ts → tracks_management/track_choice_manager.ts} +9 -9
  78. package/src/core/api/{get_player_state.ts → utils.ts} +62 -11
  79. package/src/core/decrypt/content_decryptor.ts +112 -13
  80. package/src/core/decrypt/session_events_listener.ts +34 -30
  81. package/src/core/decrypt/utils/check_key_statuses.ts +89 -45
  82. package/src/core/decrypt/utils/persistent_sessions_store.ts +1 -2
  83. package/src/core/fetchers/index.ts +0 -12
  84. package/src/core/fetchers/segment/__tests__/task_prioritizer.test.ts +763 -0
  85. package/src/core/fetchers/segment/index.ts +0 -12
  86. package/src/core/fetchers/segment/prioritized_segment_fetcher.ts +40 -47
  87. package/src/core/fetchers/segment/segment_fetcher.ts +249 -268
  88. package/src/core/fetchers/segment/segment_fetcher_creator.ts +6 -7
  89. package/src/core/fetchers/segment/task_prioritizer.ts +460 -0
  90. package/src/core/fetchers/utils/try_urls_with_backoff.ts +3 -3
  91. package/src/core/init/create_media_source.ts +1 -1
  92. package/src/core/init/stall_avoider.ts +2 -1
  93. package/src/core/segment_buffers/implementations/audio_video/audio_video_segment_buffer.ts +1 -1
  94. package/src/core/segment_buffers/implementations/text/html/html_text_segment_buffer.ts +3 -3
  95. package/src/core/segment_buffers/implementations/types.ts +6 -2
  96. package/src/core/stream/orchestrator/{get_blacklisted_ranges.ts → get_time_ranges_for_content.ts} +1 -1
  97. package/src/core/stream/orchestrator/stream_orchestrator.ts +115 -56
  98. package/src/core/stream/representation/downloading_queue.ts +269 -142
  99. package/src/core/stream/types.ts +3 -1
  100. package/src/errors/encrypted_media_error.ts +20 -1
  101. package/src/experimental/tools/VideoThumbnailLoader/index.ts +1 -1
  102. package/src/experimental/tools/VideoThumbnailLoader/load_and_push_segment.ts +74 -0
  103. package/src/experimental/tools/VideoThumbnailLoader/prepare_source_buffer.ts +50 -16
  104. package/src/experimental/tools/VideoThumbnailLoader/remove_buffer_around_time.ts +14 -21
  105. package/src/experimental/tools/VideoThumbnailLoader/types.ts +7 -4
  106. package/src/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader.ts +407 -0
  107. package/src/experimental/tools/VideoThumbnailLoader/video_thumbnail_loader_error.ts +1 -2
  108. package/src/features/__tests__/initialize_features.test.ts +3 -1
  109. package/src/features/initialize_features.ts +2 -1
  110. package/src/features/list/__tests__/directfile.test.ts +1 -1
  111. package/src/features/list/directfile.ts +1 -1
  112. package/src/features/types.ts +1 -1
  113. package/src/manifest/index.ts +2 -0
  114. package/src/public_types.ts +53 -0
  115. package/src/utils/reference.ts +58 -4
  116. package/dist/_esm5.processed/core/api/get_player_state.d.ts +0 -28
  117. package/dist/_esm5.processed/core/api/get_player_state.js +0 -56
  118. package/dist/_esm5.processed/core/fetchers/segment/prioritizer.d.ts +0 -232
  119. package/dist/_esm5.processed/core/fetchers/segment/prioritizer.js +0 -422
  120. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/create_request.d.ts +0 -29
  121. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/create_request.js +0 -68
  122. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/get_complete_segment_id.d.ts +0 -24
  123. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/get_complete_segment_id.js +0 -29
  124. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/get_content_infos.d.ts +0 -25
  125. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/get_content_infos.js +0 -40
  126. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/get_initialized_source_buffer.d.ts +0 -33
  127. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/get_initialized_source_buffer.js +0 -124
  128. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/load_segments.d.ts +0 -17
  129. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/load_segments.js +0 -41
  130. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/push_data.d.ts +0 -22
  131. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/push_data.js +0 -21
  132. package/dist/_esm5.processed/experimental/tools/VideoThumbnailLoader/thumbnail_loader.js +0 -212
  133. package/src/core/api/emit_seek_events.ts +0 -66
  134. package/src/core/fetchers/segment/__tests__/prioritizer.test.ts +0 -962
  135. package/src/core/fetchers/segment/prioritizer.ts +0 -558
  136. package/src/experimental/tools/VideoThumbnailLoader/create_request.ts +0 -113
  137. package/src/experimental/tools/VideoThumbnailLoader/get_complete_segment_id.ts +0 -34
  138. package/src/experimental/tools/VideoThumbnailLoader/get_content_infos.ts +0 -48
  139. package/src/experimental/tools/VideoThumbnailLoader/get_initialized_source_buffer.ts +0 -171
  140. package/src/experimental/tools/VideoThumbnailLoader/load_segments.ts +0 -69
  141. package/src/experimental/tools/VideoThumbnailLoader/push_data.ts +0 -48
  142. package/src/experimental/tools/VideoThumbnailLoader/thumbnail_loader.ts +0 -311
@@ -100,6 +100,7 @@ import createOrLoadSession from "./create_or_load_session";
100
100
  import initMediaKeys from "./init_media_keys";
101
101
  import SessionEventsListener, { BlacklistedSessionError, } from "./session_events_listener";
102
102
  import setServerCertificate from "./set_server_certificate";
103
+ import { DecommissionedSessionError } from "./utils/check_key_statuses";
103
104
  import cleanOldStoredPersistentInfo from "./utils/clean_old_stored_persistent_info";
104
105
  import getDrmSystemId from "./utils/get_drm_system_id";
105
106
  import InitDataValuesContainer from "./utils/init_data_values_container";
@@ -351,7 +352,7 @@ var ContentDecryptor = /** @class */ (function (_super) {
351
352
  .reduce(function (acc, kid) { return "".concat(acc, ", ").concat(bytesToHex(kid)); }, "");
352
353
  log.debug("DRM: Blacklisting new key ids", hexKids);
353
354
  }
354
- updateDecipherability(initializationData.content.manifest, [], keyIds);
355
+ updateDecipherability(initializationData.content.manifest, [], keyIds, []);
355
356
  }
356
357
  return [2 /*return*/];
357
358
  }
@@ -380,7 +381,7 @@ var ContentDecryptor = /** @class */ (function (_super) {
380
381
  createdSess.keyStatuses.blacklisted.push(innerKid);
381
382
  }
382
383
  }
383
- updateDecipherability(initializationData.content.manifest, createdSess.keyStatuses.whitelisted, createdSess.keyStatuses.blacklisted);
384
+ updateDecipherability(initializationData.content.manifest, createdSess.keyStatuses.whitelisted, createdSess.keyStatuses.blacklisted, []);
384
385
  return [2 /*return*/];
385
386
  }
386
387
  }
@@ -428,7 +429,7 @@ var ContentDecryptor = /** @class */ (function (_super) {
428
429
  _this.trigger("warning", evt.value);
429
430
  return;
430
431
  }
431
- var linkedKeys = getKeyIdsLinkedToSession(initializationData, sessionInfo.record, options.singleLicensePer, sessionInfo.source === "created-session" /* MediaKeySessionLoadingType.Created */, evt.value.whitelistedKeyIds, evt.value.blacklistedKeyIDs);
432
+ var linkedKeys = getKeyIdsLinkedToSession(initializationData, sessionInfo.record, options.singleLicensePer, sessionInfo.source === "created-session" /* MediaKeySessionLoadingType.Created */, evt.value.whitelistedKeyIds, evt.value.blacklistedKeyIds);
432
433
  sessionInfo.record.associateKeyIds(linkedKeys.whitelisted);
433
434
  sessionInfo.record.associateKeyIds(linkedKeys.blacklisted);
434
435
  sessionInfo.keyStatuses = { whitelisted: linkedKeys.whitelisted,
@@ -443,11 +444,36 @@ var ContentDecryptor = /** @class */ (function (_super) {
443
444
  isSessionPersisted = true;
444
445
  }
445
446
  if (initializationData.content !== undefined) {
446
- updateDecipherability(initializationData.content.manifest, linkedKeys.whitelisted, linkedKeys.blacklisted);
447
+ updateDecipherability(initializationData.content.manifest, linkedKeys.whitelisted, linkedKeys.blacklisted, []);
447
448
  }
448
449
  _this._unlockInitDataQueue();
449
450
  },
450
451
  error: function (err) {
452
+ var _a;
453
+ if (err instanceof DecommissionedSessionError) {
454
+ log.warn("DRM: A session's closing condition has been triggered");
455
+ _this._lockInitDataQueue();
456
+ var indexOf = _this._currentSessions.indexOf(sessionInfo);
457
+ if (indexOf >= 0) {
458
+ _this._currentSessions.splice(indexOf);
459
+ }
460
+ if (initializationData.content !== undefined) {
461
+ updateDecipherability(initializationData.content.manifest, [], [], sessionInfo.record.getAssociatedKeyIds());
462
+ }
463
+ (_a = stores.persistentSessionsStore) === null || _a === void 0 ? void 0 : _a.delete(mediaKeySession.sessionId);
464
+ stores.loadedSessionsStore.closeSession(mediaKeySession)
465
+ .catch(function (e) {
466
+ var closeError = e instanceof Error ? e :
467
+ "unknown error";
468
+ log.warn("DRM: failed to close expired session", closeError);
469
+ })
470
+ .then(function () { return _this._unlockInitDataQueue(); })
471
+ .catch(function (retryError) { return _this._onFatalError(retryError); });
472
+ if (!_this._isStopped()) {
473
+ _this.trigger("warning", err.reason);
474
+ }
475
+ return;
476
+ }
451
477
  if (!(err instanceof BlacklistedSessionError)) {
452
478
  _this._onFatalError(err);
453
479
  return;
@@ -559,7 +585,7 @@ var ContentDecryptor = /** @class */ (function (_super) {
559
585
  }
560
586
  log.info("DRM: Current initialization data is linked to blacklisted keys. " +
561
587
  "Marking Representations as not decipherable");
562
- updateDecipherability(initializationData.content.manifest, [], initializationData.keyIds);
588
+ updateDecipherability(initializationData.content.manifest, [], initializationData.keyIds, []);
563
589
  return true;
564
590
  }
565
591
  }
@@ -586,13 +612,23 @@ var ContentDecryptor = /** @class */ (function (_super) {
586
612
  }
587
613
  return false;
588
614
  };
615
+ /**
616
+ * Callback that should be called if an error that made the current
617
+ * `ContentDecryptor` instance unusable arised.
618
+ * This callbacks takes care of resetting state and sending the right events.
619
+ *
620
+ * Once called, no further actions should be taken.
621
+ *
622
+ * @param {*} err - The error object which describes the issue. Will be
623
+ * formatted and sent in an "error" event.
624
+ */
589
625
  ContentDecryptor.prototype._onFatalError = function (err) {
590
626
  if (this._canceller.isUsed) {
591
627
  return;
592
628
  }
593
629
  var formattedErr = err instanceof Error ?
594
630
  err :
595
- new OtherError("NONE", "Unknown encryption error");
631
+ new OtherError("NONE", "Unknown decryption error");
596
632
  this.error = formattedErr;
597
633
  this._initDataQueue.length = 0;
598
634
  this._stateData = { state: ContentDecryptorState.Error,
@@ -615,6 +651,10 @@ var ContentDecryptor = /** @class */ (function (_super) {
615
651
  return this._stateData.state === ContentDecryptorState.Disposed ||
616
652
  this._stateData.state === ContentDecryptorState.Error;
617
653
  };
654
+ /**
655
+ * Start processing the next initialization data of the `_initDataQueue` if it
656
+ * isn't lock.
657
+ */
618
658
  ContentDecryptor.prototype._processCurrentInitDataQueue = function () {
619
659
  while (this._stateData.isInitDataQueueLocked === false) {
620
660
  var initData = this._initDataQueue.shift();
@@ -624,11 +664,23 @@ var ContentDecryptor = /** @class */ (function (_super) {
624
664
  this.onInitializationData(initData);
625
665
  }
626
666
  };
667
+ /**
668
+ * Lock new initialization data (from the `_initDataQueue`) from being
669
+ * processed until `_unlockInitDataQueue` is called.
670
+ *
671
+ * You may want to call this method when performing operations which may have
672
+ * an impact on the handling of other initialization data.
673
+ */
627
674
  ContentDecryptor.prototype._lockInitDataQueue = function () {
628
675
  if (this._stateData.isInitDataQueueLocked === false) {
629
676
  this._stateData.isInitDataQueueLocked = true;
630
677
  }
631
678
  };
679
+ /**
680
+ * Unlock `_initDataQueue` and start processing the first element.
681
+ *
682
+ * Should have no effect if the `_initDataQueue` was not locked.
683
+ */
632
684
  ContentDecryptor.prototype._unlockInitDataQueue = function () {
633
685
  if (this._stateData.isMediaKeysAttached !== true) {
634
686
  log.error("DRM: Trying to unlock in the wrong state");
@@ -651,7 +703,25 @@ function canCreatePersistentSession(mediaKeySystemAccess) {
651
703
  return sessionTypes !== undefined &&
652
704
  arrayIncludes(sessionTypes, "persistent-license");
653
705
  }
654
- function updateDecipherability(manifest, whitelistedKeyIds, blacklistedKeyIDs) {
706
+ /**
707
+ * Change the decipherability of Representations which have their key id in one
708
+ * of the given Arrays:
709
+ *
710
+ * - Those who have a key id listed in `whitelistedKeyIds` will have their
711
+ * decipherability updated to `true`
712
+ *
713
+ * - Those who have a key id listed in `blacklistedKeyIds` will have their
714
+ * decipherability updated to `false`
715
+ *
716
+ * - Those who have a key id listed in `delistedKeyIds` will have their
717
+ * decipherability updated to `undefined`.
718
+ *
719
+ * @param {Object} manifest
720
+ * @param {Array.<Uint8Array>} whitelistedKeyIds
721
+ * @param {Array.<Uint8Array>} blacklistedKeyIds
722
+ * @param {Array.<Uint8Array>} delistedKeyIds
723
+ */
724
+ function updateDecipherability(manifest, whitelistedKeyIds, blacklistedKeyIds, delistedKeyIds) {
655
725
  manifest.updateRepresentationsDeciperability(function (representation) {
656
726
  if (representation.contentProtections === undefined) {
657
727
  return representation.decipherable;
@@ -660,8 +730,8 @@ function updateDecipherability(manifest, whitelistedKeyIds, blacklistedKeyIDs) {
660
730
  if (contentKIDs !== undefined) {
661
731
  for (var i = 0; i < contentKIDs.length; i++) {
662
732
  var elt = contentKIDs[i];
663
- for (var j = 0; j < blacklistedKeyIDs.length; j++) {
664
- if (areKeyIdsEqual(blacklistedKeyIDs[j], elt.keyId)) {
733
+ for (var j = 0; j < blacklistedKeyIds.length; j++) {
734
+ if (areKeyIdsEqual(blacklistedKeyIds[j], elt.keyId)) {
665
735
  return false;
666
736
  }
667
737
  }
@@ -670,11 +740,22 @@ function updateDecipherability(manifest, whitelistedKeyIds, blacklistedKeyIDs) {
670
740
  return true;
671
741
  }
672
742
  }
743
+ for (var j = 0; j < delistedKeyIds.length; j++) {
744
+ if (areKeyIdsEqual(delistedKeyIds[j], elt.keyId)) {
745
+ return undefined;
746
+ }
747
+ }
673
748
  }
674
749
  }
675
750
  return representation.decipherable;
676
751
  });
677
752
  }
753
+ /**
754
+ * Update decipherability to `false` to any Representation which is linked to
755
+ * the given initialization data.
756
+ * @param {Object} manifest
757
+ * @param {Object} initData
758
+ */
678
759
  function blackListProtectionData(manifest, initData) {
679
760
  manifest.updateRepresentationsDeciperability(function (representation) {
680
761
  var _a, _b;
@@ -874,6 +955,12 @@ function getKeyIdsLinkedToSession(initializationData, keySessionRecord, singleLi
874
955
  /** associatedKeyIds starts with the whitelisted one. */
875
956
  blacklisted: associatedKeyIds.slice(usableKeyIds.length) };
876
957
  }
958
+ /**
959
+ * Push all kei ids in the given `set` and add it to the `arr` Array only if it
960
+ * isn't already present in it.
961
+ * @param {Set.<Uint8Array>} set
962
+ * @param {Array.<Uint8Array>} arr
963
+ */
877
964
  function mergeKeyIdSetIntoArray(set, arr) {
878
965
  var setArr = Array.from(set.values());
879
966
  var _loop_4 = function (kid) {
@@ -887,6 +974,11 @@ function mergeKeyIdSetIntoArray(set, arr) {
887
974
  _loop_4(kid);
888
975
  }
889
976
  }
977
+ /**
978
+ * Add to the given `set` all key ids found in the given `Period`.
979
+ * @param {Set.<Uint8Array>} set
980
+ * @param {Object} period
981
+ */
890
982
  function addKeyIdsFromPeriod(set, period) {
891
983
  for (var _i = 0, _a = period.getAdaptations(); _i < _a.length; _i++) {
892
984
  var adaptation = _a[_i];
@@ -38,17 +38,8 @@ export declare class BlacklistedSessionError extends Error {
38
38
  */
39
39
  export default function SessionEventsListener(session: MediaKeySession | ICustomMediaKeySession, keySystemOptions: IKeySystemOption, keySystem: string): Observable<IEMEWarningEvent | IKeysUpdateEvent>;
40
40
  /**
41
- * Some key ids have updated their status.
42
- *
43
- * We put them in two different list:
44
- *
45
- * - `blacklistedKeyIDs`: Those key ids won't be used for decryption and the
46
- * corresponding media it decrypts should not be pushed to the buffer
47
- * Note that a blacklisted key id can become whitelisted in the future.
48
- *
49
- * - `whitelistedKeyIds`: Those key ids were found and their corresponding
50
- * keys are now being considered for decryption.
51
- * Note that a whitelisted key id can become blacklisted in the future.
41
+ * Some key ids related to the current MediaKeySession have updated their
42
+ * statuses.
52
43
  *
53
44
  * Note that each `IKeysUpdateEvent` is independent of any other.
54
45
  *
@@ -56,7 +47,7 @@ export default function SessionEventsListener(session: MediaKeySession | ICustom
56
47
  * one, as it can for example be linked to a whole other decryption session.
57
48
  *
58
49
  * However, if a key id is encountered in both an older and a newer
59
- * `IKeysUpdateEvent`, only the older status should be considered.
50
+ * `IKeysUpdateEvent`, only the newer, updated, status should be considered.
60
51
  */
61
52
  export interface IKeysUpdateEvent {
62
53
  type: "keys-update";
@@ -65,13 +56,19 @@ export interface IKeysUpdateEvent {
65
56
  /** Information on key ids linked to a MediaKeySession. */
66
57
  export interface IKeyUpdateValue {
67
58
  /**
68
- * The list of key ids that are blacklisted.
69
- * As such, their corresponding keys won't be used by that session, despite
70
- * the fact that they were part of the pushed license.
59
+ * The list of key ids linked to the corresponding MediaKeySession that are
60
+ * now "blacklisted", i.e. the decryption keys they are linked to are blocked
61
+ * from ever being used anymore.
62
+ *
63
+ * Blacklisted key ids correspond to keys linked to a MediaKeySession that
64
+ * cannot and should not be used, due to various reasons, which mainly involve
65
+ * unmet output restrictions and CDM internal errors linked to that key.
66
+ *
67
+ * Content linked to key ids in `blacklistedKeyIds` should be refrained from
68
+ * being used.
71
69
  *
72
- * Reasons for blacklisting a keys depend on options, but mainly involve unmet
73
- * output restrictions and CDM internal errors linked to that key id.
70
+ * Note that a key id may only be blacklisted temporarily.
74
71
  */
75
- blacklistedKeyIDs: Uint8Array[];
72
+ blacklistedKeyIds: Uint8Array[];
76
73
  whitelistedKeyIds: Uint8Array[];
77
74
  }
@@ -148,12 +148,13 @@ function getKeyStatusesEvents(session, options, keySystem) {
148
148
  if (session.keyStatuses.size === 0) {
149
149
  return EMPTY;
150
150
  }
151
- var _a = checkKeyStatuses(session, options, keySystem), warnings = _a.warnings, blacklistedKeyIDs = _a.blacklistedKeyIDs, whitelistedKeyIds = _a.whitelistedKeyIds;
152
- var warnings$ = warnings.length > 0 ? observableOf.apply(void 0, warnings) :
153
- EMPTY;
151
+ var _a = checkKeyStatuses(session, options, keySystem), warning = _a.warning, blacklistedKeyIds = _a.blacklistedKeyIds, whitelistedKeyIds = _a.whitelistedKeyIds;
154
152
  var keysUpdate$ = observableOf({ type: "keys-update",
155
- value: { whitelistedKeyIds: whitelistedKeyIds, blacklistedKeyIDs: blacklistedKeyIDs } });
156
- return observableConcat(warnings$, keysUpdate$);
153
+ value: { whitelistedKeyIds: whitelistedKeyIds, blacklistedKeyIds: blacklistedKeyIds } });
154
+ if (warning !== undefined) {
155
+ return observableConcat(observableOf({ type: "warning", value: warning }), keysUpdate$);
156
+ }
157
+ return keysUpdate$;
157
158
  });
158
159
  }
159
160
  /**
@@ -196,8 +197,9 @@ function updateSessionWithMessage(session, message) {
196
197
  ignoreElements());
197
198
  }
198
199
  /**
199
- * @param {MediaKeySession}
200
- * @param {Object} keySystem
200
+ * @param {MediaKeySession} session
201
+ * @param {Object} keySystemOptions
202
+ * @param {string} keySystem
201
203
  * @param {Event} keyStatusesEvent
202
204
  * @returns {Observable}
203
205
  */
@@ -14,29 +14,26 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { ICustomMediaKeySession } from "../../../compat";
17
- import { IEMEWarningEvent } from "../types";
18
- export interface IKeyStatusesCheckingOptions {
17
+ import { EncryptedMediaError } from "../../../errors";
18
+ import { IKeySystemOption, IPlayerError } from "../../../public_types";
19
+ /**
20
+ * Error thrown when the MediaKeySession has to be closed due to a trigger
21
+ * specified by user configuration.
22
+ * Such MediaKeySession should be closed immediately and may be re-created if
23
+ * needed again.
24
+ * @class DecommissionedSessionError
25
+ * @extends Error
26
+ */
27
+ export declare class DecommissionedSessionError extends Error {
28
+ reason: IPlayerError;
19
29
  /**
20
- * If explicitely set to `false`, we won't throw on error when a used license
21
- * is expired.
30
+ * Creates a new `DecommissionedSessionError`.
31
+ * @param {Error} reason - Error that led to the decision to close the
32
+ * current MediaKeySession. Should be used for reporting purposes.
22
33
  */
23
- throwOnLicenseExpiration?: boolean;
24
- /** Avoid throwing when invalid key statuses are encountered. */
25
- fallbackOn?: {
26
- /**
27
- * If set to `true`, we won't throw when an "internal-error" key status is
28
- * encountered but just add a warning and the corresponding key id to the list
29
- * of blacklisted key ids.
30
- */
31
- keyInternalError?: boolean;
32
- /**
33
- * If set to `true`, we won't throw when an "output-restricted" key status is
34
- * encountered but just add a warning and the corresponding key id to the list
35
- * of blacklisted key ids.
36
- */
37
- keyOutputRestricted?: boolean;
38
- };
34
+ constructor(reason: IPlayerError);
39
35
  }
36
+ export declare type IKeyStatusesCheckingOptions = Pick<IKeySystemOption, "throwOnLicenseExpiration" | "fallbackOn" | "onKeyExpiration">;
40
37
  /**
41
38
  * Look at the current key statuses in the sessions and construct the
42
39
  * appropriate warnings, whitelisted and blacklisted key ids.
@@ -49,7 +46,7 @@ export interface IKeyStatusesCheckingOptions {
49
46
  * @returns {Object} - Warnings to send, whitelisted and blacklisted key ids.
50
47
  */
51
48
  export default function checkKeyStatuses(session: MediaKeySession | ICustomMediaKeySession, options: IKeyStatusesCheckingOptions, keySystem: string): {
52
- warnings: IEMEWarningEvent[];
53
- blacklistedKeyIDs: Uint8Array[];
49
+ warning: EncryptedMediaError | undefined;
50
+ blacklistedKeyIds: Uint8Array[];
54
51
  whitelistedKeyIds: Uint8Array[];
55
52
  };
@@ -13,10 +13,60 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
+ var __extends = (this && this.__extends) || (function () {
17
+ var extendStatics = function (d, b) {
18
+ extendStatics = Object.setPrototypeOf ||
19
+ ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
20
+ function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
21
+ return extendStatics(d, b);
22
+ };
23
+ return function (d, b) {
24
+ if (typeof b !== "function" && b !== null)
25
+ throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
26
+ extendStatics(d, b);
27
+ function __() { this.constructor = d; }
28
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
29
+ };
30
+ })();
31
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
32
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
33
+ if (ar || !(i in from)) {
34
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
35
+ ar[i] = from[i];
36
+ }
37
+ }
38
+ return to.concat(ar || Array.prototype.slice.call(from));
39
+ };
16
40
  /* eslint-disable-next-line max-len */
17
41
  import getUUIDKidFromKeyStatusKID from "../../../compat/eme/get_uuid_kid_from_keystatus_kid";
18
42
  import { EncryptedMediaError } from "../../../errors";
43
+ import assertUnreachable from "../../../utils/assert_unreachable";
19
44
  import { bytesToHex } from "../../../utils/string_parsing";
45
+ /**
46
+ * Error thrown when the MediaKeySession has to be closed due to a trigger
47
+ * specified by user configuration.
48
+ * Such MediaKeySession should be closed immediately and may be re-created if
49
+ * needed again.
50
+ * @class DecommissionedSessionError
51
+ * @extends Error
52
+ */
53
+ var DecommissionedSessionError = /** @class */ (function (_super) {
54
+ __extends(DecommissionedSessionError, _super);
55
+ /**
56
+ * Creates a new `DecommissionedSessionError`.
57
+ * @param {Error} reason - Error that led to the decision to close the
58
+ * current MediaKeySession. Should be used for reporting purposes.
59
+ */
60
+ function DecommissionedSessionError(reason) {
61
+ var _this = _super.call(this) || this;
62
+ // @see https://stackoverflow.com/questions/41102060/typescript-extending-error-class
63
+ Object.setPrototypeOf(_this, DecommissionedSessionError.prototype);
64
+ _this.reason = reason;
65
+ return _this;
66
+ }
67
+ return DecommissionedSessionError;
68
+ }(Error));
69
+ export { DecommissionedSessionError };
20
70
  var KEY_STATUSES = { EXPIRED: "expired",
21
71
  INTERNAL_ERROR: "internal-error",
22
72
  OUTPUT_RESTRICTED: "output-restricted" };
@@ -32,10 +82,10 @@ var KEY_STATUSES = { EXPIRED: "expired",
32
82
  * @returns {Object} - Warnings to send, whitelisted and blacklisted key ids.
33
83
  */
34
84
  export default function checkKeyStatuses(session, options, keySystem) {
35
- var warnings = [];
36
- var blacklistedKeyIDs = [];
85
+ var _a = options.fallbackOn, fallbackOn = _a === void 0 ? {} : _a, throwOnLicenseExpiration = options.throwOnLicenseExpiration, onKeyExpiration = options.onKeyExpiration;
86
+ var blacklistedKeyIds = [];
37
87
  var whitelistedKeyIds = [];
38
- var _a = options.fallbackOn, fallbackOn = _a === void 0 ? {} : _a, throwOnLicenseExpiration = options.throwOnLicenseExpiration;
88
+ var badKeyStatuses = [];
39
89
  session.keyStatuses.forEach(function (_arg1, _arg2) {
40
90
  // Hack present because the order of the arguments has changed in spec
41
91
  // and is not the same between some versions of Edge and Chrome.
@@ -44,32 +94,49 @@ export default function checkKeyStatuses(session, options, keySystem) {
44
94
  [_arg2, _arg1]);
45
95
  })(), keyStatus = _a[0], keyStatusKeyId = _a[1];
46
96
  var keyId = getUUIDKidFromKeyStatusKID(keySystem, new Uint8Array(keyStatusKeyId));
97
+ var keyStatusObj = { keyId: keyId.buffer, keyStatus: keyStatus };
47
98
  switch (keyStatus) {
48
99
  case KEY_STATUSES.EXPIRED: {
49
- var error = new EncryptedMediaError("KEY_STATUS_CHANGE_ERROR", "A decryption key expired (".concat(bytesToHex(keyId), ")"));
50
- if (throwOnLicenseExpiration !== false) {
100
+ var error = new EncryptedMediaError("KEY_STATUS_CHANGE_ERROR", "A decryption key expired (".concat(bytesToHex(keyId), ")"), { keyStatuses: __spreadArray([keyStatusObj], badKeyStatuses, true) });
101
+ if (onKeyExpiration === "error" ||
102
+ (onKeyExpiration === undefined && throwOnLicenseExpiration === false)) {
51
103
  throw error;
52
104
  }
53
- warnings.push({ type: "warning", value: error });
54
- whitelistedKeyIds.push(keyId);
105
+ switch (onKeyExpiration) {
106
+ case "close-session":
107
+ throw new DecommissionedSessionError(error);
108
+ case "fallback":
109
+ blacklistedKeyIds.push(keyId);
110
+ break;
111
+ default:
112
+ // I weirdly stopped relying on switch-cases here due to some TypeScript
113
+ // issue, not checking properly `case undefined` (bug?)
114
+ if (onKeyExpiration === "continue" || onKeyExpiration === undefined) {
115
+ whitelistedKeyIds.push(keyId);
116
+ }
117
+ else {
118
+ // Compile-time check throwing when not all possible cases are handled
119
+ assertUnreachable(onKeyExpiration);
120
+ }
121
+ break;
122
+ }
123
+ badKeyStatuses.push(keyStatusObj);
55
124
  break;
56
125
  }
57
126
  case KEY_STATUSES.INTERNAL_ERROR: {
58
- var error = new EncryptedMediaError("KEY_STATUS_CHANGE_ERROR", "A \"".concat(keyStatus, "\" status has been encountered (").concat(bytesToHex(keyId), ")"));
59
127
  if (fallbackOn.keyInternalError !== true) {
60
- throw error;
128
+ throw new EncryptedMediaError("KEY_STATUS_CHANGE_ERROR", "A \"".concat(keyStatus, "\" status has been encountered (").concat(bytesToHex(keyId), ")"), { keyStatuses: __spreadArray([keyStatusObj], badKeyStatuses, true) });
61
129
  }
62
- warnings.push({ type: "warning", value: error });
63
- blacklistedKeyIDs.push(keyId);
130
+ badKeyStatuses.push(keyStatusObj);
131
+ blacklistedKeyIds.push(keyId);
64
132
  break;
65
133
  }
66
134
  case KEY_STATUSES.OUTPUT_RESTRICTED: {
67
- var error = new EncryptedMediaError("KEY_STATUS_CHANGE_ERROR", "A \"".concat(keyStatus, "\" status has been encountered (").concat(bytesToHex(keyId), ")"));
68
135
  if (fallbackOn.keyOutputRestricted !== true) {
69
- throw error;
136
+ throw new EncryptedMediaError("KEY_STATUS_CHANGE_ERROR", "A \"".concat(keyStatus, "\" status has been encountered (").concat(bytesToHex(keyId), ")"), { keyStatuses: __spreadArray([keyStatusObj], badKeyStatuses, true) });
70
137
  }
71
- warnings.push({ type: "warning", value: error });
72
- blacklistedKeyIDs.push(keyId);
138
+ badKeyStatuses.push(keyStatusObj);
139
+ blacklistedKeyIds.push(keyId);
73
140
  break;
74
141
  }
75
142
  default:
@@ -77,5 +144,9 @@ export default function checkKeyStatuses(session, options, keySystem) {
77
144
  break;
78
145
  }
79
146
  });
80
- return { warnings: warnings, blacklistedKeyIDs: blacklistedKeyIDs, whitelistedKeyIds: whitelistedKeyIds };
147
+ var warning;
148
+ if (badKeyStatuses.length > 0) {
149
+ warning = new EncryptedMediaError("KEY_STATUS_CHANGE_ERROR", "One or several problematic key statuses have been encountered", { keyStatuses: badKeyStatuses });
150
+ }
151
+ return { warning: warning, blacklistedKeyIds: blacklistedKeyIds, whitelistedKeyIds: whitelistedKeyIds };
81
152
  }
@@ -72,8 +72,7 @@ export default class PersistentSessionsStore {
72
72
  add(initData: IProcessedProtectionData, keyIds: Uint8Array[] | undefined, session: MediaKeySession | ICustomMediaKeySession): void;
73
73
  /**
74
74
  * Delete stored MediaKeySession information based on its session id.
75
- * @param {Uint8Array} initData
76
- * @param {string|undefined} initDataType
75
+ * @param {string} sessionId
77
76
  */
78
77
  delete(sessionId: string): void;
79
78
  deleteOldSessions(sessionsToDelete: number): void;
@@ -148,8 +148,7 @@ var PersistentSessionsStore = /** @class */ (function () {
148
148
  };
149
149
  /**
150
150
  * Delete stored MediaKeySession information based on its session id.
151
- * @param {Uint8Array} initData
152
- * @param {string|undefined} initDataType
151
+ * @param {string} sessionId
153
152
  */
154
153
  PersistentSessionsStore.prototype.delete = function (sessionId) {
155
154
  var index = -1;
@@ -14,5 +14,5 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import ManifestFetcher, { IManifestFetcherParsedResult, IManifestFetcherParserOptions, IManifestFetcherWarningEvent } from "./manifest";
17
- import SegmentFetcherCreator, { IPrioritizedSegmentFetcher, IPrioritizedSegmentFetcherEvent, ISegmentFetcherChunkCompleteEvent, ISegmentFetcherChunkEvent, ISegmentFetcherCreatorBackoffOptions, ISegmentFetcherEvent, ISegmentFetcherRetry } from "./segment";
18
- export { ManifestFetcher, SegmentFetcherCreator, IManifestFetcherParserOptions, IManifestFetcherParsedResult, IManifestFetcherWarningEvent, IPrioritizedSegmentFetcher, IPrioritizedSegmentFetcherEvent, ISegmentFetcherEvent, ISegmentFetcherCreatorBackoffOptions, ISegmentFetcherChunkEvent, ISegmentFetcherChunkCompleteEvent, ISegmentFetcherRetry, };
17
+ import SegmentFetcherCreator, { IPrioritizedSegmentFetcher, ISegmentFetcherCreatorBackoffOptions } from "./segment";
18
+ export { ManifestFetcher, SegmentFetcherCreator, IManifestFetcherParserOptions, IManifestFetcherParsedResult, IManifestFetcherWarningEvent, IPrioritizedSegmentFetcher, ISegmentFetcherCreatorBackoffOptions, };
@@ -13,8 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { IPrioritizedSegmentFetcher, IPrioritizedSegmentFetcherEvent } from "./prioritized_segment_fetcher";
17
- import { ISegmentFetcherChunkCompleteEvent, ISegmentFetcherChunkEvent, ISegmentFetcherEvent, ISegmentFetcherRetry } from "./segment_fetcher";
16
+ import { IPrioritizedSegmentFetcher } from "./prioritized_segment_fetcher";
18
17
  import SegmentFetcherCreator, { ISegmentFetcherCreatorBackoffOptions } from "./segment_fetcher_creator";
19
18
  export default SegmentFetcherCreator;
20
- export { IPrioritizedSegmentFetcher, IPrioritizedSegmentFetcherEvent, ISegmentFetcherChunkCompleteEvent, ISegmentFetcherChunkEvent, ISegmentFetcherEvent, ISegmentFetcherRetry, ISegmentFetcherCreatorBackoffOptions, };
19
+ export { IPrioritizedSegmentFetcher, ISegmentFetcherCreatorBackoffOptions, };
@@ -13,26 +13,26 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { Observable } from "rxjs";
17
- import ObservablePrioritizer, { IEndedTaskEvent, IInterruptedTaskEvent } from "./prioritizer";
18
- import { ISegmentFetcher, ISegmentFetcherChunkCompleteEvent, ISegmentFetcherChunkEvent, ISegmentFetcherRetry, ISegmentLoaderContent } from "./segment_fetcher";
16
+ import { CancellationSignal } from "../../../utils/task_canceller";
17
+ import { ISegmentFetcher, ISegmentFetcherCallbacks, ISegmentLoaderContent } from "./segment_fetcher";
18
+ import TaskPrioritizer, { ITaskPrioritizerCallbacks } from "./task_prioritizer";
19
19
  /**
20
20
  * This function basically put in relation:
21
21
  * - an `ISegmentFetcher`, which will be used to perform the segment requests
22
- * - a prioritizer, which will handle the priority of a segment request
22
+ * - a `TaskPrioritizer`, which will handle the priority of a segment request
23
23
  *
24
24
  * and returns functions to fetch segments with a given priority.
25
25
  * @param {Object} prioritizer
26
26
  * @param {Object} fetcher
27
27
  * @returns {Object}
28
28
  */
29
- export default function applyPrioritizerToSegmentFetcher<TSegmentDataType>(prioritizer: ObservablePrioritizer<IPrioritizedSegmentFetcherEvent<TSegmentDataType>>, fetcher: ISegmentFetcher<TSegmentDataType>): IPrioritizedSegmentFetcher<TSegmentDataType>;
29
+ export default function applyPrioritizerToSegmentFetcher<TSegmentDataType>(prioritizer: TaskPrioritizer<void>, fetcher: ISegmentFetcher<TSegmentDataType>): IPrioritizedSegmentFetcher<TSegmentDataType>;
30
30
  /** Oject returned by `applyPrioritizerToSegmentFetcher`. */
31
31
  export interface IPrioritizedSegmentFetcher<TSegmentDataType> {
32
32
  /** Create a new request for a segment with a given priority. */
33
- createRequest: (content: ISegmentLoaderContent, priority?: number) => Observable<IPrioritizedSegmentFetcherEvent<TSegmentDataType>>;
33
+ createRequest: (content: ISegmentLoaderContent, priority: number, callbacks: IPrioritizedSegmentFetcherCallbacks<TSegmentDataType>, cancellationSignal: CancellationSignal) => Promise<void>;
34
34
  /** Update priority of a request created through `createRequest`. */
35
- updatePriority: (observable: Observable<IPrioritizedSegmentFetcherEvent<TSegmentDataType>>, priority: number) => void;
35
+ updatePriority: (task: Promise<void>, priority: number) => void;
36
36
  }
37
- /** Event sent by a `IPrioritizedSegmentFetcher`. */
38
- export declare type IPrioritizedSegmentFetcherEvent<TSegmentDataType> = ISegmentFetcherChunkEvent<TSegmentDataType> | ISegmentFetcherChunkCompleteEvent | ISegmentFetcherRetry | IInterruptedTaskEvent | IEndedTaskEvent;
37
+ /** Callbacks awaited by `applyPrioritizerToSegmentFetcher`. */
38
+ export declare type IPrioritizedSegmentFetcherCallbacks<TSegmentDataType> = ISegmentFetcherCallbacks<TSegmentDataType> & ITaskPrioritizerCallbacks;