hls.js 1.5.14 → 1.5.16

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.mjs CHANGED
@@ -411,7 +411,7 @@ function enableLogs(debugConfig, id) {
411
411
  // Some browsers don't allow to use bind on console object anyway
412
412
  // fallback to default if needed
413
413
  try {
414
- exportedLogger.log(`Debug logs enabled for "${id}" in hls.js version ${"1.5.14"}`);
414
+ exportedLogger.log(`Debug logs enabled for "${id}" in hls.js version ${"1.5.16"}`);
415
415
  } catch (e) {
416
416
  exportedLogger = fakeLogger;
417
417
  }
@@ -1071,15 +1071,19 @@ function keySystemFormatToKeySystemDomain(format) {
1071
1071
 
1072
1072
  // System IDs for which we can extract a key ID from "encrypted" event PSSH
1073
1073
  var KeySystemIds = {
1074
+ CENC: "1077efecc0b24d02ace33c1e52e2fb4b",
1075
+ CLEARKEY: "e2719d58a985b3c9781ab030af78d30e",
1076
+ FAIRPLAY: "94ce86fb07ff4f43adb893d2fa968ca2",
1077
+ PLAYREADY: "9a04f07998404286ab92e65be0885f95",
1074
1078
  WIDEVINE: "edef8ba979d64acea3c827dcd51d21ed"
1075
1079
  };
1076
1080
  function keySystemIdToKeySystemDomain(systemId) {
1077
1081
  if (systemId === KeySystemIds.WIDEVINE) {
1078
1082
  return KeySystems.WIDEVINE;
1079
- // } else if (systemId === KeySystemIds.PLAYREADY) {
1080
- // return KeySystems.PLAYREADY;
1081
- // } else if (systemId === KeySystemIds.CENC || systemId === KeySystemIds.CLEARKEY) {
1082
- // return KeySystems.CLEARKEY;
1083
+ } else if (systemId === KeySystemIds.PLAYREADY) {
1084
+ return KeySystems.PLAYREADY;
1085
+ } else if (systemId === KeySystemIds.CENC || systemId === KeySystemIds.CLEARKEY) {
1086
+ return KeySystems.CLEARKEY;
1083
1087
  }
1084
1088
  }
1085
1089
  function keySystemDomainToKeySystemFormat(keySystem) {
@@ -1952,7 +1956,6 @@ function parseSinf(sinf) {
1952
1956
  return findBox(sinf, ['schi', 'tenc'])[0];
1953
1957
  }
1954
1958
  }
1955
- logger.error(`[eme] missing 'schm' box`);
1956
1959
  return null;
1957
1960
  }
1958
1961
 
@@ -2627,43 +2630,77 @@ function mp4pssh(systemId, keyids, data) {
2627
2630
  // 16 bytes
2628
2631
  kidCount, kids, dataSize, data || new Uint8Array());
2629
2632
  }
2630
- function parsePssh(initData) {
2631
- if (!(initData instanceof ArrayBuffer) || initData.byteLength < 32) {
2632
- return null;
2633
+ function parseMultiPssh(initData) {
2634
+ const results = [];
2635
+ if (initData instanceof ArrayBuffer) {
2636
+ const length = initData.byteLength;
2637
+ let offset = 0;
2638
+ while (offset + 32 < length) {
2639
+ const view = new DataView(initData, offset);
2640
+ const pssh = parsePssh(view);
2641
+ results.push(pssh);
2642
+ offset += pssh.size;
2643
+ }
2633
2644
  }
2634
- const result = {
2635
- version: 0,
2636
- systemId: '',
2637
- kids: null,
2638
- data: null
2639
- };
2640
- const view = new DataView(initData);
2641
- const boxSize = view.getUint32(0);
2642
- if (initData.byteLength !== boxSize && boxSize > 44) {
2643
- return null;
2645
+ return results;
2646
+ }
2647
+ function parsePssh(view) {
2648
+ const size = view.getUint32(0);
2649
+ const offset = view.byteOffset;
2650
+ const length = view.byteLength;
2651
+ if (length < size) {
2652
+ return {
2653
+ offset,
2654
+ size: length
2655
+ };
2644
2656
  }
2645
2657
  const type = view.getUint32(4);
2646
2658
  if (type !== 0x70737368) {
2647
- return null;
2659
+ return {
2660
+ offset,
2661
+ size
2662
+ };
2648
2663
  }
2649
- result.version = view.getUint32(8) >>> 24;
2650
- if (result.version > 1) {
2651
- return null;
2664
+ const version = view.getUint32(8) >>> 24;
2665
+ if (version !== 0 && version !== 1) {
2666
+ return {
2667
+ offset,
2668
+ size
2669
+ };
2652
2670
  }
2653
- result.systemId = Hex.hexDump(new Uint8Array(initData, 12, 16));
2671
+ const buffer = view.buffer;
2672
+ const systemId = Hex.hexDump(new Uint8Array(buffer, offset + 12, 16));
2654
2673
  const dataSizeOrKidCount = view.getUint32(28);
2655
- if (result.version === 0) {
2656
- if (boxSize - 32 < dataSizeOrKidCount) {
2657
- return null;
2674
+ let kids = null;
2675
+ let data = null;
2676
+ if (version === 0) {
2677
+ if (size - 32 < dataSizeOrKidCount || dataSizeOrKidCount < 22) {
2678
+ return {
2679
+ offset,
2680
+ size
2681
+ };
2658
2682
  }
2659
- result.data = new Uint8Array(initData, 32, dataSizeOrKidCount);
2660
- } else if (result.version === 1) {
2661
- result.kids = [];
2683
+ data = new Uint8Array(buffer, offset + 32, dataSizeOrKidCount);
2684
+ } else if (version === 1) {
2685
+ if (!dataSizeOrKidCount || length < offset + 32 + dataSizeOrKidCount * 16 + 16) {
2686
+ return {
2687
+ offset,
2688
+ size
2689
+ };
2690
+ }
2691
+ kids = [];
2662
2692
  for (let i = 0; i < dataSizeOrKidCount; i++) {
2663
- result.kids.push(new Uint8Array(initData, 32 + i * 16, 16));
2693
+ kids.push(new Uint8Array(buffer, offset + 32 + i * 16, 16));
2664
2694
  }
2665
2695
  }
2666
- return result;
2696
+ return {
2697
+ version,
2698
+ systemId,
2699
+ kids,
2700
+ data,
2701
+ offset,
2702
+ size
2703
+ };
2667
2704
  }
2668
2705
 
2669
2706
  let keyUriToKeyIdMap = {};
@@ -22252,7 +22289,8 @@ class EMEController {
22252
22289
  initDataType,
22253
22290
  initData
22254
22291
  } = event;
22255
- this.debug(`"${event.type}" event: init data type: "${initDataType}"`);
22292
+ const logMessage = `"${event.type}" event: init data type: "${initDataType}"`;
22293
+ this.debug(logMessage);
22256
22294
 
22257
22295
  // Ignore event when initData is null
22258
22296
  if (initData === null) {
@@ -22267,24 +22305,31 @@ class EMEController {
22267
22305
  const sinf = base64Decode(JSON.parse(json).sinf);
22268
22306
  const tenc = parseSinf(new Uint8Array(sinf));
22269
22307
  if (!tenc) {
22270
- return;
22308
+ throw new Error(`'schm' box missing or not cbcs/cenc with schi > tenc`);
22271
22309
  }
22272
22310
  keyId = tenc.subarray(8, 24);
22273
22311
  keySystemDomain = KeySystems.FAIRPLAY;
22274
22312
  } catch (error) {
22275
- this.warn('Failed to parse sinf "encrypted" event message initData');
22313
+ this.warn(`${logMessage} Failed to parse sinf: ${error}`);
22276
22314
  return;
22277
22315
  }
22278
22316
  } else {
22279
- // Support clear-lead key-session creation (otherwise depend on playlist keys)
22280
- const psshInfo = parsePssh(initData);
22281
- if (psshInfo === null) {
22317
+ // Support Widevine clear-lead key-session creation (otherwise depend on playlist keys)
22318
+ const psshResults = parseMultiPssh(initData);
22319
+ const psshInfo = psshResults.filter(pssh => pssh.systemId === KeySystemIds.WIDEVINE)[0];
22320
+ if (!psshInfo) {
22321
+ if (psshResults.length === 0 || psshResults.some(pssh => !pssh.systemId)) {
22322
+ this.warn(`${logMessage} contains incomplete or invalid pssh data`);
22323
+ } else {
22324
+ this.log(`ignoring ${logMessage} for ${psshResults.map(pssh => keySystemIdToKeySystemDomain(pssh.systemId)).join(',')} pssh data in favor of playlist keys`);
22325
+ }
22282
22326
  return;
22283
22327
  }
22284
- if (psshInfo.version === 0 && psshInfo.systemId === KeySystemIds.WIDEVINE && psshInfo.data) {
22285
- keyId = psshInfo.data.subarray(8, 24);
22286
- }
22287
22328
  keySystemDomain = keySystemIdToKeySystemDomain(psshInfo.systemId);
22329
+ if (psshInfo.version === 0 && psshInfo.data) {
22330
+ const offset = psshInfo.data.length - 22;
22331
+ keyId = psshInfo.data.subarray(offset, offset + 16);
22332
+ }
22288
22333
  }
22289
22334
  if (!keySystemDomain || !keyId) {
22290
22335
  return;
@@ -22299,12 +22344,15 @@ class EMEController {
22299
22344
  // Match playlist key
22300
22345
  const keyContext = mediaKeySessions[i];
22301
22346
  const decryptdata = keyContext.decryptdata;
22302
- if (decryptdata.pssh || !decryptdata.keyId) {
22347
+ if (!decryptdata.keyId) {
22303
22348
  continue;
22304
22349
  }
22305
22350
  const oldKeyIdHex = Hex.hexDump(decryptdata.keyId);
22306
22351
  if (keyIdHex === oldKeyIdHex || decryptdata.uri.replace(/-/g, '').indexOf(keyIdHex) !== -1) {
22307
22352
  keySessionContextPromise = keyIdToKeySessionPromise[oldKeyIdHex];
22353
+ if (decryptdata.pssh) {
22354
+ break;
22355
+ }
22308
22356
  delete keyIdToKeySessionPromise[oldKeyIdHex];
22309
22357
  decryptdata.pssh = new Uint8Array(initData);
22310
22358
  decryptdata.keyId = keyId;
@@ -24231,9 +24279,8 @@ class ContentSteeringController {
24231
24279
  }
24232
24280
  if (pathwayLevels.length !== levels.length) {
24233
24281
  this.log(`Found ${pathwayLevels.length}/${levels.length} levels in Pathway "${this.pathwayId}"`);
24234
- return pathwayLevels;
24235
24282
  }
24236
- return levels;
24283
+ return pathwayLevels;
24237
24284
  }
24238
24285
  getLevelsForPathway(pathwayId) {
24239
24286
  if (this.levels === null) {
@@ -27734,7 +27781,7 @@ class Hls {
27734
27781
  * Get the video-dev/hls.js package version.
27735
27782
  */
27736
27783
  static get version() {
27737
- return "1.5.14";
27784
+ return "1.5.16";
27738
27785
  }
27739
27786
 
27740
27787
  /**