hls.js 1.5.18 → 1.5.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/hls.js CHANGED
@@ -552,7 +552,7 @@
552
552
  // Some browsers don't allow to use bind on console object anyway
553
553
  // fallback to default if needed
554
554
  try {
555
- exportedLogger.log("Debug logs enabled for \"" + id + "\" in hls.js version " + "1.5.18");
555
+ exportedLogger.log("Debug logs enabled for \"" + id + "\" in hls.js version " + "1.5.19");
556
556
  } catch (e) {
557
557
  exportedLogger = fakeLogger;
558
558
  }
@@ -1378,6 +1378,27 @@
1378
1378
  };
1379
1379
  return [baseConfig];
1380
1380
  }
1381
+ function parsePlayReadyWRM(keyBytes) {
1382
+ var keyBytesUtf16 = new Uint16Array(keyBytes.buffer, keyBytes.byteOffset, keyBytes.byteLength / 2);
1383
+ var keyByteStr = String.fromCharCode.apply(null, Array.from(keyBytesUtf16));
1384
+
1385
+ // Parse Playready WRMHeader XML
1386
+ var xmlKeyBytes = keyByteStr.substring(keyByteStr.indexOf('<'), keyByteStr.length);
1387
+ var parser = new DOMParser();
1388
+ var xmlDoc = parser.parseFromString(xmlKeyBytes, 'text/xml');
1389
+ var keyData = xmlDoc.getElementsByTagName('KID')[0];
1390
+ if (keyData) {
1391
+ var keyId = keyData.childNodes[0] ? keyData.childNodes[0].nodeValue : keyData.getAttribute('VALUE');
1392
+ if (keyId) {
1393
+ var keyIdArray = base64Decode(keyId).subarray(0, 16);
1394
+ // KID value in PRO is a base64-encoded little endian GUID interpretation of UUID
1395
+ // KID value in ‘tenc’ is a big endian UUID GUID interpretation of UUID
1396
+ changeEndianness(keyIdArray);
1397
+ return keyIdArray;
1398
+ }
1399
+ }
1400
+ return null;
1401
+ }
1381
1402
 
1382
1403
  function sliceUint8(array, start, end) {
1383
1404
  // @ts-expect-error This polyfills IE11 usage of Uint8Array slice.
@@ -3011,6 +3032,8 @@
3011
3032
  if (keyBytes) {
3012
3033
  switch (this.keyFormat) {
3013
3034
  case KeySystemFormats.WIDEVINE:
3035
+ // Setting `pssh` on this LevelKey/DecryptData allows HLS.js to generate a session using
3036
+ // the playlist-key before the "encrypted" event. (Comment out to only use "encrypted" path.)
3014
3037
  this.pssh = keyBytes;
3015
3038
  // In case of widevine keyID is embedded in PSSH box. Read Key ID.
3016
3039
  if (keyBytes.length >= 22) {
@@ -3020,25 +3043,11 @@
3020
3043
  case KeySystemFormats.PLAYREADY:
3021
3044
  {
3022
3045
  var PlayReadyKeySystemUUID = new Uint8Array([0x9a, 0x04, 0xf0, 0x79, 0x98, 0x40, 0x42, 0x86, 0xab, 0x92, 0xe6, 0x5b, 0xe0, 0x88, 0x5f, 0x95]);
3046
+
3047
+ // Setting `pssh` on this LevelKey/DecryptData allows HLS.js to generate a session using
3048
+ // the playlist-key before the "encrypted" event. (Comment out to only use "encrypted" path.)
3023
3049
  this.pssh = mp4pssh(PlayReadyKeySystemUUID, null, keyBytes);
3024
- var keyBytesUtf16 = new Uint16Array(keyBytes.buffer, keyBytes.byteOffset, keyBytes.byteLength / 2);
3025
- var keyByteStr = String.fromCharCode.apply(null, Array.from(keyBytesUtf16));
3026
-
3027
- // Parse Playready WRMHeader XML
3028
- var xmlKeyBytes = keyByteStr.substring(keyByteStr.indexOf('<'), keyByteStr.length);
3029
- var parser = new DOMParser();
3030
- var xmlDoc = parser.parseFromString(xmlKeyBytes, 'text/xml');
3031
- var keyData = xmlDoc.getElementsByTagName('KID')[0];
3032
- if (keyData) {
3033
- var keyId = keyData.childNodes[0] ? keyData.childNodes[0].nodeValue : keyData.getAttribute('VALUE');
3034
- if (keyId) {
3035
- var keyIdArray = base64Decode(keyId).subarray(0, 16);
3036
- // KID value in PRO is a base64-encoded little endian GUID interpretation of UUID
3037
- // KID value in ‘tenc’ is a big endian UUID GUID interpretation of UUID
3038
- changeEndianness(keyIdArray);
3039
- this.keyId = keyIdArray;
3040
- }
3041
- }
3050
+ this.keyId = parsePlayReadyWRM(keyBytes);
3042
3051
  break;
3043
3052
  }
3044
3053
  default:
@@ -3057,15 +3066,15 @@
3057
3066
 
3058
3067
  // Default behavior: assign a new keyId for each uri
3059
3068
  if (!this.keyId || this.keyId.byteLength !== 16) {
3060
- var _keyId = keyUriToKeyIdMap[this.uri];
3061
- if (!_keyId) {
3069
+ var keyId = keyUriToKeyIdMap[this.uri];
3070
+ if (!keyId) {
3062
3071
  var val = Object.keys(keyUriToKeyIdMap).length % Number.MAX_SAFE_INTEGER;
3063
- _keyId = new Uint8Array(16);
3064
- var dv = new DataView(_keyId.buffer, 12, 4); // Just set the last 4 bytes
3072
+ keyId = new Uint8Array(16);
3073
+ var dv = new DataView(keyId.buffer, 12, 4); // Just set the last 4 bytes
3065
3074
  dv.setUint32(0, val);
3066
- keyUriToKeyIdMap[this.uri] = _keyId;
3075
+ keyUriToKeyIdMap[this.uri] = keyId;
3067
3076
  }
3068
- this.keyId = _keyId;
3077
+ this.keyId = keyId;
3069
3078
  }
3070
3079
  return this;
3071
3080
  };
@@ -5543,15 +5552,16 @@
5543
5552
  delete oldDetails.fragmentHint.endPTS;
5544
5553
  }
5545
5554
  // check if old/new playlists have fragments in common
5546
- // loop through overlapping SN and update startPTS , cc, and duration if any found
5547
- var ccOffset = 0;
5555
+ // loop through overlapping SN and update startPTS, cc, and duration if any found
5548
5556
  var PTSFrag;
5549
- mapFragmentIntersection(oldDetails, newDetails, function (oldFrag, newFrag) {
5550
- if (oldFrag.relurl) {
5551
- // Do not compare CC if the old fragment has no url. This is a level.fragmentHint used by LL-HLS parts.
5552
- // It maybe be off by 1 if it was created before any parts or discontinuity tags were appended to the end
5553
- // of the playlist.
5554
- ccOffset = oldFrag.cc - newFrag.cc;
5557
+ mapFragmentIntersection(oldDetails, newDetails, function (oldFrag, newFrag, newFragIndex, newFragments) {
5558
+ if (newDetails.skippedSegments) {
5559
+ if (newFrag.cc !== oldFrag.cc) {
5560
+ var ccOffset = oldFrag.cc - newFrag.cc;
5561
+ for (var _i = newFragIndex; _i < newFragments.length; _i++) {
5562
+ newFragments[_i].cc += ccOffset;
5563
+ }
5564
+ }
5555
5565
  }
5556
5566
  if (isFiniteNumber(oldFrag.startPTS) && isFiniteNumber(oldFrag.endPTS)) {
5557
5567
  newFrag.start = newFrag.startPTS = oldFrag.startPTS;
@@ -5576,8 +5586,9 @@
5576
5586
  currentInitSegment = oldFrag.initSegment;
5577
5587
  }
5578
5588
  });
5589
+ var newFragments = newDetails.fragments;
5579
5590
  if (currentInitSegment) {
5580
- var fragmentsToCheck = newDetails.fragmentHint ? newDetails.fragments.concat(newDetails.fragmentHint) : newDetails.fragments;
5591
+ var fragmentsToCheck = newDetails.fragmentHint ? newFragments.concat(newDetails.fragmentHint) : newFragments;
5581
5592
  fragmentsToCheck.forEach(function (frag) {
5582
5593
  var _currentInitSegment;
5583
5594
  if (frag && (!frag.initSegment || frag.initSegment.relurl === ((_currentInitSegment = currentInitSegment) == null ? void 0 : _currentInitSegment.relurl))) {
@@ -5586,29 +5597,22 @@
5586
5597
  });
5587
5598
  }
5588
5599
  if (newDetails.skippedSegments) {
5589
- newDetails.deltaUpdateFailed = newDetails.fragments.some(function (frag) {
5600
+ newDetails.deltaUpdateFailed = newFragments.some(function (frag) {
5590
5601
  return !frag;
5591
5602
  });
5592
5603
  if (newDetails.deltaUpdateFailed) {
5593
5604
  logger.warn('[level-helper] Previous playlist missing segments skipped in delta playlist');
5594
- for (var _i = newDetails.skippedSegments; _i--;) {
5595
- newDetails.fragments.shift();
5605
+ for (var _i2 = newDetails.skippedSegments; _i2--;) {
5606
+ newFragments.shift();
5607
+ }
5608
+ newDetails.startSN = newFragments[0].sn;
5609
+ } else {
5610
+ if (newDetails.canSkipDateRanges) {
5611
+ newDetails.dateRanges = mergeDateRanges(oldDetails.dateRanges, newDetails.dateRanges, newDetails.recentlyRemovedDateranges);
5596
5612
  }
5597
- newDetails.startSN = newDetails.fragments[0].sn;
5598
- newDetails.startCC = newDetails.fragments[0].cc;
5599
- } else if (newDetails.canSkipDateRanges) {
5600
- newDetails.dateRanges = mergeDateRanges(oldDetails.dateRanges, newDetails.dateRanges, newDetails.recentlyRemovedDateranges);
5601
- }
5602
- }
5603
- var newFragments = newDetails.fragments;
5604
- if (ccOffset) {
5605
- logger.warn('discontinuity sliding from playlist, take drift into account');
5606
- for (var _i2 = 0; _i2 < newFragments.length; _i2++) {
5607
- newFragments[_i2].cc += ccOffset;
5608
5613
  }
5609
- }
5610
- if (newDetails.skippedSegments) {
5611
5614
  newDetails.startCC = newDetails.fragments[0].cc;
5615
+ newDetails.endCC = newFragments[newFragments.length - 1].cc;
5612
5616
  }
5613
5617
 
5614
5618
  // Merge parts
@@ -5692,7 +5696,7 @@
5692
5696
  _newFrag = newDetails.fragments[i] = _oldFrag;
5693
5697
  }
5694
5698
  if (_oldFrag && _newFrag) {
5695
- intersectionFn(_oldFrag, _newFrag);
5699
+ intersectionFn(_oldFrag, _newFrag, i, newFrags);
5696
5700
  }
5697
5701
  }
5698
5702
  }
@@ -22598,6 +22602,7 @@
22598
22602
  */
22599
22603
  var EMEController = /*#__PURE__*/function () {
22600
22604
  function EMEController(hls) {
22605
+ var _this = this;
22601
22606
  this.hls = void 0;
22602
22607
  this.config = void 0;
22603
22608
  this.media = null;
@@ -22607,12 +22612,161 @@
22607
22612
  this.mediaKeySessions = [];
22608
22613
  this.keyIdToKeySessionPromise = {};
22609
22614
  this.setMediaKeysQueue = EMEController.CDMCleanupPromise ? [EMEController.CDMCleanupPromise] : [];
22610
- this.onMediaEncrypted = this._onMediaEncrypted.bind(this);
22611
- this.onWaitingForKey = this._onWaitingForKey.bind(this);
22612
22615
  this.debug = logger.debug.bind(logger, LOGGER_PREFIX);
22613
22616
  this.log = logger.log.bind(logger, LOGGER_PREFIX);
22614
22617
  this.warn = logger.warn.bind(logger, LOGGER_PREFIX);
22615
22618
  this.error = logger.error.bind(logger, LOGGER_PREFIX);
22619
+ this.onMediaEncrypted = function (event) {
22620
+ var initDataType = event.initDataType,
22621
+ initData = event.initData;
22622
+ var logMessage = "\"" + event.type + "\" event: init data type: \"" + initDataType + "\"";
22623
+ _this.debug(logMessage);
22624
+
22625
+ // Ignore event when initData is null
22626
+ if (initData === null) {
22627
+ return;
22628
+ }
22629
+ if (!_this.keyFormatPromise) {
22630
+ var keySystems = Object.keys(_this.keySystemAccessPromises);
22631
+ if (!keySystems.length) {
22632
+ keySystems = getKeySystemsForConfig(_this.config);
22633
+ }
22634
+ var keyFormats = keySystems.map(keySystemDomainToKeySystemFormat).filter(function (k) {
22635
+ return !!k;
22636
+ });
22637
+ _this.keyFormatPromise = _this.getKeyFormatPromise(keyFormats);
22638
+ }
22639
+ _this.keyFormatPromise.then(function (keySystemFormat) {
22640
+ var keySystem = keySystemFormatToKeySystemDomain(keySystemFormat);
22641
+ var keyId;
22642
+ var keySystemDomain;
22643
+ if (initDataType === 'sinf') {
22644
+ if (keySystem !== KeySystems.FAIRPLAY) {
22645
+ _this.warn("Ignoring unexpected \"" + event.type + "\" event with init data type: \"" + initDataType + "\" for selected key-system " + keySystem);
22646
+ return;
22647
+ }
22648
+ // Match sinf keyId to playlist skd://keyId=
22649
+ var json = bin2str(new Uint8Array(initData));
22650
+ try {
22651
+ var sinf = base64Decode(JSON.parse(json).sinf);
22652
+ var tenc = parseSinf(sinf);
22653
+ if (!tenc) {
22654
+ throw new Error("'schm' box missing or not cbcs/cenc with schi > tenc");
22655
+ }
22656
+ keyId = tenc.subarray(8, 24);
22657
+ keySystemDomain = KeySystems.FAIRPLAY;
22658
+ } catch (error) {
22659
+ _this.warn(logMessage + " Failed to parse sinf: " + error);
22660
+ return;
22661
+ }
22662
+ } else {
22663
+ if (keySystem !== KeySystems.WIDEVINE && keySystem !== KeySystems.PLAYREADY) {
22664
+ _this.warn("Ignoring unexpected \"" + event.type + "\" event with init data type: \"" + initDataType + "\" for selected key-system " + keySystem);
22665
+ return;
22666
+ }
22667
+ // Support Widevine/PlayReady clear-lead key-session creation (otherwise depend on playlist keys)
22668
+ var psshResults = parseMultiPssh(initData);
22669
+ var psshInfos = psshResults.filter(function (pssh) {
22670
+ return !!pssh.systemId && keySystemIdToKeySystemDomain(pssh.systemId) === keySystem;
22671
+ });
22672
+ if (psshInfos.length > 1) {
22673
+ _this.warn(logMessage + " Using first of " + psshInfos.length + " pssh found for selected key-system " + keySystem);
22674
+ }
22675
+ var psshInfo = psshInfos[0];
22676
+ if (!psshInfo) {
22677
+ if (psshResults.length === 0 || psshResults.some(function (pssh) {
22678
+ return !pssh.systemId;
22679
+ })) {
22680
+ _this.warn(logMessage + " contains incomplete or invalid pssh data");
22681
+ } else {
22682
+ _this.log("ignoring " + logMessage + " for " + psshResults.map(function (pssh) {
22683
+ return keySystemIdToKeySystemDomain(pssh.systemId);
22684
+ }).join(',') + " pssh data in favor of playlist keys");
22685
+ }
22686
+ return;
22687
+ }
22688
+ keySystemDomain = keySystemIdToKeySystemDomain(psshInfo.systemId);
22689
+ if (psshInfo.version === 0 && psshInfo.data) {
22690
+ if (keySystemDomain === KeySystems.WIDEVINE) {
22691
+ var offset = psshInfo.data.length - 22;
22692
+ keyId = psshInfo.data.subarray(offset, offset + 16);
22693
+ } else if (keySystemDomain === KeySystems.PLAYREADY) {
22694
+ keyId = parsePlayReadyWRM(psshInfo.data);
22695
+ }
22696
+ }
22697
+ }
22698
+ if (!keySystemDomain || !keyId) {
22699
+ _this.log("Unable to handle " + logMessage + " with key-system " + keySystem);
22700
+ return;
22701
+ }
22702
+ var keyIdHex = Hex.hexDump(keyId);
22703
+ var keyIdToKeySessionPromise = _this.keyIdToKeySessionPromise,
22704
+ mediaKeySessions = _this.mediaKeySessions;
22705
+ var keySessionContextPromise = keyIdToKeySessionPromise[keyIdHex];
22706
+ var _loop = function _loop() {
22707
+ // Match playlist key
22708
+ var keyContext = mediaKeySessions[i];
22709
+ var decryptdata = keyContext.decryptdata;
22710
+ if (!decryptdata.keyId) {
22711
+ return 0; // continue
22712
+ }
22713
+ var oldKeyIdHex = Hex.hexDump(decryptdata.keyId);
22714
+ if (keyIdHex === oldKeyIdHex || decryptdata.uri.replace(/-/g, '').indexOf(keyIdHex) !== -1) {
22715
+ keySessionContextPromise = keyIdToKeySessionPromise[oldKeyIdHex];
22716
+ if (decryptdata.pssh) {
22717
+ return 1; // break
22718
+ }
22719
+ delete keyIdToKeySessionPromise[oldKeyIdHex];
22720
+ decryptdata.pssh = new Uint8Array(initData);
22721
+ decryptdata.keyId = keyId;
22722
+ keySessionContextPromise = keyIdToKeySessionPromise[keyIdHex] = keySessionContextPromise.then(function () {
22723
+ return _this.generateRequestWithPreferredKeySession(keyContext, initDataType, initData, 'encrypted-event-key-match');
22724
+ });
22725
+ keySessionContextPromise.catch(function (error) {
22726
+ return _this.handleError(error);
22727
+ });
22728
+ return 1; // break
22729
+ }
22730
+ },
22731
+ _ret;
22732
+ for (var i = 0; i < mediaKeySessions.length; i++) {
22733
+ _ret = _loop();
22734
+ if (_ret === 0) continue;
22735
+ if (_ret === 1) break;
22736
+ }
22737
+ if (!keySessionContextPromise) {
22738
+ if (keySystemDomain !== keySystem) {
22739
+ _this.log("Ignoring \"" + logMessage + "\" with " + keySystemDomain + " init data for selected key-system " + keySystem);
22740
+ return;
22741
+ }
22742
+ // "Clear-lead" (misc key not encountered in playlist)
22743
+ keySessionContextPromise = keyIdToKeySessionPromise[keyIdHex] = _this.getKeySystemSelectionPromise([keySystemDomain]).then(function (_ref) {
22744
+ var _keySystemToKeySystem;
22745
+ var keySystem = _ref.keySystem,
22746
+ mediaKeys = _ref.mediaKeys;
22747
+ _this.throwIfDestroyed();
22748
+ var decryptdata = new LevelKey('ISO-23001-7', keyIdHex, (_keySystemToKeySystem = keySystemDomainToKeySystemFormat(keySystem)) != null ? _keySystemToKeySystem : '');
22749
+ decryptdata.pssh = new Uint8Array(initData);
22750
+ decryptdata.keyId = keyId;
22751
+ return _this.attemptSetMediaKeys(keySystem, mediaKeys).then(function () {
22752
+ _this.throwIfDestroyed();
22753
+ var keySessionContext = _this.createMediaKeySessionContext({
22754
+ decryptdata: decryptdata,
22755
+ keySystem: keySystem,
22756
+ mediaKeys: mediaKeys
22757
+ });
22758
+ return _this.generateRequestWithPreferredKeySession(keySessionContext, initDataType, initData, 'encrypted-event-no-match');
22759
+ });
22760
+ });
22761
+ keySessionContextPromise.catch(function (error) {
22762
+ return _this.handleError(error);
22763
+ });
22764
+ }
22765
+ });
22766
+ };
22767
+ this.onWaitingForKey = function (event) {
22768
+ _this.log("\"" + event.type + "\" event");
22769
+ };
22616
22770
  this.hls = hls;
22617
22771
  this.config = hls.config;
22618
22772
  this.registerListeners();
@@ -22627,9 +22781,9 @@
22627
22781
  config.licenseXhrSetup = config.licenseResponseCallback = undefined;
22628
22782
  config.drmSystems = config.drmSystemOptions = {};
22629
22783
  // @ts-ignore
22630
- this.hls = this.onMediaEncrypted = this.onWaitingForKey = this.keyIdToKeySessionPromise = null;
22784
+ this.hls = this.config = this.keyIdToKeySessionPromise = null;
22631
22785
  // @ts-ignore
22632
- this.config = null;
22786
+ this.onMediaEncrypted = this.onWaitingForKey = null;
22633
22787
  };
22634
22788
  _proto.registerListeners = function registerListeners() {
22635
22789
  this.hls.on(Events.MEDIA_ATTACHED, this.onMediaAttached, this);
@@ -22656,7 +22810,13 @@
22656
22810
  if (keySystem === KeySystems.WIDEVINE && widevineLicenseUrl) {
22657
22811
  return widevineLicenseUrl;
22658
22812
  }
22659
- throw new Error("no license server URL configured for key-system \"" + keySystem + "\"");
22813
+ };
22814
+ _proto.getLicenseServerUrlOrThrow = function getLicenseServerUrlOrThrow(keySystem) {
22815
+ var url = this.getLicenseServerUrl(keySystem);
22816
+ if (url === undefined) {
22817
+ throw new Error("no license server URL configured for key-system \"" + keySystem + "\"");
22818
+ }
22819
+ return url;
22660
22820
  };
22661
22821
  _proto.getServerCertificateUrl = function getServerCertificateUrl(keySystem) {
22662
22822
  var drmSystems = this.config.drmSystems;
@@ -22668,7 +22828,7 @@
22668
22828
  }
22669
22829
  };
22670
22830
  _proto.attemptKeySystemAccess = function attemptKeySystemAccess(keySystemsToAttempt) {
22671
- var _this = this;
22831
+ var _this2 = this;
22672
22832
  var levels = this.hls.levels;
22673
22833
  var uniqueCodec = function uniqueCodec(value, i, a) {
22674
22834
  return !!value && a.indexOf(value) === i;
@@ -22685,7 +22845,7 @@
22685
22845
  return new Promise(function (resolve, reject) {
22686
22846
  var attempt = function attempt(keySystems) {
22687
22847
  var keySystem = keySystems.shift();
22688
- _this.getMediaKeysPromise(keySystem, audioCodecs, videoCodecs).then(function (mediaKeys) {
22848
+ _this2.getMediaKeysPromise(keySystem, audioCodecs, videoCodecs).then(function (mediaKeys) {
22689
22849
  return resolve({
22690
22850
  keySystem: keySystem,
22691
22851
  mediaKeys: mediaKeys
@@ -22720,7 +22880,7 @@
22720
22880
  return requestMediaKeySystemAccessFunc(keySystem, supportedConfigurations);
22721
22881
  };
22722
22882
  _proto.getMediaKeysPromise = function getMediaKeysPromise(keySystem, audioCodecs, videoCodecs) {
22723
- var _this2 = this;
22883
+ var _this3 = this;
22724
22884
  // This can throw, but is caught in event handler callpath
22725
22885
  var mediaKeySystemConfigs = getSupportedMediaKeySystemConfigurations(keySystem, audioCodecs, videoCodecs, this.config.drmSystemOptions);
22726
22886
  var keySystemAccessPromises = this.keySystemAccessPromises[keySystem];
@@ -22732,23 +22892,23 @@
22732
22892
  keySystemAccess: keySystemAccess
22733
22893
  };
22734
22894
  keySystemAccess.catch(function (error) {
22735
- _this2.log("Failed to obtain access to key-system \"" + keySystem + "\": " + error);
22895
+ _this3.log("Failed to obtain access to key-system \"" + keySystem + "\": " + error);
22736
22896
  });
22737
22897
  return keySystemAccess.then(function (mediaKeySystemAccess) {
22738
- _this2.log("Access for key-system \"" + mediaKeySystemAccess.keySystem + "\" obtained");
22739
- var certificateRequest = _this2.fetchServerCertificate(keySystem);
22740
- _this2.log("Create media-keys for \"" + keySystem + "\"");
22898
+ _this3.log("Access for key-system \"" + mediaKeySystemAccess.keySystem + "\" obtained");
22899
+ var certificateRequest = _this3.fetchServerCertificate(keySystem);
22900
+ _this3.log("Create media-keys for \"" + keySystem + "\"");
22741
22901
  _keySystemAccessPromises.mediaKeys = mediaKeySystemAccess.createMediaKeys().then(function (mediaKeys) {
22742
- _this2.log("Media-keys created for \"" + keySystem + "\"");
22902
+ _this3.log("Media-keys created for \"" + keySystem + "\"");
22743
22903
  return certificateRequest.then(function (certificate) {
22744
22904
  if (certificate) {
22745
- return _this2.setMediaKeysServerCertificate(mediaKeys, keySystem, certificate);
22905
+ return _this3.setMediaKeysServerCertificate(mediaKeys, keySystem, certificate);
22746
22906
  }
22747
22907
  return mediaKeys;
22748
22908
  });
22749
22909
  });
22750
22910
  _keySystemAccessPromises.mediaKeys.catch(function (error) {
22751
- _this2.error("Failed to create media-keys for \"" + keySystem + "\"}: " + error);
22911
+ _this3.error("Failed to create media-keys for \"" + keySystem + "\"}: " + error);
22752
22912
  });
22753
22913
  return _keySystemAccessPromises.mediaKeys;
22754
22914
  });
@@ -22757,10 +22917,10 @@
22757
22917
  return keySystemAccessPromises.mediaKeys;
22758
22918
  });
22759
22919
  };
22760
- _proto.createMediaKeySessionContext = function createMediaKeySessionContext(_ref) {
22761
- var decryptdata = _ref.decryptdata,
22762
- keySystem = _ref.keySystem,
22763
- mediaKeys = _ref.mediaKeys;
22920
+ _proto.createMediaKeySessionContext = function createMediaKeySessionContext(_ref2) {
22921
+ var decryptdata = _ref2.decryptdata,
22922
+ keySystem = _ref2.keySystem,
22923
+ mediaKeys = _ref2.mediaKeys;
22764
22924
  this.log("Creating key-system session \"" + keySystem + "\" keyId: " + Hex.hexDump(decryptdata.keyId || []));
22765
22925
  var mediaKeysSession = mediaKeys.createSession();
22766
22926
  var mediaKeySessionContext = {
@@ -22809,14 +22969,14 @@
22809
22969
  return this.keyFormatPromise;
22810
22970
  };
22811
22971
  _proto.getKeyFormatPromise = function getKeyFormatPromise(keyFormats) {
22812
- var _this3 = this;
22972
+ var _this4 = this;
22813
22973
  return new Promise(function (resolve, reject) {
22814
- var keySystemsInConfig = getKeySystemsForConfig(_this3.config);
22974
+ var keySystemsInConfig = getKeySystemsForConfig(_this4.config);
22815
22975
  var keySystemsToAttempt = keyFormats.map(keySystemFormatToKeySystemDomain).filter(function (value) {
22816
22976
  return !!value && keySystemsInConfig.indexOf(value) !== -1;
22817
22977
  });
22818
- return _this3.getKeySystemSelectionPromise(keySystemsToAttempt).then(function (_ref2) {
22819
- var keySystem = _ref2.keySystem;
22978
+ return _this4.getKeySystemSelectionPromise(keySystemsToAttempt).then(function (_ref3) {
22979
+ var keySystem = _ref3.keySystem;
22820
22980
  var keySystemFormat = keySystemDomainToKeySystemFormat(keySystem);
22821
22981
  if (keySystemFormat) {
22822
22982
  resolve(keySystemFormat);
@@ -22827,31 +22987,31 @@
22827
22987
  });
22828
22988
  };
22829
22989
  _proto.loadKey = function loadKey(data) {
22830
- var _this4 = this;
22990
+ var _this5 = this;
22831
22991
  var decryptdata = data.keyInfo.decryptdata;
22832
22992
  var keyId = this.getKeyIdString(decryptdata);
22833
22993
  var keyDetails = "(keyId: " + keyId + " format: \"" + decryptdata.keyFormat + "\" method: " + decryptdata.method + " uri: " + decryptdata.uri + ")";
22834
22994
  this.log("Starting session for key " + keyDetails);
22835
22995
  var keySessionContextPromise = this.keyIdToKeySessionPromise[keyId];
22836
22996
  if (!keySessionContextPromise) {
22837
- keySessionContextPromise = this.keyIdToKeySessionPromise[keyId] = this.getKeySystemForKeyPromise(decryptdata).then(function (_ref3) {
22838
- var keySystem = _ref3.keySystem,
22839
- mediaKeys = _ref3.mediaKeys;
22840
- _this4.throwIfDestroyed();
22841
- _this4.log("Handle encrypted media sn: " + data.frag.sn + " " + data.frag.type + ": " + data.frag.level + " using key " + keyDetails);
22842
- return _this4.attemptSetMediaKeys(keySystem, mediaKeys).then(function () {
22843
- _this4.throwIfDestroyed();
22844
- var keySessionContext = _this4.createMediaKeySessionContext({
22997
+ keySessionContextPromise = this.keyIdToKeySessionPromise[keyId] = this.getKeySystemForKeyPromise(decryptdata).then(function (_ref4) {
22998
+ var keySystem = _ref4.keySystem,
22999
+ mediaKeys = _ref4.mediaKeys;
23000
+ _this5.throwIfDestroyed();
23001
+ _this5.log("Handle encrypted media sn: " + data.frag.sn + " " + data.frag.type + ": " + data.frag.level + " using key " + keyDetails);
23002
+ return _this5.attemptSetMediaKeys(keySystem, mediaKeys).then(function () {
23003
+ _this5.throwIfDestroyed();
23004
+ var keySessionContext = _this5.createMediaKeySessionContext({
22845
23005
  keySystem: keySystem,
22846
23006
  mediaKeys: mediaKeys,
22847
23007
  decryptdata: decryptdata
22848
23008
  });
22849
23009
  var scheme = 'cenc';
22850
- return _this4.generateRequestWithPreferredKeySession(keySessionContext, scheme, decryptdata.pssh, 'playlist-key');
23010
+ return _this5.generateRequestWithPreferredKeySession(keySessionContext, scheme, decryptdata.pssh, 'playlist-key');
22851
23011
  });
22852
23012
  });
22853
23013
  keySessionContextPromise.catch(function (error) {
22854
- return _this4.handleError(error);
23014
+ return _this5.handleError(error);
22855
23015
  });
22856
23016
  }
22857
23017
  return keySessionContextPromise;
@@ -22902,121 +23062,6 @@
22902
23062
  }
22903
23063
  return this.attemptKeySystemAccess(keySystemsToAttempt);
22904
23064
  };
22905
- _proto._onMediaEncrypted = function _onMediaEncrypted(event) {
22906
- var _this5 = this;
22907
- var initDataType = event.initDataType,
22908
- initData = event.initData;
22909
- var logMessage = "\"" + event.type + "\" event: init data type: \"" + initDataType + "\"";
22910
- this.debug(logMessage);
22911
-
22912
- // Ignore event when initData is null
22913
- if (initData === null) {
22914
- return;
22915
- }
22916
- var keyId;
22917
- var keySystemDomain;
22918
- if (initDataType === 'sinf' && this.config.drmSystems[KeySystems.FAIRPLAY]) {
22919
- // Match sinf keyId to playlist skd://keyId=
22920
- var json = bin2str(new Uint8Array(initData));
22921
- try {
22922
- var sinf = base64Decode(JSON.parse(json).sinf);
22923
- var tenc = parseSinf(new Uint8Array(sinf));
22924
- if (!tenc) {
22925
- throw new Error("'schm' box missing or not cbcs/cenc with schi > tenc");
22926
- }
22927
- keyId = tenc.subarray(8, 24);
22928
- keySystemDomain = KeySystems.FAIRPLAY;
22929
- } catch (error) {
22930
- this.warn(logMessage + " Failed to parse sinf: " + error);
22931
- return;
22932
- }
22933
- } else {
22934
- // Support Widevine clear-lead key-session creation (otherwise depend on playlist keys)
22935
- var psshResults = parseMultiPssh(initData);
22936
- var psshInfo = psshResults.filter(function (pssh) {
22937
- return pssh.systemId === KeySystemIds.WIDEVINE;
22938
- })[0];
22939
- if (!psshInfo) {
22940
- if (psshResults.length === 0 || psshResults.some(function (pssh) {
22941
- return !pssh.systemId;
22942
- })) {
22943
- this.warn(logMessage + " contains incomplete or invalid pssh data");
22944
- } else {
22945
- this.log("ignoring " + logMessage + " for " + psshResults.map(function (pssh) {
22946
- return keySystemIdToKeySystemDomain(pssh.systemId);
22947
- }).join(',') + " pssh data in favor of playlist keys");
22948
- }
22949
- return;
22950
- }
22951
- keySystemDomain = keySystemIdToKeySystemDomain(psshInfo.systemId);
22952
- if (psshInfo.version === 0 && psshInfo.data) {
22953
- var offset = psshInfo.data.length - 22;
22954
- keyId = psshInfo.data.subarray(offset, offset + 16);
22955
- }
22956
- }
22957
- if (!keySystemDomain || !keyId) {
22958
- return;
22959
- }
22960
- var keyIdHex = Hex.hexDump(keyId);
22961
- var keyIdToKeySessionPromise = this.keyIdToKeySessionPromise,
22962
- mediaKeySessions = this.mediaKeySessions;
22963
- var keySessionContextPromise = keyIdToKeySessionPromise[keyIdHex];
22964
- var _loop = function _loop() {
22965
- // Match playlist key
22966
- var keyContext = mediaKeySessions[i];
22967
- var decryptdata = keyContext.decryptdata;
22968
- if (!decryptdata.keyId) {
22969
- return 0; // continue
22970
- }
22971
- var oldKeyIdHex = Hex.hexDump(decryptdata.keyId);
22972
- if (keyIdHex === oldKeyIdHex || decryptdata.uri.replace(/-/g, '').indexOf(keyIdHex) !== -1) {
22973
- keySessionContextPromise = keyIdToKeySessionPromise[oldKeyIdHex];
22974
- if (decryptdata.pssh) {
22975
- return 1; // break
22976
- }
22977
- delete keyIdToKeySessionPromise[oldKeyIdHex];
22978
- decryptdata.pssh = new Uint8Array(initData);
22979
- decryptdata.keyId = keyId;
22980
- keySessionContextPromise = keyIdToKeySessionPromise[keyIdHex] = keySessionContextPromise.then(function () {
22981
- return _this5.generateRequestWithPreferredKeySession(keyContext, initDataType, initData, 'encrypted-event-key-match');
22982
- });
22983
- return 1; // break
22984
- }
22985
- },
22986
- _ret;
22987
- for (var i = 0; i < mediaKeySessions.length; i++) {
22988
- _ret = _loop();
22989
- if (_ret === 0) continue;
22990
- if (_ret === 1) break;
22991
- }
22992
- if (!keySessionContextPromise) {
22993
- // Clear-lead key (not encountered in playlist)
22994
- keySessionContextPromise = keyIdToKeySessionPromise[keyIdHex] = this.getKeySystemSelectionPromise([keySystemDomain]).then(function (_ref4) {
22995
- var _keySystemToKeySystem;
22996
- var keySystem = _ref4.keySystem,
22997
- mediaKeys = _ref4.mediaKeys;
22998
- _this5.throwIfDestroyed();
22999
- var decryptdata = new LevelKey('ISO-23001-7', keyIdHex, (_keySystemToKeySystem = keySystemDomainToKeySystemFormat(keySystem)) != null ? _keySystemToKeySystem : '');
23000
- decryptdata.pssh = new Uint8Array(initData);
23001
- decryptdata.keyId = keyId;
23002
- return _this5.attemptSetMediaKeys(keySystem, mediaKeys).then(function () {
23003
- _this5.throwIfDestroyed();
23004
- var keySessionContext = _this5.createMediaKeySessionContext({
23005
- decryptdata: decryptdata,
23006
- keySystem: keySystem,
23007
- mediaKeys: mediaKeys
23008
- });
23009
- return _this5.generateRequestWithPreferredKeySession(keySessionContext, initDataType, initData, 'encrypted-event-no-match');
23010
- });
23011
- });
23012
- }
23013
- keySessionContextPromise.catch(function (error) {
23014
- return _this5.handleError(error);
23015
- });
23016
- };
23017
- _proto._onWaitingForKey = function _onWaitingForKey(event) {
23018
- this.log("\"" + event.type + "\" event");
23019
- };
23020
23065
  _proto.attemptSetMediaKeys = function attemptSetMediaKeys(keySystem, mediaKeys) {
23021
23066
  var _this6 = this;
23022
23067
  var queue = this.setMediaKeysQueue.slice();
@@ -23319,7 +23364,7 @@
23319
23364
  var _this12 = this;
23320
23365
  var keyLoadPolicy = this.config.keyLoadPolicy.default;
23321
23366
  return new Promise(function (resolve, reject) {
23322
- var url = _this12.getLicenseServerUrl(keySessionContext.keySystem);
23367
+ var url = _this12.getLicenseServerUrlOrThrow(keySessionContext.keySystem);
23323
23368
  _this12.log("Sending license request to URL: " + url);
23324
23369
  var xhr = new XMLHttpRequest();
23325
23370
  xhr.responseType = 'arraybuffer';
@@ -23388,6 +23433,8 @@
23388
23433
 
23389
23434
  // keep reference of media
23390
23435
  this.media = media;
23436
+ media.removeEventListener('encrypted', this.onMediaEncrypted);
23437
+ media.removeEventListener('waitingforkey', this.onWaitingForKey);
23391
23438
  media.addEventListener('encrypted', this.onMediaEncrypted);
23392
23439
  media.addEventListener('waitingforkey', this.onWaitingForKey);
23393
23440
  };
@@ -26807,7 +26854,7 @@
26807
26854
  };
26808
26855
  _proto.load = function load(frag) {
26809
26856
  var _this2 = this;
26810
- if (!frag.decryptdata && frag.encrypted && this.emeController) {
26857
+ if (!frag.decryptdata && frag.encrypted && this.emeController && this.config.emeEnabled) {
26811
26858
  // Multiple keys, but none selected, resolve in eme-controller
26812
26859
  return this.emeController.selectKeySystemFormat(frag).then(function (keySystemFormat) {
26813
26860
  return _this2.loadInternal(frag, keySystemFormat);
@@ -29322,7 +29369,7 @@
29322
29369
  * Get the video-dev/hls.js package version.
29323
29370
  */
29324
29371
  function get() {
29325
- return "1.5.18";
29372
+ return "1.5.19";
29326
29373
  }
29327
29374
  }, {
29328
29375
  key: "Events",