shaka-player 4.1.3 → 4.2.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 (59) hide show
  1. package/CHANGELOG.md +33 -34
  2. package/demo/common/assets.js +25 -0
  3. package/demo/common/message_ids.js +2 -0
  4. package/demo/config.js +5 -1
  5. package/demo/index.html +1 -1
  6. package/demo/locales/en.json +2 -0
  7. package/demo/locales/source.json +8 -0
  8. package/dist/demo.compiled.debug.js +25 -23
  9. package/dist/demo.compiled.debug.map +3 -3
  10. package/dist/demo.compiled.js +25 -23
  11. package/dist/demo.compiled.map +3 -3
  12. package/dist/deps.js +3 -2
  13. package/dist/locales.js +31 -31
  14. package/dist/receiver.compiled.debug.js +24 -22
  15. package/dist/receiver.compiled.debug.map +3 -3
  16. package/dist/receiver.compiled.js +24 -22
  17. package/dist/receiver.compiled.map +3 -3
  18. package/dist/shaka-player.compiled.d.ts +57 -4
  19. package/dist/shaka-player.compiled.debug.d.ts +57 -4
  20. package/dist/shaka-player.compiled.debug.externs.js +62 -4
  21. package/dist/shaka-player.compiled.debug.js +285 -241
  22. package/dist/shaka-player.compiled.debug.map +4 -4
  23. package/dist/shaka-player.compiled.externs.js +62 -4
  24. package/dist/shaka-player.compiled.js +815 -798
  25. package/dist/shaka-player.compiled.map +4 -4
  26. package/dist/shaka-player.ui.d.ts +57 -4
  27. package/dist/shaka-player.ui.debug.d.ts +57 -4
  28. package/dist/shaka-player.ui.debug.externs.js +62 -4
  29. package/dist/shaka-player.ui.debug.js +283 -239
  30. package/dist/shaka-player.ui.debug.map +4 -4
  31. package/dist/shaka-player.ui.externs.js +62 -4
  32. package/dist/shaka-player.ui.js +979 -960
  33. package/dist/shaka-player.ui.map +4 -4
  34. package/docs/tutorials/fairplay.md +149 -0
  35. package/docs/tutorials/ui.md +6 -6
  36. package/externs/shaka/abr_manager.js +8 -0
  37. package/externs/shaka/manifest.js +43 -0
  38. package/externs/shaka/player.js +13 -2
  39. package/lib/abr/simple_abr_manager.js +72 -4
  40. package/lib/hls/hls_parser.js +117 -25
  41. package/lib/media/drm_engine.js +0 -2
  42. package/lib/media/segment_index.js +8 -0
  43. package/lib/media/segment_reference.js +7 -1
  44. package/lib/media/streaming_engine.js +38 -2
  45. package/lib/net/networking_engine.js +1 -0
  46. package/lib/player.js +8 -1
  47. package/lib/polyfill/patchedmediakeys_apple.js +729 -0
  48. package/lib/text/vtt_text_parser.js +61 -4
  49. package/lib/util/error.js +21 -1
  50. package/lib/util/fairplay_utils.js +100 -2
  51. package/lib/util/platform.js +12 -1
  52. package/lib/util/player_configuration.js +3 -10
  53. package/package.json +1 -1
  54. package/shaka-player.uncompiled.js +1 -0
  55. package/test/hls/hls_parser_unit.js +49 -33
  56. package/test/media/streaming_engine_unit.js +79 -5
  57. package/test/test/util/simple_fakes.js +4 -0
  58. package/test/test/util/streaming_engine_util.js +10 -2
  59. package/test/text/vtt_text_parser_unit.js +26 -0
@@ -1668,8 +1668,6 @@ shaka.media.DrmEngine = class {
1668
1668
  'com.widevine.alpha',
1669
1669
  'com.microsoft.playready',
1670
1670
  'com.microsoft.playready.recommendation',
1671
- 'com.apple.fps.3_0',
1672
- 'com.apple.fps.2_0',
1673
1671
  'com.apple.fps.1_0',
1674
1672
  'com.apple.fps',
1675
1673
  'com.adobe.primetime',
@@ -529,6 +529,14 @@ shaka.media.SegmentIterator = class {
529
529
  this.currentPartialPosition_ = partialSegmentIndex;
530
530
  }
531
531
 
532
+ /**
533
+ * @return {number}
534
+ * @export
535
+ */
536
+ currentPosition() {
537
+ return this.currentPosition_;
538
+ }
539
+
532
540
  /**
533
541
  * @return {shaka.media.SegmentReference}
534
542
  * @export
@@ -166,12 +166,15 @@ shaka.media.SegmentReference = class {
166
166
  * @param {shaka.media.SegmentReference.Status=} status
167
167
  * The segment status is used to indicate that a segment does not exist or is
168
168
  * not available.
169
+ * @param {?shaka.extern.HlsAes128Key=} hlsAes128Key
170
+ * The segment's AES-128-CBC full segment encryption key and iv.
169
171
  */
170
172
  constructor(
171
173
  startTime, endTime, uris, startByte, endByte, initSegmentReference,
172
174
  timestampOffset, appendWindowStart, appendWindowEnd,
173
175
  partialReferences = [], tilesLayout = '', tileDuration = null,
174
- syncTime = null, status = shaka.media.SegmentReference.Status.AVAILABLE) {
176
+ syncTime = null, status = shaka.media.SegmentReference.Status.AVAILABLE,
177
+ hlsAes128Key = null) {
175
178
  // A preload hinted Partial Segment has the same startTime and endTime.
176
179
  goog.asserts.assert(startTime <= endTime,
177
180
  'startTime must be less than or equal to endTime');
@@ -233,6 +236,9 @@ shaka.media.SegmentReference = class {
233
236
 
234
237
  /** @type {shaka.media.SegmentReference.Status} */
235
238
  this.status = status;
239
+
240
+ /** @type {?shaka.extern.HlsAes128Key} */
241
+ this.hlsAes128Key = hlsAes128Key;
236
242
  }
237
243
 
238
244
  /**
@@ -1233,7 +1233,10 @@ shaka.media.StreamingEngine = class {
1233
1233
  stream.mimeType == 'audio/mp4';
1234
1234
  const isReadableStreamSupported = window.ReadableStream;
1235
1235
  // Enable MP4 low latency streaming with ReadableStream chunked data.
1236
- if (this.config_.lowLatencyMode && isReadableStreamSupported && isMP4) {
1236
+ // Disabled when AES-128 is present, as we cannot decrypt part of a
1237
+ // segment.
1238
+ if (this.config_.lowLatencyMode && isReadableStreamSupported && isMP4 &&
1239
+ !reference.hlsAes128Key) {
1237
1240
  let remaining = new Uint8Array(0);
1238
1241
  const streamDataCallback = async (data) => {
1239
1242
  this.destroyer_.ensureNotDestroyed();
@@ -1273,11 +1276,16 @@ shaka.media.StreamingEngine = class {
1273
1276
  'ReadableStream is not supported by the browser.');
1274
1277
  }
1275
1278
  const fetchSegment = this.fetch_(mediaState, reference);
1276
- const result = await fetchSegment;
1279
+ let result = await fetchSegment;
1277
1280
  this.destroyer_.ensureNotDestroyed();
1278
1281
  if (this.fatalError_) {
1279
1282
  return;
1280
1283
  }
1284
+ if (reference.hlsAes128Key) {
1285
+ goog.asserts.assert(iter, 'mediaState.segmentIterator should exist');
1286
+ result = await this.aes128Decrypt_(result, reference, iter);
1287
+ }
1288
+ this.destroyer_.ensureNotDestroyed();
1281
1289
 
1282
1290
  // If the text stream gets switched between fetch_() and append_(), the
1283
1291
  // new text parser is initialized, but the new init segment is not
@@ -1368,6 +1376,34 @@ shaka.media.StreamingEngine = class {
1368
1376
  }
1369
1377
  }
1370
1378
 
1379
+ /**
1380
+ * @param {!BufferSource} rawResult
1381
+ * @param {!shaka.media.SegmentReference} reference
1382
+ * @param {!shaka.media.SegmentIterator} iter
1383
+ * @return {!Promise.<!BufferSource>} finalResult
1384
+ * @private
1385
+ */
1386
+ async aes128Decrypt_(rawResult, reference, iter) {
1387
+ const key = reference.hlsAes128Key;
1388
+ if (!key.cryptoKey) {
1389
+ goog.asserts.assert(key.fetchKey, 'If AES-128 cryptoKey was not ' +
1390
+ 'preloaded, fetchKey function should be provided');
1391
+ await key.fetchKey();
1392
+ goog.asserts.assert(key.cryptoKey, 'AES-128 cryptoKey should now be set');
1393
+ }
1394
+ let iv = key.iv;
1395
+ if (!iv) {
1396
+ iv = shaka.util.BufferUtils.toUint8(new ArrayBuffer(16));
1397
+ let sequence = key.firstMediaSequenceNumber + iter.currentPosition();
1398
+ for (let i = iv.byteLength - 1; i >= 0; i--) {
1399
+ iv[i] = sequence & 0xff;
1400
+ sequence >>= 8;
1401
+ }
1402
+ }
1403
+ return window.crypto.subtle.decrypt(
1404
+ {name: 'AES-CBC', iv}, key.cryptoKey, rawResult);
1405
+ }
1406
+
1371
1407
 
1372
1408
  /**
1373
1409
  * Clear per-stream error states and retry any failed streams.
@@ -749,6 +749,7 @@ shaka.net.NetworkingEngine.RequestType = {
749
749
  'APP': 3,
750
750
  'TIMING': 4,
751
751
  'SERVER_CERTIFICATE': 5,
752
+ 'KEY': 6,
752
753
  };
753
754
 
754
755
 
package/lib/player.js CHANGED
@@ -1948,6 +1948,12 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
1948
1948
  if (!this.abrManager_ || this.abrManagerFactory_ != abrFactory) {
1949
1949
  this.abrManagerFactory_ = abrFactory;
1950
1950
  this.abrManager_ = abrFactory();
1951
+ if (typeof this.abrManager_.setMediaElement != 'function') {
1952
+ shaka.Deprecate.deprecateFeature(5,
1953
+ 'AbrManager',
1954
+ 'Please use an AbrManager with setMediaElement function.');
1955
+ this.abrManager_.setMediaElement = () => {};
1956
+ }
1951
1957
  this.abrManager_.configure(this.config_.abr);
1952
1958
  }
1953
1959
 
@@ -1970,6 +1976,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
1970
1976
  this.abrManager_.init((variant, clearBuffer, safeMargin) => {
1971
1977
  return this.switch_(variant, clearBuffer, safeMargin);
1972
1978
  });
1979
+ this.abrManager_.setMediaElement(mediaElement);
1973
1980
 
1974
1981
  this.playhead_ = this.createPlayhead(has.startTime);
1975
1982
  this.playheadObservers_ = this.createPlayheadObserversForMSE_();
@@ -6551,7 +6558,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
6551
6558
  * @define {string} A version number taken from git at compile time.
6552
6559
  * @export
6553
6560
  */
6554
- shaka.Player.version = 'v4.1.3-uncompiled';
6561
+ shaka.Player.version = 'v4.2.0-uncompiled';
6555
6562
 
6556
6563
  // Initialize the deprecation system using the version string we just set
6557
6564
  // on the player.