@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.
- package/CHANGELOG.md +34 -10
- package/README.md +80 -0
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.LICENSE.txt +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.LICENSE.txt +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/umd/nrvideo.min.js +1 -1
- package/dist/umd/nrvideo.min.js.LICENSE.txt +1 -1
- package/dist/umd/nrvideo.min.js.map +1 -1
- package/package.json +1 -1
- package/src/agent.js +57 -1
- package/src/constants.js +11 -1
- package/src/core.js +1 -1
- package/src/eventAggregator.js +48 -0
- package/src/harvestScheduler.js +86 -3
- package/src/obfuscate.js +33 -0
- package/src/optimizedHttpClient.js +6 -2
- package/src/recordEvent.js +1 -1
- package/src/videoConfiguration.js +79 -7
- package/src/videotracker.js +49 -13
- package/src/videotrackerstate.js +72 -21
package/src/videotrackerstate.js
CHANGED
|
@@ -104,14 +104,19 @@ class VideoTrackerState {
|
|
|
104
104
|
this.partialAverageBitrate = 0;
|
|
105
105
|
|
|
106
106
|
/**
|
|
107
|
-
*
|
|
107
|
+
* Total duration (ms) of all closed bitrate segments for weighted average
|
|
108
108
|
*/
|
|
109
|
-
this.
|
|
109
|
+
this._totalBitrateDuration = 0;
|
|
110
110
|
|
|
111
111
|
/**
|
|
112
|
-
* Had
|
|
112
|
+
* Had Startup Error: TRUE if CONTENT_ERROR occurs before CONTENT_START.
|
|
113
113
|
*/
|
|
114
|
-
this.
|
|
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["
|
|
358
|
-
kpi["
|
|
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 +=
|
|
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
|
|
674
|
-
// Had Startup
|
|
680
|
+
// Track error flags for content errors only
|
|
681
|
+
// Had Startup Error: error before content started
|
|
675
682
|
if (!this.isStarted) {
|
|
676
|
-
this.
|
|
683
|
+
this.hadStartupError = true;
|
|
677
684
|
} else {
|
|
678
|
-
// Had Playback
|
|
679
|
-
this.
|
|
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
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
783
|
+
Log.debug("startAdsTime");
|
|
733
784
|
return this._totalAdPlaytime.start();
|
|
734
785
|
}
|
|
735
786
|
|
|
736
787
|
stopAdsTime() {
|
|
737
|
-
|
|
788
|
+
Log.debug("stopAdsTime");
|
|
738
789
|
return this._totalAdPlaytime.stop();
|
|
739
790
|
}
|
|
740
791
|
|