hls.js 1.5.14-0.canary.10555 → 1.5.14-0.canary.10559

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
@@ -523,7 +523,7 @@
523
523
  // Some browsers don't allow to use bind on console object anyway
524
524
  // fallback to default if needed
525
525
  try {
526
- newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.5.14-0.canary.10555");
526
+ newLogger.log("Debug logs enabled for \"" + context + "\" in hls.js version " + "1.5.14-0.canary.10559");
527
527
  } catch (e) {
528
528
  /* log fn threw an exception. All logger methods are no-ops. */
529
529
  return createLogger();
@@ -1458,15 +1458,19 @@
1458
1458
 
1459
1459
  // System IDs for which we can extract a key ID from "encrypted" event PSSH
1460
1460
  var KeySystemIds = {
1461
+ CENC: "1077efecc0b24d02ace33c1e52e2fb4b",
1462
+ CLEARKEY: "e2719d58a985b3c9781ab030af78d30e",
1463
+ FAIRPLAY: "94ce86fb07ff4f43adb893d2fa968ca2",
1464
+ PLAYREADY: "9a04f07998404286ab92e65be0885f95",
1461
1465
  WIDEVINE: "edef8ba979d64acea3c827dcd51d21ed"
1462
1466
  };
1463
1467
  function keySystemIdToKeySystemDomain(systemId) {
1464
1468
  if (systemId === KeySystemIds.WIDEVINE) {
1465
1469
  return KeySystems.WIDEVINE;
1466
- // } else if (systemId === KeySystemIds.PLAYREADY) {
1467
- // return KeySystems.PLAYREADY;
1468
- // } else if (systemId === KeySystemIds.CENC || systemId === KeySystemIds.CLEARKEY) {
1469
- // return KeySystems.CLEARKEY;
1470
+ } else if (systemId === KeySystemIds.PLAYREADY) {
1471
+ return KeySystems.PLAYREADY;
1472
+ } else if (systemId === KeySystemIds.CENC || systemId === KeySystemIds.CLEARKEY) {
1473
+ return KeySystems.CLEARKEY;
1470
1474
  }
1471
1475
  }
1472
1476
  function keySystemDomainToKeySystemFormat(keySystem) {
@@ -2081,7 +2085,6 @@
2081
2085
  return findBox(sinf, ['schi', 'tenc'])[0];
2082
2086
  }
2083
2087
  }
2084
- logger.error("[eme] missing 'schm' box");
2085
2088
  return null;
2086
2089
  }
2087
2090
 
@@ -2751,43 +2754,77 @@
2751
2754
  // 16 bytes
2752
2755
  kidCount, kids, dataSize, data || new Uint8Array());
2753
2756
  }
2754
- function parsePssh(initData) {
2755
- if (!(initData instanceof ArrayBuffer) || initData.byteLength < 32) {
2756
- return null;
2757
+ function parseMultiPssh(initData) {
2758
+ var results = [];
2759
+ if (initData instanceof ArrayBuffer) {
2760
+ var length = initData.byteLength;
2761
+ var offset = 0;
2762
+ while (offset + 32 < length) {
2763
+ var view = new DataView(initData, offset);
2764
+ var pssh = parsePssh(view);
2765
+ results.push(pssh);
2766
+ offset += pssh.size;
2767
+ }
2757
2768
  }
2758
- var result = {
2759
- version: 0,
2760
- systemId: '',
2761
- kids: null,
2762
- data: null
2763
- };
2764
- var view = new DataView(initData);
2765
- var boxSize = view.getUint32(0);
2766
- if (initData.byteLength !== boxSize && boxSize > 44) {
2767
- return null;
2769
+ return results;
2770
+ }
2771
+ function parsePssh(view) {
2772
+ var size = view.getUint32(0);
2773
+ var offset = view.byteOffset;
2774
+ var length = view.byteLength;
2775
+ if (length < size) {
2776
+ return {
2777
+ offset: offset,
2778
+ size: length
2779
+ };
2768
2780
  }
2769
2781
  var type = view.getUint32(4);
2770
2782
  if (type !== 0x70737368) {
2771
- return null;
2783
+ return {
2784
+ offset: offset,
2785
+ size: size
2786
+ };
2772
2787
  }
2773
- result.version = view.getUint32(8) >>> 24;
2774
- if (result.version > 1) {
2775
- return null;
2788
+ var version = view.getUint32(8) >>> 24;
2789
+ if (version !== 0 && version !== 1) {
2790
+ return {
2791
+ offset: offset,
2792
+ size: size
2793
+ };
2776
2794
  }
2777
- result.systemId = Hex.hexDump(new Uint8Array(initData, 12, 16));
2795
+ var buffer = view.buffer;
2796
+ var systemId = Hex.hexDump(new Uint8Array(buffer, offset + 12, 16));
2778
2797
  var dataSizeOrKidCount = view.getUint32(28);
2779
- if (result.version === 0) {
2780
- if (boxSize - 32 < dataSizeOrKidCount) {
2781
- return null;
2798
+ var kids = null;
2799
+ var data = null;
2800
+ if (version === 0) {
2801
+ if (size - 32 < dataSizeOrKidCount || dataSizeOrKidCount < 22) {
2802
+ return {
2803
+ offset: offset,
2804
+ size: size
2805
+ };
2782
2806
  }
2783
- result.data = new Uint8Array(initData, 32, dataSizeOrKidCount);
2784
- } else if (result.version === 1) {
2785
- result.kids = [];
2807
+ data = new Uint8Array(buffer, offset + 32, dataSizeOrKidCount);
2808
+ } else if (version === 1) {
2809
+ if (!dataSizeOrKidCount || length < offset + 32 + dataSizeOrKidCount * 16 + 16) {
2810
+ return {
2811
+ offset: offset,
2812
+ size: size
2813
+ };
2814
+ }
2815
+ kids = [];
2786
2816
  for (var i = 0; i < dataSizeOrKidCount; i++) {
2787
- result.kids.push(new Uint8Array(initData, 32 + i * 16, 16));
2817
+ kids.push(new Uint8Array(buffer, offset + 32 + i * 16, 16));
2788
2818
  }
2789
2819
  }
2790
- return result;
2820
+ return {
2821
+ version: version,
2822
+ systemId: systemId,
2823
+ kids: kids,
2824
+ data: data,
2825
+ offset: offset,
2826
+ size: size
2827
+ };
2791
2828
  }
2792
2829
 
2793
2830
  var keyUriToKeyIdMap = {};
@@ -17325,7 +17362,7 @@
17325
17362
  return !remuxResult.audio && !remuxResult.video && !remuxResult.text && !remuxResult.id3 && !remuxResult.initSegment;
17326
17363
  }
17327
17364
 
17328
- var version = "1.5.14-0.canary.10555";
17365
+ var version = "1.5.14-0.canary.10559";
17329
17366
 
17330
17367
  // ensure the worker ends up in the bundle
17331
17368
  // If the worker should not be included this gets aliased to empty.js
@@ -24169,7 +24206,8 @@
24169
24206
  _this.onMediaEncrypted = function (event) {
24170
24207
  var initDataType = event.initDataType,
24171
24208
  initData = event.initData;
24172
- _this.debug("\"" + event.type + "\" event: init data type: \"" + initDataType + "\"");
24209
+ var logMessage = "\"" + event.type + "\" event: init data type: \"" + initDataType + "\"";
24210
+ _this.debug(logMessage);
24173
24211
 
24174
24212
  // Ignore event when initData is null
24175
24213
  if (initData === null) {
@@ -24184,24 +24222,37 @@
24184
24222
  var sinf = base64Decode(JSON.parse(json).sinf);
24185
24223
  var tenc = parseSinf(new Uint8Array(sinf));
24186
24224
  if (!tenc) {
24187
- return;
24225
+ throw new Error("'schm' box missing or not cbcs/cenc with schi > tenc");
24188
24226
  }
24189
24227
  keyId = tenc.subarray(8, 24);
24190
24228
  keySystemDomain = KeySystems.FAIRPLAY;
24191
24229
  } catch (error) {
24192
- _this.warn('Failed to parse sinf "encrypted" event message initData');
24230
+ _this.warn(logMessage + " Failed to parse sinf: " + error);
24193
24231
  return;
24194
24232
  }
24195
24233
  } else {
24196
- // Support clear-lead key-session creation (otherwise depend on playlist keys)
24197
- var psshInfo = parsePssh(initData);
24198
- if (psshInfo === null) {
24234
+ // Support Widevine clear-lead key-session creation (otherwise depend on playlist keys)
24235
+ var psshResults = parseMultiPssh(initData);
24236
+ var psshInfo = psshResults.filter(function (pssh) {
24237
+ return pssh.systemId === KeySystemIds.WIDEVINE;
24238
+ })[0];
24239
+ if (!psshInfo) {
24240
+ if (psshResults.length === 0 || psshResults.some(function (pssh) {
24241
+ return !pssh.systemId;
24242
+ })) {
24243
+ _this.warn(logMessage + " contains incomplete or invalid pssh data");
24244
+ } else {
24245
+ _this.log("ignoring " + logMessage + " for " + psshResults.map(function (pssh) {
24246
+ return keySystemIdToKeySystemDomain(pssh.systemId);
24247
+ }).join(',') + " pssh data in favor of playlist keys");
24248
+ }
24199
24249
  return;
24200
24250
  }
24201
- if (psshInfo.version === 0 && psshInfo.systemId === KeySystemIds.WIDEVINE && psshInfo.data) {
24202
- keyId = psshInfo.data.subarray(8, 24);
24203
- }
24204
24251
  keySystemDomain = keySystemIdToKeySystemDomain(psshInfo.systemId);
24252
+ if (psshInfo.version === 0 && psshInfo.data) {
24253
+ var offset = psshInfo.data.length - 22;
24254
+ keyId = psshInfo.data.subarray(offset, offset + 16);
24255
+ }
24205
24256
  }
24206
24257
  if (!keySystemDomain || !keyId) {
24207
24258
  return;
@@ -24215,12 +24266,15 @@
24215
24266
  // Match playlist key
24216
24267
  var keyContext = mediaKeySessions[i];
24217
24268
  var decryptdata = keyContext.decryptdata;
24218
- if (decryptdata.pssh || !decryptdata.keyId) {
24269
+ if (!decryptdata.keyId) {
24219
24270
  return 0; // continue
24220
24271
  }
24221
24272
  var oldKeyIdHex = Hex.hexDump(decryptdata.keyId);
24222
24273
  if (keyIdHex === oldKeyIdHex || decryptdata.uri.replace(/-/g, '').indexOf(keyIdHex) !== -1) {
24223
24274
  keySessionContextPromise = keyIdToKeySessionPromise[oldKeyIdHex];
24275
+ if (decryptdata.pssh) {
24276
+ return 1; // break
24277
+ }
24224
24278
  delete keyIdToKeySessionPromise[oldKeyIdHex];
24225
24279
  decryptdata.pssh = new Uint8Array(initData);
24226
24280
  decryptdata.keyId = keyId;