@newrelic/video-videojs 4.1.2 → 4.2.1

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.
@@ -23,6 +23,7 @@ import {
23
23
  parseHlsManifestForAdBreaks,
24
24
  parseDashManifestForAdBreaks,
25
25
  detectAdBreaksFromVhsPlaylist,
26
+ whichAdSegmentMarker,
26
27
  enrichAdScheduleWithTrackingMetadata,
27
28
  extractHlsTargetDurationSeconds,
28
29
  extractDashMinimumUpdatePeriodSeconds,
@@ -51,12 +52,10 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
51
52
  /**
52
53
  * Checks if tracker should be used for this player source
53
54
  */
54
- static isUsing(player) {
55
- return (
56
- player &&
57
- typeof player.currentSrc === 'function' &&
58
- player.currentSrc().includes(MEDIATAILOR_HOST_MARKER)
59
- );
55
+ static isUsing(player, options = {}) {
56
+ // Opt-in flag is the single source of truth.
57
+ // Accepts { mediatailor: true } or { mediatailor: { trackingUrl, adSegmentPrefix } }.
58
+ return Boolean(options && options.mediatailor);
60
59
  }
61
60
 
62
61
  /**
@@ -87,11 +86,32 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
87
86
  constructor(player, options = {}) {
88
87
  super(player);
89
88
 
89
+ // Normalize mediatailor option: true | { trackingUrl, adSegmentPrefix } | undefined
90
+ const mtOptions =
91
+ options.mediatailor === true ? {} : options.mediatailor || {};
92
+
90
93
  // Initialize state
91
94
  this.streamType = null; // 'vod' or 'live'
92
95
  this.manifestFormat = null; // 'hls' or 'dash'
93
96
  this.playbackManifestUrl = player.currentSrc();
94
97
 
98
+ // trackingUrl: optional override for the MediaTailor tracking endpoint.
99
+ // When not provided, the tracker derives it automatically from the playback URL.
100
+ this.explicitTrackingUrl = mtOptions.trackingUrl || null;
101
+
102
+ // adSegmentPrefix: only needed when the customer configured a CDN ad-segment
103
+ // prefix in AWS MediaTailor that does NOT follow the AWS-recommended /tm/ path.
104
+ // Most setups (default AWS hostname or CDN following AWS conventions) are
105
+ // detected automatically via MT_DEFAULT_AD_SEGMENT_PATH ('/tm/') and do not
106
+ // need this override.
107
+ this.adSegmentPrefix = mtOptions.adSegmentPrefix || null;
108
+
109
+ if (this.adSegmentPrefix) {
110
+ Log.debug(`[MT] ad segment detection: custom prefix "${this.adSegmentPrefix}"`);
111
+ } else {
112
+ Log.debug('[MT] ad segment detection: default (segments.mediatailor hostname or /tm/ path)');
113
+ }
114
+
95
115
  // Ad tracking state
96
116
  this.adSchedule = [];
97
117
  this.currentAdBreak = null;
@@ -120,19 +140,19 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
120
140
  this.mediaPlaylistUrl = null;
121
141
  this.lastMediaPlaylistText = null;
122
142
 
123
- console.log(`[MT - ${getTimestamp()}] MediaTailorAdsTracker initialized`, {
143
+ Log.debug(`[MT - ${getTimestamp()}] MediaTailorAdsTracker initialized`, {
124
144
  endpoint: this.playbackManifestUrl,
125
145
  trackingAPITimeout: TRACKING_API_TIMEOUT_MS,
126
146
  });
127
147
 
128
148
  this.manifestFormat = detectManifestFormatFromUrl(this.playbackManifestUrl);
129
- console.log(
149
+ Log.debug(
130
150
  `[MT - ${getTimestamp()}] Manifest type: ${this.manifestFormat.toUpperCase()}`,
131
151
  );
132
152
 
133
153
  this.player.one('loadedmetadata', () => {
134
154
  this.streamType = detectPlaybackStreamType(this.player.duration());
135
- console.log(
155
+ Log.debug(
136
156
  `[MT - ${getTimestamp()}] Stream type: ${this.streamType.toUpperCase()}`,
137
157
  );
138
158
  this.initializeTracking();
@@ -143,20 +163,22 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
143
163
  * Initializes tracking based on detected stream type
144
164
  */
145
165
  initializeTracking() {
146
- console.log(
166
+ Log.debug(
147
167
  `[MT - ${getTimestamp()}] Initializing ${this.manifestFormat.toUpperCase()} ${this.streamType.toUpperCase()} tracking`,
148
168
  );
149
169
 
150
- // Extract tracking URL from sessionized URL
151
- this.trackingEndpointUrl = buildTrackingEndpointUrl(this.playbackManifestUrl);
170
+ // Prefer explicit tracking URL (explicit POST session) over derived one
171
+ this.trackingEndpointUrl =
172
+ this.explicitTrackingUrl ||
173
+ buildTrackingEndpointUrl(this.playbackManifestUrl);
152
174
  if (this.trackingEndpointUrl) {
153
- console.log(
175
+ Log.debug(
154
176
  `[MT - ${getTimestamp()}] Tracking URL extracted:`,
155
177
  this.trackingEndpointUrl,
156
178
  );
157
179
  } else {
158
- console.warn(
159
- `[MT - ${getTimestamp()}] No sessionId found - user must initialize session externally`,
180
+ Log.warn(
181
+ `[MT - ${getTimestamp()}] Could not derive tracking URL from playback URL — pass trackingUrl in mediatailor options if needed`,
160
182
  );
161
183
  }
162
184
 
@@ -191,7 +213,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
191
213
  this.player.on('waiting', this.onWaiting);
192
214
  this.player.on('ended', this.onEnded);
193
215
  this.player.on('timeupdate', this.onTimeUpdate);
194
- console.log(`[MT - ${getTimestamp()}] Event listeners registered`);
216
+ Log.debug(`[MT - ${getTimestamp()}] Event listeners registered`);
195
217
  }
196
218
 
197
219
  /**
@@ -228,7 +250,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
228
250
  * Sets up VOD tracking (single parse, no polling)
229
251
  */
230
252
  setupVODTracking() {
231
- console.log(`[MT - ${getTimestamp()}] VOD mode: Single manifest parse`);
253
+ Log.debug(`[MT - ${getTimestamp()}] VOD mode: Single manifest parse`);
232
254
  this.hookPlayerManifest();
233
255
  }
234
256
 
@@ -236,7 +258,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
236
258
  * Sets up Live tracking (continuous polling)
237
259
  */
238
260
  setupLiveTracking() {
239
- console.log(`[MT - ${getTimestamp()}] Live mode: Continuous polling`);
261
+ Log.debug(`[MT - ${getTimestamp()}] Live mode: Continuous polling`);
240
262
  this.hookPlayerManifest();
241
263
 
242
264
  const pollingInterval = this.getLiveRefreshIntervalMs();
@@ -250,7 +272,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
250
272
  this.getAndProcessTrackingMetadata();
251
273
  }, pollingInterval);
252
274
 
253
- console.log(`[MT - ${getTimestamp()}] Live polling started`, {
275
+ Log.debug(`[MT - ${getTimestamp()}] Live polling started`, {
254
276
  pollingInterval,
255
277
  });
256
278
  }
@@ -271,7 +293,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
271
293
  if (!this.liveRefreshIntervalSeconds) return;
272
294
 
273
295
  const newInterval = this.getLiveRefreshIntervalMs();
274
- console.log(
296
+ Log.debug(
275
297
  `[MT - ${getTimestamp()}] Updating live polling interval: ${this.liveRefreshIntervalSeconds}s`,
276
298
  );
277
299
 
@@ -295,7 +317,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
295
317
  hookPlayerManifest() {
296
318
  const tech = this.player.tech({ IWillNotUseThisInPlugins: true });
297
319
  if (!tech) {
298
- console.log(`[MT - ${getTimestamp()}] No tech - using fallback fetch`);
320
+ Log.debug(`[MT - ${getTimestamp()}] No tech - using fallback fetch`);
299
321
  this.getManifestDirectly();
300
322
  return;
301
323
  }
@@ -316,7 +338,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
316
338
  }
317
339
 
318
340
  // Fallback: Direct manifest fetch
319
- console.log(
341
+ Log.debug(
320
342
  `[MT - ${getTimestamp()}] Using fallback: direct manifest fetch`,
321
343
  );
322
344
  this.getManifestDirectly();
@@ -328,7 +350,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
328
350
  hookHLSViaVHS(tech) {
329
351
  if (!tech.vhs || !tech.vhs.playlists) return false;
330
352
 
331
- console.log(`[MT - ${getTimestamp()}] Hooked: VHS`);
353
+ Log.debug(`[MT - ${getTimestamp()}] Hooked: VHS`);
332
354
 
333
355
  // Parse already-loaded playlist
334
356
  const currentPlaylist = tech.vhs.playlists.media();
@@ -337,7 +359,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
337
359
  currentPlaylist.segments &&
338
360
  currentPlaylist.segments.length > 0
339
361
  ) {
340
- console.log(`[MT - ${getTimestamp()}] Parsing existing playlist`);
362
+ Log.debug(`[MT - ${getTimestamp()}] Parsing existing playlist`);
341
363
  this.parseVhsPlaylistForAdBreaks(currentPlaylist);
342
364
  }
343
365
 
@@ -362,7 +384,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
362
384
  tech.el_.canPlayType &&
363
385
  tech.el_.canPlayType(HLS_MIME_TYPE)
364
386
  ) {
365
- console.log(
387
+ Log.debug(
366
388
  `[MT - ${getTimestamp()}] Native HLS detected - using fallback`,
367
389
  );
368
390
  this.getManifestDirectly();
@@ -377,7 +399,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
377
399
  hookHLSViaContribHls(tech) {
378
400
  if (!tech.hls || !tech.hls.playlists) return false;
379
401
 
380
- console.log(`[MT - ${getTimestamp()}] Hooked: contrib-hls (legacy)`);
402
+ Log.debug(`[MT - ${getTimestamp()}] Hooked: contrib-hls (legacy)`);
381
403
 
382
404
  // Parse already-loaded playlist
383
405
  const currentPlaylist = tech.hls.playlists.media();
@@ -406,7 +428,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
406
428
  hookDASHViaShaka(tech) {
407
429
  if (!tech.shakaPlayer) return false;
408
430
 
409
- console.log(`[MT - ${getTimestamp()}] Hooked: Shaka Player`);
431
+ Log.debug(`[MT - ${getTimestamp()}] Hooked: Shaka Player`);
410
432
  tech.shakaPlayer.addEventListener('emsg', (event) => {
411
433
  this.handleDASHEmsgEvent(event);
412
434
  });
@@ -420,7 +442,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
420
442
  hookDASHViaDashJs(tech) {
421
443
  if (!tech.dash || !tech.dash.on) return false;
422
444
 
423
- console.log(`[MT - ${getTimestamp()}] Hooked: dash.js`);
445
+ Log.debug(`[MT - ${getTimestamp()}] Hooked: dash.js`);
424
446
  tech.dash.on('EVENT_MODE_ON_RECEIVE', (event) => {
425
447
  this.handleDASHEventStream(event);
426
448
  });
@@ -432,7 +454,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
432
454
  * Fetches manifest directly (fallback when hooks unavailable)
433
455
  */
434
456
  async getManifestDirectly() {
435
- console.log(
457
+ Log.debug(
436
458
  `[MT - ${getTimestamp()}] Fallback: fetching manifest directly`,
437
459
  );
438
460
 
@@ -445,7 +467,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
445
467
  await this.fetchAndParseDashManifest(manifestUrl);
446
468
  }
447
469
  } catch (error) {
448
- console.log(`[MT - ${getTimestamp()}] Fallback fetch error:`, error);
470
+ Log.debug(`[MT - ${getTimestamp()}] Fallback fetch error:`, error);
449
471
  }
450
472
  }
451
473
 
@@ -454,17 +476,17 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
454
476
  */
455
477
  async fetchAndParseHlsManifest(manifestUrl) {
456
478
  try {
457
- console.log(`[MT - ${getTimestamp()}] Fetching HLS master manifest`);
479
+ Log.debug(`[MT - ${getTimestamp()}] Fetching HLS master manifest`);
458
480
 
459
481
  // Fetch master manifest
460
482
  const { mediaPlaylistUrl } = await fetchHlsMasterManifest(manifestUrl);
461
483
 
462
484
  if (!mediaPlaylistUrl) {
463
- console.log(`[MT - ${getTimestamp()}] No media playlist found`);
485
+ Log.debug(`[MT - ${getTimestamp()}] No media playlist found`);
464
486
  return;
465
487
  }
466
488
 
467
- console.log(`[MT - ${getTimestamp()}] Fetching media playlist`);
489
+ Log.debug(`[MT - ${getTimestamp()}] Fetching media playlist`);
468
490
 
469
491
  // Fetch media playlist
470
492
  const mediaText = await fetchHlsMediaPlaylist(mediaPlaylistUrl);
@@ -478,13 +500,13 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
478
500
  // Parse for ads
479
501
  const ads = parseHlsManifestForAdBreaks(mediaText);
480
502
  if (ads.length > 0) {
481
- console.log(
503
+ Log.debug(
482
504
  `[MT - ${getTimestamp()}] Detected ${ads.length} ad break(s)`,
483
505
  );
484
506
  this.mergeNewAds(ads);
485
507
  }
486
508
  } catch (error) {
487
- console.log(`[MT - ${getTimestamp()}] HLS fetch error:`, error);
509
+ Log.debug(`[MT - ${getTimestamp()}] HLS fetch error:`, error);
488
510
  }
489
511
  }
490
512
 
@@ -493,7 +515,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
493
515
  */
494
516
  async fetchAndParseDashManifest(manifestUrl) {
495
517
  try {
496
- console.log(`[MT - ${getTimestamp()}] Fetching DASH manifest`);
518
+ Log.debug(`[MT - ${getTimestamp()}] Fetching DASH manifest`);
497
519
 
498
520
  // Fetch DASH manifest
499
521
  const xmlText = await fetchDashManifest(manifestUrl);
@@ -508,7 +530,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
508
530
  // Parse for ads
509
531
  const ads = parseDashManifestForAdBreaks(xmlText);
510
532
 
511
- console.log(
533
+ Log.debug(
512
534
  `[MT - ${getTimestamp()}] DASH: ${ads.length} ad break(s) found`,
513
535
  );
514
536
 
@@ -520,14 +542,14 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
520
542
  !this.hasAttemptedTrackingFetch
521
543
  ) {
522
544
  // No SCTE-35 markers in manifest - fall back to tracking API directly
523
- console.log(
545
+ Log.debug(
524
546
  `[MT - ${getTimestamp()}] DASH: no manifest cues, fetching tracking API`,
525
547
  );
526
548
  this.hasAttemptedTrackingFetch = true;
527
549
  this.getAndProcessTrackingMetadata();
528
550
  }
529
551
  } catch (error) {
530
- console.log(`[MT - ${getTimestamp()}] DASH fetch error:`, error);
552
+ Log.debug(`[MT - ${getTimestamp()}] DASH fetch error:`, error);
531
553
  }
532
554
  }
533
555
 
@@ -535,14 +557,14 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
535
557
  * Handles DASH emsg events from Shaka Player
536
558
  */
537
559
  handleDASHEmsgEvent(event) {
538
- console.log(`[MT - ${getTimestamp()}] DASH emsg event:`, event);
560
+ Log.debug(`[MT - ${getTimestamp()}] DASH emsg event:`, event);
539
561
 
540
562
  try {
541
563
  // Shaka Player emits emsg events with event.detail containing the emsg box data
542
564
  const emsgData = event.detail;
543
565
 
544
566
  if (!emsgData) {
545
- console.log(`[MT - ${getTimestamp()}] No emsg data in event`);
567
+ Log.debug(`[MT - ${getTimestamp()}] No emsg data in event`);
546
568
  return;
547
569
  }
548
570
 
@@ -551,14 +573,14 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
551
573
  const schemeIdUri = emsgData.schemeIdUri || '';
552
574
 
553
575
  if (!schemeIdUri.includes(SCTE35_SCHEME_MARKER)) {
554
- console.log(
576
+ Log.debug(
555
577
  `[MT - ${getTimestamp()}] Non-SCTE-35 emsg, skipping:`,
556
578
  schemeIdUri,
557
579
  );
558
580
  return;
559
581
  }
560
582
 
561
- console.log(`[MT - ${getTimestamp()}] SCTE-35 emsg detected:`, {
583
+ Log.debug(`[MT - ${getTimestamp()}] SCTE-35 emsg detected:`, {
562
584
  schemeIdUri: emsgData.schemeIdUri,
563
585
  value: emsgData.value,
564
586
  timescale: emsgData.timescale,
@@ -592,14 +614,14 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
592
614
  pods: [],
593
615
  };
594
616
 
595
- console.log(
617
+ Log.debug(
596
618
  `[MT - ${getTimestamp()}] Adding ad break from DASH emsg:`,
597
619
  adBreak,
598
620
  );
599
621
  this.mergeNewAds([adBreak]);
600
622
  }
601
623
  } catch (error) {
602
- console.log(
624
+ Log.debug(
603
625
  `[MT - ${getTimestamp()}] Error parsing DASH emsg event:`,
604
626
  error,
605
627
  );
@@ -610,14 +632,14 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
610
632
  * Handles DASH event stream from dash.js
611
633
  */
612
634
  handleDASHEventStream(event) {
613
- console.log(`[MT - ${getTimestamp()}] DASH event stream:`, event);
635
+ Log.debug(`[MT - ${getTimestamp()}] DASH event stream:`, event);
614
636
 
615
637
  try {
616
638
  // dash.js emits events with different structure
617
639
  const eventData = event.event || event;
618
640
 
619
641
  if (!eventData) {
620
- console.log(`[MT - ${getTimestamp()}] No event data`);
642
+ Log.debug(`[MT - ${getTimestamp()}] No event data`);
621
643
  return;
622
644
  }
623
645
 
@@ -625,14 +647,14 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
625
647
  const schemeIdUri = eventData.schemeIdUri || '';
626
648
 
627
649
  if (!schemeIdUri.includes(SCTE35_SCHEME_MARKER)) {
628
- console.log(
650
+ Log.debug(
629
651
  `[MT - ${getTimestamp()}] Non-SCTE-35 event, skipping:`,
630
652
  schemeIdUri,
631
653
  );
632
654
  return;
633
655
  }
634
656
 
635
- console.log(`[MT - ${getTimestamp()}] SCTE-35 event stream detected:`, {
657
+ Log.debug(`[MT - ${getTimestamp()}] SCTE-35 event stream detected:`, {
636
658
  id: eventData.id,
637
659
  schemeIdUri: eventData.schemeIdUri,
638
660
  presentationTime: eventData.presentationTime,
@@ -658,14 +680,14 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
658
680
  pods: [],
659
681
  };
660
682
 
661
- console.log(
683
+ Log.debug(
662
684
  `[MT - ${getTimestamp()}] Adding ad break from DASH event stream:`,
663
685
  adBreak,
664
686
  );
665
687
  this.mergeNewAds([adBreak]);
666
688
  }
667
689
  } catch (error) {
668
- console.log(
690
+ Log.debug(
669
691
  `[MT - ${getTimestamp()}] Error parsing DASH event stream:`,
670
692
  error,
671
693
  );
@@ -676,14 +698,14 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
676
698
  * Parses VHS playlist object for ads
677
699
  */
678
700
  parseVhsPlaylistForAdBreaks(playlist) {
679
- console.log(
701
+ Log.debug(
680
702
  `[MT - ${getTimestamp()}] Parsing VHS playlist (${
681
703
  playlist.segments?.length || 0
682
704
  } segments)`,
683
705
  );
684
706
 
685
707
  if (!playlist.segments || playlist.segments.length === 0) {
686
- console.log(`[MT - ${getTimestamp()}] No segments in playlist`);
708
+ Log.debug(`[MT - ${getTimestamp()}] No segments in playlist`);
687
709
  return;
688
710
  }
689
711
 
@@ -693,10 +715,23 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
693
715
  );
694
716
 
695
717
  // VHS strips CUE tags - detect via discontinuityStarts + MediaTailor segments
696
- const ads = detectAdBreaksFromVhsPlaylist(playlist);
718
+ const ads = detectAdBreaksFromVhsPlaylist(playlist, {
719
+ adSegmentPrefix: this.adSegmentPrefix,
720
+ });
697
721
 
698
722
  if (ads.length > 0) {
699
- console.log(
723
+ // Log which detection path matched — only on first detection to avoid noise
724
+ if (!this._detectionPathLogged) {
725
+ const firstSeg = playlist.segments && playlist.segments.find(s =>
726
+ whichAdSegmentMarker(s, { adSegmentPrefix: this.adSegmentPrefix })
727
+ );
728
+ if (firstSeg) {
729
+ const path = whichAdSegmentMarker(firstSeg, { adSegmentPrefix: this.adSegmentPrefix });
730
+ Log.debug(`[MT] ad segment detection matched via: ${path}`);
731
+ this._detectionPathLogged = true;
732
+ }
733
+ }
734
+ Log.debug(
700
735
  `[MT - ${getTimestamp()}] VHS detected ${ads.length} ad break(s), ${ads.reduce(
701
736
  (sum, ab) => sum + ab.pods.length,
702
737
  0,
@@ -704,7 +739,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
704
739
  );
705
740
  this.mergeNewAds(ads);
706
741
  } else {
707
- console.log(`[MT - ${getTimestamp()}] No ads detected in VHS playlist`);
742
+ Log.debug(`[MT - ${getTimestamp()}] No ads detected in VHS playlist`);
708
743
  }
709
744
  }
710
745
 
@@ -716,7 +751,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
716
751
  if (this.streamType !== STREAM_TYPE.LIVE) return;
717
752
 
718
753
  if (this.isFetchingManifest) {
719
- console.log(
754
+ Log.debug(
720
755
  `[MT - ${getTimestamp()}] Manifest fetch already in progress, skipping`,
721
756
  );
722
757
  return;
@@ -735,7 +770,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
735
770
  await this.fetchAndParseDashManifest(this.playbackManifestUrl);
736
771
  }
737
772
  } catch (error) {
738
- console.log(`[MT - ${getTimestamp()}] Manifest poll error:`, error);
773
+ Log.debug(`[MT - ${getTimestamp()}] Manifest poll error:`, error);
739
774
  } finally {
740
775
  this.isFetchingManifest = false;
741
776
  }
@@ -747,7 +782,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
747
782
  mergeNewAds(newAds) {
748
783
  this.adSchedule = mergeAdSchedules(this.adSchedule, newAds);
749
784
 
750
- console.log(
785
+ Log.debug(
751
786
  `[MT - ${getTimestamp()}] Ad schedule: ${this.adSchedule.length} ad break(s)`,
752
787
  );
753
788
 
@@ -758,7 +793,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
758
793
  !this.hasAttemptedTrackingFetch
759
794
  ) {
760
795
  this.hasAttemptedTrackingFetch = true;
761
- console.log(
796
+ Log.debug(
762
797
  `[MT - ${getTimestamp()}] Fetching tracking metadata (first manifest parse)`,
763
798
  );
764
799
  this.getAndProcessTrackingMetadata();
@@ -782,7 +817,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
782
817
  }
783
818
 
784
819
  this.liveRefreshIntervalSeconds = intervalSeconds;
785
- console.log(
820
+ Log.debug(
786
821
  `[MT - ${getTimestamp()}] Derived live polling interval from ${source}: ${intervalSeconds}s`,
787
822
  );
788
823
 
@@ -798,7 +833,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
798
833
  if (this.isDisposed || !this.trackingEndpointUrl) return;
799
834
 
800
835
  if (this.isFetchingTracking) {
801
- console.log(
836
+ Log.debug(
802
837
  `[MT - ${getTimestamp()}] Tracking fetch already in progress, skipping`,
803
838
  );
804
839
  return;
@@ -807,7 +842,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
807
842
  this.isFetchingTracking = true;
808
843
 
809
844
  try {
810
- console.log(`[MT - ${getTimestamp()}] Fetching tracking metadata`);
845
+ Log.debug(`[MT - ${getTimestamp()}] Fetching tracking metadata`);
811
846
 
812
847
  this.trackingAbortController = new AbortController();
813
848
 
@@ -818,35 +853,35 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
818
853
  );
819
854
 
820
855
  if (this.isDisposed) {
821
- console.log(
856
+ Log.debug(
822
857
  `[MT - ${getTimestamp()}] Disposed during tracking fetch, ignoring result`,
823
858
  );
824
859
  return;
825
860
  }
826
861
 
827
862
  if (data.avails && data.avails.length > 0) {
828
- console.log(
863
+ Log.debug(
829
864
  `[MT - ${getTimestamp()}] Enriching with ${data.avails.length} avail(s)`,
830
865
  );
831
866
  this.enrichWithTrackingMetadata(data.avails);
832
867
  this.trackingFetchRetries = 0;
833
868
  } else {
834
- console.log(`[MT - ${getTimestamp()}] Tracking API returned 0 avails`);
869
+ Log.debug(`[MT - ${getTimestamp()}] Tracking API returned 0 avails`);
835
870
  }
836
871
  } catch (error) {
837
872
  if (error.name === 'AbortError' || this.isDisposed) {
838
- console.log(`[MT - ${getTimestamp()}] Tracking fetch aborted`);
873
+ Log.debug(`[MT - ${getTimestamp()}] Tracking fetch aborted`);
839
874
  return;
840
875
  }
841
876
 
842
- console.log(
877
+ Log.debug(
843
878
  `[MT - ${getTimestamp()}] Tracking API error: ${error.message}`,
844
879
  error,
845
880
  );
846
881
 
847
882
  if (this.trackingFetchRetries < this.maxTrackingRetries) {
848
883
  this.trackingFetchRetries++;
849
- console.log(
884
+ Log.debug(
850
885
  `[MT - ${getTimestamp()}] Retrying tracking fetch (${this.trackingFetchRetries}/${this.maxTrackingRetries})`,
851
886
  );
852
887
  this.isFetchingTracking = false;
@@ -854,7 +889,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
854
889
  return;
855
890
  }
856
891
 
857
- console.log(
892
+ Log.debug(
858
893
  `[MT - ${getTimestamp()}] Max retries reached, continuing with manifest data only`,
859
894
  );
860
895
  } finally {
@@ -875,14 +910,14 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
875
910
  this.adSchedule.sort((a, b) => a.startTime - b.startTime);
876
911
  }
877
912
 
878
- console.log(
913
+ Log.debug(
879
914
  `[MT - ${getTimestamp()}] Enrichment complete: ${
880
915
  this.adSchedule.length
881
916
  } ad break(s)`,
882
917
  );
883
918
 
884
919
  // Log enriched schedule with full details
885
- console.log(
920
+ Log.debug(
886
921
  `[MT - ${getTimestamp()}] Enriched schedule:`,
887
922
  this.adSchedule.map((ab) => ({
888
923
  id: ab.id,
@@ -901,7 +936,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
901
936
  );
902
937
 
903
938
  // Log current player time for debugging
904
- console.log(
939
+ Log.debug(
905
940
  `[MT - ${getTimestamp()}] Current player time: ${this.player.currentTime()}s`,
906
941
  );
907
942
  }
@@ -919,7 +954,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
919
954
  });
920
955
 
921
956
  quartilesToFire.forEach(({ quartile, key }) => {
922
- console.log(`[MT - ${getTimestamp()}] → AD_QUARTILE ${quartile * 25}%`);
957
+ Log.debug(`[MT - ${getTimestamp()}] → AD_QUARTILE ${quartile * 25}%`);
923
958
  this.sendAdQuartile({ quartile });
924
959
  adObject[`hasFired${key.toUpperCase()}`] = true;
925
960
  });
@@ -938,7 +973,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
938
973
  Math.floor(currentTime) % 5 === 0 &&
939
974
  Math.floor(currentTime * 10) % 10 === 0
940
975
  ) {
941
- console.log(
976
+ Log.debug(
942
977
  `[MT - ${getTimestamp()}] TimeUpdate: ${currentTime.toFixed(2)}s, Active break: ${
943
978
  activeAdBreak ? activeAdBreak.id : 'none'
944
979
  }, Schedule count: ${this.adSchedule.length}`,
@@ -952,7 +987,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
952
987
  if (!activeAdBreak.hasFiredStart) {
953
988
  this.currentAdBreak = activeAdBreak;
954
989
  this.setIsAd(true); // Switch to ad mode
955
- console.log(
990
+ Log.debug(
956
991
  `[MT - ${getTimestamp()}] setIsAd(true) - Entering ad break`,
957
992
  );
958
993
 
@@ -969,7 +1004,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
969
1004
  // Store position on the ad break for reuse
970
1005
  activeAdBreak.adPosition = adPosition;
971
1006
 
972
- console.log(`[MT - ${getTimestamp()}] → AD_BREAK_START`, {
1007
+ Log.debug(`[MT - ${getTimestamp()}] → AD_BREAK_START`, {
973
1008
  startTime: activeAdBreak.startTime,
974
1009
  duration: activeAdBreak.duration,
975
1010
  podCount: activeAdBreak.pods?.length || 0,
@@ -990,14 +1025,14 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
990
1025
  if (!this.currentAdPod || this.currentAdPod !== activePod) {
991
1026
  // End previous pod
992
1027
  if (this.currentAdPod) {
993
- console.log(`[MT - ${getTimestamp()}] → AD_END (pod transition)`);
1028
+ Log.debug(`[MT - ${getTimestamp()}] → AD_END (pod transition)`);
994
1029
  this.sendEnd();
995
1030
  }
996
1031
 
997
1032
  // Start new pod
998
1033
  this.currentAdPod = activePod;
999
1034
 
1000
- console.log(`[MT - ${getTimestamp()}] → AD_START (new pod)`, {
1035
+ Log.debug(`[MT - ${getTimestamp()}] → AD_START (new pod)`, {
1001
1036
  startTime: activePod.startTime,
1002
1037
  duration: activePod.duration,
1003
1038
  position: activeAdBreak.adPosition,
@@ -1030,7 +1065,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
1030
1065
  } else {
1031
1066
  // No pods - treat entire break as single ad
1032
1067
  if (!activeAdBreak.hasFiredAdStart) {
1033
- console.log(`[MT - ${getTimestamp()}] → AD_START (no pods)`, {
1068
+ Log.debug(`[MT - ${getTimestamp()}] → AD_START (no pods)`, {
1034
1069
  startTime: activeAdBreak.startTime,
1035
1070
  duration: activeAdBreak.duration,
1036
1071
  position: activeAdBreak.adPosition,
@@ -1059,25 +1094,25 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
1059
1094
 
1060
1095
  // End last pod
1061
1096
  if (this.currentAdPod) {
1062
- console.log(`[MT - ${getTimestamp()}] → AD_END (final pod)`);
1097
+ Log.debug(`[MT - ${getTimestamp()}] → AD_END (final pod)`);
1063
1098
  this.sendEnd();
1064
1099
  this.currentAdPod = null;
1065
1100
  }
1066
1101
 
1067
1102
  // End ad break
1068
1103
  if (!this.currentAdBreak.hasFiredEnd) {
1069
- console.log(`[MT - ${getTimestamp()}] → AD_BREAK_END`);
1104
+ Log.debug(`[MT - ${getTimestamp()}] → AD_BREAK_END`);
1070
1105
  this.sendAdBreakEnd();
1071
1106
  this.currentAdBreak.hasFiredEnd = true;
1072
1107
  }
1073
1108
 
1074
1109
  this.currentAdBreak = null;
1075
1110
  this.setIsAd(false); // Switch back to content mode
1076
- console.log(`[MT - ${getTimestamp()}] setIsAd(false) - Exiting ad break`);
1111
+ Log.debug(`[MT - ${getTimestamp()}] setIsAd(false) - Exiting ad break`);
1077
1112
 
1078
1113
  // Check if video has ended after exiting last ad break
1079
1114
  if (this.player.ended() && !this.hasEndedContent) {
1080
- console.log(
1115
+ Log.debug(
1081
1116
  `[MT - ${getTimestamp()}] Video ended after last ad → CONTENT_END`,
1082
1117
  );
1083
1118
  this.sendContentEnd();
@@ -1104,7 +1139,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
1104
1139
  */
1105
1140
  handleAdEvent(eventName, sendMethod) {
1106
1141
  if (this.isAd()) {
1107
- console.log(`[MT - ${getTimestamp()}] → ${eventName}`);
1142
+ Log.debug(`[MT - ${getTimestamp()}] → ${eventName}`);
1108
1143
  sendMethod.call(this);
1109
1144
  }
1110
1145
  }
@@ -1121,7 +1156,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
1121
1156
  */
1122
1157
  onPlaying() {
1123
1158
  if (this.isAd()) {
1124
- console.log(`[MT - ${getTimestamp()}] → AD_RESUME`);
1159
+ Log.debug(`[MT - ${getTimestamp()}] → AD_RESUME`);
1125
1160
  this.sendResume();
1126
1161
  this.sendBufferEnd(); // Playing event also ends any buffering
1127
1162
  }
@@ -1153,7 +1188,7 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
1153
1188
  */
1154
1189
  onEnded() {
1155
1190
  if (!this.hasEndedContent) {
1156
- console.log(`[MT - ${getTimestamp()}] Video ended → CONTENT_END`);
1191
+ Log.debug(`[MT - ${getTimestamp()}] Video ended → CONTENT_END`);
1157
1192
  this.sendContentEnd();
1158
1193
  this.hasEndedContent = true;
1159
1194
  }
@@ -1216,25 +1251,25 @@ export default class MediaTailorAdsTracker extends VideojsAdsTracker {
1216
1251
  this.trackingPollTimer = null;
1217
1252
  }
1218
1253
 
1219
- console.log(`[MT - ${getTimestamp()}] Polling stopped`);
1254
+ Log.debug(`[MT - ${getTimestamp()}] Polling stopped`);
1220
1255
  }
1221
1256
 
1222
1257
  /**
1223
1258
  * Cleanup when tracker is destroyed
1224
1259
  */
1225
1260
  dispose() {
1226
- console.log(`[MT - ${getTimestamp()}] Disposing MediaTailorAdsTracker`);
1261
+ Log.debug(`[MT - ${getTimestamp()}] Disposing MediaTailorAdsTracker`);
1227
1262
 
1228
1263
  this.isDisposed = true;
1229
1264
 
1230
1265
  if (this.trackingAbortController) {
1231
- console.log(`[MT - ${getTimestamp()}] Aborting in-flight tracking fetch`);
1266
+ Log.debug(`[MT - ${getTimestamp()}] Aborting in-flight tracking fetch`);
1232
1267
  this.trackingAbortController.abort();
1233
1268
  this.trackingAbortController = null;
1234
1269
  }
1235
1270
 
1236
1271
  if (this.manifestAbortController) {
1237
- console.log(`[MT - ${getTimestamp()}] Aborting in-flight manifest fetch`);
1272
+ Log.debug(`[MT - ${getTimestamp()}] Aborting in-flight manifest fetch`);
1238
1273
  this.manifestAbortController.abort();
1239
1274
  this.manifestAbortController = null;
1240
1275
  }