shaka-player 4.8.7 → 4.8.9

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.
@@ -1391,7 +1391,7 @@ shaka.extern.ManifestConfiguration;
1391
1391
  * @property {number} liveSyncMinPlaybackRate
1392
1392
  * Minimum playback rate used for latency chasing. It is recommended to use a
1393
1393
  * value between 0 and 1. Effective only if liveSync is true. Defaults to
1394
- * <code>1</code>.
1394
+ * <code>0.95</code>.
1395
1395
  * @property {boolean} liveSyncPanicMode
1396
1396
  * If <code>true</code>, panic mode for live sync is enabled. When enabled,
1397
1397
  * will set the playback rate to the <code>liveSyncMinPlaybackRate</code>
@@ -642,6 +642,15 @@ shaka.cea.Cea608DataChannel = class {
642
642
  // b1 -> |P|0|0|1|X|X|X|X|
643
643
  return (b1 & 0x70) === 0x10;
644
644
  }
645
+
646
+ /**
647
+ * Checks if the data contains a XDS control code.
648
+ * @param {number} b1 Byte 1.
649
+ * @return {boolean}
650
+ */
651
+ static isXdsControlCode(b1) {
652
+ return b1 >= 0x01 && b1 <= 0x0F;
653
+ }
645
654
  };
646
655
 
647
656
  /**
@@ -307,16 +307,20 @@ shaka.cea.CeaDecoder = class {
307
307
  ccPacket.ccData1 &= 0x7f;
308
308
  ccPacket.ccData2 &= 0x7f;
309
309
 
310
+ // Ignore XDS
311
+ if (shaka.cea.Cea608DataChannel.isXdsControlCode(ccPacket.ccData1)) {
312
+ return null;
313
+ }
314
+
310
315
  // Check for empty captions and skip them.
311
316
  if (!ccPacket.ccData1 && !ccPacket.ccData2) {
312
317
  return null;
313
318
  }
314
319
 
315
- this.streams_.add(selectedMode);
316
-
317
320
  // Process the clean CC data pair.
318
321
  let parsedClosedCaption = null;
319
322
  if (shaka.cea.Cea608DataChannel.isControlCode(ccPacket.ccData1)) {
323
+ this.streams_.add(selectedMode);
320
324
  parsedClosedCaption = selectedStream.handleControlCode(ccPacket);
321
325
  } else {
322
326
  // Handle as a Basic North American Character.
@@ -506,7 +506,12 @@ shaka.dash.SegmentTemplate = class {
506
506
  // references were generated. Otherwise, the update would start creating
507
507
  // negative positions for segments in periods which begin in the future.
508
508
  let nextPosition = Math.max(minPosition, maxPosition + 1);
509
- segmentIndex.updateEvery(segmentDuration, () => {
509
+ let updateTime = segmentDuration;
510
+ // For low latency we need to evict very frequently.
511
+ if (context.representation.availabilityTimeOffset) {
512
+ updateTime = 0.1;
513
+ }
514
+ segmentIndex.updateEvery(updateTime, () => {
510
515
  // Evict any references outside the window.
511
516
  const availabilityStartTime =
512
517
  presentationTimeline.getSegmentAvailabilityStart();
@@ -13,6 +13,7 @@ goog.require('shaka.media.TimeRangesUtils');
13
13
  goog.require('shaka.util.EventManager');
14
14
  goog.require('shaka.util.FakeEvent');
15
15
  goog.require('shaka.util.IReleasable');
16
+ goog.require('shaka.util.Platform');
16
17
  goog.require('shaka.util.Timer');
17
18
 
18
19
 
@@ -217,7 +218,14 @@ shaka.media.GapJumpingController = class {
217
218
 
218
219
  // StreamingEngine can buffer past the seek end, but still don't allow
219
220
  // seeking past it.
220
- const jumpTo = buffered.start(gapIndex);
221
+ let jumpTo = buffered.start(gapIndex);
222
+ // Workaround for Xbox with Legacy Edge. On this platform video element
223
+ // often rounds value we want to set as currentTime and we are not able
224
+ // to jump over the gap.
225
+ if (shaka.util.Platform.isLegacyEdge() ||
226
+ shaka.util.Platform.isXboxOne()) {
227
+ jumpTo = Math.ceil((jumpTo + 0.01) * 100) / 100;
228
+ }
221
229
  const seekEnd = this.timeline_.getSeekRangeEnd();
222
230
  if (jumpTo >= seekEnd) {
223
231
  return;
@@ -41,27 +41,23 @@ shaka.media.ManifestFilterer = class {
41
41
  }
42
42
 
43
43
  /**
44
- * Filters a manifest, removing unplayable streams/variants.
44
+ * Filters a manifest, removing unplayable streams/variants and choosing
45
+ * the codecs.
45
46
  *
46
47
  * @param {?shaka.extern.Manifest} manifest
47
48
  * @return {!Promise.<boolean>} tracksChanged
48
49
  */
49
50
  async filterManifest(manifest) {
50
- await this.filterManifestWithStreamUtils_(manifest);
51
- return this.filterManifestWithRestrictions(manifest);
52
- }
53
-
54
- /**
55
- * Filters a manifest, removing unplayable streams/variants.
56
- *
57
- * @param {?shaka.extern.Manifest} manifest
58
- * @private
59
- */
60
- async filterManifestWithStreamUtils_(manifest) {
61
51
  goog.asserts.assert(manifest, 'Manifest should exist!');
62
52
  await shaka.util.StreamUtils.filterManifest(this.drmEngine_, manifest,
63
53
  this.config_.drm.preferredKeySystems);
54
+ shaka.util.StreamUtils.chooseCodecsAndFilterManifest(
55
+ manifest,
56
+ this.config_.preferredVideoCodecs,
57
+ this.config_.preferredAudioCodecs,
58
+ this.config_.preferredDecodingAttributes);
64
59
  this.checkPlayableVariants_(manifest);
60
+ return this.filterManifestWithRestrictions(manifest);
65
61
  }
66
62
 
67
63
 
@@ -553,7 +553,9 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
553
553
 
554
554
  const tracksChangedInitial = this.manifestFilterer_.applyRestrictions(
555
555
  this.manifest_);
556
- if (tracksChangedInitial) {
556
+ const tracksChangedBefore = await this.manifestFilterer_.filterManifest(
557
+ this.manifest_);
558
+ if (tracksChangedInitial || tracksChangedBefore) {
557
559
  const event = this.makeEvent_(
558
560
  shaka.util.FakeEvent.EventName.TracksChanged);
559
561
  await Promise.resolve();
@@ -568,7 +570,6 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
568
570
 
569
571
  // Now that we have drm information, filter the manifest (again) so that
570
572
  // we can ensure we only use variants with the selected key system.
571
- // const tracksChanged =
572
573
  const tracksChangedAfter = await this.manifestFilterer_.filterManifest(
573
574
  this.manifest_);
574
575
  if (tracksChangedAfter) {
@@ -630,14 +631,6 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
630
631
  this.config_.preferredVideoLabel,
631
632
  this.config_.mediaSource.codecSwitchingStrategy,
632
633
  this.config_.manifest.dash.enableAudioGroups);
633
-
634
- // If the content is multi-codec and the browser can play more than one of
635
- // them, choose codecs now before we initialize streaming.
636
- shaka.util.StreamUtils.chooseCodecsAndFilterManifest(
637
- this.manifest_,
638
- this.config_.preferredVideoCodecs,
639
- this.config_.preferredAudioCodecs,
640
- this.config_.preferredDecodingAttributes);
641
634
  }
642
635
 
643
636
  // Make the ABR manager.
package/lib/player.js CHANGED
@@ -2369,7 +2369,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
2369
2369
  this.config_.streaming.vodDynamicPlaybackRate) {
2370
2370
  const onTimeUpdate = () => this.onTimeUpdate_();
2371
2371
  this.loadEventManager_.listen(mediaElement, 'timeupdate', onTimeUpdate);
2372
- } else if (!isLive) {
2372
+ }
2373
+ if (!isLive) {
2373
2374
  const onVideoProgress = () => this.onVideoProgress_();
2374
2375
  this.loadEventManager_.listen(
2375
2376
  mediaElement, 'timeupdate', onVideoProgress);
@@ -2732,7 +2733,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
2732
2733
  this.config_.streaming.vodDynamicPlaybackRate) {
2733
2734
  const onTimeUpdate = () => this.onTimeUpdate_();
2734
2735
  this.loadEventManager_.listen(mediaElement, 'timeupdate', onTimeUpdate);
2735
- } else if (!isLive) {
2736
+ }
2737
+ if (!isLive) {
2736
2738
  const onVideoProgress = () => this.onVideoProgress_();
2737
2739
  this.loadEventManager_.listen(
2738
2740
  mediaElement, 'timeupdate', onVideoProgress);
@@ -6527,8 +6529,11 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
6527
6529
  shaka.log.debug('switch_');
6528
6530
  goog.asserts.assert(this.config_.abr.enabled,
6529
6531
  'AbrManager should not call switch while disabled!');
6530
- goog.asserts.assert(this.manifest_, 'We need a manifest to switch ' +
6531
- 'variants.');
6532
+
6533
+ if (!this.manifest_) {
6534
+ // It could come from a preload manager operation.
6535
+ return;
6536
+ }
6532
6537
 
6533
6538
  if (!this.streamingEngine_) {
6534
6539
  // There's no way to change it.
@@ -7234,7 +7239,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
7234
7239
  * @export
7235
7240
  */
7236
7241
  // eslint-disable-next-line no-useless-concat
7237
- shaka.Player.version = 'v4.8.7' + '-uncompiled'; // x-release-please-version
7242
+ shaka.Player.version = 'v4.8.9' + '-uncompiled'; // x-release-please-version
7238
7243
 
7239
7244
  // Initialize the deprecation system using the version string we just set
7240
7245
  // on the player.
@@ -0,0 +1,62 @@
1
+ /*! @license
2
+ * Shaka Player
3
+ * Copyright 2016 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ goog.provide('shaka.polyfill.PatchedMediaKeysCert');
8
+
9
+ goog.require('shaka.log');
10
+ goog.require('shaka.polyfill');
11
+ goog.require('shaka.util.Platform');
12
+
13
+
14
+ /**
15
+ * @summary A polyfill to fix setServerCertificate implementation on
16
+ * older platforms which claim to support modern EME.
17
+ * @export
18
+ */
19
+ shaka.polyfill.PatchedMediaKeysCert = class {
20
+ /**
21
+ * Installs the polyfill if needed.
22
+ * @export
23
+ */
24
+ static install() {
25
+ if (!window.MediaKeys) {
26
+ // No MediaKeys available
27
+ return;
28
+ }
29
+ // eslint-disable-next-line no-restricted-syntax
30
+ if (MediaKeys.prototype.setServerCertificate &&
31
+ !shaka.polyfill.PatchedMediaKeysCert.hasInvalidImplementation_()) {
32
+ // setServerCertificate is there and userAgent seems to be valid.
33
+ return;
34
+ }
35
+
36
+ shaka.log.info('Patching MediaKeys.setServerCertificate');
37
+ // eslint-disable-next-line no-restricted-syntax
38
+ MediaKeys.prototype.setServerCertificate =
39
+ shaka.polyfill.PatchedMediaKeysCert.setServerCertificate_;
40
+ }
41
+
42
+ /**
43
+ * @param {!BufferSource} certificate
44
+ * @return {!Promise<boolean>}
45
+ * @private
46
+ */
47
+ static setServerCertificate_(certificate) {
48
+ shaka.log.debug('PatchedMediaKeysCert.setServerCertificate');
49
+ return Promise.resolve(false);
50
+ }
51
+
52
+ /**
53
+ * @return {boolean}
54
+ * @private
55
+ */
56
+ static hasInvalidImplementation_() {
57
+ return shaka.util.Platform.isTizen3() || shaka.util.Platform.isTizen4() ||
58
+ shaka.util.Platform.isTizen5_0() || shaka.util.Platform.isWebOS3();
59
+ }
60
+ };
61
+
62
+ shaka.polyfill.register(shaka.polyfill.PatchedMediaKeysCert.install);
@@ -108,6 +108,33 @@ shaka.util.Platform = class {
108
108
  return shaka.util.Platform.userAgentContains_('Tizen');
109
109
  }
110
110
 
111
+ /**
112
+ * Check if the current platform is a Tizen 6 TV.
113
+ *
114
+ * @return {boolean}
115
+ */
116
+ static isTizen6() {
117
+ return shaka.util.Platform.userAgentContains_('Tizen 6');
118
+ }
119
+
120
+ /**
121
+ * Check if the current platform is a Tizen 5.0 TV.
122
+ *
123
+ * @return {boolean}
124
+ */
125
+ static isTizen5_0() {
126
+ return shaka.util.Platform.userAgentContains_('Tizen 5.0');
127
+ }
128
+
129
+ /**
130
+ * Check if the current platform is a Tizen 5 TV.
131
+ *
132
+ * @return {boolean}
133
+ */
134
+ static isTizen5() {
135
+ return shaka.util.Platform.userAgentContains_('Tizen 5');
136
+ }
137
+
111
138
  /**
112
139
  * Check if the current platform is a Tizen 4 TV.
113
140
  *
@@ -588,8 +615,8 @@ shaka.util.Platform = class {
588
615
  */
589
616
  static supportsSmoothCodecSwitching() {
590
617
  const Platform = shaka.util.Platform;
591
- if (Platform.isTizen2() || Platform.isTizen3() ||
592
- Platform.isTizen4() || Platform.isWebOS3() ||
618
+ if (Platform.isTizen2() || Platform.isTizen3() || Platform.isTizen4() ||
619
+ Platform.isTizen5() || Platform.isTizen6() || Platform.isWebOS3() ||
593
620
  Platform.isWebOS4() || Platform.isWebOS5()) {
594
621
  return false;
595
622
  }
@@ -239,7 +239,7 @@ shaka.util.PlayerConfiguration = class {
239
239
  liveSyncMaxLatency: 1,
240
240
  liveSyncPlaybackRate: 1.1,
241
241
  liveSyncMinLatency: 0,
242
- liveSyncMinPlaybackRate: 1,
242
+ liveSyncMinPlaybackRate: 0.95,
243
243
  liveSyncPanicMode: false,
244
244
  liveSyncPanicThreshold: 60,
245
245
  allowMediaSourceRecoveries: true,
@@ -548,7 +548,7 @@ shaka.util.StreamUtils = class {
548
548
  if (!a) {
549
549
  return b;
550
550
  } else {
551
- const res = shaka.util.ObjectUtils.cloneObject(a);
551
+ const res = shaka.util.ObjectUtils.shallowCloneObject(a);
552
552
  res.supported = a.supported && b.supported;
553
553
  res.powerEfficient = a.powerEfficient && b.powerEfficient;
554
554
  res.smooth = a.smooth && b.smooth;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "shaka-player",
3
3
  "description": "DASH/EME video player library",
4
- "version": "4.8.7",
4
+ "version": "4.8.9",
5
5
  "homepage": "https://github.com/shaka-project/shaka-player",
6
6
  "author": "Google",
7
7
  "maintainers": [