shaka-player 4.11.4 → 4.11.5

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.
@@ -152,6 +152,14 @@ shaka.hls.HlsParser = class {
152
152
  */
153
153
  this.lowestSyncTime_ = Infinity;
154
154
 
155
+ /**
156
+ * Flag to indicate if any of the media playlists use
157
+ * EXT-X-PROGRAM-DATE-TIME.
158
+ *
159
+ * @private {boolean}
160
+ */
161
+ this.usesProgramDateTime_ = false;
162
+
155
163
  /**
156
164
  * Whether the streams have previously been "finalized"; that is to say,
157
165
  * whether we have loaded enough streams to know information about the asset
@@ -621,9 +629,10 @@ shaka.hls.HlsParser = class {
621
629
  * Align the streams by sequence number by dropping early segments. Then
622
630
  * offset the streams to begin at presentation time 0.
623
631
  * @param {!Array.<!shaka.hls.HlsParser.StreamInfo>} streamInfos
632
+ * @param {boolean=} force
624
633
  * @private
625
634
  */
626
- syncStreamsWithSequenceNumber_(streamInfos) {
635
+ syncStreamsWithSequenceNumber_(streamInfos, force = false) {
627
636
  // We assume that, when this is first called, we have enough info to
628
637
  // determine how to use the program date times (e.g. we have both a video
629
638
  // and an audio, and all other videos and audios match those).
@@ -678,7 +687,7 @@ shaka.hls.HlsParser = class {
678
687
  this.minSequenceNumber_);
679
688
 
680
689
  for (const streamInfo of streamInfos) {
681
- if (!this.ignoreManifestProgramDateTimeFor_(streamInfo.type)) {
690
+ if (!this.ignoreManifestProgramDateTimeFor_(streamInfo.type) && !force) {
682
691
  continue;
683
692
  }
684
693
  const segmentIndex = streamInfo.stream.segmentIndex;
@@ -2750,8 +2759,12 @@ shaka.hls.HlsParser = class {
2750
2759
  }
2751
2760
  }
2752
2761
  this.notifySegmentsForStreams_(streamInfos.map((s) => s.stream));
2753
- if (this.config_.hls.ignoreManifestProgramDateTime) {
2754
- this.syncStreamsWithSequenceNumber_(streamInfos);
2762
+ const liveWithNoProgramaDateTime =
2763
+ this.isLive_() && !this.usesProgramDateTime_;
2764
+ if (this.config_.hls.ignoreManifestProgramDateTime ||
2765
+ liveWithNoProgramaDateTime) {
2766
+ this.syncStreamsWithSequenceNumber_(
2767
+ streamInfos, liveWithNoProgramaDateTime);
2755
2768
  } else {
2756
2769
  this.syncStreamsWithProgramDateTime_(streamInfos);
2757
2770
  if (this.config_.hls.ignoreManifestProgramDateTimeForTypes.length > 0) {
@@ -3624,6 +3637,7 @@ shaka.hls.HlsParser = class {
3624
3637
  syncTime = shaka.util.TXml.parseDate(dateTimeTag.value);
3625
3638
  goog.asserts.assert(syncTime != null,
3626
3639
  'EXT-X-PROGRAM-DATE-TIME format not valid');
3640
+ this.usesProgramDateTime_ = true;
3627
3641
  }
3628
3642
  }
3629
3643
 
@@ -78,6 +78,9 @@ shaka.media.PresentationTimeline = class {
78
78
  /** @private {boolean} */
79
79
  this.static_ = true;
80
80
 
81
+ /** @private {boolean} */
82
+ this.isLive2VodTransition_ = false;
83
+
81
84
  /** @private {number} */
82
85
  this.userSeekStart_ = 0;
83
86
 
@@ -179,6 +182,9 @@ shaka.media.PresentationTimeline = class {
179
182
  */
180
183
  setStatic(isStatic) {
181
184
  // NOTE: the argument name is not "static" because that's a keyword in ES6
185
+ if (isStatic && !this.static_) {
186
+ this.isLive2VodTransition_ = true;
187
+ }
182
188
  this.static_ = isStatic;
183
189
  }
184
190
 
@@ -419,7 +425,7 @@ shaka.media.PresentationTimeline = class {
419
425
  // No data yet, and Math.min(null, startTime) is always 0. So just store
420
426
  // startTime.
421
427
  this.minSegmentStartTime_ = startTime;
422
- } else {
428
+ } else if (!this.isLive2VodTransition_) {
423
429
  this.minSegmentStartTime_ =
424
430
  Math.min(this.minSegmentStartTime_, startTime);
425
431
  }
package/lib/player.js CHANGED
@@ -7080,6 +7080,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
7080
7080
  oldTrack = shaka.util.StreamUtils.variantToTrack(currentVariant);
7081
7081
  }
7082
7082
  const newTrack = shaka.util.StreamUtils.variantToTrack(variant);
7083
+ newTrack.active = true;
7083
7084
 
7084
7085
  if (fromAdaptation) {
7085
7086
  // Dispatch an 'adaptation' event
@@ -7231,27 +7232,28 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
7231
7232
  * @private
7232
7233
  */
7233
7234
  onSegmentAppended_(start, end, contentType, isMuxed) {
7234
- // When we append a segment to media source (via streaming engine) we are
7235
- // changing what data we have buffered, so notify the playhead of the
7236
- // change.
7237
- if (this.playhead_) {
7238
- this.playhead_.notifyOfBufferingChange();
7239
- // Skip the initial buffer gap
7240
- const startTime = this.mediaSourceEngine_.bufferStart(contentType);
7241
- const ContentType = shaka.util.ManifestParserUtils.ContentType;
7242
- if (
7243
- !this.isLive() &&
7244
- // If not paused then GapJumpingController will handle this gap.
7245
- this.video_.paused &&
7246
- startTime != null &&
7247
- contentType != ContentType.TEXT &&
7248
- startTime > 0 &&
7249
- this.playhead_.getTime() < startTime
7250
- ) {
7251
- this.playhead_.setStartTime(startTime);
7252
- }
7253
- }
7254
- this.pollBufferState_();
7235
+ const ContentType = shaka.util.ManifestParserUtils.ContentType;
7236
+ if (contentType != ContentType.TEXT) {
7237
+ // When we append a segment to media source (via streaming engine) we are
7238
+ // changing what data we have buffered, so notify the playhead of the
7239
+ // change.
7240
+ if (this.playhead_) {
7241
+ this.playhead_.notifyOfBufferingChange();
7242
+ // Skip the initial buffer gap
7243
+ const startTime = this.mediaSourceEngine_.bufferStart(contentType);
7244
+ if (
7245
+ !this.isLive() &&
7246
+ // If not paused then GapJumpingController will handle this gap.
7247
+ this.video_.paused &&
7248
+ startTime != null &&
7249
+ startTime > 0 &&
7250
+ this.playhead_.getTime() < startTime
7251
+ ) {
7252
+ this.playhead_.setStartTime(startTime);
7253
+ }
7254
+ }
7255
+ this.pollBufferState_();
7256
+ }
7255
7257
 
7256
7258
  // Dispatch an event for users to consume, too.
7257
7259
  const data = new Map()
@@ -8072,7 +8074,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
8072
8074
  * @export
8073
8075
  */
8074
8076
  // eslint-disable-next-line no-useless-concat, max-len
8075
- shaka.Player.version = 'v4.11.4' + '-uncompiled'; // x-release-please-version
8077
+ shaka.Player.version = 'v4.11.5' + '-uncompiled'; // x-release-please-version
8076
8078
 
8077
8079
  // Initialize the deprecation system using the version string we just set
8078
8080
  // on the player.
@@ -7,6 +7,7 @@
7
7
  goog.provide('shaka.polyfill.EncryptionScheme');
8
8
 
9
9
  goog.require('shaka.polyfill');
10
+ goog.require('shaka.util.Platform');
10
11
 
11
12
  /**
12
13
  * @summary A polyfill to add support for EncryptionScheme queries in EME.
@@ -23,6 +24,14 @@ shaka.polyfill.EncryptionScheme = class {
23
24
  * @export
24
25
  */
25
26
  static install() {
27
+ // Skip polyfill for PlayStation 4 and SkyQ devices due to known crashes
28
+ // caused by unsupported encryptionScheme handling. These platforms do not
29
+ // require the polyfill, and forcing encryptionScheme processing can result
30
+ // in playback crashes.
31
+ if (shaka.util.Platform.isPS4() || shaka.util.Platform.isSkyQ()) {
32
+ return;
33
+ }
34
+
26
35
  EncryptionSchemePolyfills.install();
27
36
  }
28
37
  };
@@ -301,7 +301,8 @@ shaka.util.Platform = class {
301
301
  !shaka.util.Platform.isPS4() &&
302
302
  !shaka.util.Platform.isAmazonFireTV() &&
303
303
  !shaka.util.Platform.isWPE() &&
304
- !shaka.util.Platform.isZenterio();
304
+ !shaka.util.Platform.isZenterio() &&
305
+ !shaka.util.Platform.isSkyQ();
305
306
  }
306
307
 
307
308
  /**
@@ -346,6 +347,13 @@ shaka.util.Platform = class {
346
347
  return shaka.util.Platform.userAgentContains_('SOPOpenBrowser');
347
348
  }
348
349
 
350
+ /**
351
+ * Check if the current platform is SkyQ STB.
352
+ */
353
+ static isSkyQ() {
354
+ return shaka.util.Platform.userAgentContains_('Sky_STB');
355
+ }
356
+
349
357
  /**
350
358
  * Check if the current platform is Amazon Fire TV.
351
359
  * https://developer.amazon.com/docs/fire-tv/identify-amazon-fire-tv-devices.html
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.11.4",
4
+ "version": "4.11.5",
5
5
  "homepage": "https://github.com/shaka-project/shaka-player",
6
6
  "author": "Google",
7
7
  "maintainers": [
@@ -19,6 +19,7 @@ goog.require('shaka.ui.SettingsMenu');
19
19
  goog.require('shaka.ui.Utils');
20
20
  goog.require('shaka.util.Dom');
21
21
  goog.require('shaka.util.FakeEvent');
22
+ goog.require('shaka.util.Functional');
22
23
  goog.requireType('shaka.ui.Controls');
23
24
 
24
25
 
@@ -91,6 +92,7 @@ shaka.ui.ResolutionSelection = class extends shaka.ui.SettingsMenu {
91
92
  return false;
92
93
  }
93
94
  if (this.controls.getConfig().showAudioChannelCountVariants &&
95
+ track.channelsCount && selectedTrack.channelsCount &&
94
96
  track.channelsCount != selectedTrack.channelsCount) {
95
97
  return false;
96
98
  }
@@ -117,7 +119,8 @@ shaka.ui.ResolutionSelection = class extends shaka.ui.SettingsMenu {
117
119
  return tracks.findIndex((t) => t.bandwidth == track.bandwidth) == idx;
118
120
  });
119
121
  } else {
120
- const audiosIds = [...new Set(tracks.map((t) => t.audioId))];
122
+ const audiosIds = [...new Set(tracks.map((t) => t.audioId))]
123
+ .filter(shaka.util.Functional.isNotNull);
121
124
  if (audiosIds.length > 1) {
122
125
  tracks = tracks.filter((track, idx) => {
123
126
  // Keep the first one with the same height and framerate or bandwidth.