@newrelic/video-core 4.1.4-beta → 4.1.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.
@@ -104,14 +104,19 @@ class VideoTrackerState {
104
104
  this.partialAverageBitrate = 0;
105
105
 
106
106
  /**
107
- * Had Startup Failure: TRUE if CONTENT_ERROR occurs before CONTENT_START.
107
+ * Total duration (ms) of all closed bitrate segments for weighted average
108
108
  */
109
- this.hadStartupFailure = false;
109
+ this._totalBitrateDuration = 0;
110
110
 
111
111
  /**
112
- * Had Playback Failure: TRUE if CONTENT_ERROR occurs during content playback.
112
+ * Had Startup Error: TRUE if CONTENT_ERROR occurs before CONTENT_START.
113
113
  */
114
- this.hadPlaybackFailure = false;
114
+ this.hadStartupError = false;
115
+
116
+ /**
117
+ * Had Playback Error: TRUE if CONTENT_ERROR occurs during content playback.
118
+ */
119
+ this.hadPlaybackError = false;
115
120
 
116
121
  /**
117
122
  * The amount of ms the user has been rebuffering during content playback.
@@ -354,8 +359,8 @@ class VideoTrackerState {
354
359
  if (this.peakBitrate > 0) {
355
360
  kpi["peakBitrate"] = this.peakBitrate;
356
361
  }
357
- kpi["hadStartupFailure"] = this.hadStartupFailure;
358
- kpi["hadPlaybackFailure"] = this.hadPlaybackFailure;
362
+ kpi["hadStartupError"] = this.hadStartupError;
363
+ kpi["hadPlaybackError"] = this.hadPlaybackError;
359
364
  kpi["totalRebufferingTime"] = this.totalRebufferingTime;
360
365
  // Calculate rebuffering ratio as percentage (avoid division by zero)
361
366
  kpi["rebufferingRatio"] = this.totalPlaytime > 0
@@ -549,8 +554,10 @@ class VideoTrackerState {
549
554
  }
550
555
 
551
556
  // Accumulate total rebuffering time for content only
557
+ // Use exact stopped duration (stopTime - startTime) instead of live getDeltaTime()
552
558
  if (!this.isAd() && this.initialBufferingHappened) {
553
- this.totalRebufferingTime += this.timeSinceBufferBegin.getDeltaTime();
559
+ this.totalRebufferingTime +=
560
+ (this.timeSinceBufferBegin.stopTime - this.timeSinceBufferBegin.startTime);
554
561
  }
555
562
 
556
563
  return true;
@@ -670,13 +677,13 @@ class VideoTrackerState {
670
677
  } else {
671
678
  this.timeSinceLastError.start();
672
679
 
673
- // Track failure flags for content errors only
674
- // Had Startup Failure: error before content started
680
+ // Track error flags for content errors only
681
+ // Had Startup Error: error before content started
675
682
  if (!this.isStarted) {
676
- this.hadStartupFailure = true;
683
+ this.hadStartupError = true;
677
684
  } else {
678
- // Had Playback Failure: any content error
679
- this.hadPlaybackFailure = true;
685
+ // Had Playback Error: any content error during playback
686
+ this.hadPlaybackError = true;
680
687
  }
681
688
  }
682
689
  }
@@ -696,14 +703,57 @@ class VideoTrackerState {
696
703
  if (bitrate && typeof bitrate === "number") {
697
704
  this.peakBitrate = Math.max(this.peakBitrate, bitrate);
698
705
 
699
- if(this._lastBitrate === null || this._lastBitrate !== bitrate) {
700
- const deltaPlaytime = this._lastBitrateChangeTimestamp === null ? this.totalPlaytime : Date.now() - this._lastBitrateChangeTimestamp;
701
- const currentWeightedBitrate = (bitrate * deltaPlaytime);
702
- this.partialAverageBitrate += currentWeightedBitrate;
703
- this.weightedBitrate = currentWeightedBitrate / deltaPlaytime;
706
+ const now = Date.now();
707
+
708
+ // If not playing (buffering, paused, etc.), close the current segment
709
+ // so non-play time is excluded from the weighted average
710
+ if (!this.isPlaying) {
711
+ if (this._lastBitrate !== null && this._lastBitrateChangeTimestamp !== null) {
712
+ const segmentDuration = now - this._lastBitrateChangeTimestamp;
713
+ if (segmentDuration > 0) {
714
+ this.partialAverageBitrate += this._lastBitrate * segmentDuration;
715
+ this._totalBitrateDuration += segmentDuration;
716
+ }
717
+ this._lastBitrateChangeTimestamp = null; // Mark as paused
718
+ }
704
719
  this._lastBitrate = bitrate;
705
- this._lastBitrateChangeTimestamp = Date.now();
720
+ return;
721
+ }
722
+
723
+ // Playing: restart timestamp if returning from non-play state
724
+ if (this._lastBitrateChangeTimestamp === null && this._lastBitrate !== null) {
725
+ this._lastBitrateChangeTimestamp = now;
726
+ }
727
+
728
+ // Close the PREVIOUS segment when bitrate changes
729
+ if (this._lastBitrate !== null && this._lastBitrate !== bitrate
730
+ && this._lastBitrateChangeTimestamp !== null) {
731
+ const segmentDuration = now - this._lastBitrateChangeTimestamp;
732
+ if (segmentDuration > 0) {
733
+ this.partialAverageBitrate += this._lastBitrate * segmentDuration;
734
+ this._totalBitrateDuration += segmentDuration;
735
+ }
736
+ this._lastBitrateChangeTimestamp = now;
737
+ }
738
+
739
+ // Initialize timestamp on first observation
740
+ if (this._lastBitrateChangeTimestamp === null) {
741
+ this._lastBitrateChangeTimestamp = now;
742
+ }
743
+
744
+ this._lastBitrate = bitrate;
745
+
746
+ // Compute weighted average including current in-progress segment
747
+ let totalWeighted = this.partialAverageBitrate;
748
+ let totalDuration = this._totalBitrateDuration;
749
+ const currentSegment = now - this._lastBitrateChangeTimestamp;
750
+ if (currentSegment > 0) {
751
+ totalWeighted += bitrate * currentSegment;
752
+ totalDuration += currentSegment;
706
753
  }
754
+ this.weightedBitrate = totalDuration > 0
755
+ ? Math.round(totalWeighted / totalDuration)
756
+ : bitrate;
707
757
  }
708
758
  }
709
759
 
@@ -713,6 +763,7 @@ class VideoTrackerState {
713
763
  resetViewIdTrackedState() {
714
764
  this.peakBitrate = 0;
715
765
  this.partialAverageBitrate = 0;
766
+ this._totalBitrateDuration = 0;
716
767
  this.startupTime = null;
717
768
  this._lastBitrate = null;
718
769
  this._lastBitrateChangeTimestamp = null;
@@ -720,7 +771,7 @@ class VideoTrackerState {
720
771
 
721
772
  /** Methods to manage total ads time chrono */
722
773
  clearTotalAdsTime() {
723
- console.log("clear total ads time", this.totalAdTime);
774
+ Log.debug("clear total ads time", this.totalAdTime);
724
775
  this._totalAdPlaytime.reset();
725
776
  }
726
777
 
@@ -729,12 +780,12 @@ class VideoTrackerState {
729
780
  }
730
781
 
731
782
  startAdsTime() {
732
- console.log("startAdsTime");
783
+ Log.debug("startAdsTime");
733
784
  return this._totalAdPlaytime.start();
734
785
  }
735
786
 
736
787
  stopAdsTime() {
737
- console.log("stopAdsTime");
788
+ Log.debug("stopAdsTime");
738
789
  return this._totalAdPlaytime.stop();
739
790
  }
740
791