rx-player 3.27.0-dev.2022032100 → 3.27.0

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 (60) hide show
  1. package/CHANGELOG.md +5 -2
  2. package/VERSION +1 -1
  3. package/dist/_esm5.processed/compat/eme/custom_media_keys/old_webkit_media_keys.js +15 -11
  4. package/dist/_esm5.processed/compat/eme/custom_media_keys/webkit_media_keys.js +22 -6
  5. package/dist/_esm5.processed/compat/eme/generate_key_request.d.ts +4 -6
  6. package/dist/_esm5.processed/compat/eme/generate_key_request.js +4 -6
  7. package/dist/_esm5.processed/compat/get_start_date.d.ts +30 -0
  8. package/dist/_esm5.processed/compat/get_start_date.js +44 -0
  9. package/dist/_esm5.processed/compat/index.d.ts +2 -1
  10. package/dist/_esm5.processed/compat/index.js +2 -1
  11. package/dist/_esm5.processed/config.d.ts +1 -5
  12. package/dist/_esm5.processed/core/api/public_api.js +25 -25
  13. package/dist/_esm5.processed/core/decrypt/content_decryptor.js +11 -3
  14. package/dist/_esm5.processed/core/decrypt/create_or_load_session.js +1 -1
  15. package/dist/_esm5.processed/core/decrypt/create_session.d.ts +3 -1
  16. package/dist/_esm5.processed/core/decrypt/create_session.js +15 -5
  17. package/dist/_esm5.processed/core/decrypt/utils/loaded_sessions_store.d.ts +94 -1
  18. package/dist/_esm5.processed/core/decrypt/utils/loaded_sessions_store.js +237 -96
  19. package/dist/_esm5.processed/core/segment_buffers/garbage_collector.js +4 -1
  20. package/dist/_esm5.processed/core/stream/orchestrator/stream_orchestrator.js +2 -1
  21. package/dist/_esm5.processed/core/stream/period/period_stream.js +9 -3
  22. package/dist/_esm5.processed/core/stream/representation/append_segment_to_buffer.js +4 -3
  23. package/dist/_esm5.processed/core/stream/representation/force_garbage_collection.js +3 -2
  24. package/dist/_esm5.processed/core/stream/representation/get_buffer_status.d.ts +2 -2
  25. package/dist/_esm5.processed/core/stream/representation/get_buffer_status.js +9 -3
  26. package/dist/_esm5.processed/core/stream/representation/get_needed_segments.d.ts +11 -1
  27. package/dist/_esm5.processed/core/stream/representation/get_needed_segments.js +27 -45
  28. package/dist/_esm5.processed/core/stream/representation/representation_stream.js +6 -4
  29. package/dist/_esm5.processed/default_config.d.ts +2 -35
  30. package/dist/_esm5.processed/default_config.js +2 -35
  31. package/dist/_esm5.processed/transports/dash/add_segment_integrity_checks_to_loader.js +39 -38
  32. package/dist/_esm5.processed/utils/reference.js +0 -2
  33. package/dist/_esm5.processed/utils/task_canceller.d.ts +8 -1
  34. package/dist/_esm5.processed/utils/task_canceller.js +9 -1
  35. package/dist/rx-player.js +927 -587
  36. package/dist/rx-player.min.js +1 -1
  37. package/package.json +1 -1
  38. package/sonar-project.properties +1 -1
  39. package/src/compat/eme/custom_media_keys/old_webkit_media_keys.ts +16 -12
  40. package/src/compat/eme/custom_media_keys/webkit_media_keys.ts +21 -8
  41. package/src/compat/eme/generate_key_request.ts +4 -6
  42. package/src/compat/get_start_date.ts +48 -0
  43. package/src/compat/index.ts +2 -0
  44. package/src/core/api/public_api.ts +23 -27
  45. package/src/core/decrypt/content_decryptor.ts +15 -4
  46. package/src/core/decrypt/create_or_load_session.ts +4 -1
  47. package/src/core/decrypt/create_session.ts +23 -9
  48. package/src/core/decrypt/utils/loaded_sessions_store.ts +254 -102
  49. package/src/core/segment_buffers/garbage_collector.ts +4 -0
  50. package/src/core/stream/orchestrator/stream_orchestrator.ts +2 -1
  51. package/src/core/stream/period/period_stream.ts +9 -4
  52. package/src/core/stream/representation/append_segment_to_buffer.ts +17 -13
  53. package/src/core/stream/representation/force_garbage_collection.ts +4 -1
  54. package/src/core/stream/representation/get_buffer_status.ts +21 -13
  55. package/src/core/stream/representation/get_needed_segments.ts +40 -55
  56. package/src/core/stream/representation/representation_stream.ts +6 -4
  57. package/src/default_config.ts +20 -57
  58. package/src/transports/dash/add_segment_integrity_checks_to_loader.ts +41 -44
  59. package/src/utils/reference.ts +0 -2
  60. package/src/utils/task_canceller.ts +16 -1
package/dist/rx-player.js CHANGED
@@ -624,18 +624,25 @@ var OldWebkitMediaKeySession = /*#__PURE__*/function (_EventEmitter) {
624
624
  _this.sessionId = "";
625
625
  _this._closeSession = noop/* default */.Z; // Just here to make TypeScript happy
626
626
 
627
- _this.closed = new Promise(function (resolve) {
628
- _this._closeSession = resolve;
629
- });
630
627
  _this.keyStatuses = new Map();
631
628
  _this.expiration = NaN;
632
629
 
633
- _this._onSessionRelatedEvent = function (evt) {
630
+ var onSessionRelatedEvent = function onSessionRelatedEvent(evt) {
634
631
  _this.trigger(evt.type, evt);
635
632
  };
636
633
 
634
+ _this.closed = new Promise(function (resolve) {
635
+ _this._closeSession = function () {
636
+ ["keymessage", "message", "keyadded", "ready", "keyerror", "error"].forEach(function (evt) {
637
+ mediaElement.removeEventListener(evt, onSessionRelatedEvent);
638
+ mediaElement.removeEventListener("webkit" + evt, onSessionRelatedEvent);
639
+ });
640
+ resolve();
641
+ };
642
+ });
637
643
  ["keymessage", "message", "keyadded", "ready", "keyerror", "error"].forEach(function (evt) {
638
- return mediaElement.addEventListener(evt, _this._onSessionRelatedEvent);
644
+ mediaElement.addEventListener(evt, onSessionRelatedEvent);
645
+ mediaElement.addEventListener("webkit" + evt, onSessionRelatedEvent);
639
646
  });
640
647
  return _this;
641
648
  }
@@ -692,8 +699,6 @@ var OldWebkitMediaKeySession = /*#__PURE__*/function (_EventEmitter) {
692
699
  var _this4 = this;
693
700
 
694
701
  return new Promise(function (resolve) {
695
- _this4._unbindSession();
696
-
697
702
  _this4._closeSession();
698
703
 
699
704
  resolve();
@@ -715,14 +720,6 @@ var OldWebkitMediaKeySession = /*#__PURE__*/function (_EventEmitter) {
715
720
  return Promise.resolve();
716
721
  };
717
722
 
718
- _proto._unbindSession = function _unbindSession() {
719
- var _this5 = this;
720
-
721
- ["keymessage", "message", "keyadded", "ready", "keyerror", "error"].forEach(function (evt) {
722
- return _this5._vid.removeEventListener(evt, _this5._onSessionRelatedEvent);
723
- });
724
- };
725
-
726
723
  return OldWebkitMediaKeySession;
727
724
  }(event_emitter/* default */.Z);
728
725
 
@@ -941,11 +938,6 @@ var WebkitMediaKeySession = /*#__PURE__*/function (_EventEmitter) {
941
938
  });
942
939
  _this.keyStatuses = new Map();
943
940
  _this.expiration = NaN;
944
-
945
- _this._onEvent = function (evt) {
946
- _this.trigger(evt.type, evt);
947
- };
948
-
949
941
  return _this;
950
942
  }
951
943
 
@@ -961,9 +953,20 @@ var WebkitMediaKeySession = /*#__PURE__*/function (_EventEmitter) {
961
953
  }
962
954
 
963
955
  try {
956
+ var uInt8Arraylicense;
957
+
958
+ if (license instanceof ArrayBuffer) {
959
+ uInt8Arraylicense = new Uint8Array(license);
960
+ } else if (license instanceof Uint8Array) {
961
+ uInt8Arraylicense = license;
962
+ } else {
963
+ uInt8Arraylicense = new Uint8Array(license.buffer);
964
+ }
964
965
  /* eslint-disable @typescript-eslint/no-unsafe-member-access */
965
966
  // eslint-disable-next-line @typescript-eslint/no-unsafe-call
966
- resolve(_this2._nativeSession.update(license));
967
+
968
+
969
+ resolve(_this2._nativeSession.update(uInt8Arraylicense));
967
970
  /* eslint-enable @typescript-eslint/no-unsafe-member-access */
968
971
  } catch (err) {
969
972
  reject(err);
@@ -1047,6 +1050,10 @@ var WebkitMediaKeySession = /*#__PURE__*/function (_EventEmitter) {
1047
1050
 
1048
1051
  this._unbindSession(); // If previous session was linked
1049
1052
 
1053
+
1054
+ var onEvent = function onEvent(evt) {
1055
+ _this5.trigger(evt.type, evt);
1056
+ };
1050
1057
  /* eslint-disable @typescript-eslint/no-unsafe-call */
1051
1058
 
1052
1059
  /* eslint-disable @typescript-eslint/no-unsafe-member-access */
@@ -1055,12 +1062,14 @@ var WebkitMediaKeySession = /*#__PURE__*/function (_EventEmitter) {
1055
1062
 
1056
1063
 
1057
1064
  ["keymessage", "message", "keyadded", "ready", "keyerror", "error"].forEach(function (evt) {
1058
- return session.addEventListener(evt, _this5._onEvent);
1065
+ session.addEventListener(evt, onEvent);
1066
+ session.addEventListener("webkit" + evt, onEvent);
1059
1067
  });
1060
1068
 
1061
1069
  this._unbindSession = function () {
1062
1070
  ["keymessage", "message", "keyadded", "ready", "keyerror", "error"].forEach(function (evt) {
1063
- return session.removeEventListener(evt, _this5._onEvent);
1071
+ session.removeEventListener(evt, onEvent);
1072
+ session.removeEventListener("webkit" + evt, onEvent);
1064
1073
  });
1065
1074
  };
1066
1075
  /* eslint-disable @typescript-eslint/no-unsafe-return */
@@ -3216,36 +3225,6 @@ var DEFAULT_CONFIG = {
3216
3225
  */
3217
3226
  EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION: 1000,
3218
3227
 
3219
- /**
3220
- * Attempts to closing a MediaKeySession can fail, most likely because the
3221
- * MediaKeySession was not initialized yet.
3222
- * When we consider that we're in one of these case, we will retry to close it.
3223
- *
3224
- * To avoid going into an infinite loop of retry, this number indicates a
3225
- * maximum number of attemps we're going to make (`0` meaning no retry at all,
3226
- * `1` only one retry and so on).
3227
- */
3228
- EME_SESSION_CLOSING_MAX_RETRY: 5,
3229
-
3230
- /**
3231
- * When closing a MediaKeySession failed due to the reasons explained for the
3232
- * `EME_SESSION_CLOSING_MAX_RETRY` config property, we may (among other
3233
- * triggers) choose to wait a delay raising exponentially at each retry before
3234
- * that new attempt.
3235
- * This value indicates the initial value for this delay, in milliseconds.
3236
- */
3237
- EME_SESSION_CLOSING_INITIAL_DELAY: 100,
3238
-
3239
- /**
3240
- * When closing a MediaKeySession failed due to the reasons explained for the
3241
- * `EME_SESSION_CLOSING_MAX_RETRY` config property, we may (among other
3242
- * triggers) choose to wait a delay raising exponentially at each retry before
3243
- * that new attempt.
3244
- * This value indicates the maximum possible value for this delay, in
3245
- * milliseconds.
3246
- */
3247
- EME_SESSION_CLOSING_MAX_DELAY: 1000,
3248
-
3249
3228
  /**
3250
3229
  * After loading a persistent MediaKeySession, the RxPlayer needs to ensure
3251
3230
  * that its keys still allow to decrypt a content.
@@ -3388,18 +3367,11 @@ var DEFAULT_CONFIG = {
3388
3367
  */
3389
3368
  BUFFERED_HISTORY_MAXIMUM_ENTRIES: 200,
3390
3369
 
3391
- /**
3392
- * Minimum buffer (in seconds) we should have, regardless of memory
3393
- * constraints
3394
- */
3395
- MIN_BUFFER_LENGTH: 5,
3396
-
3397
3370
  /**
3398
3371
  * Minimum buffer in seconds ahead relative to current time
3399
- * we should be able to download
3400
- * Before trying to agressively free up memory
3372
+ * we should be able to download, even in cases of saturated memory.
3401
3373
  */
3402
- MIN_BUFFER_DISTANCE_BEFORE_CLEAN_UP: 10,
3374
+ MIN_BUFFER_AHEAD: 5,
3403
3375
 
3404
3376
  /**
3405
3377
  * Distance in seconds behind the current position
@@ -4722,146 +4694,6 @@ function getInitData(encryptedEvent) {
4722
4694
  values: values
4723
4695
  };
4724
4696
  }
4725
- // EXTERNAL MODULE: ./src/parsers/containers/isobmff/get_box.ts
4726
- var get_box = __webpack_require__(2297);
4727
- ;// CONCATENATED MODULE: ./src/compat/eme/generate_key_request.ts
4728
- /**
4729
- * Copyright 2015 CANAL+ Group
4730
- *
4731
- * Licensed under the Apache License, Version 2.0 (the "License");
4732
- * you may not use this file except in compliance with the License.
4733
- * You may obtain a copy of the License at
4734
- *
4735
- * http://www.apache.org/licenses/LICENSE-2.0
4736
- *
4737
- * Unless required by applicable law or agreed to in writing, software
4738
- * distributed under the License is distributed on an "AS IS" BASIS,
4739
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4740
- * See the License for the specific language governing permissions and
4741
- * limitations under the License.
4742
- */
4743
-
4744
-
4745
-
4746
-
4747
- /**
4748
- * Modify "initialization data" sent to a `generateKeyRequest` EME call to
4749
- * improve the player's browser compatibility:
4750
- *
4751
- * 1. some browsers/CDM have problems when the CENC PSSH box is the first
4752
- * encountered PSSH box in the initialization data (for the moment just
4753
- * Edge was noted with this behavior).
4754
- * We found however that it works on every browser when the CENC pssh
4755
- * box(es) is/are the last box(es) encountered.
4756
- *
4757
- * To that end, we move CENC pssh boxes at the end of the initialization
4758
- * data in this function.
4759
- *
4760
- * 2. Some poorly encoded/packaged contents communicate both a CENC with a
4761
- * pssh version of 0 and one with a version of 1. We found out that this is
4762
- * not always well handled on some devices/browsers (on Edge and some other
4763
- * embedded devices that shall remain nameless for now!).
4764
- *
4765
- * Here this function will filter out CENC pssh with a version different to
4766
- * 1 when one(s) with a version of 1 is/are already present.
4767
- *
4768
- * If the initData is unrecognized or if a CENC PSSH is not found, this function
4769
- * throws.
4770
- * @param {Uint8Array} initData - Initialization data you want to patch
4771
- * @returns {Uint8Array} - Initialization data, patched
4772
- */
4773
-
4774
- function patchInitData(initData) {
4775
- log/* default.info */.Z.info("Compat: Trying to move CENC PSSH from init data at the end of it.");
4776
- var foundCencV1 = false;
4777
- var concatenatedCencs = new Uint8Array();
4778
- var resInitData = new Uint8Array();
4779
- var offset = 0;
4780
-
4781
- while (offset < initData.length) {
4782
- if (initData.length < offset + 8 || (0,byte_parsing/* be4toi */.pX)(initData, offset + 4) !== PSSH_TO_INTEGER) {
4783
- log/* default.warn */.Z.warn("Compat: unrecognized initialization data. Cannot patch it.");
4784
- throw new Error("Compat: unrecognized initialization data. Cannot patch it.");
4785
- }
4786
-
4787
- var len = (0,byte_parsing/* be4toi */.pX)(new Uint8Array(initData), offset);
4788
-
4789
- if (offset + len > initData.length) {
4790
- log/* default.warn */.Z.warn("Compat: unrecognized initialization data. Cannot patch it.");
4791
- throw new Error("Compat: unrecognized initialization data. Cannot patch it.");
4792
- }
4793
-
4794
- var currentPSSH = initData.subarray(offset, offset + len); // yep
4795
-
4796
- if (initData[offset + 12] === 0x10 && initData[offset + 13] === 0x77 && initData[offset + 14] === 0xEF && initData[offset + 15] === 0xEC && initData[offset + 16] === 0xC0 && initData[offset + 17] === 0xB2 && initData[offset + 18] === 0x4D && initData[offset + 19] === 0x02 && initData[offset + 20] === 0xAC && initData[offset + 21] === 0xE3 && initData[offset + 22] === 0x3C && initData[offset + 23] === 0x1E && initData[offset + 24] === 0x52 && initData[offset + 25] === 0xE2 && initData[offset + 26] === 0xFB && initData[offset + 27] === 0x4B) {
4797
- var cencOffsets = (0,get_box/* getNextBoxOffsets */.Xj)(currentPSSH);
4798
- var version = cencOffsets === null ? undefined : currentPSSH[cencOffsets[1]];
4799
- log/* default.info */.Z.info("Compat: CENC PSSH found with version", version);
4800
-
4801
- if (version === undefined) {
4802
- log/* default.warn */.Z.warn("Compat: could not read version of CENC PSSH");
4803
- } else if (foundCencV1 === (version === 1)) {
4804
- // Either `concatenatedCencs` only contains v1 or does not contain any
4805
- concatenatedCencs = (0,byte_parsing/* concat */.zo)(concatenatedCencs, currentPSSH);
4806
- } else if (version === 1) {
4807
- log/* default.warn */.Z.warn("Compat: cenc version 1 encountered, " + "removing every other cenc pssh box.");
4808
- concatenatedCencs = currentPSSH;
4809
- foundCencV1 = true;
4810
- } else {
4811
- log/* default.warn */.Z.warn("Compat: filtering out cenc pssh box with wrong version", version);
4812
- }
4813
- } else {
4814
- resInitData = (0,byte_parsing/* concat */.zo)(resInitData, currentPSSH);
4815
- }
4816
-
4817
- offset += len;
4818
- }
4819
-
4820
- if (offset !== initData.length) {
4821
- log/* default.warn */.Z.warn("Compat: unrecognized initialization data. Cannot patch it.");
4822
- throw new Error("Compat: unrecognized initialization data. Cannot patch it.");
4823
- }
4824
-
4825
- return (0,byte_parsing/* concat */.zo)(resInitData, concatenatedCencs);
4826
- }
4827
- /**
4828
- * Generate a request from session.
4829
- * @param {MediaKeySession} session - MediaKeySession on which the request will
4830
- * be done.
4831
- * @param {Uint8Array} initData - Initialization data given e.g. by the
4832
- * "encrypted" event for the corresponding request.
4833
- * @param {string} initDataType - Initialization data type given e.g. by the
4834
- * "encrypted" event for the corresponding request.
4835
- * @param {string} sessionType - Type of session you want to generate. Consult
4836
- * EME Specification for more information on session types.
4837
- * @returns {Promise} - Emit when done. Errors if fails.
4838
- */
4839
-
4840
- function generateKeyRequest(session, initializationDataType, initializationData) {
4841
- log/* default.debug */.Z.debug("Compat: Calling generateRequest on the MediaKeySession");
4842
- var patchedInit;
4843
-
4844
- try {
4845
- patchedInit = patchInitData(initializationData);
4846
- } catch (_e) {
4847
- patchedInit = initializationData;
4848
- }
4849
-
4850
- var initDataType = initializationDataType !== null && initializationDataType !== void 0 ? initializationDataType : "";
4851
- return session.generateRequest(initDataType, patchedInit)["catch"](function (error) {
4852
- if (initDataType !== "" || !(error instanceof TypeError)) {
4853
- throw error;
4854
- } // On newer EME versions of the specification, the initialization data
4855
- // type given to generateRequest cannot be an empty string (it returns
4856
- // a rejected promise with a TypeError in that case).
4857
- // Retry with a default "cenc" value for initialization data type if
4858
- // we're in that condition.
4859
-
4860
-
4861
- log/* default.warn */.Z.warn("Compat: error while calling `generateRequest` with an empty " + "initialization data type. Retrying with a default \"cenc\" value.", error);
4862
- return session.generateRequest("cenc", patchedInit);
4863
- });
4864
- }
4865
4697
  // EXTERNAL MODULE: ./src/compat/event_listeners.ts + 6 modules
4866
4698
  var event_listeners = __webpack_require__(4804);
4867
4699
  // EXTERNAL MODULE: ./src/config.ts + 2 modules
@@ -4979,92 +4811,6 @@ function _attachMediaKeys() {
4979
4811
  }));
4980
4812
  return _attachMediaKeys.apply(this, arguments);
4981
4813
  }
4982
- ;// CONCATENATED MODULE: ./src/compat/eme/load_session.ts
4983
-
4984
-
4985
-
4986
- /**
4987
- * Copyright 2015 CANAL+ Group
4988
- *
4989
- * Licensed under the Apache License, Version 2.0 (the "License");
4990
- * you may not use this file except in compliance with the License.
4991
- * You may obtain a copy of the License at
4992
- *
4993
- * http://www.apache.org/licenses/LICENSE-2.0
4994
- *
4995
- * Unless required by applicable law or agreed to in writing, software
4996
- * distributed under the License is distributed on an "AS IS" BASIS,
4997
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4998
- * See the License for the specific language governing permissions and
4999
- * limitations under the License.
5000
- */
5001
-
5002
- var EME_WAITING_DELAY_LOADED_SESSION_EMPTY_KEYSTATUSES = 100;
5003
- /**
5004
- * Load a persistent session, based on its `sessionId`, on the given
5005
- * MediaKeySession.
5006
- *
5007
- * Returns an Observable which emits:
5008
- * - true if the persistent MediaKeySession was found and loaded
5009
- * - false if no persistent MediaKeySession was found with that `sessionId`.
5010
- * Then completes.
5011
- *
5012
- * The Observable throws if anything goes wrong in the process.
5013
- * @param {MediaKeySession} session
5014
- * @param {string} sessionId
5015
- * @returns {Observable}
5016
- */
5017
-
5018
- function loadSession(_x, _x2) {
5019
- return _loadSession.apply(this, arguments);
5020
- }
5021
-
5022
- function _loadSession() {
5023
- _loadSession = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee(session, sessionId) {
5024
- var isLoaded;
5025
- return regenerator_default().wrap(function _callee$(_context) {
5026
- while (1) {
5027
- switch (_context.prev = _context.next) {
5028
- case 0:
5029
- log/* default.info */.Z.info("Compat/DRM: Load persisted session", sessionId);
5030
- _context.next = 3;
5031
- return session.load(sessionId);
5032
-
5033
- case 3:
5034
- isLoaded = _context.sent;
5035
-
5036
- if (!(!isLoaded || session.keyStatuses.size > 0)) {
5037
- _context.next = 6;
5038
- break;
5039
- }
5040
-
5041
- return _context.abrupt("return", isLoaded);
5042
-
5043
- case 6:
5044
- return _context.abrupt("return", new Promise(function (resolve) {
5045
- session.addEventListener("keystatuseschange", resolveWithLoadedStatus);
5046
- var timeout = setTimeout(resolveWithLoadedStatus, EME_WAITING_DELAY_LOADED_SESSION_EMPTY_KEYSTATUSES);
5047
-
5048
- function resolveWithLoadedStatus() {
5049
- cleanUp();
5050
- resolve(isLoaded);
5051
- }
5052
-
5053
- function cleanUp() {
5054
- clearTimeout(timeout);
5055
- session.removeEventListener("keystatuseschange", resolveWithLoadedStatus);
5056
- }
5057
- }));
5058
-
5059
- case 7:
5060
- case "end":
5061
- return _context.stop();
5062
- }
5063
- }
5064
- }, _callee);
5065
- }));
5066
- return _loadSession.apply(this, arguments);
5067
- }
5068
4814
  ;// CONCATENATED MODULE: ./src/core/decrypt/utils/is_session_usable.ts
5069
4815
  /**
5070
4816
  * Copyright 2015 CANAL+ Group
@@ -5141,7 +4887,6 @@ function isSessionUsable(loadedSession) {
5141
4887
  */
5142
4888
 
5143
4889
 
5144
-
5145
4890
  /**
5146
4891
  * Create a new Session or load a persistent one on the given MediaKeys,
5147
4892
  * according to wanted settings and what is currently stored.
@@ -5155,10 +4900,11 @@ function isSessionUsable(loadedSession) {
5155
4900
  * @param {Object} stores
5156
4901
  * @param {Object} initData
5157
4902
  * @param {string} wantedSessionType
4903
+ * @param {Object} cancelSignal
5158
4904
  * @returns {Promise}
5159
4905
  */
5160
4906
 
5161
- function createSession(stores, initData, wantedSessionType) {
4907
+ function createSession(stores, initData, wantedSessionType, cancelSignal) {
5162
4908
  var loadedSessionsStore = stores.loadedSessionsStore,
5163
4909
  persistentSessionsStore = stores.persistentSessionsStore;
5164
4910
 
@@ -5169,7 +4915,7 @@ function createSession(stores, initData, wantedSessionType) {
5169
4915
  return createTemporarySession(loadedSessionsStore, initData);
5170
4916
  }
5171
4917
 
5172
- return createAndTryToRetrievePersistentSession(loadedSessionsStore, persistentSessionsStore, initData);
4918
+ return createAndTryToRetrievePersistentSession(loadedSessionsStore, persistentSessionsStore, initData, cancelSignal);
5173
4919
  }
5174
4920
  /**
5175
4921
  * Create a new temporary MediaKeySession linked to the given initData and
@@ -5195,16 +4941,17 @@ function createTemporarySession(loadedSessionsStore, initData) {
5195
4941
  * @param {Object} loadedSessionsStore
5196
4942
  * @param {Object} persistentSessionsStore
5197
4943
  * @param {Object} initData
4944
+ * @param {Object} cancelSignal
5198
4945
  * @returns {Promise}
5199
4946
  */
5200
4947
 
5201
4948
 
5202
- function createAndTryToRetrievePersistentSession(_x, _x2, _x3) {
4949
+ function createAndTryToRetrievePersistentSession(_x, _x2, _x3, _x4) {
5203
4950
  return _createAndTryToRetrievePersistentSession.apply(this, arguments);
5204
4951
  }
5205
4952
 
5206
4953
  function _createAndTryToRetrievePersistentSession() {
5207
- _createAndTryToRetrievePersistentSession = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee2(loadedSessionsStore, persistentSessionsStore, initData) {
4954
+ _createAndTryToRetrievePersistentSession = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee2(loadedSessionsStore, persistentSessionsStore, initData, cancelSignal) {
5208
4955
  var entry, storedEntry, hasLoadedSession, recreatePersistentSession, _recreatePersistentSession;
5209
4956
 
5210
4957
  return regenerator_default().wrap(function _callee2$(_context2) {
@@ -5218,6 +4965,14 @@ function _createAndTryToRetrievePersistentSession() {
5218
4965
  while (1) {
5219
4966
  switch (_context.prev = _context.next) {
5220
4967
  case 0:
4968
+ if (!(cancelSignal.cancellationError !== null)) {
4969
+ _context.next = 2;
4970
+ break;
4971
+ }
4972
+
4973
+ throw cancelSignal.cancellationError;
4974
+
4975
+ case 2:
5221
4976
  log/* default.info */.Z.info("DRM: Removing previous persistent session.");
5222
4977
  persistentEntry = persistentSessionsStore.get(initData);
5223
4978
 
@@ -5225,10 +4980,18 @@ function _createAndTryToRetrievePersistentSession() {
5225
4980
  persistentSessionsStore["delete"](persistentEntry.sessionId);
5226
4981
  }
5227
4982
 
5228
- _context.next = 5;
4983
+ _context.next = 7;
5229
4984
  return loadedSessionsStore.closeSession(entry.mediaKeySession);
5230
4985
 
5231
- case 5:
4986
+ case 7:
4987
+ if (!(cancelSignal.cancellationError !== null)) {
4988
+ _context.next = 9;
4989
+ break;
4990
+ }
4991
+
4992
+ throw cancelSignal.cancellationError;
4993
+
4994
+ case 9:
5232
4995
  newEntry = loadedSessionsStore.createSession(initData, "persistent-license");
5233
4996
  return _context.abrupt("return", {
5234
4997
  type: "created-session"
@@ -5237,7 +5000,7 @@ function _createAndTryToRetrievePersistentSession() {
5237
5000
  value: newEntry
5238
5001
  });
5239
5002
 
5240
- case 7:
5003
+ case 11:
5241
5004
  case "end":
5242
5005
  return _context.stop();
5243
5006
  }
@@ -5251,12 +5014,20 @@ function _createAndTryToRetrievePersistentSession() {
5251
5014
  return _recreatePersistentSession.apply(this, arguments);
5252
5015
  };
5253
5016
 
5017
+ if (!(cancelSignal.cancellationError !== null)) {
5018
+ _context2.next = 4;
5019
+ break;
5020
+ }
5021
+
5022
+ throw cancelSignal.cancellationError;
5023
+
5024
+ case 4:
5254
5025
  log/* default.info */.Z.info("DRM: Creating persistent MediaKeySession");
5255
5026
  entry = loadedSessionsStore.createSession(initData, "persistent-license");
5256
5027
  storedEntry = persistentSessionsStore.getAndReuse(initData);
5257
5028
 
5258
5029
  if (!(storedEntry === null)) {
5259
- _context2.next = 7;
5030
+ _context2.next = 9;
5260
5031
  break;
5261
5032
  }
5262
5033
 
@@ -5267,16 +5038,16 @@ function _createAndTryToRetrievePersistentSession() {
5267
5038
  value: entry
5268
5039
  });
5269
5040
 
5270
- case 7:
5271
- _context2.prev = 7;
5272
- _context2.next = 10;
5273
- return loadSession(entry.mediaKeySession, storedEntry.sessionId);
5041
+ case 9:
5042
+ _context2.prev = 9;
5043
+ _context2.next = 12;
5044
+ return loadedSessionsStore.loadPersistentSession(entry.mediaKeySession, storedEntry.sessionId);
5274
5045
 
5275
- case 10:
5046
+ case 12:
5276
5047
  hasLoadedSession = _context2.sent;
5277
5048
 
5278
5049
  if (hasLoadedSession) {
5279
- _context2.next = 15;
5050
+ _context2.next = 17;
5280
5051
  break;
5281
5052
  }
5282
5053
 
@@ -5289,9 +5060,9 @@ function _createAndTryToRetrievePersistentSession() {
5289
5060
  value: entry
5290
5061
  });
5291
5062
 
5292
- case 15:
5063
+ case 17:
5293
5064
  if (!(hasLoadedSession && isSessionUsable(entry.mediaKeySession))) {
5294
- _context2.next = 19;
5065
+ _context2.next = 21;
5295
5066
  break;
5296
5067
  }
5297
5068
 
@@ -5304,23 +5075,23 @@ function _createAndTryToRetrievePersistentSession() {
5304
5075
  value: entry
5305
5076
  });
5306
5077
 
5307
- case 19:
5078
+ case 21:
5308
5079
  // Unusable persistent session: recreate a new session from scratch.
5309
5080
  log/* default.warn */.Z.warn("DRM: Previous persistent session not usable anymore.");
5310
5081
  return _context2.abrupt("return", recreatePersistentSession());
5311
5082
 
5312
- case 23:
5313
- _context2.prev = 23;
5314
- _context2.t0 = _context2["catch"](7);
5083
+ case 25:
5084
+ _context2.prev = 25;
5085
+ _context2.t0 = _context2["catch"](9);
5315
5086
  log/* default.warn */.Z.warn("DRM: Unable to load persistent session: " + (_context2.t0 instanceof Error ? _context2.t0.toString() : "Unknown Error"));
5316
5087
  return _context2.abrupt("return", recreatePersistentSession());
5317
5088
 
5318
- case 27:
5089
+ case 29:
5319
5090
  case "end":
5320
5091
  return _context2.stop();
5321
5092
  }
5322
5093
  }
5323
- }, _callee2, null, [[7, 23]]);
5094
+ }, _callee2, null, [[9, 25]]);
5324
5095
  }));
5325
5096
  return _createAndTryToRetrievePersistentSession.apply(this, arguments);
5326
5097
  }
@@ -5516,7 +5287,7 @@ function _createOrLoadSession() {
5516
5287
 
5517
5288
  case 20:
5518
5289
  _context.next = 22;
5519
- return createSession(stores, initializationData, wantedSessionType);
5290
+ return createSession(stores, initializationData, wantedSessionType, cancelSignal);
5520
5291
 
5521
5292
  case 22:
5522
5293
  evt = _context.sent;
@@ -5915,6 +5686,230 @@ function getMediaKeySystemAccess(mediaElement, keySystemsConfigs, cancelSignal)
5915
5686
  return _recursivelyTestKeySystems.apply(this, arguments);
5916
5687
  }
5917
5688
  }
5689
+ // EXTERNAL MODULE: ./src/parsers/containers/isobmff/get_box.ts
5690
+ var get_box = __webpack_require__(2297);
5691
+ ;// CONCATENATED MODULE: ./src/compat/eme/generate_key_request.ts
5692
+ /**
5693
+ * Copyright 2015 CANAL+ Group
5694
+ *
5695
+ * Licensed under the Apache License, Version 2.0 (the "License");
5696
+ * you may not use this file except in compliance with the License.
5697
+ * You may obtain a copy of the License at
5698
+ *
5699
+ * http://www.apache.org/licenses/LICENSE-2.0
5700
+ *
5701
+ * Unless required by applicable law or agreed to in writing, software
5702
+ * distributed under the License is distributed on an "AS IS" BASIS,
5703
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5704
+ * See the License for the specific language governing permissions and
5705
+ * limitations under the License.
5706
+ */
5707
+
5708
+
5709
+
5710
+
5711
+ /**
5712
+ * Modify "initialization data" sent to a `generateKeyRequest` EME call to
5713
+ * improve the player's browser compatibility:
5714
+ *
5715
+ * 1. some browsers/CDM have problems when the CENC PSSH box is the first
5716
+ * encountered PSSH box in the initialization data (for the moment just
5717
+ * Edge was noted with this behavior).
5718
+ * We found however that it works on every browser when the CENC pssh
5719
+ * box(es) is/are the last box(es) encountered.
5720
+ *
5721
+ * To that end, we move CENC pssh boxes at the end of the initialization
5722
+ * data in this function.
5723
+ *
5724
+ * 2. Some poorly encoded/packaged contents communicate both a CENC with a
5725
+ * pssh version of 0 and one with a version of 1. We found out that this is
5726
+ * not always well handled on some devices/browsers (on Edge and some other
5727
+ * embedded devices that shall remain nameless for now!).
5728
+ *
5729
+ * Here this function will filter out CENC pssh with a version different to
5730
+ * 1 when one(s) with a version of 1 is/are already present.
5731
+ *
5732
+ * If the initData is unrecognized or if a CENC PSSH is not found, this function
5733
+ * throws.
5734
+ * @param {Uint8Array} initData - Initialization data you want to patch
5735
+ * @returns {Uint8Array} - Initialization data, patched
5736
+ */
5737
+
5738
+ function patchInitData(initData) {
5739
+ log/* default.info */.Z.info("Compat: Trying to move CENC PSSH from init data at the end of it.");
5740
+ var foundCencV1 = false;
5741
+ var concatenatedCencs = new Uint8Array();
5742
+ var resInitData = new Uint8Array();
5743
+ var offset = 0;
5744
+
5745
+ while (offset < initData.length) {
5746
+ if (initData.length < offset + 8 || (0,byte_parsing/* be4toi */.pX)(initData, offset + 4) !== PSSH_TO_INTEGER) {
5747
+ log/* default.warn */.Z.warn("Compat: unrecognized initialization data. Cannot patch it.");
5748
+ throw new Error("Compat: unrecognized initialization data. Cannot patch it.");
5749
+ }
5750
+
5751
+ var len = (0,byte_parsing/* be4toi */.pX)(new Uint8Array(initData), offset);
5752
+
5753
+ if (offset + len > initData.length) {
5754
+ log/* default.warn */.Z.warn("Compat: unrecognized initialization data. Cannot patch it.");
5755
+ throw new Error("Compat: unrecognized initialization data. Cannot patch it.");
5756
+ }
5757
+
5758
+ var currentPSSH = initData.subarray(offset, offset + len); // yep
5759
+
5760
+ if (initData[offset + 12] === 0x10 && initData[offset + 13] === 0x77 && initData[offset + 14] === 0xEF && initData[offset + 15] === 0xEC && initData[offset + 16] === 0xC0 && initData[offset + 17] === 0xB2 && initData[offset + 18] === 0x4D && initData[offset + 19] === 0x02 && initData[offset + 20] === 0xAC && initData[offset + 21] === 0xE3 && initData[offset + 22] === 0x3C && initData[offset + 23] === 0x1E && initData[offset + 24] === 0x52 && initData[offset + 25] === 0xE2 && initData[offset + 26] === 0xFB && initData[offset + 27] === 0x4B) {
5761
+ var cencOffsets = (0,get_box/* getNextBoxOffsets */.Xj)(currentPSSH);
5762
+ var version = cencOffsets === null ? undefined : currentPSSH[cencOffsets[1]];
5763
+ log/* default.info */.Z.info("Compat: CENC PSSH found with version", version);
5764
+
5765
+ if (version === undefined) {
5766
+ log/* default.warn */.Z.warn("Compat: could not read version of CENC PSSH");
5767
+ } else if (foundCencV1 === (version === 1)) {
5768
+ // Either `concatenatedCencs` only contains v1 or does not contain any
5769
+ concatenatedCencs = (0,byte_parsing/* concat */.zo)(concatenatedCencs, currentPSSH);
5770
+ } else if (version === 1) {
5771
+ log/* default.warn */.Z.warn("Compat: cenc version 1 encountered, " + "removing every other cenc pssh box.");
5772
+ concatenatedCencs = currentPSSH;
5773
+ foundCencV1 = true;
5774
+ } else {
5775
+ log/* default.warn */.Z.warn("Compat: filtering out cenc pssh box with wrong version", version);
5776
+ }
5777
+ } else {
5778
+ resInitData = (0,byte_parsing/* concat */.zo)(resInitData, currentPSSH);
5779
+ }
5780
+
5781
+ offset += len;
5782
+ }
5783
+
5784
+ if (offset !== initData.length) {
5785
+ log/* default.warn */.Z.warn("Compat: unrecognized initialization data. Cannot patch it.");
5786
+ throw new Error("Compat: unrecognized initialization data. Cannot patch it.");
5787
+ }
5788
+
5789
+ return (0,byte_parsing/* concat */.zo)(resInitData, concatenatedCencs);
5790
+ }
5791
+ /**
5792
+ * Generate a request from session.
5793
+ * @param {MediaKeySession} session - MediaKeySession on which the request will
5794
+ * be done.
5795
+ * @param {string} initializationDataType - Initialization data type given e.g.
5796
+ * by the "encrypted" event for the corresponding request.
5797
+ * @param {Uint8Array} initializationData - Initialization data given e.g. by
5798
+ * the "encrypted" event for the corresponding request.
5799
+ * @returns {Promise} - Emit when done. Errors if fails.
5800
+ */
5801
+
5802
+ function generateKeyRequest(session, initializationDataType, initializationData) {
5803
+ log/* default.debug */.Z.debug("Compat: Calling generateRequest on the MediaKeySession");
5804
+ var patchedInit;
5805
+
5806
+ try {
5807
+ patchedInit = patchInitData(initializationData);
5808
+ } catch (_e) {
5809
+ patchedInit = initializationData;
5810
+ }
5811
+
5812
+ var initDataType = initializationDataType !== null && initializationDataType !== void 0 ? initializationDataType : "";
5813
+ return session.generateRequest(initDataType, patchedInit)["catch"](function (error) {
5814
+ if (initDataType !== "" || !(error instanceof TypeError)) {
5815
+ throw error;
5816
+ } // On newer EME versions of the specification, the initialization data
5817
+ // type given to generateRequest cannot be an empty string (it returns
5818
+ // a rejected promise with a TypeError in that case).
5819
+ // Retry with a default "cenc" value for initialization data type if
5820
+ // we're in that condition.
5821
+
5822
+
5823
+ log/* default.warn */.Z.warn("Compat: error while calling `generateRequest` with an empty " + "initialization data type. Retrying with a default \"cenc\" value.", error);
5824
+ return session.generateRequest("cenc", patchedInit);
5825
+ });
5826
+ }
5827
+ ;// CONCATENATED MODULE: ./src/compat/eme/load_session.ts
5828
+
5829
+
5830
+
5831
+ /**
5832
+ * Copyright 2015 CANAL+ Group
5833
+ *
5834
+ * Licensed under the Apache License, Version 2.0 (the "License");
5835
+ * you may not use this file except in compliance with the License.
5836
+ * You may obtain a copy of the License at
5837
+ *
5838
+ * http://www.apache.org/licenses/LICENSE-2.0
5839
+ *
5840
+ * Unless required by applicable law or agreed to in writing, software
5841
+ * distributed under the License is distributed on an "AS IS" BASIS,
5842
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
5843
+ * See the License for the specific language governing permissions and
5844
+ * limitations under the License.
5845
+ */
5846
+
5847
+ var EME_WAITING_DELAY_LOADED_SESSION_EMPTY_KEYSTATUSES = 100;
5848
+ /**
5849
+ * Load a persistent session, based on its `sessionId`, on the given
5850
+ * MediaKeySession.
5851
+ *
5852
+ * Returns an Observable which emits:
5853
+ * - true if the persistent MediaKeySession was found and loaded
5854
+ * - false if no persistent MediaKeySession was found with that `sessionId`.
5855
+ * Then completes.
5856
+ *
5857
+ * The Observable throws if anything goes wrong in the process.
5858
+ * @param {MediaKeySession} session
5859
+ * @param {string} sessionId
5860
+ * @returns {Observable}
5861
+ */
5862
+
5863
+ function loadSession(_x, _x2) {
5864
+ return _loadSession.apply(this, arguments);
5865
+ }
5866
+
5867
+ function _loadSession() {
5868
+ _loadSession = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee(session, sessionId) {
5869
+ var isLoaded;
5870
+ return regenerator_default().wrap(function _callee$(_context) {
5871
+ while (1) {
5872
+ switch (_context.prev = _context.next) {
5873
+ case 0:
5874
+ log/* default.info */.Z.info("Compat/DRM: Load persisted session", sessionId);
5875
+ _context.next = 3;
5876
+ return session.load(sessionId);
5877
+
5878
+ case 3:
5879
+ isLoaded = _context.sent;
5880
+
5881
+ if (!(!isLoaded || session.keyStatuses.size > 0)) {
5882
+ _context.next = 6;
5883
+ break;
5884
+ }
5885
+
5886
+ return _context.abrupt("return", isLoaded);
5887
+
5888
+ case 6:
5889
+ return _context.abrupt("return", new Promise(function (resolve) {
5890
+ session.addEventListener("keystatuseschange", resolveWithLoadedStatus);
5891
+ var timeout = setTimeout(resolveWithLoadedStatus, EME_WAITING_DELAY_LOADED_SESSION_EMPTY_KEYSTATUSES);
5892
+
5893
+ function resolveWithLoadedStatus() {
5894
+ cleanUp();
5895
+ resolve(isLoaded);
5896
+ }
5897
+
5898
+ function cleanUp() {
5899
+ clearTimeout(timeout);
5900
+ session.removeEventListener("keystatuseschange", resolveWithLoadedStatus);
5901
+ }
5902
+ }));
5903
+
5904
+ case 7:
5905
+ case "end":
5906
+ return _context.stop();
5907
+ }
5908
+ }
5909
+ }, _callee);
5910
+ }));
5911
+ return _loadSession.apply(this, arguments);
5912
+ }
5918
5913
  // EXTERNAL MODULE: ./src/utils/cancellable_sleep.ts
5919
5914
  var cancellable_sleep = __webpack_require__(7864);
5920
5915
  ;// CONCATENATED MODULE: ./src/compat/eme/close_session.ts
@@ -6411,8 +6406,6 @@ function loaded_sessions_store_arrayLikeToArray(arr, len) { if (len == null || l
6411
6406
 
6412
6407
 
6413
6408
 
6414
-
6415
-
6416
6409
  /**
6417
6410
  * Create and store MediaKeySessions linked to a single MediaKeys
6418
6411
  * instance.
@@ -6434,7 +6427,7 @@ var LoadedSessionsStore = /*#__PURE__*/function () {
6434
6427
  }
6435
6428
  /**
6436
6429
  * Create a new MediaKeySession and store it in this store.
6437
- * @param {Object} initializationData
6430
+ * @param {Object} initData
6438
6431
  * @param {string} sessionType
6439
6432
  * @returns {Object}
6440
6433
  */
@@ -6452,7 +6445,12 @@ var LoadedSessionsStore = /*#__PURE__*/function () {
6452
6445
  var entry = {
6453
6446
  mediaKeySession: mediaKeySession,
6454
6447
  sessionType: sessionType,
6455
- keySessionRecord: keySessionRecord
6448
+ keySessionRecord: keySessionRecord,
6449
+ isGeneratingRequest: false,
6450
+ isLoadingPersistentSession: false,
6451
+ closingStatus: {
6452
+ type: "none"
6453
+ }
6456
6454
  };
6457
6455
 
6458
6456
  if (!(0,is_null_or_undefined/* default */.Z)(mediaKeySession.closed)) {
@@ -6470,11 +6468,7 @@ var LoadedSessionsStore = /*#__PURE__*/function () {
6470
6468
 
6471
6469
  log/* default.debug */.Z.debug("DRM-LSS: Add MediaKeySession", entry.sessionType);
6472
6470
 
6473
- this._storage.push({
6474
- keySessionRecord: keySessionRecord,
6475
- mediaKeySession: mediaKeySession,
6476
- sessionType: sessionType
6477
- });
6471
+ this._storage.push(Object.assign({}, entry));
6478
6472
 
6479
6473
  return entry;
6480
6474
  }
@@ -6501,29 +6495,49 @@ var LoadedSessionsStore = /*#__PURE__*/function () {
6501
6495
 
6502
6496
  this._storage.push(stored);
6503
6497
 
6504
- return {
6505
- keySessionRecord: stored.keySessionRecord,
6506
- mediaKeySession: stored.mediaKeySession,
6507
- sessionType: stored.sessionType
6508
- };
6498
+ return Object.assign({}, stored);
6509
6499
  }
6510
6500
  }
6511
6501
 
6512
6502
  return null;
6513
6503
  }
6514
6504
  /**
6515
- * Close a MediaKeySession and remove its related stored information from the
6505
+ * Get `LoadedSessionsStore`'s entry for a given MediaKeySession.
6506
+ * Returns `null` if the given MediaKeySession is not stored in the
6516
6507
  * `LoadedSessionsStore`.
6517
- * Emit when done.
6508
+ * @param {MediaKeySession} mediaKeySession
6509
+ * @returns {Object|null}
6510
+ */
6511
+ ;
6512
+
6513
+ _proto.getEntryForSession = function getEntryForSession(mediaKeySession) {
6514
+ for (var i = this._storage.length - 1; i >= 0; i--) {
6515
+ var stored = this._storage[i];
6516
+
6517
+ if (stored.mediaKeySession === mediaKeySession) {
6518
+ return Object.assign({}, stored);
6519
+ }
6520
+ }
6521
+
6522
+ return null;
6523
+ }
6524
+ /**
6525
+ * Generate a license request on the given MediaKeySession, while indicating
6526
+ * to the LoadedSessionsStore that a license-request is pending so
6527
+ * session-closing orders are properly scheduled after it is done.
6518
6528
  * @param {Object} mediaKeySession
6529
+ * @param {string} initializationDataType - Initialization data type given
6530
+ * e.g. by the "encrypted" event for the corresponding request.
6531
+ * @param {Uint8Array} initializationData - Initialization data given e.g. by
6532
+ * the "encrypted" event for the corresponding request.
6519
6533
  * @returns {Promise}
6520
6534
  */
6521
6535
  ;
6522
6536
 
6523
- _proto.closeSession =
6537
+ _proto.generateLicenseRequest =
6524
6538
  /*#__PURE__*/
6525
6539
  function () {
6526
- var _closeSession = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee(mediaKeySession) {
6540
+ var _generateLicenseRequest = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee(mediaKeySession, initializationDataType, initializationData) {
6527
6541
  var entry, _iterator, _step, stored;
6528
6542
 
6529
6543
  return regenerator_default().wrap(function _callee$(_context) {
@@ -6558,25 +6572,260 @@ var LoadedSessionsStore = /*#__PURE__*/function () {
6558
6572
  break;
6559
6573
  }
6560
6574
 
6561
- log/* default.warn */.Z.warn("DRM-LSS: No MediaKeySession found with " + "the given initData and initDataType");
6562
- return _context.abrupt("return", Promise.resolve(false));
6575
+ log/* default.error */.Z.error("DRM-LSS: generateRequest error. No MediaKeySession found with " + "the given initData and initDataType");
6576
+ return _context.abrupt("return", generateKeyRequest(mediaKeySession, initializationDataType, initializationData));
6563
6577
 
6564
6578
  case 11:
6565
- _context.next = 13;
6566
- return safelyCloseMediaKeySession(entry.mediaKeySession);
6579
+ entry.isGeneratingRequest = true; // Note the `as string` is needed due to TypeScript not understanding that
6580
+ // the `closingStatus` might change in the next checks
6567
6581
 
6568
- case 13:
6569
- return _context.abrupt("return", Promise.resolve(true));
6582
+ if (!(entry.closingStatus.type !== "none")) {
6583
+ _context.next = 14;
6584
+ break;
6585
+ }
6586
+
6587
+ throw new Error("The `MediaKeySession` is being closed.");
6570
6588
 
6571
6589
  case 14:
6590
+ _context.prev = 14;
6591
+ _context.next = 17;
6592
+ return generateKeyRequest(mediaKeySession, initializationDataType, initializationData);
6593
+
6594
+ case 17:
6595
+ _context.next = 26;
6596
+ break;
6597
+
6598
+ case 19:
6599
+ _context.prev = 19;
6600
+ _context.t0 = _context["catch"](14);
6601
+
6602
+ if (!(entry === undefined)) {
6603
+ _context.next = 23;
6604
+ break;
6605
+ }
6606
+
6607
+ throw _context.t0;
6608
+
6609
+ case 23:
6610
+ entry.isGeneratingRequest = false;
6611
+
6612
+ if (entry.closingStatus.type === "awaiting") {
6613
+ entry.closingStatus.start();
6614
+ }
6615
+
6616
+ throw _context.t0;
6617
+
6618
+ case 26:
6619
+ if (!(entry === undefined)) {
6620
+ _context.next = 28;
6621
+ break;
6622
+ }
6623
+
6624
+ return _context.abrupt("return", undefined);
6625
+
6626
+ case 28:
6627
+ entry.isGeneratingRequest = false;
6628
+
6629
+ if (entry.closingStatus.type === "awaiting") {
6630
+ entry.closingStatus.start();
6631
+ }
6632
+
6633
+ case 30:
6572
6634
  case "end":
6573
6635
  return _context.stop();
6574
6636
  }
6575
6637
  }
6576
- }, _callee, this);
6638
+ }, _callee, this, [[14, 19]]);
6639
+ }));
6640
+
6641
+ function generateLicenseRequest(_x, _x2, _x3) {
6642
+ return _generateLicenseRequest.apply(this, arguments);
6643
+ }
6644
+
6645
+ return generateLicenseRequest;
6646
+ }()
6647
+ /**
6648
+ * @param {Object} mediaKeySession
6649
+ * @param {string} sessionId
6650
+ * @returns {Promise}
6651
+ */
6652
+ ;
6653
+
6654
+ _proto.loadPersistentSession =
6655
+ /*#__PURE__*/
6656
+ function () {
6657
+ var _loadPersistentSession = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee2(mediaKeySession, sessionId) {
6658
+ var entry, _iterator2, _step2, stored, ret;
6659
+
6660
+ return regenerator_default().wrap(function _callee2$(_context2) {
6661
+ while (1) {
6662
+ switch (_context2.prev = _context2.next) {
6663
+ case 0:
6664
+ _iterator2 = loaded_sessions_store_createForOfIteratorHelperLoose(this._storage);
6665
+
6666
+ case 1:
6667
+ if ((_step2 = _iterator2()).done) {
6668
+ _context2.next = 8;
6669
+ break;
6670
+ }
6671
+
6672
+ stored = _step2.value;
6673
+
6674
+ if (!(stored.mediaKeySession === mediaKeySession)) {
6675
+ _context2.next = 6;
6676
+ break;
6677
+ }
6678
+
6679
+ entry = stored;
6680
+ return _context2.abrupt("break", 8);
6681
+
6682
+ case 6:
6683
+ _context2.next = 1;
6684
+ break;
6685
+
6686
+ case 8:
6687
+ if (!(entry === undefined)) {
6688
+ _context2.next = 11;
6689
+ break;
6690
+ }
6691
+
6692
+ log/* default.error */.Z.error("DRM-LSS: loadPersistentSession error. No MediaKeySession found with " + "the given initData and initDataType");
6693
+ return _context2.abrupt("return", loadSession(mediaKeySession, sessionId));
6694
+
6695
+ case 11:
6696
+ entry.isLoadingPersistentSession = true; // Note the `as string` is needed due to TypeScript not understanding that
6697
+ // the `closingStatus` might change in the next checks
6698
+
6699
+ if (!(entry.closingStatus.type !== "none")) {
6700
+ _context2.next = 14;
6701
+ break;
6702
+ }
6703
+
6704
+ throw new Error("The `MediaKeySession` is being closed.");
6705
+
6706
+ case 14:
6707
+ _context2.prev = 14;
6708
+ _context2.next = 17;
6709
+ return loadSession(mediaKeySession, sessionId);
6710
+
6711
+ case 17:
6712
+ ret = _context2.sent;
6713
+ _context2.next = 27;
6714
+ break;
6715
+
6716
+ case 20:
6717
+ _context2.prev = 20;
6718
+ _context2.t0 = _context2["catch"](14);
6719
+
6720
+ if (!(entry === undefined)) {
6721
+ _context2.next = 24;
6722
+ break;
6723
+ }
6724
+
6725
+ throw _context2.t0;
6726
+
6727
+ case 24:
6728
+ entry.isLoadingPersistentSession = false;
6729
+
6730
+ if (entry.closingStatus.type === "awaiting") {
6731
+ entry.closingStatus.start();
6732
+ }
6733
+
6734
+ throw _context2.t0;
6735
+
6736
+ case 27:
6737
+ if (!(entry === undefined)) {
6738
+ _context2.next = 29;
6739
+ break;
6740
+ }
6741
+
6742
+ return _context2.abrupt("return", ret);
6743
+
6744
+ case 29:
6745
+ entry.isLoadingPersistentSession = false;
6746
+
6747
+ if (entry.closingStatus.type === "awaiting") {
6748
+ entry.closingStatus.start();
6749
+ }
6750
+
6751
+ return _context2.abrupt("return", ret);
6752
+
6753
+ case 32:
6754
+ case "end":
6755
+ return _context2.stop();
6756
+ }
6757
+ }
6758
+ }, _callee2, this, [[14, 20]]);
6577
6759
  }));
6578
6760
 
6579
- function closeSession(_x) {
6761
+ function loadPersistentSession(_x4, _x5) {
6762
+ return _loadPersistentSession.apply(this, arguments);
6763
+ }
6764
+
6765
+ return loadPersistentSession;
6766
+ }()
6767
+ /**
6768
+ * Close a MediaKeySession and remove its related stored information from the
6769
+ * `LoadedSessionsStore`.
6770
+ * Emit when done.
6771
+ * @param {Object} mediaKeySession
6772
+ * @returns {Promise}
6773
+ */
6774
+ ;
6775
+
6776
+ _proto.closeSession =
6777
+ /*#__PURE__*/
6778
+ function () {
6779
+ var _closeSession = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee3(mediaKeySession) {
6780
+ var entry, _iterator3, _step3, stored;
6781
+
6782
+ return regenerator_default().wrap(function _callee3$(_context3) {
6783
+ while (1) {
6784
+ switch (_context3.prev = _context3.next) {
6785
+ case 0:
6786
+ _iterator3 = loaded_sessions_store_createForOfIteratorHelperLoose(this._storage);
6787
+
6788
+ case 1:
6789
+ if ((_step3 = _iterator3()).done) {
6790
+ _context3.next = 8;
6791
+ break;
6792
+ }
6793
+
6794
+ stored = _step3.value;
6795
+
6796
+ if (!(stored.mediaKeySession === mediaKeySession)) {
6797
+ _context3.next = 6;
6798
+ break;
6799
+ }
6800
+
6801
+ entry = stored;
6802
+ return _context3.abrupt("break", 8);
6803
+
6804
+ case 6:
6805
+ _context3.next = 1;
6806
+ break;
6807
+
6808
+ case 8:
6809
+ if (!(entry === undefined)) {
6810
+ _context3.next = 11;
6811
+ break;
6812
+ }
6813
+
6814
+ log/* default.warn */.Z.warn("DRM-LSS: No MediaKeySession found with " + "the given initData and initDataType");
6815
+ return _context3.abrupt("return", Promise.resolve(false));
6816
+
6817
+ case 11:
6818
+ return _context3.abrupt("return", this._closeEntry(entry));
6819
+
6820
+ case 12:
6821
+ case "end":
6822
+ return _context3.stop();
6823
+ }
6824
+ }
6825
+ }, _callee3, this);
6826
+ }));
6827
+
6828
+ function closeSession(_x6) {
6580
6829
  return _closeSession.apply(this, arguments);
6581
6830
  }
6582
6831
 
@@ -6611,11 +6860,13 @@ var LoadedSessionsStore = /*#__PURE__*/function () {
6611
6860
  _proto.closeAllSessions =
6612
6861
  /*#__PURE__*/
6613
6862
  function () {
6614
- var _closeAllSessions = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee2() {
6863
+ var _closeAllSessions = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee4() {
6864
+ var _this2 = this;
6865
+
6615
6866
  var allEntries, closingProms;
6616
- return regenerator_default().wrap(function _callee2$(_context2) {
6867
+ return regenerator_default().wrap(function _callee4$(_context4) {
6617
6868
  while (1) {
6618
- switch (_context2.prev = _context2.next) {
6869
+ switch (_context4.prev = _context4.next) {
6619
6870
  case 0:
6620
6871
  allEntries = this._storage;
6621
6872
  log/* default.debug */.Z.debug("DRM-LSS: Closing all current MediaKeySessions", allEntries.length); // re-initialize the storage, so that new interactions with the
@@ -6624,17 +6875,17 @@ var LoadedSessionsStore = /*#__PURE__*/function () {
6624
6875
 
6625
6876
  this._storage = [];
6626
6877
  closingProms = allEntries.map(function (entry) {
6627
- return safelyCloseMediaKeySession(entry.mediaKeySession);
6878
+ return _this2._closeEntry(entry);
6628
6879
  });
6629
- _context2.next = 6;
6880
+ _context4.next = 6;
6630
6881
  return Promise.all(closingProms);
6631
6882
 
6632
6883
  case 6:
6633
6884
  case "end":
6634
- return _context2.stop();
6885
+ return _context4.stop();
6635
6886
  }
6636
6887
  }
6637
- }, _callee2, this);
6888
+ }, _callee4, this);
6638
6889
  }));
6639
6890
 
6640
6891
  function closeAllSessions() {
@@ -6642,7 +6893,15 @@ var LoadedSessionsStore = /*#__PURE__*/function () {
6642
6893
  }
6643
6894
 
6644
6895
  return closeAllSessions;
6645
- }();
6896
+ }()
6897
+ /**
6898
+ * Get the index of a stored MediaKeySession entry based on its
6899
+ * `KeySessionRecord`.
6900
+ * Returns -1 if not found.
6901
+ * @param {Object} record
6902
+ * @returns {number}
6903
+ */
6904
+ ;
6646
6905
 
6647
6906
  _proto.getIndex = function getIndex(record) {
6648
6907
  for (var i = 0; i < this._storage.length; i++) {
@@ -6654,122 +6913,124 @@ var LoadedSessionsStore = /*#__PURE__*/function () {
6654
6913
  }
6655
6914
 
6656
6915
  return -1;
6657
- };
6658
-
6659
- return LoadedSessionsStore;
6660
- }();
6661
- /**
6662
- * Close a MediaKeySession with multiple attempts if needed and do not throw if
6663
- * this action throws an error.
6664
- * Emits then complete when done.
6665
- * @param {MediaKeySession} mediaKeySession
6666
- * @returns {Observable}
6667
- */
6668
-
6669
-
6670
-
6671
-
6672
- function safelyCloseMediaKeySession(mediaKeySession) {
6673
- return recursivelyTryToCloseMediaKeySession(0);
6674
- /**
6675
- * Perform a new attempt at closing the MediaKeySession.
6676
- * If this operation fails due to a not-"callable" (an EME term)
6677
- * MediaKeySession, retry based on either a timer or on MediaKeySession
6678
- * events, whichever comes first.
6679
- * Emits then complete when done.
6680
- * @param {number} retryNb - The attempt number starting at 0.
6681
- * @returns {Observable}
6682
- */
6683
-
6684
- function recursivelyTryToCloseMediaKeySession(_x2) {
6685
- return _recursivelyTryToCloseMediaKeySession.apply(this, arguments);
6686
6916
  }
6687
6917
  /**
6688
- * Log error anouncing that we could not close the MediaKeySession and emits
6689
- * then complete through Observable.
6690
- * TODO Emit warning?
6691
- * @returns {Observable}
6918
+ * Prepare the closure of a `MediaKeySession` stored as an entry of the
6919
+ * `LoadedSessionsStore`.
6920
+ * Allows to postpone the closure action if another MediaKeySession action
6921
+ * is already pending.
6922
+ * @param {Object} entry
6923
+ * @returns {Promise.<boolean>}
6692
6924
  */
6925
+ ;
6693
6926
 
6694
-
6695
- function _recursivelyTryToCloseMediaKeySession() {
6696
- _recursivelyTryToCloseMediaKeySession = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee3(retryNb) {
6697
- var _config$getCurrent, EME_SESSION_CLOSING_MAX_RETRY, EME_SESSION_CLOSING_INITIAL_DELAY, EME_SESSION_CLOSING_MAX_DELAY, nextRetryNb, delay, ksChangeSub, ksChangeProm, ksMsgSub, ksMsgProm, sleepTimer, sleepProm;
6698
-
6699
- return regenerator_default().wrap(function _callee3$(_context3) {
6927
+ _proto._closeEntry =
6928
+ /*#__PURE__*/
6929
+ function () {
6930
+ var _closeEntry2 = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee5(entry) {
6931
+ var mediaKeySession;
6932
+ return regenerator_default().wrap(function _callee5$(_context5) {
6700
6933
  while (1) {
6701
- switch (_context3.prev = _context3.next) {
6934
+ switch (_context5.prev = _context5.next) {
6702
6935
  case 0:
6703
- log/* default.debug */.Z.debug("DRM: Trying to close a MediaKeySession", mediaKeySession.sessionId, retryNb);
6704
- _context3.prev = 1;
6705
- _context3.next = 4;
6706
- return closeSession(mediaKeySession);
6936
+ mediaKeySession = entry.mediaKeySession;
6937
+ return _context5.abrupt("return", new Promise(function (resolve, reject) {
6938
+ if (entry !== undefined && (entry.isLoadingPersistentSession || entry.isGeneratingRequest)) {
6939
+ entry.closingStatus = {
6940
+ type: "awaiting",
6941
+ start: tryClosingEntryAndResolve
6942
+ };
6943
+ } else {
6944
+ tryClosingEntryAndResolve();
6945
+ }
6707
6946
 
6708
- case 4:
6709
- log/* default.debug */.Z.debug("DRM: Succeeded to close MediaKeySession");
6710
- return _context3.abrupt("return", undefined);
6947
+ function tryClosingEntryAndResolve() {
6948
+ if (entry !== undefined) {
6949
+ entry.closingStatus = {
6950
+ type: "pending"
6951
+ };
6952
+ }
6711
6953
 
6712
- case 8:
6713
- _context3.prev = 8;
6714
- _context3.t0 = _context3["catch"](1);
6954
+ safelyCloseMediaKeySession(mediaKeySession).then(function () {
6955
+ if (entry !== undefined) {
6956
+ entry.closingStatus = {
6957
+ type: "done"
6958
+ };
6959
+ }
6715
6960
 
6716
- if (!(!(_context3.t0 instanceof Error) || _context3.t0.name !== "InvalidStateError" || mediaKeySession.sessionId !== "")) {
6717
- _context3.next = 12;
6718
- break;
6719
- }
6961
+ resolve(true);
6962
+ })["catch"](function (err) {
6963
+ if (entry !== undefined) {
6964
+ entry.closingStatus = {
6965
+ type: "failed"
6966
+ };
6967
+ }
6720
6968
 
6721
- return _context3.abrupt("return", failToCloseSession(_context3.t0));
6969
+ reject(err);
6970
+ });
6971
+ }
6972
+ }));
6722
6973
 
6723
- case 12:
6724
- _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(), EME_SESSION_CLOSING_MAX_RETRY = _config$getCurrent.EME_SESSION_CLOSING_MAX_RETRY, EME_SESSION_CLOSING_INITIAL_DELAY = _config$getCurrent.EME_SESSION_CLOSING_INITIAL_DELAY, EME_SESSION_CLOSING_MAX_DELAY = _config$getCurrent.EME_SESSION_CLOSING_MAX_DELAY; // We will retry either:
6725
- // - when an event indicates that the MediaKeySession is
6726
- // initialized (`callable` is the proper EME term here)
6727
- // - after a delay, raising exponentially
6974
+ case 2:
6975
+ case "end":
6976
+ return _context5.stop();
6977
+ }
6978
+ }
6979
+ }, _callee5);
6980
+ }));
6728
6981
 
6729
- nextRetryNb = retryNb + 1;
6982
+ function _closeEntry(_x7) {
6983
+ return _closeEntry2.apply(this, arguments);
6984
+ }
6730
6985
 
6731
- if (!(nextRetryNb > EME_SESSION_CLOSING_MAX_RETRY)) {
6732
- _context3.next = 16;
6733
- break;
6734
- }
6986
+ return _closeEntry;
6987
+ }();
6735
6988
 
6736
- return _context3.abrupt("return", failToCloseSession(_context3.t0));
6989
+ return LoadedSessionsStore;
6990
+ }();
6991
+ /**
6992
+ * Close a MediaKeySession and just log an error if it fails (while resolving).
6993
+ * Emits then complete when done.
6994
+ * @param {MediaKeySession} mediaKeySession
6995
+ * @returns {Observable}
6996
+ */
6737
6997
 
6738
- case 16:
6739
- delay = Math.min(Math.pow(2, retryNb) * EME_SESSION_CLOSING_INITIAL_DELAY, EME_SESSION_CLOSING_MAX_DELAY);
6740
- log/* default.warn */.Z.warn("DRM: attempt to close a mediaKeySession failed, " + "scheduling retry...", delay);
6741
- ksChangeProm = new Promise(function (res) {
6742
- ksChangeSub = (0,event_listeners/* onKeyStatusesChange$ */.eX)(mediaKeySession).subscribe(res);
6743
- });
6744
- ksMsgProm = new Promise(function (res) {
6745
- ksMsgSub = (0,event_listeners/* onKeyMessage$ */.GJ)(mediaKeySession).subscribe(res);
6746
- });
6747
- sleepProm = new Promise(function (res) {
6748
- sleepTimer = window.setTimeout(res, delay);
6749
- });
6750
- _context3.next = 23;
6751
- return Promise.race([ksChangeProm, ksMsgProm, sleepProm]);
6752
6998
 
6753
- case 23:
6754
- ksChangeSub === null || ksChangeSub === void 0 ? void 0 : ksChangeSub.unsubscribe();
6755
- ksMsgSub === null || ksMsgSub === void 0 ? void 0 : ksMsgSub.unsubscribe();
6756
- clearTimeout(sleepTimer);
6757
- return _context3.abrupt("return", recursivelyTryToCloseMediaKeySession(nextRetryNb));
6758
6999
 
6759
- case 27:
6760
- case "end":
6761
- return _context3.stop();
6762
- }
6763
- }
6764
- }, _callee3, null, [[1, 8]]);
6765
- }));
6766
- return _recursivelyTryToCloseMediaKeySession.apply(this, arguments);
6767
- }
6768
7000
 
6769
- function failToCloseSession(err) {
6770
- log/* default.error */.Z.error("DRM: Could not close MediaKeySession: " + (err instanceof Error ? err.toString() : "Unknown error"));
6771
- return Promise.resolve(null);
6772
- }
7001
+ function safelyCloseMediaKeySession(_x8) {
7002
+ return _safelyCloseMediaKeySession.apply(this, arguments);
7003
+ }
7004
+
7005
+ function _safelyCloseMediaKeySession() {
7006
+ _safelyCloseMediaKeySession = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee6(mediaKeySession) {
7007
+ return regenerator_default().wrap(function _callee6$(_context6) {
7008
+ while (1) {
7009
+ switch (_context6.prev = _context6.next) {
7010
+ case 0:
7011
+ log/* default.debug */.Z.debug("DRM: Trying to close a MediaKeySession", mediaKeySession.sessionId);
7012
+ _context6.prev = 1;
7013
+ _context6.next = 4;
7014
+ return closeSession(mediaKeySession);
7015
+
7016
+ case 4:
7017
+ log/* default.debug */.Z.debug("DRM: Succeeded to close MediaKeySession");
7018
+ return _context6.abrupt("return");
7019
+
7020
+ case 8:
7021
+ _context6.prev = 8;
7022
+ _context6.t0 = _context6["catch"](1);
7023
+ log/* default.error */.Z.error("DRM: Could not close MediaKeySession: " + (_context6.t0 instanceof Error ? _context6.t0.toString() : "Unknown error"));
7024
+ return _context6.abrupt("return");
7025
+
7026
+ case 12:
7027
+ case "end":
7028
+ return _context6.stop();
7029
+ }
7030
+ }
7031
+ }, _callee6, null, [[1, 8]]);
7032
+ }));
7033
+ return _safelyCloseMediaKeySession.apply(this, arguments);
6773
7034
  }
6774
7035
  // EXTERNAL MODULE: ./src/utils/assert.ts
6775
7036
  var assert = __webpack_require__(811);
@@ -9088,7 +9349,7 @@ var ContentDecryptor = /*#__PURE__*/function (_EventEmitter) {
9088
9349
  var _processInitializationData2 = (0,asyncToGenerator/* default */.Z)( /*#__PURE__*/regenerator_default().mark(function _callee2(initializationData, mediaKeysData) {
9089
9350
  var _this4 = this;
9090
9351
 
9091
- var mediaKeySystemAccess, stores, options, firstCreatedSession, keyIds, hexKids, period, createdSessions, periodKeys, _iterator, _step, createdSess, periodKeysArr, _i, _periodKeysArr, kid, _iterator2, _step2, innerKid, wantedSessionType, _config$getCurrent, EME_DEFAULT_MAX_SIMULTANEOUS_MEDIA_KEY_SESSIONS, EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION, maxSessionCacheSize, sessionRes, sessionInfo, _sessionRes$value, mediaKeySession, sessionType, isSessionPersisted, sub, requestData;
9352
+ var mediaKeySystemAccess, stores, options, firstCreatedSession, keyIds, hexKids, period, createdSessions, periodKeys, _iterator, _step, createdSess, periodKeysArr, _i, _periodKeysArr, kid, _iterator2, _step2, innerKid, wantedSessionType, _config$getCurrent, EME_DEFAULT_MAX_SIMULTANEOUS_MEDIA_KEY_SESSIONS, EME_MAX_STORED_PERSISTENT_SESSION_INFORMATION, maxSessionCacheSize, sessionRes, sessionInfo, _sessionRes$value, mediaKeySession, sessionType, isSessionPersisted, sub, requestData, entry, indexInCurrent;
9092
9353
 
9093
9354
  return regenerator_default().wrap(function _callee2$(_context2) {
9094
9355
  while (1) {
@@ -9350,28 +9611,47 @@ var ContentDecryptor = /*#__PURE__*/function (_EventEmitter) {
9350
9611
  if (!(sessionRes.type === "created-session"
9351
9612
  /* Created */
9352
9613
  )) {
9353
- _context2.next = 63;
9614
+ _context2.next = 68;
9354
9615
  break;
9355
9616
  }
9356
9617
 
9357
9618
  requestData = initializationData.values.constructRequestData();
9358
9619
  _context2.prev = 55;
9359
9620
  _context2.next = 58;
9360
- return generateKeyRequest(mediaKeySession, initializationData.type, requestData);
9621
+ return stores.loadedSessionsStore.generateLicenseRequest(mediaKeySession, initializationData.type, requestData);
9361
9622
 
9362
9623
  case 58:
9363
- _context2.next = 63;
9624
+ _context2.next = 68;
9364
9625
  break;
9365
9626
 
9366
9627
  case 60:
9367
9628
  _context2.prev = 60;
9368
9629
  _context2.t0 = _context2["catch"](55);
9630
+ // First check that the error was not due to the MediaKeySession closing
9631
+ // or being closed
9632
+ entry = stores.loadedSessionsStore.getEntryForSession(mediaKeySession);
9633
+
9634
+ if (!(entry === null || entry.closingStatus.type !== "none")) {
9635
+ _context2.next = 67;
9636
+ break;
9637
+ }
9638
+
9639
+ // MediaKeySession closing/closed: Just remove from handled list and abort.
9640
+ indexInCurrent = this._currentSessions.indexOf(sessionInfo);
9641
+
9642
+ if (indexInCurrent >= 0) {
9643
+ this._currentSessions.splice(indexInCurrent, 1);
9644
+ }
9645
+
9646
+ return _context2.abrupt("return", Promise.resolve());
9647
+
9648
+ case 67:
9369
9649
  throw new encrypted_media_error/* default */.Z("KEY_GENERATE_REQUEST_ERROR", _context2.t0 instanceof Error ? _context2.t0.toString() : "Unknown error");
9370
9650
 
9371
- case 63:
9651
+ case 68:
9372
9652
  return _context2.abrupt("return", Promise.resolve());
9373
9653
 
9374
- case 64:
9654
+ case 69:
9375
9655
  case "end":
9376
9656
  return _context2.stop();
9377
9657
  }
@@ -31620,60 +31900,61 @@ var check_isobmff_integrity = __webpack_require__(4460);
31620
31900
 
31621
31901
  function addSegmentIntegrityChecks(segmentLoader) {
31622
31902
  return function (url, content, initialCancelSignal, callbacks) {
31623
- return new Promise(function (res, rej) {
31624
- var canceller = new task_canceller/* default */.ZP();
31625
- var unregisterCancelLstnr = initialCancelSignal.register(function onCheckCancellation(err) {
31626
- canceller.cancel();
31627
- rej(err);
31628
- });
31629
- /**
31630
- * If the data's seems to be corrupted, cancel the loading task and reject
31631
- * with an `INTEGRITY_ERROR` error.
31632
- * @param {*} data
31633
- */
31634
-
31635
- function cancelAndRejectOnBadIntegrity(data) {
31636
- if (!(data instanceof Array) && !(data instanceof Uint8Array) || inferSegmentContainer(content.adaptation.type, content.representation) !== "mp4") {
31637
- return;
31638
- }
31639
-
31640
- try {
31641
- (0,check_isobmff_integrity/* default */.Z)(new Uint8Array(data), content.segment.isInit);
31642
- } catch (err) {
31643
- unregisterCancelLstnr();
31644
- canceller.cancel();
31645
- rej(err);
31646
- }
31647
- }
31903
+ return new Promise(function (resolve, reject) {
31904
+ var requestCanceller = new task_canceller/* default */.ZP({
31905
+ cancelOn: initialCancelSignal
31906
+ }); // Reject the `CancellationError` when `requestCanceller`'s signal emits
31907
+ // `stopRejectingOnCancel` here is a function allowing to stop this mechanism
31648
31908
 
31649
- segmentLoader(url, content, canceller.signal, Object.assign(Object.assign({}, callbacks), {
31909
+ var stopRejectingOnCancel = requestCanceller.signal.register(reject);
31910
+ segmentLoader(url, content, requestCanceller.signal, Object.assign(Object.assign({}, callbacks), {
31650
31911
  onNewChunk: function onNewChunk(data) {
31651
- cancelAndRejectOnBadIntegrity(data);
31652
-
31653
- if (!canceller.isUsed) {
31912
+ try {
31913
+ trowOnIntegrityError(data);
31654
31914
  callbacks.onNewChunk(data);
31915
+ } catch (err) {
31916
+ // Do not reject with a `CancellationError` after cancelling the request
31917
+ stopRejectingOnCancel(); // Cancel the request
31918
+
31919
+ requestCanceller.cancel(); // Reject with thrown error
31920
+
31921
+ reject(err);
31655
31922
  }
31656
31923
  }
31657
31924
  })).then(function (info) {
31658
- if (canceller.isUsed) {
31925
+ if (requestCanceller.isUsed) {
31659
31926
  return;
31660
31927
  }
31661
31928
 
31662
- unregisterCancelLstnr();
31929
+ stopRejectingOnCancel();
31663
31930
 
31664
31931
  if (info.resultType === "segment-loaded") {
31665
- cancelAndRejectOnBadIntegrity(info.resultData.responseData);
31932
+ try {
31933
+ trowOnIntegrityError(info.resultData.responseData);
31934
+ } catch (err) {
31935
+ reject(err);
31936
+ return;
31937
+ }
31666
31938
  }
31667
31939
 
31668
- res(info);
31940
+ resolve(info);
31669
31941
  }, function (error) {
31670
- // The segmentLoader's cancellations cases are all handled here
31671
- if (!task_canceller/* default.isCancellationError */.ZP.isCancellationError(error)) {
31672
- unregisterCancelLstnr();
31673
- rej(error);
31674
- }
31942
+ stopRejectingOnCancel();
31943
+ reject(error);
31675
31944
  });
31676
31945
  });
31946
+ /**
31947
+ * If the data's seems to be corrupted, throws an `INTEGRITY_ERROR` error.
31948
+ * @param {*} data
31949
+ */
31950
+
31951
+ function trowOnIntegrityError(data) {
31952
+ if (!(data instanceof ArrayBuffer) && !(data instanceof Uint8Array) || inferSegmentContainer(content.adaptation.type, content.representation) !== "mp4") {
31953
+ return;
31954
+ }
31955
+
31956
+ (0,check_isobmff_integrity/* default */.Z)(new Uint8Array(data), content.segment.isInit);
31957
+ }
31677
31958
  };
31678
31959
  }
31679
31960
  // EXTERNAL MODULE: ./src/utils/byte_parsing.ts
@@ -40190,8 +40471,7 @@ function isTimeInTimeRanges(ranges, time) {
40190
40471
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
40191
40472
  /* harmony export */ "$": function() { return /* binding */ createSharedReference; }
40192
40473
  /* harmony export */ });
40193
- /* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(1480);
40194
- /* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3887);
40474
+ /* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1480);
40195
40475
  function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
40196
40476
 
40197
40477
  function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
@@ -40214,7 +40494,6 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
40214
40494
  * limitations under the License.
40215
40495
  */
40216
40496
 
40217
-
40218
40497
  /**
40219
40498
  * Create an `ISharedReference` object encapsulating the mutable `initialValue`
40220
40499
  * value of type T.
@@ -40261,7 +40540,6 @@ function createSharedReference(initialValue) {
40261
40540
  setValue: function setValue(newVal) {
40262
40541
  if (isFinished) {
40263
40542
  if (false) {} else {
40264
- _log__WEBPACK_IMPORTED_MODULE_0__/* ["default"].error */ .Z.error("Finished shared references cannot be updated");
40265
40543
  return;
40266
40544
  }
40267
40545
  }
@@ -40300,7 +40578,7 @@ function createSharedReference(initialValue) {
40300
40578
  * @returns {Observable}
40301
40579
  */
40302
40580
  asObservable: function asObservable(skipCurrentValue) {
40303
- return new rxjs__WEBPACK_IMPORTED_MODULE_1__/* .Observable */ .y(function (obs) {
40581
+ return new rxjs__WEBPACK_IMPORTED_MODULE_0__/* .Observable */ .y(function (obs) {
40304
40582
  if (skipCurrentValue !== true) {
40305
40583
  obs.next(value);
40306
40584
  }
@@ -41464,8 +41742,11 @@ var TaskCanceller = /*#__PURE__*/function () {
41464
41742
  * Creates a new `TaskCanceller`, with its own `CancellationSignal` created
41465
41743
  * as its `signal` provide.
41466
41744
  * You can then pass this property to async task you wish to be cancellable.
41745
+ * @param {Object|undefined} options
41467
41746
  */
41468
- function TaskCanceller() {
41747
+ function TaskCanceller(options) {
41748
+ var _this = this;
41749
+
41469
41750
  var _createCancellationFu = createCancellationFunctions(),
41470
41751
  trigger = _createCancellationFu[0],
41471
41752
  register = _createCancellationFu[1];
@@ -41473,6 +41754,13 @@ var TaskCanceller = /*#__PURE__*/function () {
41473
41754
  this.isUsed = false;
41474
41755
  this._trigger = trigger;
41475
41756
  this.signal = new CancellationSignal(register);
41757
+
41758
+ if ((options === null || options === void 0 ? void 0 : options.cancelOn) !== undefined) {
41759
+ var unregisterParent = options.cancelOn.register(function () {
41760
+ _this.cancel();
41761
+ });
41762
+ this.signal.register(unregisterParent);
41763
+ }
41476
41764
  }
41477
41765
  /**
41478
41766
  * "Trigger" the `TaskCanceller`, notify through its associated
@@ -41530,17 +41818,17 @@ var CancellationSignal = /*#__PURE__*/function () {
41530
41818
  * cancelled.
41531
41819
  */
41532
41820
  function CancellationSignal(registerToSource) {
41533
- var _this = this;
41821
+ var _this2 = this;
41534
41822
 
41535
41823
  this.isCancelled = false;
41536
41824
  this.cancellationError = null;
41537
41825
  this._listeners = [];
41538
41826
  registerToSource(function (cancellationError) {
41539
- _this.cancellationError = cancellationError;
41540
- _this.isCancelled = true;
41827
+ _this2.cancellationError = cancellationError;
41828
+ _this2.isCancelled = true;
41541
41829
 
41542
- while (_this._listeners.length > 0) {
41543
- var listener = _this._listeners.splice(_this._listeners.length - 1, 1)[0];
41830
+ while (_this2._listeners.length > 0) {
41831
+ var listener = _this2._listeners.splice(_this2._listeners.length - 1, 1)[0];
41544
41832
 
41545
41833
  listener(cancellationError);
41546
41834
  }
@@ -41572,7 +41860,7 @@ var CancellationSignal = /*#__PURE__*/function () {
41572
41860
  var _proto2 = CancellationSignal.prototype;
41573
41861
 
41574
41862
  _proto2.register = function register(fn) {
41575
- var _this2 = this;
41863
+ var _this3 = this;
41576
41864
 
41577
41865
  if (this.isCancelled) {
41578
41866
  (0,_assert__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z)(this.cancellationError !== null);
@@ -41582,7 +41870,7 @@ var CancellationSignal = /*#__PURE__*/function () {
41582
41870
  this._listeners.push(fn);
41583
41871
 
41584
41872
  return function () {
41585
- return _this2.deregister(fn);
41873
+ return _this3.deregister(fn);
41586
41874
  };
41587
41875
  }
41588
41876
  /**
@@ -41625,14 +41913,14 @@ var CancellationError = /*#__PURE__*/function (_Error) {
41625
41913
  * @param {string} message
41626
41914
  */
41627
41915
  function CancellationError() {
41628
- var _this3;
41916
+ var _this4;
41629
41917
 
41630
- _this3 = _Error.call(this) || this; // @see https://stackoverflow.com/questions/41102060/typescript-extending-error-class
41918
+ _this4 = _Error.call(this) || this; // @see https://stackoverflow.com/questions/41102060/typescript-extending-error-class
41631
41919
 
41632
- Object.setPrototypeOf((0,_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(_this3), CancellationError.prototype);
41633
- _this3.name = "CancellationError";
41634
- _this3.message = "This task was cancelled.";
41635
- return _this3;
41920
+ Object.setPrototypeOf((0,_babel_runtime_helpers_assertThisInitialized__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Z)(_this4), CancellationError.prototype);
41921
+ _this4.name = "CancellationError";
41922
+ _this4.message = "This task was cancelled.";
41923
+ return _this4;
41636
41924
  }
41637
41925
 
41638
41926
  return CancellationError;
@@ -46277,6 +46565,54 @@ function skipWhile(predicate) {
46277
46565
  var take = __webpack_require__(4727);
46278
46566
  // EXTERNAL MODULE: ./src/compat/event_listeners.ts + 6 modules
46279
46567
  var event_listeners = __webpack_require__(4804);
46568
+ ;// CONCATENATED MODULE: ./src/compat/get_start_date.ts
46569
+ /**
46570
+ * Copyright 2015 CANAL+ Group
46571
+ *
46572
+ * Licensed under the Apache License, Version 2.0 (the "License");
46573
+ * you may not use this file except in compliance with the License.
46574
+ * You may obtain a copy of the License at
46575
+ *
46576
+ * http://www.apache.org/licenses/LICENSE-2.0
46577
+ *
46578
+ * Unless required by applicable law or agreed to in writing, software
46579
+ * distributed under the License is distributed on an "AS IS" BASIS,
46580
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
46581
+ * See the License for the specific language governing permissions and
46582
+ * limitations under the License.
46583
+ */
46584
+
46585
+ /**
46586
+ * Calculating a live-offseted media position necessitate to obtain first an
46587
+ * offset, and then adding that offset to the wanted position.
46588
+ *
46589
+ * That offset is in most case present inside the Manifest file, yet in cases
46590
+ * without it or without a Manifest, such as the "directfile" mode, the RxPlayer
46591
+ * won't know that offset.
46592
+ *
46593
+ * Thankfully Safari declares a `getStartDate` method allowing to obtain that
46594
+ * offset when available. This logic is mainly useful when playing HLS contents
46595
+ * in directfile mode on Safari.
46596
+ * @param {HTMLMediaElement} mediaElement
46597
+ * @returns {number|undefined}
46598
+ */
46599
+ function getStartDate(mediaElement) {
46600
+ var _mediaElement = mediaElement;
46601
+
46602
+ if (typeof _mediaElement.getStartDate === "function") {
46603
+ var startDate = _mediaElement.getStartDate();
46604
+
46605
+ if (typeof startDate === "object" && startDate !== null) {
46606
+ var startDateNum = +startDate;
46607
+
46608
+ if (!isNaN(startDateNum)) {
46609
+ return startDateNum / 1000;
46610
+ }
46611
+ } else if (typeof startDate === "number" && !isNaN(startDate)) {
46612
+ return startDate;
46613
+ }
46614
+ }
46615
+ }
46280
46616
  ;// CONCATENATED MODULE: ./src/compat/fullscreen.ts
46281
46617
  /**
46282
46618
  * Copyright 2015 CANAL+ Group
@@ -52318,6 +52654,11 @@ function clearBuffer(segmentBuffer, position, maxBufferBehind, maxBufferAhead) {
52318
52654
  collectBufferAhead();
52319
52655
  var clean$ = (0,from/* from */.D)(cleanedupRanges.map(function (range) {
52320
52656
  log/* default.debug */.Z.debug("GC: cleaning range from SegmentBuffer", range);
52657
+
52658
+ if (range.start >= range.end) {
52659
+ return (0,of.of)(null);
52660
+ }
52661
+
52321
52662
  return segmentBuffer.removeBuffer(range.start, range.end);
52322
52663
  })).pipe((0,concatAll/* concatAll */.u)(), // NOTE As of now (RxJS 7.4.0), RxJS defines `ignoreElements` default
52323
52664
  // first type parameter as `any` instead of the perfectly fine `unknown`,
@@ -53052,9 +53393,7 @@ function getNeededSegments(_ref) {
53052
53393
  segmentsBeingPushed = _ref.segmentsBeingPushed,
53053
53394
  maxBufferSize = _ref.maxBufferSize;
53054
53395
  var representation = content.representation;
53055
- var availableBufferSize = getAvailableBufferSize(bufferedSegments, segmentsBeingPushed, maxBufferSize); // Current buffer length in seconds
53056
-
53057
- var bufferLength = getBufferLength(bufferedSegments, segmentsBeingPushed);
53396
+ var availableBufferSize = getAvailableBufferSize(bufferedSegments, segmentsBeingPushed, maxBufferSize);
53058
53397
  var availableSegmentsForRange = representation.index.getSegments(neededRange.start, neededRange.end - neededRange.start); // Remove from `bufferedSegments` any segments we would prefer to replace:
53059
53398
  // - segments in the wrong track / bad quality
53060
53399
  // - garbage-collected segments
@@ -53091,10 +53430,9 @@ function getNeededSegments(_ref) {
53091
53430
 
53092
53431
  var _config$getCurrent = config/* default.getCurrent */.Z.getCurrent(),
53093
53432
  MINIMUM_SEGMENT_SIZE = _config$getCurrent.MINIMUM_SEGMENT_SIZE,
53094
- MIN_BUFFER_LENGTH = _config$getCurrent.MIN_BUFFER_LENGTH,
53095
- MIN_BUFFER_DISTANCE_BEFORE_CLEAN_UP = _config$getCurrent.MIN_BUFFER_DISTANCE_BEFORE_CLEAN_UP;
53433
+ MIN_BUFFER_AHEAD = _config$getCurrent.MIN_BUFFER_AHEAD;
53096
53434
 
53097
- var isMemorySaturated = false;
53435
+ var shouldStopLoadingSegments = false;
53098
53436
  /**
53099
53437
  * Epsilon compensating for rounding errors when comparing the start and end
53100
53438
  * time of multiple segments.
@@ -53102,7 +53440,8 @@ function getNeededSegments(_ref) {
53102
53440
 
53103
53441
  var ROUNDING_ERROR = Math.min(1 / 60, MINIMUM_SEGMENT_SIZE);
53104
53442
  var isBufferFull = false;
53105
- var neededSegments = availableSegmentsForRange.filter(function (segment) {
53443
+ var segmentsOnHold = [];
53444
+ var segmentsToLoad = availableSegmentsForRange.filter(function (segment) {
53106
53445
  var contentObject = (0,object_assign/* default */.Z)({
53107
53446
  segment: segment
53108
53447
  }, content); // First, check that the segment is not already being pushed
@@ -53125,17 +53464,8 @@ function getNeededSegments(_ref) {
53125
53464
  return true; // never skip initialization segments
53126
53465
  }
53127
53466
 
53128
- if (isMemorySaturated) {
53129
- // If we are so saturated in memory
53130
- // That we cannot download atleast till
53131
- // NeededRange.Start ( current position ) + a CONST
53132
- // Then the buffer is full
53133
- if (time < neededRange.start + MIN_BUFFER_DISTANCE_BEFORE_CLEAN_UP) {
53134
- isBufferFull = true;
53135
- }
53136
- }
53137
-
53138
- if (isMemorySaturated && bufferLength > MIN_BUFFER_LENGTH) {
53467
+ if (shouldStopLoadingSegments) {
53468
+ segmentsOnHold.push(segment);
53139
53469
  return false;
53140
53470
  }
53141
53471
 
@@ -53184,32 +53514,42 @@ function getNeededSegments(_ref) {
53184
53514
  return false; // already downloaded
53185
53515
  }
53186
53516
  }
53517
+ }
53518
+
53519
+ var estimatedSegmentSize = duration * content.representation.bitrate / 8000;
53520
+
53521
+ if (availableBufferSize - estimatedSegmentSize < 0) {
53522
+ isBufferFull = true;
53523
+
53524
+ if (time > neededRange.start + MIN_BUFFER_AHEAD) {
53525
+ shouldStopLoadingSegments = true;
53526
+ segmentsOnHold.push(segment);
53527
+ return false;
53528
+ }
53187
53529
  } // check if there is an hole in place of the segment currently
53188
53530
 
53189
53531
 
53190
53532
  for (var _i = 0; _i < segmentsToKeep.length; _i++) {
53191
- var _completeSeg = segmentsToKeep[_i];
53533
+ var _completeSeg = segmentsToKeep[_i]; // For the first already-loaded segment, take the first one ending after
53534
+ // this one' s start
53192
53535
 
53193
- if (_completeSeg.end > time) {
53194
- // `true` if `completeSeg` starts too far after `time`
53195
- return _completeSeg.start > time + ROUNDING_ERROR || // `true` if `completeSeg` ends too soon before `end`
53196
- getLastContiguousSegment(segmentsToKeep, _i).end < end - ROUNDING_ERROR;
53197
- }
53198
- }
53536
+ if (_completeSeg.end + ROUNDING_ERROR > time) {
53537
+ var shouldLoad = _completeSeg.start > time + ROUNDING_ERROR || getLastContiguousSegment(segmentsToKeep, _i).end < end - ROUNDING_ERROR;
53199
53538
 
53200
- var estimatedSegmentSize = duration * content.representation.bitrate / 8000;
53539
+ if (shouldLoad) {
53540
+ availableBufferSize -= estimatedSegmentSize;
53541
+ }
53201
53542
 
53202
- if (availableBufferSize - estimatedSegmentSize < 0 && bufferLength > MIN_BUFFER_LENGTH) {
53203
- isMemorySaturated = true;
53204
- return false;
53543
+ return shouldLoad;
53544
+ }
53205
53545
  }
53206
53546
 
53207
53547
  availableBufferSize -= estimatedSegmentSize;
53208
- bufferLength += duration;
53209
53548
  return true;
53210
53549
  });
53211
53550
  return {
53212
- neededSegments: neededSegments,
53551
+ segmentsToLoad: segmentsToLoad,
53552
+ segmentsOnHold: segmentsOnHold,
53213
53553
  isBufferFull: isBufferFull
53214
53554
  };
53215
53555
  }
@@ -53232,29 +53572,12 @@ function getAvailableBufferSize(bufferedSegments, segmentsBeingPushed, maxVideoB
53232
53572
  }, 0);
53233
53573
  return bufferedSegments.reduce(function (size, chunk) {
53234
53574
  if (chunk.chunkSize !== undefined) {
53235
- return size - chunk.chunkSize / 8000;
53575
+ return size - chunk.chunkSize / 1000;
53236
53576
  } else {
53237
53577
  return size;
53238
53578
  }
53239
53579
  }, availableBufferSize);
53240
53580
  }
53241
- /**
53242
- * Compute the length of the buffer in seconds
53243
- * @param bufferedSegments
53244
- * @param segmentsBeingPushed
53245
- * @returns bufferLength in seconds
53246
- */
53247
-
53248
-
53249
- function getBufferLength(bufferedSegments, segmentsBeingPushed) {
53250
- var bufferLength = bufferedSegments.reduce(function (length, segment) {
53251
- return length + (segment.end - segment.start);
53252
- }, 0);
53253
- var bufferBeingPushed = segmentsBeingPushed.reduce(function (length, segment) {
53254
- return length + segment.segment.duration;
53255
- }, 0);
53256
- return bufferLength + bufferBeingPushed;
53257
- }
53258
53581
  /**
53259
53582
  * From the given array of buffered chunks (`bufferedSegments`) returns the last
53260
53583
  * buffered chunk contiguous with the one at the `startIndex` index given.
@@ -53628,10 +53951,11 @@ function getBufferStatus(content, wantedStartPosition, playbackObserver, fastSwi
53628
53951
  segmentsBeingPushed: segmentsBeingPushed,
53629
53952
  maxBufferSize: maxBufferSize
53630
53953
  }),
53631
- neededSegments = _getNeededSegments.neededSegments,
53954
+ segmentsToLoad = _getNeededSegments.segmentsToLoad,
53955
+ segmentsOnHold = _getNeededSegments.segmentsOnHold,
53632
53956
  isBufferFull = _getNeededSegments.isBufferFull;
53633
53957
 
53634
- var prioritizedNeededSegments = neededSegments.map(function (segment) {
53958
+ var prioritizedNeededSegments = segmentsToLoad.map(function (segment) {
53635
53959
  return {
53636
53960
  priority: getSegmentPriority(segment.time, wantedStartPosition),
53637
53961
  segment: segment
@@ -53645,7 +53969,7 @@ function getBufferStatus(content, wantedStartPosition, playbackObserver, fastSwi
53645
53969
  var hasFinishedLoading;
53646
53970
  var lastPosition = representation.index.getLastPosition();
53647
53971
 
53648
- if (!representation.index.isInitialized() || period.end === undefined || prioritizedNeededSegments.length > 0) {
53972
+ if (!representation.index.isInitialized() || period.end === undefined || prioritizedNeededSegments.length > 0 || segmentsOnHold.length > 0) {
53649
53973
  hasFinishedLoading = false;
53650
53974
  } else {
53651
53975
  if (lastPosition === undefined) {
@@ -53686,6 +54010,10 @@ function getBufferStatus(content, wantedStartPosition, playbackObserver, fastSwi
53686
54010
  }));
53687
54011
  }
53688
54012
 
54013
+ if (segmentsOnHold.length > 0) {
54014
+ nextSegmentStart = nextSegmentStart !== null ? Math.min(nextSegmentStart, segmentsOnHold[0].time) : segmentsOnHold[0].time;
54015
+ }
54016
+
53689
54017
  if (prioritizedNeededSegments.length > 0) {
53690
54018
  nextSegmentStart = nextSegmentStart !== null ? Math.min(nextSegmentStart, prioritizedNeededSegments[0].segment.time) : prioritizedNeededSegments[0].segment.time;
53691
54019
  }
@@ -53783,7 +54111,7 @@ function forceGarbageCollection(currentPosition, bufferingQueue) {
53783
54111
  return (0,from/* from */.D)(cleanedupRanges.map(function (_ref) {
53784
54112
  var start = _ref.start,
53785
54113
  end = _ref.end;
53786
- return bufferingQueue.removeBuffer(start, end);
54114
+ return start >= end ? (0,of.of)(null) : bufferingQueue.removeBuffer(start, end);
53787
54115
  })).pipe((0,concatAll/* concatAll */.u)());
53788
54116
  });
53789
54117
  }
@@ -53882,7 +54210,7 @@ function appendSegmentToBuffer(playbackObserver, segmentBuffer, dataInfos) {
53882
54210
  throw new media_error/* default */.Z("BUFFER_APPEND_ERROR", reason);
53883
54211
  }
53884
54212
 
53885
- return playbackObserver.observe(true).pipe((0,mergeMap/* mergeMap */.z)(function (observation) {
54213
+ return playbackObserver.observe(true).pipe((0,take/* take */.q)(1), (0,mergeMap/* mergeMap */.z)(function (observation) {
53886
54214
  var currentPos = observation.position + observation.wantedTimeOffset;
53887
54215
  return (0,concat/* concat */.z)(forceGarbageCollection(currentPos, segmentBuffer).pipe((0,ignoreElements/* ignoreElements */.l)()), append$).pipe((0,catchError/* catchError */.K)(function (forcedGCError) {
53888
54216
  var reason = forcedGCError instanceof Error ? forcedGCError.toString() : "Could not clean the buffer";
@@ -54241,8 +54569,11 @@ function RepresentationStream(_ref) {
54241
54569
 
54242
54570
  if (status.isBufferFull) {
54243
54571
  var gcedPosition = Math.max(0, wantedStartPosition - UPTO_CURRENT_POSITION_CLEANUP);
54244
- bufferRemoval = segmentBuffer.removeBuffer(0, gcedPosition) // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
54245
- .pipe((0,ignoreElements/* ignoreElements */.l)());
54572
+
54573
+ if (gcedPosition > 0) {
54574
+ bufferRemoval = segmentBuffer.removeBuffer(0, gcedPosition) // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
54575
+ .pipe((0,ignoreElements/* ignoreElements */.l)());
54576
+ }
54246
54577
  }
54247
54578
 
54248
54579
  return status.shouldRefreshManifest ? (0,concat/* concat */.z)((0,of.of)(stream_events_generators/* default.needsManifestRefresh */.Z.needsManifestRefresh()), bufferStatusEvt, bufferRemoval) : (0,concat/* concat */.z)(bufferStatusEvt, bufferRemoval);
@@ -55226,7 +55557,13 @@ function PeriodStream(_ref) {
55226
55557
  return reloadAfterSwitch(period, bufferType, playbackObserver, 0);
55227
55558
  }
55228
55559
 
55229
- cleanBuffer$ = segmentBufferStatus.value.removeBuffer(period.start, period.end == null ? Infinity : period.end);
55560
+ if (period.end === undefined) {
55561
+ cleanBuffer$ = segmentBufferStatus.value.removeBuffer(period.start, Infinity);
55562
+ } else if (period.end <= period.start) {
55563
+ cleanBuffer$ = (0,of.of)(null);
55564
+ } else {
55565
+ cleanBuffer$ = segmentBufferStatus.value.removeBuffer(period.start, period.end);
55566
+ }
55230
55567
  } else {
55231
55568
  if (segmentBufferStatus.type === "uninitialized") {
55232
55569
  segmentBuffersStore.disableSegmentBuffer(bufferType);
@@ -55949,7 +56286,7 @@ function StreamOrchestrator(content, playbackObserver, abrManager, segmentBuffer
55949
56286
  return concat/* concat.apply */.z.apply(void 0, rangesToClean.map(function (_ref4) {
55950
56287
  var start = _ref4.start,
55951
56288
  end = _ref4.end;
55952
- return segmentBuffer.removeBuffer(start, end).pipe((0,ignoreElements/* ignoreElements */.l)());
56289
+ return start >= end ? empty/* EMPTY */.E : segmentBuffer.removeBuffer(start, end).pipe((0,ignoreElements/* ignoreElements */.l)());
55953
56290
  }).concat([playbackObserver.observe(true).pipe((0,take/* take */.q)(1), (0,mergeMap/* mergeMap */.z)(function (observation) {
55954
56291
  return (0,concat/* concat */.z)((0,of.of)(stream_events_generators/* default.needsDecipherabilityFlush */.Z.needsDecipherabilityFlush(observation.position, !observation.isPaused, observation.duration)), (0,defer/* defer */.P)(function () {
55955
56292
  var lastPosition = observation.position + observation.wantedTimeOffset;
@@ -60153,7 +60490,7 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
60153
60490
  videoElement.preload = "auto";
60154
60491
  _this.version =
60155
60492
  /* PLAYER_VERSION */
60156
- "3.27.0-dev.2022032100";
60493
+ "3.27.0";
60157
60494
  _this.log = log/* default */.Z;
60158
60495
  _this.state = "STOPPED";
60159
60496
  _this.videoElement = videoElement;
@@ -61045,25 +61382,8 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
61045
61382
  manifest = _this$_priv_contentIn4.manifest;
61046
61383
 
61047
61384
  if (isDirectFile) {
61048
- // Calculating the "wall-clock time" necessitate to obtain first an offset,
61049
- // and then adding that offset to the HTMLMediaElement's current position.
61050
- // That offset is in most case present inside the Manifest file, yet in
61051
- // directfile mode, the RxPlayer won't parse that file, the browser does it.
61052
- //
61053
- // Thankfully Safari declares a `getStartDate` method allowing to obtain
61054
- // that offset when available. This logic is thus mainly useful when
61055
- // playing HLS contents in directfile mode on Safari.
61056
- var mediaElement = this.videoElement;
61057
-
61058
- if (typeof mediaElement.getStartDate === "function") {
61059
- var startDate = mediaElement.getStartDate();
61060
-
61061
- if (typeof startDate === "number" && !isNaN(startDate)) {
61062
- return startDate + mediaElement.currentTime;
61063
- }
61064
- }
61065
-
61066
- return mediaElement.currentTime;
61385
+ var startDate = getStartDate(this.videoElement);
61386
+ return (startDate !== null && startDate !== void 0 ? startDate : 0) + this.videoElement.currentTime;
61067
61387
  }
61068
61388
 
61069
61389
  if (manifest !== null) {
@@ -61371,6 +61691,8 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
61371
61691
  ;
61372
61692
 
61373
61693
  _proto.seekTo = function seekTo(time) {
61694
+ var _a;
61695
+
61374
61696
  if (this.videoElement === null) {
61375
61697
  throw new Error("Disposed player");
61376
61698
  }
@@ -61400,7 +61722,19 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
61400
61722
  } else if (!(0,is_null_or_undefined/* default */.Z)(timeObj.position)) {
61401
61723
  positionWanted = timeObj.position;
61402
61724
  } else if (!(0,is_null_or_undefined/* default */.Z)(timeObj.wallClockTime)) {
61403
- positionWanted = isDirectFile || manifest === null ? timeObj.wallClockTime : timeObj.wallClockTime - (manifest.availabilityStartTime !== undefined ? manifest.availabilityStartTime : 0);
61725
+ if (manifest !== null) {
61726
+ positionWanted = timeObj.wallClockTime - ((_a = manifest.availabilityStartTime) !== null && _a !== void 0 ? _a : 0);
61727
+ } else if (isDirectFile && this.videoElement !== null) {
61728
+ var startDate = getStartDate(this.videoElement);
61729
+
61730
+ if (startDate !== undefined) {
61731
+ positionWanted = timeObj.wallClockTime - startDate;
61732
+ }
61733
+ }
61734
+
61735
+ if (positionWanted === undefined) {
61736
+ positionWanted = timeObj.wallClockTime;
61737
+ }
61404
61738
  } else {
61405
61739
  throw new Error("invalid time object. You must set one of the " + "following properties: \"relative\", \"position\" or " + "\"wallClockTime\"");
61406
61740
  }
@@ -62892,6 +63226,12 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
62892
63226
  var ast = (_a = manifest.availabilityStartTime) !== null && _a !== void 0 ? _a : 0;
62893
63227
  positionData.wallClockTime = observation.position + ast;
62894
63228
  positionData.liveGap = maximumPosition - observation.position;
63229
+ } else if (isDirectFile && this.videoElement !== null) {
63230
+ var startDate = getStartDate(this.videoElement);
63231
+
63232
+ if (startDate !== undefined) {
63233
+ positionData.wallClockTime = startDate + observation.position;
63234
+ }
62895
63235
  }
62896
63236
 
62897
63237
  this.trigger("positionUpdate", positionData);
@@ -62982,7 +63322,7 @@ var Player = /*#__PURE__*/function (_EventEmitter) {
62982
63322
 
62983
63323
  Player.version =
62984
63324
  /* PLAYER_VERSION */
62985
- "3.27.0-dev.2022032100";
63325
+ "3.27.0";
62986
63326
  /* harmony default export */ var public_api = (Player);
62987
63327
  ;// CONCATENATED MODULE: ./src/core/api/index.ts
62988
63328
  /**