shaka-player 4.10.7 → 4.10.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.
Files changed (35) hide show
  1. package/dist/locales.js +34 -34
  2. package/dist/shaka-player.compiled.d.ts +5 -0
  3. package/dist/shaka-player.compiled.debug.d.ts +5 -0
  4. package/dist/shaka-player.compiled.debug.externs.js +16 -0
  5. package/dist/shaka-player.compiled.debug.js +220 -217
  6. package/dist/shaka-player.compiled.debug.map +3 -3
  7. package/dist/shaka-player.compiled.externs.js +16 -0
  8. package/dist/shaka-player.compiled.js +250 -246
  9. package/dist/shaka-player.compiled.map +3 -3
  10. package/dist/shaka-player.ui.d.ts +5 -0
  11. package/dist/shaka-player.ui.debug.d.ts +5 -0
  12. package/dist/shaka-player.ui.debug.externs.js +16 -0
  13. package/dist/shaka-player.ui.debug.js +239 -236
  14. package/dist/shaka-player.ui.debug.map +3 -3
  15. package/dist/shaka-player.ui.externs.js +16 -0
  16. package/dist/shaka-player.ui.js +346 -342
  17. package/dist/shaka-player.ui.map +3 -3
  18. package/externs/shaka/ads.js +5 -0
  19. package/externs/shaka/net.js +1 -0
  20. package/lib/ads/client_side_ad.js +8 -0
  21. package/lib/ads/interstitial_ad.js +7 -0
  22. package/lib/ads/interstitial_ad_manager.js +8 -6
  23. package/lib/ads/media_tailor_ad.js +7 -0
  24. package/lib/ads/server_side_ad.js +7 -0
  25. package/lib/dash/dash_parser.js +8 -4
  26. package/lib/hls/hls_parser.js +8 -2
  27. package/lib/media/adaptation_set.js +6 -0
  28. package/lib/media/streaming_engine.js +13 -16
  29. package/lib/player.js +6 -2
  30. package/lib/text/ui_text_displayer.js +37 -10
  31. package/lib/util/periods.js +1 -1
  32. package/lib/util/stream_utils.js +16 -8
  33. package/package.json +1 -1
  34. package/ui/seek_bar.js +1 -1
  35. package/ui/skip_ad_button.js +1 -1
@@ -210,6 +210,11 @@ shaka.extern.IAdManager.Factory;
210
210
  * @exportDoc
211
211
  */
212
212
  shaka.extern.IAd = class {
213
+ /**
214
+ * @return {boolean}
215
+ */
216
+ needsSkipUI() {}
217
+
213
218
  /**
214
219
  * @return {number}
215
220
  */
@@ -26,6 +26,7 @@
26
26
  *
27
27
  * @property {number} maxAttempts
28
28
  * The maximum number of times the request should be attempted.
29
+ * The minimum supported value is 1 (only one request without retries).
29
30
  * @property {number} baseDelay
30
31
  * The delay before the first retry, in milliseconds.
31
32
  * @property {number} backoffFactor
@@ -50,6 +50,14 @@ shaka.ads.ClientSideAd = class {
50
50
  });
51
51
  }
52
52
 
53
+ /**
54
+ * @override
55
+ * @export
56
+ */
57
+ needsSkipUI() {
58
+ return false;
59
+ }
60
+
53
61
  /**
54
62
  * @override
55
63
  * @export
@@ -36,6 +36,13 @@ shaka.ads.InterstitialAd = class {
36
36
  this.adPosition_ = adPosition;
37
37
  }
38
38
 
39
+ /**
40
+ * @override
41
+ * @export
42
+ */
43
+ needsSkipUI() {
44
+ return true;
45
+ }
39
46
 
40
47
  /**
41
48
  * @override
@@ -91,7 +91,7 @@ shaka.ads.InterstitialAdManager = class {
91
91
  if (this.playingAd_) {
92
92
  return;
93
93
  }
94
- const needPreRoll = this.lastTime_ == null;
94
+ const needPreRoll = this.lastTime_ == null || this.lastTime_ == 0;
95
95
  this.lastTime_ = this.baseVideo_.currentTime;
96
96
  const currentInterstitial = this.getCurrentInterstitial_(needPreRoll);
97
97
  if (currentInterstitial) {
@@ -342,7 +342,7 @@ shaka.ads.InterstitialAdManager = class {
342
342
  }).length;
343
343
  }
344
344
 
345
- if (interstitial.once) {
345
+ if (interstitial.once || interstitial.pre) {
346
346
  oncePlayed++;
347
347
  this.interstitials_.delete(interstitial);
348
348
  this.cuepointsChanged_();
@@ -384,7 +384,8 @@ shaka.ads.InterstitialAdManager = class {
384
384
  const updateBaseVideoTime = () => {
385
385
  if (!this.usingBaseVideo_) {
386
386
  if (interstitial.resumeOffset == null) {
387
- if (interstitial.timelineRange && interstitial.endTime) {
387
+ if (interstitial.timelineRange && interstitial.endTime &&
388
+ interstitial.endTime != Infinity) {
388
389
  if (this.baseVideo_.currentTime != interstitial.endTime) {
389
390
  this.baseVideo_.currentTime = interstitial.endTime;
390
391
  }
@@ -423,7 +424,8 @@ shaka.ads.InterstitialAdManager = class {
423
424
  if (this.usingBaseVideo_) {
424
425
  let offset = interstitial.resumeOffset;
425
426
  if (offset == null) {
426
- if (interstitial.timelineRange && interstitial.endTime) {
427
+ if (interstitial.timelineRange && interstitial.endTime &&
428
+ interstitial.endTime != Infinity) {
427
429
  offset = interstitial.endTime - (this.lastTime_ || 0);
428
430
  } else {
429
431
  offset = (Date.now() - initialTime) / 1000;
@@ -604,14 +606,14 @@ shaka.ads.InterstitialAdManager = class {
604
606
  pre = data.includes('PRE');
605
607
  post = data.includes('POST');
606
608
  }
607
- let timelineRange = true;
609
+ let timelineRange = false;
608
610
  const timelineOccupies =
609
611
  interstitial.values.find((v) => v.key == 'X-TIMELINE-OCCUPIES');
610
612
  if (timelineOccupies) {
611
613
  const data = /** @type {string} */(timelineOccupies.data);
612
614
  timelineRange = data.includes('RANGE');
613
615
  } else if (!resume && this.basePlayer_.isLive()) {
614
- timelineRange = true;
616
+ timelineRange = !pre && !post;
615
617
  }
616
618
  if (assetUri) {
617
619
  const uri = /** @type {string} */(assetUri.data);
@@ -43,6 +43,13 @@ shaka.ads.MediaTailorAd = class {
43
43
  this.isSkipped_ = false;
44
44
  }
45
45
 
46
+ /**
47
+ * @override
48
+ * @export
49
+ */
50
+ needsSkipUI() {
51
+ return true;
52
+ }
46
53
 
47
54
  /**
48
55
  * @override
@@ -35,6 +35,13 @@ shaka.ads.ServerSideAd = class {
35
35
  this.adProgressData_ = data;
36
36
  }
37
37
 
38
+ /**
39
+ * @override
40
+ * @export
41
+ */
42
+ needsSkipUI() {
43
+ return true;
44
+ }
38
45
 
39
46
  /**
40
47
  * @override
@@ -1723,7 +1723,8 @@ shaka.dash.DashParser = class {
1723
1723
  for (const prop of accessibilities) {
1724
1724
  const schemeId = prop.attributes['schemeIdUri'];
1725
1725
  const value = prop.attributes['value'];
1726
- if (schemeId == 'urn:scte:dash:cc:cea-608:2015' ) {
1726
+ if (schemeId == 'urn:scte:dash:cc:cea-608:2015' &&
1727
+ !this.config_.disableText) {
1727
1728
  let channelId = 1;
1728
1729
  if (value != null) {
1729
1730
  const channelAssignments = value.split(';');
@@ -1764,7 +1765,8 @@ shaka.dash.DashParser = class {
1764
1765
  // 'CC1' as channel id and 'und' as language info.
1765
1766
  closedCaptions.set('CC1', 'und');
1766
1767
  }
1767
- } else if (schemeId == 'urn:scte:dash:cc:cea-708:2015') {
1768
+ } else if (schemeId == 'urn:scte:dash:cc:cea-708:2015' &&
1769
+ !this.config_.disableText) {
1768
1770
  let serviceNumber = 1;
1769
1771
  if (value != null) {
1770
1772
  for (const captionStr of value.split(';')) {
@@ -2042,13 +2044,15 @@ shaka.dash.DashParser = class {
2042
2044
 
2043
2045
  const duration = context.periodInfo.duration || 0;
2044
2046
  const getBaseUris = context.representation.getBaseUris;
2047
+ const mimeType = context.representation.mimeType;
2048
+ const codecs = context.representation.codecs;
2045
2049
  streamInfo = {
2046
2050
  generateSegmentIndex: () => {
2047
2051
  const segmentIndex = shaka.media.SegmentIndex.forSingleSegment(
2048
2052
  periodStart, duration, getBaseUris());
2049
2053
  segmentIndex.forEachTopLevelReference((ref) => {
2050
- ref.mimeType = context.representation.mimeType;
2051
- ref.codecs = context.representation.codecs;
2054
+ ref.mimeType = mimeType;
2055
+ ref.codecs = codecs;
2052
2056
  });
2053
2057
  return Promise.resolve(segmentIndex);
2054
2058
  },
@@ -1889,7 +1889,11 @@ shaka.hls.HlsParser = class {
1889
1889
  // the value NONE. If the value is a quoted-string, it MUST match the
1890
1890
  // value of the GROUP-ID attribute of an EXT-X-MEDIA tag elsewhere in the
1891
1891
  // Playlist whose TYPE attribute is CLOSED-CAPTIONS.
1892
- if (type == ContentType.VIDEO) {
1892
+ if (type == ContentType.VIDEO ) {
1893
+ if (this.config_.disableText) {
1894
+ this.needsClosedCaptionsDetection_ = false;
1895
+ return null;
1896
+ }
1893
1897
  if (closedCaptionsAttr) {
1894
1898
  if (closedCaptionsAttr != 'NONE') {
1895
1899
  return this.groupIdToClosedCaptionsMap_.get(closedCaptionsAttr);
@@ -2800,7 +2804,9 @@ shaka.hls.HlsParser = class {
2800
2804
  languageValue = basicInfo.language;
2801
2805
  channelsCount = basicInfo.channelCount;
2802
2806
  sampleRate = basicInfo.sampleRate;
2803
- closedCaptions = basicInfo.closedCaptions;
2807
+ if (!this.config_.disableText) {
2808
+ closedCaptions = basicInfo.closedCaptions;
2809
+ }
2804
2810
 
2805
2811
  height = basicInfo.height;
2806
2812
  width = basicInfo.width;
@@ -150,6 +150,12 @@ shaka.media.AdaptationSet = class {
150
150
  }
151
151
  }
152
152
 
153
+ // Don't adapt between spatial and non spatial audio, which may
154
+ // annoy the user.
155
+ if (a.spatialAudio !== b.spatialAudio) {
156
+ return false;
157
+ }
158
+
153
159
  // We can only adapt between base-codecs.
154
160
  if (compareCodecs && !AdaptationSet.canTransitionBetween_(a, b)) {
155
161
  return false;
@@ -1827,12 +1827,10 @@ shaka.media.StreamingEngine = class {
1827
1827
  });
1828
1828
 
1829
1829
  if (!waitingForAnotherStreamToRecover) {
1830
- if (this.config_.maxDisabledTime > 0) {
1831
- const handled = this.playerInterface_.disableStream(
1832
- mediaState.stream, this.config_.maxDisabledTime);
1833
- if (handled) {
1834
- return;
1835
- }
1830
+ const handled = this.playerInterface_.disableStream(
1831
+ mediaState.stream, this.config_.maxDisabledTime);
1832
+ if (handled) {
1833
+ return;
1836
1834
  }
1837
1835
  // Reduction schedule: 80%, 60%, 40%, 20%, 16%, 12%, 8%, 4%, fail.
1838
1836
  // Note: percentages are used for comparisons to avoid rounding errors.
@@ -2319,10 +2317,11 @@ shaka.media.StreamingEngine = class {
2319
2317
  this.playerInterface_.onManifestUpdate();
2320
2318
  } else {
2321
2319
  // All other schemes are dispatched as a general 'emsg' event.
2320
+ const endTime = startTime + (eventDuration / timescale);
2322
2321
  /** @type {shaka.extern.EmsgInfo} */
2323
2322
  const emsg = {
2324
2323
  startTime: startTime,
2325
- endTime: startTime + (eventDuration / timescale),
2324
+ endTime: endTime,
2326
2325
  schemeIdUri: schemeId,
2327
2326
  value: value,
2328
2327
  timescale: timescale,
@@ -2355,17 +2354,17 @@ shaka.media.StreamingEngine = class {
2355
2354
  schemeId == 'https://developer.apple.com/streaming/emsg-id3') {
2356
2355
  // See https://aomediacodec.github.io/id3-emsg/
2357
2356
  const frames = shaka.util.Id3Utils.getID3Frames(messageData);
2358
- if (frames.length && reference) {
2357
+ if (frames.length) {
2359
2358
  /** @private {shaka.extern.ID3Metadata} */
2360
2359
  const metadata = {
2361
- cueTime: reference.startTime,
2360
+ cueTime: startTime,
2362
2361
  data: messageData,
2363
2362
  frames: frames,
2364
- dts: reference.startTime,
2365
- pts: reference.startTime,
2363
+ dts: startTime,
2364
+ pts: startTime,
2366
2365
  };
2367
2366
  this.playerInterface_.onMetadata(
2368
- [metadata], /* offset= */ 0, reference.endTime);
2367
+ [metadata], /* offset= */ 0, endTime);
2369
2368
  }
2370
2369
  }
2371
2370
  }
@@ -2722,11 +2721,9 @@ shaka.media.StreamingEngine = class {
2722
2721
  // use the backoff system to delay and backoff the error handling.
2723
2722
  await this.failureCallbackBackoff_.attempt();
2724
2723
  this.destroyer_.ensureNotDestroyed();
2725
-
2726
- const maxDisabledTime = this.getDisabledTime_(error);
2727
2724
  // Try to recover from network errors
2728
- if (error.category === shaka.util.Error.Category.NETWORK &&
2729
- maxDisabledTime > 0) {
2725
+ if (error.category === shaka.util.Error.Category.NETWORK) {
2726
+ const maxDisabledTime = this.getDisabledTime_(error);
2730
2727
  error.handled = this.playerInterface_.disableStream(
2731
2728
  mediaState.stream, maxDisabledTime);
2732
2729
 
package/lib/player.js CHANGED
@@ -3147,7 +3147,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
3147
3147
  */
3148
3148
  processTimedMetadataMediaSrc_(metadata, offset, segmentEndTime) {
3149
3149
  for (const sample of metadata) {
3150
- if (sample.data && sample.cueTime && sample.frames) {
3150
+ if (sample.data && typeof(sample.cueTime) == 'number' && sample.frames) {
3151
3151
  const start = sample.cueTime + offset;
3152
3152
  let end = segmentEndTime;
3153
3153
  // This can happen when the ID3 info arrives in a previous segment.
@@ -7227,6 +7227,10 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
7227
7227
  return false;
7228
7228
  }
7229
7229
 
7230
+ if (disableTime == 0) {
7231
+ return false;
7232
+ }
7233
+
7230
7234
  // It only makes sense to disable a stream if we have an alternative else we
7231
7235
  // end up disabling all variants.
7232
7236
  const hasAltStream = this.manifest_.variants.some((variant) => {
@@ -7813,7 +7817,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
7813
7817
  * @export
7814
7818
  */
7815
7819
  // eslint-disable-next-line no-useless-concat
7816
- shaka.Player.version = 'v4.10.7' + '-uncompiled'; // x-release-please-version
7820
+ shaka.Player.version = 'v4.10.9' + '-uncompiled'; // x-release-please-version
7817
7821
 
7818
7822
  // Initialize the deprecation system using the version string we just set
7819
7823
  // on the player.
@@ -726,6 +726,15 @@ shaka.text.UITextDisplayer = class {
726
726
  style.display = 'flex';
727
727
  style.flexDirection = 'column';
728
728
  style.alignItems = 'center';
729
+ if (cue.textAlign == Cue.textAlign.LEFT ||
730
+ cue.textAlign == Cue.textAlign.START) {
731
+ style.width = '100%';
732
+ style.alignItems = 'start';
733
+ } else if (cue.textAlign == Cue.textAlign.RIGHT ||
734
+ cue.textAlign == Cue.textAlign.END) {
735
+ style.width = '100%';
736
+ style.alignItems = 'end';
737
+ }
729
738
 
730
739
  if (cue.displayAlign == Cue.displayAlign.BEFORE) {
731
740
  style.justifyContent = 'flex-start';
@@ -811,23 +820,41 @@ shaka.text.UITextDisplayer = class {
811
820
 
812
821
  style.lineHeight = cue.lineHeight;
813
822
 
814
- // The position defines the indent of the text container in the
815
- // direction defined by the writing direction.
816
- if (cue.position != null) {
817
- if (cue.writingMode == Cue.writingMode.HORIZONTAL_TOP_TO_BOTTOM) {
818
- style.paddingLeft = cue.position;
819
- } else {
820
- style.paddingTop = cue.position;
821
- }
822
- }
823
-
824
823
  // The positionAlign attribute is an alignment for the text container in
825
824
  // the dimension of the writing direction.
826
825
  const computedPositionAlign = this.computeCuePositionAlignment_(cue);
827
826
  if (computedPositionAlign == Cue.positionAlign.LEFT) {
828
827
  style.cssFloat = 'left';
828
+ if (cue.position !== null) {
829
+ style.position = 'absolute';
830
+ if (cue.writingMode == Cue.writingMode.HORIZONTAL_TOP_TO_BOTTOM) {
831
+ style.left = cue.position + '%';
832
+ style.width = 'auto';
833
+ } else {
834
+ style.top = cue.position + '%';
835
+ }
836
+ }
829
837
  } else if (computedPositionAlign == Cue.positionAlign.RIGHT) {
830
838
  style.cssFloat = 'right';
839
+ if (cue.position !== null) {
840
+ style.position = 'absolute';
841
+ if (cue.writingMode == Cue.writingMode.HORIZONTAL_TOP_TO_BOTTOM) {
842
+ style.right = cue.position + '%';
843
+ style.width = 'auto';
844
+ } else {
845
+ style.bottom = cue.position + '%';
846
+ }
847
+ }
848
+ } else {
849
+ if (cue.position !== null && cue.position != 50) {
850
+ style.position = 'absolute';
851
+ if (cue.writingMode == Cue.writingMode.HORIZONTAL_TOP_TO_BOTTOM) {
852
+ style.left = cue.position + '%';
853
+ style.width = 'auto';
854
+ } else {
855
+ style.top = cue.position + '%';
856
+ }
857
+ }
831
858
  }
832
859
 
833
860
  style.textAlign = cue.textAlign;
@@ -1242,7 +1242,7 @@ shaka.util.PeriodCombiner = class {
1242
1242
  return true;
1243
1243
  } else if (candidateRoleMatches.length < bestRoleMatches.length) {
1244
1244
  return false;
1245
- } else {
1245
+ } else if (candidate.roles.length !== best.roles.length) {
1246
1246
  // Both streams have the same role overlap with the outputStream
1247
1247
  // If this is the case, choose the stream with the fewer roles overall.
1248
1248
  // Streams that match best together tend to be streams with the same
@@ -949,13 +949,17 @@ shaka.util.StreamUtils = class {
949
949
  if (!keySystemConfig.audio) {
950
950
  // KeySystemTrackConfiguration
951
951
  keySystemConfig.audio = {
952
- encryptionScheme: info.encryptionScheme,
953
952
  robustness: info.audioRobustness,
954
953
  };
954
+ if (info.encryptionScheme) {
955
+ keySystemConfig.audio.encryptionScheme = info.encryptionScheme;
956
+ }
955
957
  } else {
956
- keySystemConfig.audio.encryptionScheme =
957
- keySystemConfig.audio.encryptionScheme ||
958
- info.encryptionScheme;
958
+ if (info.encryptionScheme) {
959
+ keySystemConfig.audio.encryptionScheme =
960
+ keySystemConfig.audio.encryptionScheme ||
961
+ info.encryptionScheme;
962
+ }
959
963
  keySystemConfig.audio.robustness =
960
964
  keySystemConfig.audio.robustness ||
961
965
  info.audioRobustness;
@@ -970,13 +974,17 @@ shaka.util.StreamUtils = class {
970
974
  if (!keySystemConfig.video) {
971
975
  // KeySystemTrackConfiguration
972
976
  keySystemConfig.video = {
973
- encryptionScheme: info.encryptionScheme,
974
977
  robustness: info.videoRobustness,
975
978
  };
979
+ if (info.encryptionScheme) {
980
+ keySystemConfig.video.encryptionScheme = info.encryptionScheme;
981
+ }
976
982
  } else {
977
- keySystemConfig.video.encryptionScheme =
978
- keySystemConfig.video.encryptionScheme ||
979
- info.encryptionScheme;
983
+ if (info.encryptionScheme) {
984
+ keySystemConfig.video.encryptionScheme =
985
+ keySystemConfig.video.encryptionScheme ||
986
+ info.encryptionScheme;
987
+ }
980
988
  keySystemConfig.video.robustness =
981
989
  keySystemConfig.video.robustness ||
982
990
  info.videoRobustness;
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.10.7",
4
+ "version": "4.10.9",
5
5
  "homepage": "https://github.com/shaka-project/shaka-player",
6
6
  "author": "Google",
7
7
  "maintainers": [
package/ui/seek_bar.js CHANGED
@@ -455,8 +455,8 @@ shaka.ui.SeekBar = class extends shaka.ui.RangeElement {
455
455
  * @private
456
456
  */
457
457
  onAdCuePointsChanged_() {
458
- this.markAdBreaks_();
459
458
  const action = () => {
459
+ this.markAdBreaks_();
460
460
  const seekRange = this.player.seekRange();
461
461
  const seekRangeSize = seekRange.end - seekRange.start;
462
462
  const minSeekBarWindow =
@@ -127,7 +127,7 @@ shaka.ui.SkipAdButton = class extends shaka.ui.Element {
127
127
  * @private
128
128
  */
129
129
  onAdStarted_() {
130
- if (this.ad.isSkippable()) {
130
+ if (this.ad.isSkippable() && this.ad.needsSkipUI()) {
131
131
  shaka.ui.Utils.setDisplay(this.button_, true);
132
132
  shaka.ui.Utils.setDisplay(this.counter_, true);
133
133
  this.counter_.textContent = '';