shaka-player 4.7.2 → 4.7.4

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 (36) hide show
  1. package/README.md +3 -1
  2. package/dist/deps.js +1 -1
  3. package/dist/locales.js +31 -31
  4. package/dist/shaka-player.compiled.d.ts +4 -0
  5. package/dist/shaka-player.compiled.debug.d.ts +4 -0
  6. package/dist/shaka-player.compiled.debug.externs.js +5 -0
  7. package/dist/shaka-player.compiled.debug.js +314 -311
  8. package/dist/shaka-player.compiled.debug.map +3 -3
  9. package/dist/shaka-player.compiled.externs.js +5 -0
  10. package/dist/shaka-player.compiled.js +1120 -1121
  11. package/dist/shaka-player.compiled.map +3 -3
  12. package/dist/shaka-player.ui.d.ts +4 -0
  13. package/dist/shaka-player.ui.debug.d.ts +4 -0
  14. package/dist/shaka-player.ui.debug.externs.js +5 -0
  15. package/dist/shaka-player.ui.debug.js +339 -334
  16. package/dist/shaka-player.ui.debug.map +3 -3
  17. package/dist/shaka-player.ui.externs.js +5 -0
  18. package/dist/shaka-player.ui.js +1207 -1208
  19. package/dist/shaka-player.ui.map +3 -3
  20. package/lib/ads/client_side_ad.js +13 -2
  21. package/lib/ads/client_side_ad_manager.js +8 -5
  22. package/lib/cea/cea608_memory.js +1 -1
  23. package/lib/cea/cea_decoder.js +1 -1
  24. package/lib/dash/dash_parser.js +0 -1
  25. package/lib/hls/hls_parser.js +27 -2
  26. package/lib/media/media_source_engine.js +14 -9
  27. package/lib/media/presentation_timeline.js +11 -0
  28. package/lib/net/networking_utils.js +3 -1
  29. package/lib/offline/session_deleter.js +0 -8
  30. package/lib/player.js +12 -6
  31. package/lib/text/vtt_text_parser.js +5 -0
  32. package/lib/util/periods.js +284 -230
  33. package/package.json +1 -1
  34. package/ui/hidden_seek_button.js +5 -1
  35. package/ui/play_button.js +17 -0
  36. package/ui/small_play_button.js +2 -2
@@ -155,6 +155,7 @@ shaka.ads.ClientSideAd = class {
155
155
  * @export
156
156
  */
157
157
  setVolume(volume) {
158
+ this.video_.volume = volume;
158
159
  return this.manager_.setVolume(volume);
159
160
  }
160
161
 
@@ -197,16 +198,26 @@ shaka.ads.ClientSideAd = class {
197
198
  * @export
198
199
  */
199
200
  setMuted(muted) {
201
+ this.video_.muted = muted;
200
202
  // Emulate the "mute" functionality, where current, pre-mute
201
203
  // volume is saved and can be restored on unmute.
202
204
  if (muted) {
203
205
  this.volume_ = this.getVolume();
204
- this.setVolume(0);
206
+ this.manager_.setVolume(0);
205
207
  } else {
206
- this.setVolume(this.volume_);
208
+ this.manager_.setVolume(this.volume_);
207
209
  }
208
210
  }
209
211
 
212
+ /**
213
+ * It's required for a muted ad to start when autoplaying.
214
+ *
215
+ * @param {number} videoVolume
216
+ */
217
+ setInitialMuted(videoVolume) {
218
+ this.volume_ = videoVolume;
219
+ this.manager_.setVolume(0);
220
+ }
210
221
 
211
222
  /**
212
223
  * @override
@@ -234,10 +234,12 @@ shaka.ads.ClientSideAdManager = class {
234
234
  videoPlayHead.currentTime = this.video_.currentTime;
235
235
  });
236
236
  this.eventManager_.listen(this.video_, 'volumechange', () => {
237
+ if (!this.ad_) {
238
+ return;
239
+ }
240
+ this.ad_.setVolume(this.video_.volume);
237
241
  if (this.video_.muted) {
238
- this.imaAdsManager_.setVolume(0);
239
- } else {
240
- this.imaAdsManager_.setVolume(this.video_.volume);
242
+ this.ad_.setMuted(true);
241
243
  }
242
244
  });
243
245
  }
@@ -532,9 +534,10 @@ shaka.ads.ClientSideAdManager = class {
532
534
  if (this.ad_.isLinear()) {
533
535
  this.adContainer_.setAttribute('ad-active', 'true');
534
536
  this.video_.pause();
535
- this.ad_.setVolume(this.video_.volume);
536
537
  if (this.video_.muted) {
537
- this.ad_.setMuted(true);
538
+ this.ad_.setInitialMuted(this.video_.volume);
539
+ } else {
540
+ this.ad_.setVolume(this.video_.volume);
538
541
  }
539
542
  }
540
543
  }
@@ -79,7 +79,7 @@ shaka.cea.Cea608Memory = class {
79
79
  * @return {?shaka.extern.ICaptionDecoder.ClosedCaption}
80
80
  */
81
81
  forceEmit(startTime, endTime) {
82
- const stream = `CC${(this.fieldNum_<< 1) | this.channelNum_ +1}`;
82
+ const stream = `CC${((this.fieldNum_<< 1) | this.channelNum_) + 1}`;
83
83
  const topLevelCue = new shaka.text.Cue(
84
84
  startTime, endTime, /* payload= */ '');
85
85
  topLevelCue.lineInterpretation =
@@ -283,7 +283,7 @@ shaka.cea.CeaDecoder = class {
283
283
  // Get the correct stream for this caption packet (CC1, ..., CC4)
284
284
  const selectedChannel = fieldNum ?
285
285
  this.currentField2Channel_ : this.currentField1Channel_;
286
- const selectedMode = `CC${(fieldNum << 1) | selectedChannel + 1}`;
286
+ const selectedMode = `CC${((fieldNum << 1) | selectedChannel) + 1}`;
287
287
  const selectedStream = this.cea608ModeToStream_.get(selectedMode);
288
288
 
289
289
  // Check for bad frames (bad pairs). This can be two 0xff, two 0x00, or any
@@ -1609,7 +1609,6 @@ shaka.dash.DashParser = class {
1609
1609
  hdr,
1610
1610
  videoLayout: undefined,
1611
1611
  tilesLayout,
1612
- matchedStreams: [],
1613
1612
  accessibilityPurpose,
1614
1613
  external: false,
1615
1614
  fastSwitching: false,
@@ -979,6 +979,22 @@ shaka.hls.HlsParser = class {
979
979
  this.presentationTimeline_.setSegmentAvailabilityDuration(
980
980
  segmentAvailabilityDuration);
981
981
  }
982
+
983
+ if (!this.presentationTimeline_.isStartTimeLocked()) {
984
+ const streamInfos = Array.from(this.uriToStreamInfosMap_.values());
985
+ const activeStreamInfos =
986
+ streamInfos.filter((s) => s.stream.segmentIndex);
987
+ for (const streamInfo of activeStreamInfos) {
988
+ if (streamInfo.type != 'audio' && streamInfo.type != 'video') {
989
+ continue;
990
+ }
991
+ const firstReference = streamInfo.stream.segmentIndex.get(0);
992
+ if (firstReference && firstReference.syncTime) {
993
+ const syncTime = firstReference.syncTime;
994
+ this.presentationTimeline_.setPresentationStartTime(syncTime);
995
+ }
996
+ }
997
+ }
982
998
  } else {
983
999
  // Use the minimum duration as the presentation duration.
984
1000
  this.presentationTimeline_.setDuration(this.getMinDuration_());
@@ -2237,7 +2253,7 @@ shaka.hls.HlsParser = class {
2237
2253
  stream.keyIds = realStream.keyIds;
2238
2254
  stream.mimeType = realStream.mimeType;
2239
2255
  stream.bandwidth = realStream.bandwidth;
2240
- stream.codecs = realStream.codecs || stream.codecs;
2256
+ stream.codecs = stream.codecs || realStream.codecs;
2241
2257
 
2242
2258
  // Since we lazy-loaded this content, the player may need to create new
2243
2259
  // sessions for the DRM info in this stream.
@@ -3452,6 +3468,13 @@ shaka.hls.HlsParser = class {
3452
3468
  if (this.isLive_() && mediaSequenceToStartTime.has(position)) {
3453
3469
  firstStartTime = mediaSequenceToStartTime.get(position);
3454
3470
  }
3471
+ // This is for recovering from disconnects.
3472
+ if (firstStartTime === 0 &&
3473
+ this.presentationType_ == shaka.hls.HlsParser.PresentationType_.LIVE &&
3474
+ mediaSequenceToStartTime.size > 0 &&
3475
+ !mediaSequenceToStartTime.has(position)) {
3476
+ firstStartTime = this.presentationTimeline_.getSegmentAvailabilityStart();
3477
+ }
3455
3478
 
3456
3479
  /** @type {!Array.<!shaka.media.SegmentReference>} */
3457
3480
  const references = [];
@@ -3766,7 +3789,9 @@ shaka.hls.HlsParser = class {
3766
3789
 
3767
3790
  contentMimeType = response.headers['content-type'];
3768
3791
  } catch (error) {
3769
- if (error && error.code == shaka.util.Error.Code.HTTP_ERROR) {
3792
+ if (error &&
3793
+ (error.code == shaka.util.Error.Code.HTTP_ERROR ||
3794
+ error.code == shaka.util.Error.Code.BAD_HTTP_STATUS)) {
3770
3795
  headRequest.method = 'GET';
3771
3796
  const response = await this.makeNetworkRequest_(
3772
3797
  headRequest, requestType, {type});
@@ -168,9 +168,6 @@ shaka.media.MediaSourceEngine = class {
168
168
 
169
169
  const mediaSource = new ManagedMediaSource();
170
170
 
171
- this.eventManager_.listenOnce(
172
- mediaSource, 'sourceopen', () => this.onSourceOpen_(p));
173
-
174
171
  this.eventManager_.listen(
175
172
  mediaSource, 'startstreaming', () => {
176
173
  this.streamingAllowed_ = true;
@@ -181,6 +178,9 @@ shaka.media.MediaSourceEngine = class {
181
178
  this.streamingAllowed_ = false;
182
179
  });
183
180
 
181
+ this.eventManager_.listenOnce(
182
+ mediaSource, 'sourceopen', () => this.onSourceOpen_(p));
183
+
184
184
  // Correctly set when playback has begun.
185
185
  this.eventManager_.listenOnce(this.video_, 'playing', () => {
186
186
  this.playbackHasBegun_ = true;
@@ -460,9 +460,10 @@ shaka.media.MediaSourceEngine = class {
460
460
  * @param {shaka.util.ManifestParserUtils.ContentType} contentType
461
461
  * @param {shaka.extern.Stream} stream
462
462
  * @param {string} codecs
463
+ * @param {boolean=} forceTransmux
463
464
  * @private
464
465
  */
465
- initSourceBuffer_(contentType, stream, codecs) {
466
+ initSourceBuffer_(contentType, stream, codecs, forceTransmux = false) {
466
467
  const ContentType = shaka.util.ManifestParserUtils.ContentType;
467
468
 
468
469
  goog.asserts.assert(
@@ -474,7 +475,7 @@ shaka.media.MediaSourceEngine = class {
474
475
  if (contentType == ContentType.TEXT) {
475
476
  this.reinitText(mimeType, this.sequenceMode_, stream.external);
476
477
  } else {
477
- let needTransmux = this.config_.forceTransmux;
478
+ let needTransmux = this.config_.forceTransmux || forceTransmux;
478
479
  if (!shaka.media.Capabilities.isTypeSupported(mimeType) ||
479
480
  (!this.sequenceMode_ &&
480
481
  shaka.util.MimeUtils.RAW_FORMATS.includes(mimeType))) {
@@ -491,8 +492,10 @@ shaka.media.MediaSourceEngine = class {
491
492
  ContentType.VIDEO, (codecs || '').split(','));
492
493
  if (audioCodec && videoCodec) {
493
494
  this.needSplitMuxedContent_ = true;
494
- this.initSourceBuffer_(ContentType.AUDIO, stream, audioCodec);
495
- this.initSourceBuffer_(ContentType.VIDEO, stream, videoCodec);
495
+ this.initSourceBuffer_(
496
+ ContentType.AUDIO, stream, audioCodec, /* forceTransmux= */ true);
497
+ this.initSourceBuffer_(
498
+ ContentType.VIDEO, stream, videoCodec, /* forceTransmux= */ true);
496
499
  return;
497
500
  }
498
501
  const transmuxerPlugin =
@@ -1854,7 +1857,8 @@ shaka.media.MediaSourceEngine = class {
1854
1857
  let needTransmux = this.config_.forceTransmux;
1855
1858
  if (!shaka.media.Capabilities.isTypeSupported(newMimeType) ||
1856
1859
  (!this.sequenceMode_ &&
1857
- shaka.util.MimeUtils.RAW_FORMATS.includes(newMimeType))) {
1860
+ shaka.util.MimeUtils.RAW_FORMATS.includes(newMimeType)) ||
1861
+ codecs.includes(',')) {
1858
1862
  needTransmux = true;
1859
1863
  }
1860
1864
  const TransmuxerEngine = shaka.transmuxer.TransmuxerEngine;
@@ -1935,7 +1939,8 @@ shaka.media.MediaSourceEngine = class {
1935
1939
  let needTransmux = this.config_.forceTransmux;
1936
1940
  if (!shaka.media.Capabilities.isTypeSupported(newMimeType) ||
1937
1941
  (!this.sequenceMode_ &&
1938
- shaka.util.MimeUtils.RAW_FORMATS.includes(newMimeType))) {
1942
+ shaka.util.MimeUtils.RAW_FORMATS.includes(newMimeType)) ||
1943
+ stream.codecs.includes(',')) {
1939
1944
  needTransmux = true;
1940
1945
  }
1941
1946
  const newMimeTypeWithAllCodecs =
@@ -328,6 +328,17 @@ shaka.media.PresentationTimeline = class {
328
328
  }
329
329
 
330
330
 
331
+ /**
332
+ * Returns if the presentation timeline's start time is locked.
333
+ *
334
+ * @return {boolean}
335
+ * @export
336
+ */
337
+ isStartTimeLocked() {
338
+ return this.startTimeLocked_;
339
+ }
340
+
341
+
331
342
  /**
332
343
  * Gives PresentationTimeline a Stream's minimum segment start time.
333
344
  *
@@ -37,7 +37,9 @@ shaka.net.NetworkingUtils = class {
37
37
  const response = await netEngine.request(type, request).promise;
38
38
  mimeType = response.headers['content-type'];
39
39
  } catch (error) {
40
- if (error && error.code == shaka.util.Error.Code.HTTP_ERROR) {
40
+ if (error &&
41
+ (error.code == shaka.util.Error.Code.HTTP_ERROR ||
42
+ error.code == shaka.util.Error.Code.BAD_HTTP_STATUS)) {
41
43
  request.method = 'GET';
42
44
  const response = await netEngine.request(type, request).promise;
43
45
  mimeType = response.headers['content-type'];
@@ -71,14 +71,6 @@ shaka.offline.SessionDeleter = class {
71
71
  return [];
72
72
  }
73
73
 
74
- try {
75
- await drmEngine.setServerCertificate();
76
- } catch (e) {
77
- shaka.log.warning('Error setting server certificate', e);
78
- await drmEngine.destroy();
79
- return [];
80
- }
81
-
82
74
  /** @type {!Array.<string>} */
83
75
  const sessionIds = [];
84
76
  await Promise.all(bucket.sessionIds.map(async (sessionId) => {
package/lib/player.js CHANGED
@@ -4837,12 +4837,18 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
4837
4837
 
4838
4838
  const references = [];
4839
4839
  for (const cue of cues) {
4840
- const imageUri = shaka.util.ManifestParserUtils.resolveUris(
4841
- [uri], [cue.payload])[0];
4840
+ let uris = null;
4841
+ const getUris = () => {
4842
+ if (uris == null) {
4843
+ uris = shaka.util.ManifestParserUtils.resolveUris(
4844
+ [uri], [cue.payload]);
4845
+ }
4846
+ return uris || [];
4847
+ };
4842
4848
  const reference = new shaka.media.SegmentReference(
4843
4849
  cue.startTime,
4844
4850
  cue.endTime,
4845
- () => [imageUri],
4851
+ getUris,
4846
4852
  /* startByte= */ 0,
4847
4853
  /* endByte= */ null,
4848
4854
  /* initSegmentReference= */ null,
@@ -4850,8 +4856,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
4850
4856
  /* appendWindowStart= */ 0,
4851
4857
  /* appendWindowEnd= */ Infinity,
4852
4858
  );
4853
- if (imageUri.includes('#xywh')) {
4854
- const spriteInfo = imageUri.split('#xywh=')[1].split(',');
4859
+ if (cue.payload.includes('#xywh')) {
4860
+ const spriteInfo = cue.payload.split('#xywh=')[1].split(',');
4855
4861
  if (spriteInfo.length === 4) {
4856
4862
  reference.setThumbnailSprite({
4857
4863
  height: parseInt(spriteInfo[3], 10),
@@ -6865,7 +6871,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
6865
6871
  * @export
6866
6872
  */
6867
6873
  // eslint-disable-next-line no-useless-concat
6868
- shaka.Player.version = 'v4.7.2' + '-uncompiled'; // x-release-please-version
6874
+ shaka.Player.version = 'v4.7.4' + '-uncompiled'; // x-release-please-version
6869
6875
 
6870
6876
  // Initialize the deprecation system using the version string we just set
6871
6877
  // on the player.
@@ -451,6 +451,11 @@ shaka.text.VttTextParser = class {
451
451
  */
452
452
  static parseCueStyles(payload, rootCue, styles) {
453
453
  const VttTextParser = shaka.text.VttTextParser;
454
+ // Optimization for unstyled payloads.
455
+ if (!payload.includes('<')) {
456
+ rootCue.payload = VttTextParser.htmlUnescape_(payload);
457
+ return;
458
+ }
454
459
  if (styles.size === 0) {
455
460
  VttTextParser.addDefaultTextColor_(styles);
456
461
  }