shaka-player 4.10.13 → 4.11.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 (91) hide show
  1. package/README.md +5 -1
  2. package/dist/controls.css +3 -3
  3. package/dist/controls.css.map +1 -1
  4. package/dist/deps.js +11 -11
  5. package/dist/locales.js +38 -34
  6. package/dist/shaka-player.compiled.d.ts +68 -33
  7. package/dist/shaka-player.compiled.debug.d.ts +68 -33
  8. package/dist/shaka-player.compiled.debug.externs.js +584 -544
  9. package/dist/shaka-player.compiled.debug.js +715 -676
  10. package/dist/shaka-player.compiled.debug.map +4 -4
  11. package/dist/shaka-player.compiled.externs.js +584 -544
  12. package/dist/shaka-player.compiled.js +1394 -1371
  13. package/dist/shaka-player.compiled.map +4 -4
  14. package/dist/shaka-player.ui.d.ts +76 -34
  15. package/dist/shaka-player.ui.debug.d.ts +76 -34
  16. package/dist/shaka-player.ui.debug.externs.js +77 -26
  17. package/dist/shaka-player.ui.debug.js +774 -720
  18. package/dist/shaka-player.ui.debug.map +4 -4
  19. package/dist/shaka-player.ui.externs.js +77 -26
  20. package/dist/shaka-player.ui.js +1649 -1617
  21. package/dist/shaka-player.ui.map +4 -4
  22. package/externs/mediasession.js +10 -1
  23. package/externs/shaka/ads.js +79 -2
  24. package/externs/shaka/manifest.js +6 -1
  25. package/externs/shaka/manifest_parser.js +6 -2
  26. package/externs/shaka/net.js +23 -2
  27. package/externs/shaka/player.js +414 -103
  28. package/externs/shaka/text.js +2 -1
  29. package/lib/abr/simple_abr_manager.js +5 -0
  30. package/lib/ads/ad_manager.js +45 -1
  31. package/lib/ads/ad_utils.js +124 -1
  32. package/lib/ads/interstitial_ad.js +9 -2
  33. package/lib/ads/interstitial_ad_manager.js +216 -101
  34. package/lib/ads/media_tailor_ad.js +1 -39
  35. package/lib/ads/media_tailor_ad_manager.js +32 -16
  36. package/lib/cea/cea608_data_channel.js +40 -8
  37. package/lib/cea/cea608_memory.js +28 -0
  38. package/lib/dash/dash_parser.js +162 -25
  39. package/lib/dash/segment_base.js +3 -2
  40. package/lib/dash/segment_list.js +6 -3
  41. package/lib/dash/segment_template.js +104 -20
  42. package/lib/hls/hls_parser.js +319 -215
  43. package/lib/media/drm_engine.js +11 -3
  44. package/lib/media/media_source_engine.js +0 -8
  45. package/lib/media/preload_manager.js +16 -4
  46. package/lib/media/segment_reference.js +3 -0
  47. package/lib/media/segment_utils.js +8 -1
  48. package/lib/media/streaming_engine.js +10 -6
  49. package/lib/mss/mss_parser.js +14 -2
  50. package/lib/net/http_fetch_plugin.js +12 -5
  51. package/lib/net/http_xhr_plugin.js +7 -3
  52. package/lib/net/networking_engine.js +21 -1
  53. package/lib/offline/manifest_converter.js +1 -0
  54. package/lib/offline/storage.js +1 -0
  55. package/lib/player.js +336 -121
  56. package/lib/text/cue.js +373 -0
  57. package/lib/text/mp4_ttml_parser.js +51 -1
  58. package/lib/text/mp4_vtt_parser.js +2 -5
  59. package/lib/text/sbv_text_parser.js +2 -31
  60. package/lib/text/srt_text_parser.js +1 -1
  61. package/lib/text/text_engine.js +1 -1
  62. package/lib/text/text_utils.js +1 -0
  63. package/lib/text/ttml_text_parser.js +14 -4
  64. package/lib/text/ui_text_displayer.js +0 -4
  65. package/lib/text/vtt_text_parser.js +10 -415
  66. package/lib/util/abortable_operation.js +8 -0
  67. package/lib/util/cmcd_manager.js +38 -0
  68. package/lib/util/error.js +16 -0
  69. package/lib/util/fake_event.js +1 -0
  70. package/lib/util/manifest_parser_utils.js +12 -3
  71. package/lib/util/player_configuration.js +4 -2
  72. package/lib/util/stream_utils.js +57 -2
  73. package/lib/util/tXml.js +2 -1
  74. package/lib/util/text_parser.js +46 -0
  75. package/lib/util/ts_parser.js +32 -3
  76. package/package.json +1 -1
  77. package/shaka-player.uncompiled.js +1 -1
  78. package/ui/chapter_selection.js +179 -0
  79. package/ui/controls.js +151 -0
  80. package/ui/enums.js +1 -0
  81. package/ui/externs/ui.js +7 -1
  82. package/ui/less/containers.less +3 -4
  83. package/ui/less/overflow_menu.less +5 -0
  84. package/ui/less/tooltip.less +1 -1
  85. package/ui/locales/en.json +1 -0
  86. package/ui/locales/es.json +1 -0
  87. package/ui/locales/fr.json +1 -0
  88. package/ui/locales/source.json +4 -0
  89. package/ui/seek_bar.js +3 -2
  90. package/ui/ui.js +2 -0
  91. package/lib/polyfill/abort_controller.js +0 -158
@@ -15,6 +15,7 @@ goog.require('shaka.log');
15
15
  goog.require('shaka.media.PreloadManager');
16
16
  goog.require('shaka.net.NetworkingEngine');
17
17
  goog.require('shaka.util.Dom');
18
+ goog.require('shaka.util.Error');
18
19
  goog.require('shaka.util.EventManager');
19
20
  goog.require('shaka.util.FakeEvent');
20
21
  goog.require('shaka.util.IReleasable');
@@ -22,6 +23,7 @@ goog.require('shaka.util.Platform');
22
23
  goog.require('shaka.util.PublicPromise');
23
24
  goog.require('shaka.util.StringUtils');
24
25
  goog.require('shaka.util.Timer');
26
+ goog.require('shaka.util.TXml');
25
27
 
26
28
 
27
29
  /**
@@ -61,11 +63,11 @@ shaka.ads.InterstitialAdManager = class {
61
63
  /** @private {!Set.<string>} */
62
64
  this.interstitialIds_ = new Set();
63
65
 
64
- /** @private {!Set.<shaka.ads.InterstitialAdManager.Interstitial>} */
66
+ /** @private {!Set.<shaka.extern.AdInterstitial>} */
65
67
  this.interstitials_ = new Set();
66
68
 
67
69
  /**
68
- * @private {!Map.<shaka.ads.InterstitialAdManager.Interstitial,
70
+ * @private {!Map.<shaka.extern.AdInterstitial,
69
71
  * Promise<?shaka.media.PreloadManager>>}
70
72
  */
71
73
  this.preloadManagerInterstitials_ = new Map();
@@ -204,48 +206,147 @@ shaka.ads.InterstitialAdManager = class {
204
206
 
205
207
 
206
208
  /**
207
- * @param {shaka.extern.Interstitial} interstitial
209
+ * @param {shaka.extern.HLSInterstitial} hlsInterstitial
208
210
  */
209
- async addMetadata(interstitial) {
211
+ async addMetadata(hlsInterstitial) {
210
212
  if (this.basePlayer_.getLoadMode() == shaka.Player.LoadMode.SRC_EQUALS &&
211
213
  this.usingBaseVideo_) {
212
214
  shaka.log.alwaysWarn(
213
- 'Unsupported interstitial when using single media element',
214
- interstitial);
215
+ 'Unsupported HLS interstitial when using single media element',
216
+ hlsInterstitial);
215
217
  return;
216
218
  }
217
219
  this.updatePlayerConfig_();
218
- let cuepointsChanged = false;
219
- const interstitialsAd = await this.getInterstitialsInfo_(interstitial);
220
- if (interstitialsAd.length) {
221
- for (const interstitialAd of interstitialsAd) {
222
- const interstitialId = JSON.stringify(interstitialAd);
223
- if (this.interstitialIds_.has(interstitialId)) {
224
- continue;
220
+ const adInterstitials = await this.getInterstitialsInfo_(hlsInterstitial);
221
+ if (adInterstitials.length) {
222
+ this.addInterstitials(adInterstitials);
223
+ } else {
224
+ shaka.log.alwaysWarn('Unsupported HLS interstitial', hlsInterstitial);
225
+ }
226
+ }
227
+
228
+ /**
229
+ * @param {shaka.extern.TimelineRegionInfo} region
230
+ */
231
+ addRegion(region) {
232
+ let alternativeMPDUri;
233
+ let alternativeMPDmode;
234
+ for (const node of region.eventNode.children) {
235
+ if (node.tagName == 'AlternativeMPD') {
236
+ const uri = node.attributes['uri'];
237
+ const mode = node.attributes['mode'];
238
+ if (uri) {
239
+ alternativeMPDUri = uri;
240
+ alternativeMPDmode = mode;
241
+ break;
225
242
  }
226
- cuepointsChanged = true;
227
- this.interstitialIds_.add(interstitialId);
228
- this.interstitials_.add(interstitialAd);
229
- let shouldPreload = false;
230
- if (interstitial.pre && this.lastTime_ == null) {
231
- shouldPreload = true;
232
- } else if (interstitialAd.startTime == 0 && !interstitialAd.canJump) {
243
+ }
244
+ }
245
+ if (!alternativeMPDUri) {
246
+ shaka.log.alwaysWarn('Unsupported MPD alternate', region);
247
+ return;
248
+ }
249
+ const isReplace = alternativeMPDmode == 'replace';
250
+ const isInsert = alternativeMPDmode == 'insert';
251
+ if (!isReplace && !isInsert) {
252
+ shaka.log.warning('Unsupported MPD alternate', region);
253
+ return;
254
+ }
255
+ const interstitial = {
256
+ id: null,
257
+ startTime: region.startTime,
258
+ endTime: isReplace ? region.endTime : null,
259
+ uri: alternativeMPDUri,
260
+ isSkippable: false,
261
+ skipOffset: null,
262
+ canJump: true,
263
+ resumeOffset: isInsert ? 0 : null,
264
+ playoutLimit: null,
265
+ once: false,
266
+ pre: false,
267
+ post: false,
268
+ timelineRange: isReplace && !isInsert,
269
+ };
270
+ this.addInterstitials([interstitial]);
271
+ }
272
+
273
+ /**
274
+ * @param {string} url
275
+ * @return {!Promise}
276
+ */
277
+ async addAdUrlInterstitial(url) {
278
+ const NetworkingEngine = shaka.net.NetworkingEngine;
279
+ const context = {
280
+ type: NetworkingEngine.AdvancedRequestType.INTERSTITIAL_AD_URL,
281
+ };
282
+ const responseData = await this.makeAdRequest_(url, context);
283
+ const data = shaka.util.TXml.parseXml(responseData, 'VAST,vmap:VMAP');
284
+ if (!data) {
285
+ throw new shaka.util.Error(
286
+ shaka.util.Error.Severity.CRITICAL,
287
+ shaka.util.Error.Category.ADS,
288
+ shaka.util.Error.Code.VAST_INVALID_XML);
289
+ }
290
+ let interstitials = [];
291
+ if (data.tagName == 'VAST') {
292
+ interstitials = shaka.ads.Utils.parseVastToInterstitials(
293
+ data, this.lastTime_);
294
+ } else if (data.tagName == 'vmap:VMAP') {
295
+ for (const ad of shaka.ads.Utils.parseVMAP(data)) {
296
+ // eslint-disable-next-line no-await-in-loop
297
+ const vastResponseData = await this.makeAdRequest_(ad.uri, context);
298
+ const vast = shaka.util.TXml.parseXml(vastResponseData, 'VAST');
299
+ if (!vast) {
300
+ throw new shaka.util.Error(
301
+ shaka.util.Error.Severity.CRITICAL,
302
+ shaka.util.Error.Category.ADS,
303
+ shaka.util.Error.Code.VAST_INVALID_XML);
304
+ }
305
+ interstitials.push(...shaka.ads.Utils.parseVastToInterstitials(
306
+ vast, ad.time));
307
+ }
308
+ }
309
+ this.addInterstitials(interstitials);
310
+ }
311
+
312
+
313
+ /**
314
+ * @param {!Array.<shaka.extern.AdInterstitial>} interstitials
315
+ */
316
+ addInterstitials(interstitials) {
317
+ if (this.basePlayer_.getLoadMode() == shaka.Player.LoadMode.SRC_EQUALS &&
318
+ this.usingBaseVideo_) {
319
+ shaka.log.alwaysWarn(
320
+ 'Unsupported interstitial when using single media element',
321
+ interstitials);
322
+ return;
323
+ }
324
+ let cuepointsChanged = false;
325
+ for (const interstitial of interstitials) {
326
+ const interstitialId = JSON.stringify(interstitial);
327
+ if (this.interstitialIds_.has(interstitialId)) {
328
+ continue;
329
+ }
330
+ cuepointsChanged = true;
331
+ this.interstitialIds_.add(interstitialId);
332
+ this.interstitials_.add(interstitial);
333
+ let shouldPreload = false;
334
+ if (interstitial.pre && this.lastTime_ == null) {
335
+ shouldPreload = true;
336
+ } else if (interstitial.startTime == 0 && !interstitial.canJump) {
337
+ shouldPreload = true;
338
+ } else if (this.lastTime_ != null) {
339
+ const difference = interstitial.startTime - this.lastTime_;
340
+ if (difference > 0 && difference <= 10) {
233
341
  shouldPreload = true;
234
- } else if (this.lastTime_ != null) {
235
- const difference = interstitial.startTime - this.lastTime_;
236
- if (difference > 0 && difference <= 10) {
237
- shouldPreload = true;
238
- }
239
342
  }
240
- if (shouldPreload) {
241
- if (!this.preloadManagerInterstitials_.has(interstitialAd)) {
242
- this.preloadManagerInterstitials_.set(
243
- interstitialAd, this.player_.preload(interstitialAd.uri));
244
- }
343
+ }
344
+ if (shouldPreload) {
345
+ if (!this.preloadManagerInterstitials_.has(interstitial)) {
346
+ this.preloadManagerInterstitials_.set(
347
+ interstitial, this.player_.preload(interstitial.uri));
245
348
  }
246
349
  }
247
- } else {
248
- shaka.log.alwaysWarn('Unsupported interstitial', interstitial);
249
350
  }
250
351
  if (cuepointsChanged) {
251
352
  this.cuepointsChanged_();
@@ -274,7 +375,7 @@ shaka.ads.InterstitialAdManager = class {
274
375
  /**
275
376
  * @param {boolean} needPreRoll
276
377
  * @param {number=} numberToSkip
277
- * @return {?shaka.ads.InterstitialAdManager.Interstitial}
378
+ * @return {?shaka.extern.AdInterstitial}
278
379
  * @private
279
380
  */
280
381
  getCurrentInterstitial_(needPreRoll, numberToSkip = 0) {
@@ -314,7 +415,7 @@ shaka.ads.InterstitialAdManager = class {
314
415
 
315
416
 
316
417
  /**
317
- * @param {shaka.ads.InterstitialAdManager.Interstitial} interstitial
418
+ * @param {shaka.extern.AdInterstitial} interstitial
318
419
  * @param {number} sequenceLength
319
420
  * @param {number} adPosition
320
421
  * @param {number} initialTime the clock time the ad started at
@@ -475,7 +576,8 @@ shaka.ads.InterstitialAdManager = class {
475
576
  };
476
577
 
477
578
  const ad = new shaka.ads.InterstitialAd(this.video_,
478
- interstitial.isSkippable, onSkip, sequenceLength, adPosition);
579
+ interstitial.isSkippable, interstitial.skipOffset,
580
+ onSkip, sequenceLength, adPosition);
479
581
  if (!this.usingBaseVideo_) {
480
582
  ad.setMuted(this.baseVideo_.muted);
481
583
  ad.setVolume(this.baseVideo_.volume);
@@ -489,21 +591,36 @@ shaka.ads.InterstitialAdManager = class {
489
591
  this.onEvent_(new shaka.util.FakeEvent(
490
592
  shaka.ads.Utils.AD_SKIP_STATE_CHANGED));
491
593
  }
594
+ const eventsSent = new Set();
492
595
  this.adEventManager_.listenOnce(this.player_, 'error', error);
493
- this.adEventManager_.listenOnce(this.player_, 'firstquartile', () => {
494
- updateBaseVideoTime();
495
- this.onEvent_(
496
- new shaka.util.FakeEvent(shaka.ads.Utils.AD_FIRST_QUARTILE));
497
- });
498
- this.adEventManager_.listenOnce(this.player_, 'midpoint', () => {
499
- updateBaseVideoTime();
500
- this.onEvent_(
501
- new shaka.util.FakeEvent(shaka.ads.Utils.AD_MIDPOINT));
502
- });
503
- this.adEventManager_.listenOnce(this.player_, 'thirdquartile', () => {
504
- updateBaseVideoTime();
505
- this.onEvent_(
506
- new shaka.util.FakeEvent(shaka.ads.Utils.AD_THIRD_QUARTILE));
596
+ this.adEventManager_.listen(this.video_, 'timeupdate', () => {
597
+ const duration = this.video_.duration;
598
+ if (!duration) {
599
+ return;
600
+ }
601
+ if (interstitial.isSkippable && interstitial.skipOffset &&
602
+ ad.canSkipNow() && ad.getRemainingTime() > 0 &&
603
+ ad.getDuration() > 0) {
604
+ this.onEvent_(
605
+ new shaka.util.FakeEvent(shaka.ads.Utils.AD_SKIP_STATE_CHANGED));
606
+ }
607
+ const currentPercent = 100 * this.video_.currentTime / duration;
608
+ if (currentPercent >= 25 && !eventsSent.has('firstquartile')) {
609
+ updateBaseVideoTime();
610
+ this.onEvent_(
611
+ new shaka.util.FakeEvent(shaka.ads.Utils.AD_FIRST_QUARTILE));
612
+ eventsSent.add('firstquartile');
613
+ } else if (currentPercent >= 50 && !eventsSent.has('midpoint')) {
614
+ updateBaseVideoTime();
615
+ this.onEvent_(
616
+ new shaka.util.FakeEvent(shaka.ads.Utils.AD_MIDPOINT));
617
+ eventsSent.add('midpoint');
618
+ } else if (currentPercent >= 75 && !eventsSent.has('thirdquartile')) {
619
+ updateBaseVideoTime();
620
+ this.onEvent_(
621
+ new shaka.util.FakeEvent(shaka.ads.Utils.AD_THIRD_QUARTILE));
622
+ eventsSent.add('thirdquartile');
623
+ }
507
624
  });
508
625
  this.adEventManager_.listenOnce(this.player_, 'complete', complete);
509
626
  this.adEventManager_.listen(this.video_, 'play', () => {
@@ -556,21 +673,27 @@ shaka.ads.InterstitialAdManager = class {
556
673
 
557
674
 
558
675
  /**
559
- * @param {shaka.extern.Interstitial} interstitial
560
- * @return {!Promise.<!Array.<shaka.ads.InterstitialAdManager.Interstitial>>}
676
+ * @param {shaka.extern.HLSInterstitial} hlsInterstitial
677
+ * @return {!Promise.<!Array.<shaka.extern.AdInterstitial>>}
561
678
  * @private
562
679
  */
563
- async getInterstitialsInfo_(interstitial) {
680
+ async getInterstitialsInfo_(hlsInterstitial) {
564
681
  const interstitialsAd = [];
565
- if (!interstitial) {
682
+ if (!hlsInterstitial) {
566
683
  return interstitialsAd;
567
684
  }
568
- const assetUri = interstitial.values.find((v) => v.key == 'X-ASSET-URI');
569
- const assetList = interstitial.values.find((v) => v.key == 'X-ASSET-LIST');
685
+ const assetUri = hlsInterstitial.values.find((v) => v.key == 'X-ASSET-URI');
686
+ const assetList =
687
+ hlsInterstitial.values.find((v) => v.key == 'X-ASSET-LIST');
570
688
  if (!assetUri && !assetList) {
571
689
  return interstitialsAd;
572
690
  }
573
- const restrict = interstitial.values.find((v) => v.key == 'X-RESTRICT');
691
+ let id = null;
692
+ const hlsInterstitialId = hlsInterstitial.values.find((v) => v.key == 'ID');
693
+ if (hlsInterstitialId) {
694
+ id = /** @type {string} */(hlsInterstitialId.data);
695
+ }
696
+ const restrict = hlsInterstitial.values.find((v) => v.key == 'X-RESTRICT');
574
697
  let isSkippable = true;
575
698
  let canJump = true;
576
699
  if (restrict && restrict.data) {
@@ -579,7 +702,8 @@ shaka.ads.InterstitialAdManager = class {
579
702
  canJump = !data.includes('JUMP');
580
703
  }
581
704
  let resumeOffset = null;
582
- const resume = interstitial.values.find((v) => v.key == 'X-RESUME-OFFSET');
705
+ const resume =
706
+ hlsInterstitial.values.find((v) => v.key == 'X-RESUME-OFFSET');
583
707
  if (resume) {
584
708
  const resumeOffsetString = /** @type {string} */(resume.data);
585
709
  resumeOffset = parseFloat(resumeOffsetString);
@@ -588,7 +712,8 @@ shaka.ads.InterstitialAdManager = class {
588
712
  }
589
713
  }
590
714
  let playoutLimit = null;
591
- const playout = interstitial.values.find((v) => v.key == 'X-PLAYOUT-LIMIT');
715
+ const playout =
716
+ hlsInterstitial.values.find((v) => v.key == 'X-PLAYOUT-LIMIT');
592
717
  if (playout) {
593
718
  const playoutLimitString = /** @type {string} */(playout.data);
594
719
  playoutLimit = parseFloat(playoutLimitString);
@@ -599,7 +724,7 @@ shaka.ads.InterstitialAdManager = class {
599
724
  let once = false;
600
725
  let pre = false;
601
726
  let post = false;
602
- const cue = interstitial.values.find((v) => v.key == 'CUE');
727
+ const cue = hlsInterstitial.values.find((v) => v.key == 'CUE');
603
728
  if (cue) {
604
729
  const data = /** @type {string} */(cue.data);
605
730
  once = data.includes('ONCE');
@@ -608,7 +733,7 @@ shaka.ads.InterstitialAdManager = class {
608
733
  }
609
734
  let timelineRange = false;
610
735
  const timelineOccupies =
611
- interstitial.values.find((v) => v.key == 'X-TIMELINE-OCCUPIES');
736
+ hlsInterstitial.values.find((v) => v.key == 'X-TIMELINE-OCCUPIES');
612
737
  if (timelineOccupies) {
613
738
  const data = /** @type {string} */(timelineOccupies.data);
614
739
  timelineRange = data.includes('RANGE');
@@ -621,10 +746,12 @@ shaka.ads.InterstitialAdManager = class {
621
746
  return interstitialsAd;
622
747
  }
623
748
  interstitialsAd.push({
624
- startTime: interstitial.startTime,
625
- endTime: interstitial.endTime,
749
+ id,
750
+ startTime: hlsInterstitial.startTime,
751
+ endTime: hlsInterstitial.endTime,
626
752
  uri,
627
753
  isSkippable,
754
+ skipOffset: isSkippable ? 0 : null,
628
755
  canJump,
629
756
  resumeOffset,
630
757
  playoutLimit,
@@ -638,24 +765,25 @@ shaka.ads.InterstitialAdManager = class {
638
765
  if (!uri) {
639
766
  return interstitialsAd;
640
767
  }
641
- const type = shaka.net.NetworkingEngine.RequestType.ADS;
642
- const request = shaka.net.NetworkingEngine.makeRequest(
643
- [uri],
644
- shaka.net.NetworkingEngine.defaultRetryParameters());
645
- const op = this.basePlayer_.getNetworkingEngine().request(type, request);
646
768
  try {
647
- const response = await op.promise;
648
- const data = shaka.util.StringUtils.fromUTF8(response.data);
769
+ const NetworkingEngine = shaka.net.NetworkingEngine;
770
+ const context = {
771
+ type: NetworkingEngine.AdvancedRequestType.INTERSTITIAL_ASSET_LIST,
772
+ };
773
+ const responseData = await this.makeAdRequest_(uri, context);
774
+ const data = shaka.util.StringUtils.fromUTF8(responseData);
649
775
  const dataAsJson =
650
776
  /** @type {!shaka.ads.InterstitialAdManager.AssetsList} */ (
651
777
  JSON.parse(data));
652
778
  for (const asset of dataAsJson['ASSETS']) {
653
779
  if (asset['URI']) {
654
780
  interstitialsAd.push({
655
- startTime: interstitial.startTime,
656
- endTime: interstitial.endTime,
781
+ id,
782
+ startTime: hlsInterstitial.startTime,
783
+ endTime: hlsInterstitial.endTime,
657
784
  uri: asset['URI'],
658
785
  isSkippable,
786
+ skipOffset: isSkippable ? 0 : null,
659
787
  canJump,
660
788
  resumeOffset,
661
789
  playoutLimit,
@@ -722,6 +850,23 @@ shaka.ads.InterstitialAdManager = class {
722
850
  netEngine.clearAllResponseFilters();
723
851
  this.basePlayer_.getNetworkingEngine().copyFiltersInto(netEngine);
724
852
  }
853
+
854
+ /**
855
+ * @param {string} url
856
+ * @param {shaka.extern.RequestContext=} context
857
+ * @return {!Promise.<BufferSource>}
858
+ * @private
859
+ */
860
+ async makeAdRequest_(url, context) {
861
+ const type = shaka.net.NetworkingEngine.RequestType.ADS;
862
+ const request = shaka.net.NetworkingEngine.makeRequest(
863
+ [url],
864
+ shaka.net.NetworkingEngine.defaultRetryParameters());
865
+ const op = this.basePlayer_.getNetworkingEngine()
866
+ .request(type, request, context);
867
+ const response = await op.promise;
868
+ return response.data;
869
+ }
725
870
  };
726
871
 
727
872
 
@@ -743,33 +888,3 @@ shaka.ads.InterstitialAdManager.AssetsList;
743
888
  * @property {string} URI
744
889
  */
745
890
  shaka.ads.InterstitialAdManager.Asset;
746
-
747
-
748
- /**
749
- * @typedef {{
750
- * startTime: number,
751
- * endTime: ?number,
752
- * uri: string,
753
- * isSkippable: boolean,
754
- * canJump: boolean,
755
- * resumeOffset: ?number,
756
- * playoutLimit: ?number,
757
- * once: boolean,
758
- * pre: boolean,
759
- * post: boolean,
760
- * timelineRange: boolean
761
- * }}
762
- *
763
- * @property {number} startTime
764
- * @property {?number} endTime
765
- * @property {string} uri
766
- * @property {boolean} isSkippable
767
- * @property {boolean} canJump
768
- * @property {?number} resumeOffset
769
- * @property {?number} playoutLimit
770
- * @property {boolean} once
771
- * @property {boolean} pre
772
- * @property {boolean} post
773
- * @property {boolean} timelineRange
774
- */
775
- shaka.ads.InterstitialAdManager.Interstitial;
@@ -25,7 +25,7 @@ shaka.ads.MediaTailorAd = class {
25
25
  this.ad_ = mediaTailorAd;
26
26
 
27
27
  /** @private {?number} */
28
- this.skipOffset_ = this.parseTime_(this.ad_.skipOffset);
28
+ this.skipOffset_ = shaka.util.TextParser.parseTime(this.ad_.skipOffset);
29
29
 
30
30
  /** @private {HTMLMediaElement} */
31
31
  this.video_ = video;
@@ -318,42 +318,4 @@ shaka.ads.MediaTailorAd = class {
318
318
  isSkipped() {
319
319
  return this.isSkipped_;
320
320
  }
321
-
322
- /**
323
- * Parses a time from string.
324
- *
325
- * @param {?string} time
326
- * @return {?number}
327
- * @private
328
- */
329
- parseTime_(time) {
330
- if (!time) {
331
- return null;
332
- }
333
- const parser = new shaka.util.TextParser(time);
334
- const results = parser.readRegex(shaka.ads.MediaTailorAd.timeFormat_);
335
- if (results == null) {
336
- return null;
337
- }
338
- // This capture is optional, but will still be in the array as undefined,
339
- // in which case it is 0.
340
- const hours = Number(results[1]) || 0;
341
- const minutes = Number(results[2]);
342
- const seconds = Number(results[3]);
343
- const milliseconds = Number(results[4]) || 0;
344
- if (minutes > 59 || seconds > 59) {
345
- return null;
346
- }
347
-
348
- return (milliseconds / 1000) + seconds + (minutes * 60) + (hours * 3600);
349
- }
350
321
  };
351
-
352
- /**
353
- * @const
354
- * @private {!RegExp}
355
- * @example 00:00.000 or 00:00:00.000 or 0:00:00.000 or
356
- * 00:00.00 or 00:00:00.00 or 0:00:00.00 or 00:00:00
357
- */
358
- shaka.ads.MediaTailorAd.timeFormat_ =
359
- /(?:(\d{1,}):)?(\d{2}):(\d{2})((\.(\d{1,3})))?/g;
@@ -202,17 +202,21 @@ shaka.ads.MediaTailorAdManager = class {
202
202
  * @private
203
203
  */
204
204
  async requestSessionInfo_(url, adsParams) {
205
- const type = shaka.net.NetworkingEngine.RequestType.ADS;
206
- const request = shaka.net.NetworkingEngine.makeRequest(
205
+ const NetworkingEngine = shaka.net.NetworkingEngine;
206
+ const type = NetworkingEngine.RequestType.ADS;
207
+ const context = {
208
+ type: NetworkingEngine.AdvancedRequestType.MEDIATAILOR_SESSION_INFO,
209
+ };
210
+ const request = NetworkingEngine.makeRequest(
207
211
  [url],
208
- shaka.net.NetworkingEngine.defaultRetryParameters());
212
+ NetworkingEngine.defaultRetryParameters());
209
213
  request.method = 'POST';
210
214
  if (adsParams) {
211
215
  const body = JSON.stringify(adsParams);
212
216
  request.body = shaka.util.StringUtils.toUTF8(body);
213
217
  }
214
218
 
215
- const op = this.networkingEngine_.request(type, request);
219
+ const op = this.networkingEngine_.request(type, request, context);
216
220
  try {
217
221
  const response = await op.promise;
218
222
  const data = shaka.util.StringUtils.fromUTF8(response.data);
@@ -254,12 +258,16 @@ shaka.ads.MediaTailorAdManager = class {
254
258
  * @private
255
259
  */
256
260
  async requestTrackingInfo_(trackingUrl, firstRequest) {
257
- const type = shaka.net.NetworkingEngine.RequestType.ADS;
258
- const request = shaka.net.NetworkingEngine.makeRequest(
261
+ const NetworkingEngine = shaka.net.NetworkingEngine;
262
+ const type = NetworkingEngine.RequestType.ADS;
263
+ const context = {
264
+ type: NetworkingEngine.AdvancedRequestType.MEDIATAILOR_TRACKING_INFO,
265
+ };
266
+ const request = NetworkingEngine.makeRequest(
259
267
  [trackingUrl],
260
- shaka.net.NetworkingEngine.defaultRetryParameters());
268
+ NetworkingEngine.defaultRetryParameters());
261
269
 
262
- const op = this.networkingEngine_.request(type, request);
270
+ const op = this.networkingEngine_.request(type, request, context);
263
271
  try {
264
272
  const response = await op.promise;
265
273
  let cuepoints = [];
@@ -311,12 +319,16 @@ shaka.ads.MediaTailorAdManager = class {
311
319
  return;
312
320
  }
313
321
 
314
- const type = shaka.net.NetworkingEngine.RequestType.ADS;
315
- const request = shaka.net.NetworkingEngine.makeRequest(
322
+ const NetworkingEngine = shaka.net.NetworkingEngine;
323
+ const type = NetworkingEngine.RequestType.ADS;
324
+ const context = {
325
+ type: NetworkingEngine.AdvancedRequestType.MEDIATAILOR_STATIC_RESOURCE,
326
+ };
327
+ const request = NetworkingEngine.makeRequest(
316
328
  [nonLinearAd.staticResource],
317
- shaka.net.NetworkingEngine.defaultRetryParameters());
329
+ NetworkingEngine.defaultRetryParameters());
318
330
 
319
- const op = this.networkingEngine_.request(type, request);
331
+ const op = this.networkingEngine_.request(type, request, context);
320
332
  try {
321
333
  this.staticResources_.set(cacheKey, []);
322
334
  const response = await op.promise;
@@ -709,16 +721,20 @@ shaka.ads.MediaTailorAdManager = class {
709
721
  (event) => event.eventType == eventType);
710
722
  }
711
723
  if (trackingEvent) {
712
- const type = shaka.net.NetworkingEngine.RequestType.ADS;
724
+ const NetworkingEngine = shaka.net.NetworkingEngine;
725
+ const type = NetworkingEngine.RequestType.ADS;
726
+ const context = {
727
+ type: NetworkingEngine.AdvancedRequestType.MEDIATAILOR_TRACKING_EVENT,
728
+ };
713
729
  for (const beaconUrl of trackingEvent.beaconUrls) {
714
730
  if (!beaconUrl || beaconUrl == '') {
715
731
  continue;
716
732
  }
717
- const request = shaka.net.NetworkingEngine.makeRequest(
733
+ const request = NetworkingEngine.makeRequest(
718
734
  [beaconUrl],
719
- shaka.net.NetworkingEngine.defaultRetryParameters());
735
+ NetworkingEngine.defaultRetryParameters());
720
736
  request.method = 'POST';
721
- this.networkingEngine_.request(type, request);
737
+ this.networkingEngine_.request(type, request, context);
722
738
  }
723
739
  }
724
740
  switch (eventType) {