hls.js 1.5.14-0.canary.10557 → 1.5.14-0.canary.10561

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
@@ -421,7 +421,7 @@ function enableLogs(debugConfig, context, id) {
421
421
  // Some browsers don't allow to use bind on console object anyway
422
422
  // fallback to default if needed
423
423
  try {
424
- newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.5.14-0.canary.10557"}`);
424
+ newLogger.log(`Debug logs enabled for "${context}" in hls.js version ${"1.5.14-0.canary.10561"}`);
425
425
  } catch (e) {
426
426
  /* log fn threw an exception. All logger methods are no-ops. */
427
427
  return createLogger();
@@ -1279,15 +1279,19 @@ function keySystemFormatToKeySystemDomain(format) {
1279
1279
 
1280
1280
  // System IDs for which we can extract a key ID from "encrypted" event PSSH
1281
1281
  var KeySystemIds = {
1282
+ CENC: "1077efecc0b24d02ace33c1e52e2fb4b",
1283
+ CLEARKEY: "e2719d58a985b3c9781ab030af78d30e",
1284
+ FAIRPLAY: "94ce86fb07ff4f43adb893d2fa968ca2",
1285
+ PLAYREADY: "9a04f07998404286ab92e65be0885f95",
1282
1286
  WIDEVINE: "edef8ba979d64acea3c827dcd51d21ed"
1283
1287
  };
1284
1288
  function keySystemIdToKeySystemDomain(systemId) {
1285
1289
  if (systemId === KeySystemIds.WIDEVINE) {
1286
1290
  return KeySystems.WIDEVINE;
1287
- // } else if (systemId === KeySystemIds.PLAYREADY) {
1288
- // return KeySystems.PLAYREADY;
1289
- // } else if (systemId === KeySystemIds.CENC || systemId === KeySystemIds.CLEARKEY) {
1290
- // return KeySystems.CLEARKEY;
1291
+ } else if (systemId === KeySystemIds.PLAYREADY) {
1292
+ return KeySystems.PLAYREADY;
1293
+ } else if (systemId === KeySystemIds.CENC || systemId === KeySystemIds.CLEARKEY) {
1294
+ return KeySystems.CLEARKEY;
1291
1295
  }
1292
1296
  }
1293
1297
  function keySystemDomainToKeySystemFormat(keySystem) {
@@ -1893,7 +1897,6 @@ function parseSinf(sinf) {
1893
1897
  return findBox(sinf, ['schi', 'tenc'])[0];
1894
1898
  }
1895
1899
  }
1896
- logger.error(`[eme] missing 'schm' box`);
1897
1900
  return null;
1898
1901
  }
1899
1902
 
@@ -2558,43 +2561,77 @@ function mp4pssh(systemId, keyids, data) {
2558
2561
  // 16 bytes
2559
2562
  kidCount, kids, dataSize, data || new Uint8Array());
2560
2563
  }
2561
- function parsePssh(initData) {
2562
- if (!(initData instanceof ArrayBuffer) || initData.byteLength < 32) {
2563
- return null;
2564
+ function parseMultiPssh(initData) {
2565
+ const results = [];
2566
+ if (initData instanceof ArrayBuffer) {
2567
+ const length = initData.byteLength;
2568
+ let offset = 0;
2569
+ while (offset + 32 < length) {
2570
+ const view = new DataView(initData, offset);
2571
+ const pssh = parsePssh(view);
2572
+ results.push(pssh);
2573
+ offset += pssh.size;
2574
+ }
2564
2575
  }
2565
- const result = {
2566
- version: 0,
2567
- systemId: '',
2568
- kids: null,
2569
- data: null
2570
- };
2571
- const view = new DataView(initData);
2572
- const boxSize = view.getUint32(0);
2573
- if (initData.byteLength !== boxSize && boxSize > 44) {
2574
- return null;
2576
+ return results;
2577
+ }
2578
+ function parsePssh(view) {
2579
+ const size = view.getUint32(0);
2580
+ const offset = view.byteOffset;
2581
+ const length = view.byteLength;
2582
+ if (length < size) {
2583
+ return {
2584
+ offset,
2585
+ size: length
2586
+ };
2575
2587
  }
2576
2588
  const type = view.getUint32(4);
2577
2589
  if (type !== 0x70737368) {
2578
- return null;
2590
+ return {
2591
+ offset,
2592
+ size
2593
+ };
2579
2594
  }
2580
- result.version = view.getUint32(8) >>> 24;
2581
- if (result.version > 1) {
2582
- return null;
2595
+ const version = view.getUint32(8) >>> 24;
2596
+ if (version !== 0 && version !== 1) {
2597
+ return {
2598
+ offset,
2599
+ size
2600
+ };
2583
2601
  }
2584
- result.systemId = Hex.hexDump(new Uint8Array(initData, 12, 16));
2602
+ const buffer = view.buffer;
2603
+ const systemId = Hex.hexDump(new Uint8Array(buffer, offset + 12, 16));
2585
2604
  const dataSizeOrKidCount = view.getUint32(28);
2586
- if (result.version === 0) {
2587
- if (boxSize - 32 < dataSizeOrKidCount) {
2588
- return null;
2605
+ let kids = null;
2606
+ let data = null;
2607
+ if (version === 0) {
2608
+ if (size - 32 < dataSizeOrKidCount || dataSizeOrKidCount < 22) {
2609
+ return {
2610
+ offset,
2611
+ size
2612
+ };
2589
2613
  }
2590
- result.data = new Uint8Array(initData, 32, dataSizeOrKidCount);
2591
- } else if (result.version === 1) {
2592
- result.kids = [];
2614
+ data = new Uint8Array(buffer, offset + 32, dataSizeOrKidCount);
2615
+ } else if (version === 1) {
2616
+ if (!dataSizeOrKidCount || length < offset + 32 + dataSizeOrKidCount * 16 + 16) {
2617
+ return {
2618
+ offset,
2619
+ size
2620
+ };
2621
+ }
2622
+ kids = [];
2593
2623
  for (let i = 0; i < dataSizeOrKidCount; i++) {
2594
- result.kids.push(new Uint8Array(initData, 32 + i * 16, 16));
2624
+ kids.push(new Uint8Array(buffer, offset + 32 + i * 16, 16));
2595
2625
  }
2596
2626
  }
2597
- return result;
2627
+ return {
2628
+ version,
2629
+ systemId,
2630
+ kids,
2631
+ data,
2632
+ offset,
2633
+ size
2634
+ };
2598
2635
  }
2599
2636
 
2600
2637
  let keyUriToKeyIdMap = {};
@@ -11033,7 +11070,7 @@ function concatUint8Arrays(chunks, dataLength) {
11033
11070
  return result;
11034
11071
  }
11035
11072
 
11036
- const version = "1.5.14-0.canary.10557";
11073
+ const version = "1.5.14-0.canary.10561";
11037
11074
 
11038
11075
  // ensure the worker ends up in the bundle
11039
11076
  // If the worker should not be included this gets aliased to empty.js
@@ -23580,7 +23617,8 @@ class EMEController extends Logger {
23580
23617
  initDataType,
23581
23618
  initData
23582
23619
  } = event;
23583
- this.debug(`"${event.type}" event: init data type: "${initDataType}"`);
23620
+ const logMessage = `"${event.type}" event: init data type: "${initDataType}"`;
23621
+ this.debug(logMessage);
23584
23622
 
23585
23623
  // Ignore event when initData is null
23586
23624
  if (initData === null) {
@@ -23595,24 +23633,31 @@ class EMEController extends Logger {
23595
23633
  const sinf = base64Decode(JSON.parse(json).sinf);
23596
23634
  const tenc = parseSinf(new Uint8Array(sinf));
23597
23635
  if (!tenc) {
23598
- return;
23636
+ throw new Error(`'schm' box missing or not cbcs/cenc with schi > tenc`);
23599
23637
  }
23600
23638
  keyId = tenc.subarray(8, 24);
23601
23639
  keySystemDomain = KeySystems.FAIRPLAY;
23602
23640
  } catch (error) {
23603
- this.warn('Failed to parse sinf "encrypted" event message initData');
23641
+ this.warn(`${logMessage} Failed to parse sinf: ${error}`);
23604
23642
  return;
23605
23643
  }
23606
23644
  } else {
23607
- // Support clear-lead key-session creation (otherwise depend on playlist keys)
23608
- const psshInfo = parsePssh(initData);
23609
- if (psshInfo === null) {
23645
+ // Support Widevine clear-lead key-session creation (otherwise depend on playlist keys)
23646
+ const psshResults = parseMultiPssh(initData);
23647
+ const psshInfo = psshResults.filter(pssh => pssh.systemId === KeySystemIds.WIDEVINE)[0];
23648
+ if (!psshInfo) {
23649
+ if (psshResults.length === 0 || psshResults.some(pssh => !pssh.systemId)) {
23650
+ this.warn(`${logMessage} contains incomplete or invalid pssh data`);
23651
+ } else {
23652
+ this.log(`ignoring ${logMessage} for ${psshResults.map(pssh => keySystemIdToKeySystemDomain(pssh.systemId)).join(',')} pssh data in favor of playlist keys`);
23653
+ }
23610
23654
  return;
23611
23655
  }
23612
- if (psshInfo.version === 0 && psshInfo.systemId === KeySystemIds.WIDEVINE && psshInfo.data) {
23613
- keyId = psshInfo.data.subarray(8, 24);
23614
- }
23615
23656
  keySystemDomain = keySystemIdToKeySystemDomain(psshInfo.systemId);
23657
+ if (psshInfo.version === 0 && psshInfo.data) {
23658
+ const offset = psshInfo.data.length - 22;
23659
+ keyId = psshInfo.data.subarray(offset, offset + 16);
23660
+ }
23616
23661
  }
23617
23662
  if (!keySystemDomain || !keyId) {
23618
23663
  return;
@@ -23627,12 +23672,15 @@ class EMEController extends Logger {
23627
23672
  // Match playlist key
23628
23673
  const keyContext = mediaKeySessions[i];
23629
23674
  const decryptdata = keyContext.decryptdata;
23630
- if (decryptdata.pssh || !decryptdata.keyId) {
23675
+ if (!decryptdata.keyId) {
23631
23676
  continue;
23632
23677
  }
23633
23678
  const oldKeyIdHex = Hex.hexDump(decryptdata.keyId);
23634
23679
  if (keyIdHex === oldKeyIdHex || decryptdata.uri.replace(/-/g, '').indexOf(keyIdHex) !== -1) {
23635
23680
  keySessionContextPromise = keyIdToKeySessionPromise[oldKeyIdHex];
23681
+ if (decryptdata.pssh) {
23682
+ break;
23683
+ }
23636
23684
  delete keyIdToKeySessionPromise[oldKeyIdHex];
23637
23685
  decryptdata.pssh = new Uint8Array(initData);
23638
23686
  decryptdata.keyId = keyId;