@newrelic/video-videojs 3.0.2 → 3.2.0-beta-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.
package/src/ads/ima.js ADDED
@@ -0,0 +1,248 @@
1
+ /* global google */
2
+ import nrvideo from '@newrelic/video-core';
3
+ import VideojsAdsTracker from './videojs-ads';
4
+
5
+ export default class ImaAdsTracker extends VideojsAdsTracker {
6
+ static isUsing(player) {
7
+ return player.ima && typeof google !== 'undefined';
8
+ }
9
+
10
+ getTrackerName() {
11
+ return 'ima-ads';
12
+ }
13
+
14
+ getPlayerName() {
15
+ return 'ima';
16
+ }
17
+
18
+ getPlayerVersion() {
19
+ return (
20
+ 'ima: ' + google.ima.VERSION + '; contrib-ads: ' + this.player.ads.VERSION
21
+ );
22
+ }
23
+
24
+ getCuePoints() {
25
+ return this.player.ima.getAdsManager().getCuePoints();
26
+ }
27
+
28
+ getAdPosition() {
29
+ if (
30
+ this.lastAdData &&
31
+ this.lastAdData.podInfo &&
32
+ this.lastAdData.podInfo.podIndex !== undefined
33
+ ) {
34
+ const podIndex = this.lastAdData.podInfo.podIndex;
35
+
36
+ if (podIndex === 0) {
37
+ return 'pre';
38
+ } else if (podIndex === -1) {
39
+ return 'post';
40
+ } else {
41
+ return 'mid';
42
+ }
43
+ }
44
+ return null;
45
+ }
46
+
47
+ getDuration() {
48
+ if (this.lastAdData && this.lastAdData.duration !== undefined) {
49
+ return this.lastAdData.duration * 1000;
50
+ }
51
+ return null;
52
+ }
53
+
54
+ getVideoId() {
55
+ if (this.lastAdData && this.lastAdData.adId) {
56
+ return this.lastAdData.adId;
57
+ }
58
+ return null;
59
+ }
60
+
61
+ getAdCreativeId() {
62
+ if (this.lastAdData && this.lastAdData.creativeId) {
63
+ return this.lastAdData.creativeId;
64
+ }
65
+ return null;
66
+ }
67
+
68
+ getSrc() {
69
+ if (this.lastAdData && this.lastAdData.mediaUrl) {
70
+ return this.lastAdData.mediaUrl;
71
+ }
72
+ return null;
73
+ }
74
+
75
+ getTitle() {
76
+ if (this.lastAdData && this.lastAdData.title) {
77
+ return this.lastAdData.title;
78
+ }
79
+ return null;
80
+ }
81
+
82
+ getPlayhead() {
83
+ let manager = this.player.ima.getAdsManager();
84
+ if (manager) {
85
+ return (this.getDuration() - manager.getRemainingTime()) * 1000;
86
+ }
87
+ }
88
+
89
+ getPlayrate() {
90
+ return this.player.playbackRate();
91
+ }
92
+
93
+ getAdPartner() {
94
+ return 'ima';
95
+ }
96
+
97
+ registerListeners() {
98
+ // Shortcut events
99
+ let e = google.ima.AdEvent.Type;
100
+ let AD_ERROR = google.ima.AdErrorEvent.Type.AD_ERROR;
101
+
102
+ //store ad data
103
+ this.lastAdData = null;
104
+ // debug
105
+ nrvideo.Log.debugCommonVideoEvents(this.player.ima.addEventListener, [
106
+ null,
107
+ e.ALL_ADS_COMPLETED,
108
+ e.LINEAR_CHANGED,
109
+ e.COMPLETE,
110
+ e.USER_CLOSE,
111
+ e.IMPRESSION,
112
+ e.CONTENT_PAUSE_REQUESTED,
113
+ e.CONTENT_RESUME_REQUESTED,
114
+ e.SKIPPED,
115
+ e.SKIPPABLE_STATE_CHANGED,
116
+ e.LOADED,
117
+ e.PAUSED,
118
+ e.RESUMED,
119
+ e.STARTED,
120
+ e.AD_CAN_PLAY,
121
+ e.AD_METADATA,
122
+ e.EXPANDED_CHANGED,
123
+ e.AD_BREAK_READY,
124
+ e.LOG,
125
+ e.CLICK,
126
+ e.FIRST_QUARTILE,
127
+ e.MIDPOINT,
128
+ e.THIRD_QUARTILE,
129
+ AD_ERROR,
130
+ ]);
131
+
132
+ // Register listeners
133
+ this.player.ima.addEventListener(e.LOADED, this.onLoaded.bind(this));
134
+ this.player.ima.addEventListener(e.STARTED, this.onStart.bind(this));
135
+ this.player.ima.addEventListener(e.PAUSED, this.onPaused.bind(this));
136
+ this.player.ima.addEventListener(e.RESUMED, this.onResumed.bind(this));
137
+ this.player.ima.addEventListener(e.COMPLETE, this.onComplete.bind(this));
138
+ this.player.ima.addEventListener(e.SKIPPED, this.onSkipped.bind(this));
139
+ this.player.ima.addEventListener(e.CLICK, this.onClick.bind(this));
140
+ this.player.ima.addEventListener(
141
+ e.FIRST_QUARTILE,
142
+ this.onFirstQuartile.bind(this)
143
+ );
144
+ this.player.ima.addEventListener(e.MIDPOINT, this.onMidpoint.bind(this));
145
+ this.player.ima.addEventListener(
146
+ e.THIRD_QUARTILE,
147
+ this.onThirdQuartile.bind(this)
148
+ );
149
+ this.player.ima.addEventListener(AD_ERROR, this.onError.bind(this));
150
+ }
151
+
152
+ unregisterListeners() {
153
+ // Shortcut events
154
+ let e = google.ima.AdEvent.Type;
155
+ let AD_ERROR = google.ima.AdErrorEvent.Type.AD_ERROR;
156
+
157
+ // unregister listeners
158
+ this.player.ima.removeEventListener(e.LOADED, this.onLoaded);
159
+ this.player.ima.removeEventListener(e.STARTED, this.onLoaded.bind(this));
160
+ this.player.ima.removeEventListener(e.IMPRESSION, this.onImpression);
161
+ this.player.ima.removeEventListener(e.PAUSED, this.onPaused);
162
+ this.player.ima.removeEventListener(e.RESUMED, this.onResumed);
163
+ this.player.ima.removeEventListener(e.COMPLETE, this.onComplete);
164
+ this.player.ima.removeEventListener(e.SKIPPED, this.onSkipped);
165
+ this.player.ima.removeEventListener(e.CLICK, this.onClick);
166
+ this.player.ima.removeEventListener(e.FIRST_QUARTILE, this.onFirstQuartile);
167
+ this.player.ima.removeEventListener(e.MIDPOINT, this.onMidpoint);
168
+ this.player.ima.removeEventListener(e.THIRD_QUARTILE, this.onThirdQuartile);
169
+ this.player.ima.removeEventListener(AD_ERROR, this.onError);
170
+ //clear ad data
171
+ this.lastAdData = null;
172
+ }
173
+
174
+ onLoaded(e) {
175
+ this.lastAdData = this.getAdData();
176
+ this.sendRequest();
177
+ }
178
+
179
+ onStart(e) {
180
+ this.lastAdData = this.getAdData();
181
+ this.sendStart();
182
+ }
183
+
184
+ onComplete(e) {
185
+ this.sendEnd();
186
+ this.lastAdData = null; // Clear the data
187
+ }
188
+
189
+ onSkipped(e) {
190
+ this.sendEnd({ skipped: true });
191
+ this.lastAdData = null; // Clear the data
192
+ }
193
+
194
+ onError(e) {
195
+ const adError = e.getError();
196
+
197
+ const errorCode = adError.getErrorCode();
198
+ const errorMessage = adError.getMessage();
199
+ this.sendError({ adError, errorCode, errorMessage });
200
+ }
201
+
202
+ onClick(e) {
203
+ this.sendAdClick();
204
+ }
205
+
206
+ onFirstQuartile() {
207
+ this.sendAdQuartile({ adQuartile: 1 });
208
+ }
209
+
210
+ onMidpoint() {
211
+ this.sendAdQuartile({ adQuartile: 2 });
212
+ }
213
+
214
+ onThirdQuartile() {
215
+ this.sendAdQuartile({ adQuartile: 3 });
216
+ }
217
+
218
+ onPaused() {
219
+ this.sendPause();
220
+ }
221
+
222
+ onResumed() {
223
+ this.sendResume();
224
+ }
225
+
226
+ getAdData() {
227
+ try {
228
+ const adsManager = this.player.ima.getAdsManager();
229
+ if (adsManager) {
230
+ const currentAd = adsManager.getCurrentAd();
231
+ if (currentAd) {
232
+ return {
233
+ adId: currentAd.getAdId(),
234
+ creativeId: currentAd.getCreativeId(),
235
+ duration: currentAd.getDuration(),
236
+ mediaUrl: currentAd.getMediaUrl(),
237
+ title: currentAd.getTitle(),
238
+ podInfo: currentAd.getAdPodInfo()?.data,
239
+ // Add other properties as needed
240
+ };
241
+ }
242
+ }
243
+ return null;
244
+ } catch (err) {
245
+ return null;
246
+ }
247
+ }
248
+ }
@@ -0,0 +1,145 @@
1
+ import nrvideo from '@newrelic/video-core';
2
+ import pkg from '../../package.json';
3
+
4
+ export default class VideojsAdsTracker extends nrvideo.VideoTracker {
5
+ getTrackerName() {
6
+ return 'videojs-ads';
7
+ }
8
+
9
+ getTrackerVersion() {
10
+ return pkg.version;
11
+ }
12
+
13
+ isMuted() {
14
+ return this.player.muted();
15
+ }
16
+
17
+ getRenditionHeight() {
18
+ return null;
19
+ }
20
+
21
+ getRenditionWidth() {
22
+ return null;
23
+ }
24
+
25
+ getPlayerName() {
26
+ return 'videojs-ads';
27
+ }
28
+
29
+ getPlayerVersion() {
30
+ return this.player.ads.VERSION;
31
+ }
32
+
33
+ registerListeners() {
34
+ nrvideo.Log.debugCommonVideoEvents(this.player, [
35
+ null,
36
+ 'ads-request',
37
+ 'ads-load',
38
+ 'adstart',
39
+ 'adend',
40
+ 'adskip',
41
+ 'adserror',
42
+ 'ads-click',
43
+ 'ads-pod-started',
44
+ 'ads-pod-ended',
45
+ 'ads-first-quartile',
46
+ 'ads-midpoint',
47
+ 'ads-third-quartile',
48
+ 'ads-pause',
49
+ 'ads-play',
50
+ 'adtimeout',
51
+ ]);
52
+
53
+ // Register listeners
54
+ this.player.on('ads-request', this.onAdrequest.bind(this));
55
+ this.player.on('ads-load', this.onAdload.bind(this));
56
+ this.player.on('adstart', this.onAdstart.bind(this));
57
+ this.player.on('adend', this.onAdend.bind(this));
58
+ this.player.on('adskip', this.onAdskip.bind(this));
59
+ this.player.on('adserror', this.onAdserror.bind(this));
60
+ this.player.on('ads-click', this.onAdsClick.bind(this));
61
+ this.player.on('ads-pod-started', this.onPodStart.bind(this));
62
+ this.player.on('ads-pod-ended', this.onPodEnd.bind(this));
63
+ this.player.on('ads-first-quartile', this.onFirstQuartile.bind(this));
64
+ this.player.on('ads-midpoint', this.onMidpoint.bind(this));
65
+ this.player.on('ads-third-quartile', this.onThirdQuartile.bind(this));
66
+ this.player.on('ads-pause', this.onAdspause.bind(this));
67
+ this.player.on('ads-play', this.onAdsplay.bind(this));
68
+ }
69
+
70
+ unregisterListeners() {
71
+ // unregister listeners
72
+ this.player.off('ads-request', this.onAdrequest);
73
+ this.player.off('ads-load', this.onAdload);
74
+ this.player.off('adstart', this.onAdstart);
75
+ this.player.off('adend', this.onAdend);
76
+ this.player.off('adskip', this.onAdskip);
77
+ this.player.off('adserror', this.onAdserror);
78
+ this.player.off('ads-click', this.onAdsClick);
79
+ this.player.off('ads-pod-started', this.onPodStart);
80
+ this.player.off('ads-pod-ended', this.onPodEnd);
81
+ this.player.off('ads-first-quartile', this.onFirstQuartile);
82
+ this.player.off('ads-midpoint', this.onMidpoint);
83
+ this.player.off('ads-third-quartile', this.onThirdQuartile);
84
+ this.player.off('ads-pause', this.onAdspause);
85
+ this.player.off('ads-play', this.onAdsplay);
86
+ }
87
+
88
+ onAdrequest(e) {
89
+ this.sendRequest();
90
+ this.sendDownload({ state: 'ads-request' });
91
+ }
92
+
93
+ onAdload(e) {
94
+ this.sendDownload({ state: 'ads-load' });
95
+ }
96
+
97
+ onAdstart(e) {
98
+ this.sendRequest();
99
+ this.sendStart();
100
+ }
101
+
102
+ onAdend(e) {
103
+ this.sendEnd();
104
+ }
105
+
106
+ onAdskip(e) {
107
+ this.sendEnd({ skipped: true });
108
+ }
109
+
110
+ onAdserror(e) {
111
+ this.sendError();
112
+ }
113
+
114
+ onAdsClick(e) {
115
+ this.sendAdClick({ url: 'unknown' });
116
+ }
117
+
118
+ onPodStart(e) {
119
+ this.sendAdBreakStart();
120
+ }
121
+
122
+ onPodEnd(e) {
123
+ this.sendAdBreakEnd();
124
+ }
125
+
126
+ onFirstQuartile() {
127
+ this.sendAdQuartile({ quartile: 1 });
128
+ }
129
+
130
+ onMidpoint() {
131
+ this.sendAdQuartile({ quartile: 2 });
132
+ }
133
+
134
+ onThirdQuartile() {
135
+ this.sendAdQuartile({ quartile: 3 });
136
+ }
137
+
138
+ onAdspause() {
139
+ this.sendPause();
140
+ }
141
+
142
+ onAdsplay() {
143
+ this.sendResume();
144
+ }
145
+ }
package/src/index.js ADDED
@@ -0,0 +1,2 @@
1
+ import VideojsTracker from './tracker';
2
+ export default VideojsTracker;
@@ -0,0 +1,19 @@
1
+ if (typeof videojs !== 'undefined') {
2
+ // Cross-compatibility for Video.js 5 and 6.
3
+ const registerPlugin = videojs.registerPlugin || videojs.plugin;
4
+
5
+ /**
6
+ * Register newrelic's video.js plugin.
7
+ *
8
+ * In the plugin function, the value of `this` is a video.js `Player`
9
+ * instance. You cannot rely on the player being in a "ready" state here,
10
+ * depending on how the plugin is invoked. This may or may not be important
11
+ * to you; if not, remove the wait for "ready"!
12
+ */
13
+ registerPlugin('newrelic', function (options) {
14
+ if (!this.newrelictracker) {
15
+ this.newrelictracker = new VideojsTracker(this);
16
+ }
17
+ return this.newrelictracker;
18
+ });
19
+ }
@@ -0,0 +1,45 @@
1
+ export default class ContribHlsTech {
2
+ constructor (tech) {
3
+ this.tech = tech.vhs
4
+ }
5
+
6
+ getRenditionName () {
7
+ try {
8
+ var media = this.tech.playlists.media()
9
+ if (media && media.attributes) return media.attributes.NAME
10
+ } catch (err) { }
11
+ return null
12
+ }
13
+
14
+ getRenditionBitrate () {
15
+ try {
16
+ var media = this.tech.playlists.media()
17
+ if (media && media.attributes) return media.attributes.BANDWIDTH
18
+ } catch (err) { }
19
+ return null
20
+ }
21
+
22
+ getRenditionWidth () {
23
+ try {
24
+ var media = this.tech.playlists.media()
25
+ if (media && media.attributes && media.attributes.RESOLUTION) {
26
+ return media.attributes.RESOLUTION.width
27
+ }
28
+ } catch (err) { }
29
+ return null
30
+ }
31
+
32
+ getRenditionHeight () {
33
+ try {
34
+ var media = this.tech.playlists.media()
35
+ if (media && media.attributes && media.attributes.RESOLUTION) {
36
+ return media.attributes.RESOLUTION.height
37
+ }
38
+ } catch (err) { }
39
+ return null
40
+ }
41
+ }
42
+
43
+ ContribHlsTech.isUsing = function (tech) {
44
+ return !!tech.vhs
45
+ }
@@ -0,0 +1,45 @@
1
+ export default class HlsJs {
2
+ constructor (tech) {
3
+ this.tech = tech.vhs_
4
+ }
5
+
6
+ getResource (tech) {
7
+ return this.tech.url
8
+ }
9
+
10
+ getRenditionName (tech) {
11
+ try {
12
+ var level = this.tech.levels[this.tech.currentLevel]
13
+ if (level && level.name) return level.name
14
+ } catch (err) { }
15
+ return null
16
+ }
17
+
18
+ getRenditionBitrate (tech) {
19
+ try {
20
+ var level = this.tech.levels[this.tech.currentLevel]
21
+ if (level && level.bitrate) return level.bitrate
22
+ } catch (err) { }
23
+ return null
24
+ }
25
+
26
+ getRenditionWidth (tech) {
27
+ try {
28
+ var level = this.tech.levels[this.tech.currentLevel]
29
+ if (level && level.width) return level.width
30
+ } catch (err) { }
31
+ return null
32
+ }
33
+
34
+ getRenditionHeight (tech) {
35
+ try {
36
+ var level = this.tech.levels[this.tech.currentLevel]
37
+ if (level && level.height) return level.height
38
+ } catch (err) { }
39
+ return null
40
+ }
41
+ }
42
+
43
+ HlsJs.isUsing = function (tech) {
44
+ return !!tech.vhs_
45
+ }
@@ -0,0 +1,49 @@
1
+ export default class ShakaTech {
2
+ constructor (tech) {
3
+ this.tech = tech.shakaPlayer
4
+ }
5
+
6
+ getSrc (tech) {
7
+ try {
8
+ return this.tech.getManifestUri()
9
+ } catch (err) {}
10
+ return null
11
+ }
12
+
13
+ getRenditionBitrate (tech) {
14
+ try {
15
+ return this.tech.getStats().streamBandwidth
16
+ } catch (err) { }
17
+ return null
18
+ }
19
+
20
+ getRenditionWidth (tech) {
21
+ try {
22
+ var tracks = this.tech.getVariantTracks()
23
+ for (var i in tracks) {
24
+ var track = tracks[i]
25
+ if (track.active && track.type === 'video') {
26
+ return track.width
27
+ }
28
+ }
29
+ } catch (err) { }
30
+ return null
31
+ }
32
+
33
+ getRenditionHeight (tech) {
34
+ try {
35
+ var tracks = this.tech.getVariantTracks()
36
+ for (var i in tracks) {
37
+ var track = tracks[i]
38
+ if (track.active && track.type === 'video') {
39
+ return track.height
40
+ }
41
+ }
42
+ } catch (err) { }
43
+ return null
44
+ }
45
+ }
46
+
47
+ ShakaTech.isUsing = function (tech) {
48
+ return !!tech.shakaPlayer
49
+ }