@newrelic/video-videojs 4.2.0 → 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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@newrelic/video-videojs",
3
- "version": "4.2.0",
3
+ "version": "4.2.1",
4
4
  "description": "New relic tracker for Videojs",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
package/src/tracker.js CHANGED
@@ -30,7 +30,7 @@ export const AD_TRACKING = {
30
30
  CSAI: 'csai',
31
31
  SSAI: Object.freeze({
32
32
  DAI: 'ssai:dai',
33
- MT: 'ssai:mt',
33
+ MT: 'ssai:mt',
34
34
  }),
35
35
  };
36
36
 
@@ -42,13 +42,14 @@ export default class VideojsTracker extends nrvideo.VideoTracker {
42
42
  this.imaAdCuePoints = '';
43
43
  this.daiInitialized = false;
44
44
  this.adTracking = options?.config?.ad?.type || null;
45
+ this.previousBitrate = null;
45
46
 
46
47
  // When options are provided but config.ad is not declared, no ad tracking
47
48
  // will run. Warn so the caller knows to set it explicitly.
48
49
  if (options && !this.adTracking) {
49
50
  nrvideo.Log.warn(
50
51
  'VideojsTracker: config.ad not set — no ad tracking will run. ' +
51
- 'Set config.ad.type to enable it (e.g. AD_TRACKING.CSAI, AD_TRACKING.SSAI.MT).'
52
+ 'Set config.ad.type to enable it (e.g. AD_TRACKING.CSAI, AD_TRACKING.SSAI.MT).',
52
53
  );
53
54
  }
54
55
 
@@ -59,7 +60,7 @@ export default class VideojsTracker extends nrvideo.VideoTracker {
59
60
  this.options = Object.assign({}, this.options, {
60
61
  mediatailor: {
61
62
  segmentPrefix: adConfig.segmentPrefix,
62
- trackingUrl: adConfig.trackingUrl,
63
+ trackingUrl: adConfig.trackingUrl,
63
64
  ...this.options?.mediatailor,
64
65
  },
65
66
  });
@@ -74,13 +75,10 @@ export default class VideojsTracker extends nrvideo.VideoTracker {
74
75
  * @param {'csai'|'ssai:dai'|'ssai:mt'} type
75
76
  */
76
77
  setAdTracking(type) {
77
- const valid = [
78
- AD_TRACKING.CSAI,
79
- ...Object.values(AD_TRACKING.SSAI),
80
- ];
78
+ const valid = [AD_TRACKING.CSAI, ...Object.values(AD_TRACKING.SSAI)];
81
79
  if (!valid.includes(type)) {
82
80
  nrvideo.Log.warn(
83
- `VideojsTracker.setAdTracking: unknown value "${type}". Valid values: ${valid.join(', ')}`
81
+ `VideojsTracker.setAdTracking: unknown value "${type}". Valid values: ${valid.join(', ')}`,
84
82
  );
85
83
  return;
86
84
  }
@@ -367,6 +365,15 @@ export default class VideojsTracker extends nrvideo.VideoTracker {
367
365
  this.player.on('ads-allpods-completed', this.OnAdsAllpodsCompleted);
368
366
  this.player.on('stream-manager', this.onStreamManager);
369
367
  this.player.on('canplaythrough', this.onCanPlayThrough);
368
+
369
+ this.onQualityLevelChange = this.onQualityLevelChange.bind(this);
370
+ // Get qualityLevels lazily after player is ready
371
+ if (typeof this.player.qualityLevels === 'function') {
372
+ this.qualityLevels = this.player.qualityLevels();
373
+ if (this.qualityLevels) {
374
+ this.qualityLevels.on('change', this.onQualityLevelChange);
375
+ }
376
+ }
370
377
  }
371
378
 
372
379
  unregisterListeners() {
@@ -390,6 +397,9 @@ export default class VideojsTracker extends nrvideo.VideoTracker {
390
397
  this.player.off('ads-allpods-completed', this.OnAdsAllpodsCompleted);
391
398
  this.player.off('stream-manager', this.onStreamManager);
392
399
  this.player.off('canplaythrough', this.onCanPlayThrough);
400
+ if (this.qualityLevels) {
401
+ this.qualityLevels.off('change', this.onQualityLevelChange);
402
+ }
393
403
  }
394
404
 
395
405
  onDownload(e) {
@@ -429,13 +439,15 @@ export default class VideojsTracker extends nrvideo.VideoTracker {
429
439
  if (!this.adTracking) {
430
440
  nrvideo.Log.warn(
431
441
  'VideojsTracker: adsready fired but config.ad.type is not set — ' +
432
- 'attempting CSAI auto-detection for backward compatibility.'
442
+ 'attempting CSAI auto-detection for backward compatibility.',
433
443
  );
434
444
  }
435
445
 
436
446
  if (!this.adsTracker) {
437
447
  if (BrightcoveImaAdsTracker.isUsing(this.player)) {
438
- nrvideo.Log.debug('VideojsTracker: auto-detected BrightcoveImaAdsTracker');
448
+ nrvideo.Log.debug(
449
+ 'VideojsTracker: auto-detected BrightcoveImaAdsTracker',
450
+ );
439
451
  this.setAdsTracker(new BrightcoveImaAdsTracker(this.player));
440
452
  } else if (ImaAdsTracker.isUsing(this.player)) {
441
453
  nrvideo.Log.debug('VideojsTracker: auto-detected ImaAdsTracker');
@@ -444,7 +456,9 @@ export default class VideojsTracker extends nrvideo.VideoTracker {
444
456
  nrvideo.Log.debug('VideojsTracker: auto-detected FreewheelAdsTracker');
445
457
  this.setAdsTracker(new FreewheelAdsTracker(this.player));
446
458
  } else {
447
- nrvideo.Log.debug('VideojsTracker: no specific CSAI framework detected, using generic VideojsAdsTracker');
459
+ nrvideo.Log.debug(
460
+ 'VideojsTracker: no specific CSAI framework detected, using generic VideojsAdsTracker',
461
+ );
448
462
  this.setAdsTracker(new VideojsAdsTracker(this.player));
449
463
  }
450
464
  }
@@ -575,6 +589,24 @@ export default class VideojsTracker extends nrvideo.VideoTracker {
575
589
  this.sendStart();
576
590
  }
577
591
  }
592
+
593
+ onQualityLevelChange(e) {
594
+ if (this.qualityLevels && this.qualityLevels.selectedIndex >= 0) {
595
+ const selectedLevel =
596
+ this.qualityLevels[this.qualityLevels.selectedIndex];
597
+ if (selectedLevel) {
598
+ const newBitrate = selectedLevel.bitrate;
599
+ const oldBitrate = this.previousBitrate;
600
+
601
+ this.sendRenditionChanged({
602
+ oldBitrate,
603
+ newBitrate,
604
+ });
605
+
606
+ this.previousBitrate = newBitrate;
607
+ }
608
+ }
609
+ }
578
610
  }
579
611
 
580
612
  // Attach AD_TRACKING and Log as static properties so UMD callers can use