@gumlet/insights-js-core 1.1.4 → 1.1.6

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.
Files changed (53) hide show
  1. package/build/release/gumlet-insights.min.js +2 -0
  2. package/build/release/gumlet-insights.min.js.LICENSE.txt +10 -0
  3. package/build/release/package.json +1 -0
  4. package/package.json +3 -2
  5. package/.github/workflows/main.yml +0 -87
  6. package/.gitlab-ci.yml +0 -54
  7. package/bitbucket-pipelines.yml +0 -35
  8. package/docs/payload-documentation.md +0 -72
  9. package/html/bitmovin.html +0 -82
  10. package/html/dashjs.html +0 -55
  11. package/html/hlsjs.html +0 -72
  12. package/html/html5.html +0 -59
  13. package/html/shaka.html +0 -102
  14. package/html/videojs.html +0 -67
  15. package/index.html +0 -73
  16. package/jest.config.js +0 -187
  17. package/js/adapters/Bitmovin7Adapter.js +0 -352
  18. package/js/adapters/BitmovinAdapter.js +0 -198
  19. package/js/adapters/DashjsAdapter.js +0 -140
  20. package/js/adapters/HTML5Adapter.js +0 -774
  21. package/js/adapters/HlsjsAdapter.js +0 -152
  22. package/js/adapters/ShakaAdapter.js +0 -81
  23. package/js/adapters/VideoJsAdapter.js +0 -455
  24. package/js/analyticsStateMachines/Bitmovin7AnalyticsStateMachine.js +0 -471
  25. package/js/analyticsStateMachines/BitmovinAnalyticsStateMachine.js +0 -299
  26. package/js/analyticsStateMachines/HTML5AnalyticsStateMachine.js +0 -443
  27. package/js/analyticsStateMachines/VideoJsAnalyticsStateMachine.js +0 -503
  28. package/js/cast/CastClient.js +0 -50
  29. package/js/cast/CastReceiver.js +0 -37
  30. package/js/core/AdapterFactory.js +0 -41
  31. package/js/core/Analytics.js +0 -1367
  32. package/js/core/AnalyticsStateMachineFactory.js +0 -36
  33. package/js/core/GumletInsightsExport.js +0 -81
  34. package/js/enums/CDNProviders.js +0 -11
  35. package/js/enums/Events.js +0 -32
  36. package/js/enums/GumletEnum.js +0 -19
  37. package/js/enums/MIMETypes.js +0 -30
  38. package/js/enums/Players.js +0 -11
  39. package/js/enums/StreamTypes.js +0 -15
  40. package/js/utils/EventsCall.js +0 -22
  41. package/js/utils/HttpCall.js +0 -57
  42. package/js/utils/LicenseCall.js +0 -18
  43. package/js/utils/Logger.js +0 -40
  44. package/js/utils/PlayerDetector.js +0 -75
  45. package/js/utils/PlayerInitCall.js +0 -22
  46. package/js/utils/SessionCreationCall.js +0 -22
  47. package/js/utils/Settings.js +0 -3
  48. package/js/utils/Utils.js +0 -195
  49. package/precommit.bash +0 -8
  50. package/tests/stage1.test.js +0 -50
  51. package/webpack.config.debug.js +0 -34
  52. package/webpack.config.js +0 -40
  53. package/webpack.config.release.js +0 -62
@@ -1,152 +0,0 @@
1
- /* global Hls */
2
-
3
- import {HTML5Adapter} from './HTML5Adapter';
4
- import {MIMETypes} from '../enums/MIMETypes';
5
- import {Players} from '../enums/Players';
6
-
7
- /**
8
- * @class
9
- * @constructor
10
- */
11
- export class HlsjsAdapter extends HTML5Adapter {
12
-
13
- /**
14
- * @constructs
15
- * @param {Hls} hls
16
- * @param {AnalyticsEventCallback} eventCallback
17
- * @param {AnalyticsStateMachine} stateMachine
18
- */
19
- constructor(hls, eventCallback, stateMachine) {
20
-
21
- // we don't have a mediaEl yet per se
22
- super(null, eventCallback, stateMachine, Players.HLSJS);
23
-
24
- /**
25
- * @public
26
- * @member {Hls} hls Hls.js client instance
27
- */
28
- this.hls = hls;
29
-
30
- this.playerSoftwareName = Players.HLSJS;
31
-
32
- this.resetMedia();
33
- this.registerHlsEvents();
34
- }
35
-
36
- /**
37
- * Implemented by sub-class to deliver current quality-level info
38
- * specific to media-engine.
39
- * @override
40
- * @returns {QualityLevelInfo}
41
- */
42
- getCurrentQualityLevelInfo() {
43
- const hls = this.hls;
44
- const currentLevelObj = hls.levels[hls.currentLevel];
45
- if (!currentLevelObj) {
46
- return;
47
- }
48
-
49
- const attributes = currentLevelObj.attrs;
50
- const bitrate = parseInt(attributes.BANDWIDTH, 10);
51
- const width = parseInt(attributes.RESOLUTION.width, 10);
52
- const height = parseInt(attributes.RESOLUTION.height, 10);
53
- let audioCodec = null;
54
- let videoCodec = null;
55
-
56
- if (attributes.CODECS) {
57
- audioCodec = attributes.CODECS.split(",").length > 1 ? attributes.CODECS.split(",")[1] : "";
58
- videoCodec = attributes.CODECS.split(",").length > 1 ? attributes.CODECS.split(",")[0] : "";
59
- }
60
-
61
- return {
62
- bitrate,
63
- width,
64
- height,
65
- audioCodec,
66
- videoCodec
67
- };
68
- }
69
-
70
- /**
71
- * @override
72
- */
73
- isLive() {
74
- const hls = this.hls;
75
- if (hls.currentLevel < 0) {
76
- return false;
77
- }
78
- const currentLevelObj = hls.levels[hls.currentLevel];
79
- if (!currentLevelObj) {
80
- return false;
81
- }
82
-
83
- return currentLevelObj.details.live;
84
- }
85
-
86
- /**
87
- * @override
88
- */
89
- getPlayerVersion() {
90
- return Hls.version;
91
- }
92
-
93
- /**
94
- * @override
95
- */
96
- getMIMEType() {
97
- return MIMETypes.HLS;
98
- }
99
-
100
- /**
101
- * @override
102
- */
103
- getStreamURL() {
104
- return this.hls.url;
105
- }
106
-
107
- registerHlsEvents() {
108
- const hls = this.hls;
109
-
110
- if (!Hls) {
111
- throw new Error('Hls.js is not defined installed (must be loaded before analytics module)');
112
- }
113
-
114
- hls.on(Hls.Events.MEDIA_ATTACHING, this.onMediaAttaching.bind(this));
115
- hls.on(Hls.Events.MEDIA_DETACHING, this.onMediaDetaching.bind(this));
116
- hls.on(Hls.Events.MANIFEST_LOADING, this.onManifestLoading.bind(this));
117
-
118
- // media is already attached, event has been triggered before
119
- // or we are in the event handler of this event itself.
120
- // we can not know how the stacktrace to this constructor will look like.
121
- // therefore we will guard from this case in
122
- // the onMediaAttaching method (avoid running it twice)
123
- if (hls.media) {
124
- this.onMediaAttaching();
125
- }
126
-
127
- if (hls.url) {
128
- this.onManifestLoading();
129
- }
130
- }
131
-
132
- onMediaAttaching() {
133
- // in case we are called again (when we are triggering this ourselves
134
- // but from the event handler of MEDIA_ATTACHING) we should not run again.
135
- if (this.mediaEl) {
136
- return;
137
- }
138
-
139
- this.mediaEl = this.hls.media;
140
-
141
- this.registerMediaElement();
142
- this.onMaybeReady();
143
- }
144
-
145
- onMediaDetaching() {
146
- this.unregisterMediaElement();
147
- }
148
-
149
- onManifestLoading() {
150
- this.onMaybeReady();
151
- }
152
- }
@@ -1,81 +0,0 @@
1
- /* global shaka */
2
-
3
- import {HTML5Adapter} from './HTML5Adapter';
4
- import {MIMETypes} from '../enums/MIMETypes';
5
- import {Players} from '../enums/Players';
6
-
7
- export class ShakaAdapter extends HTML5Adapter {
8
-
9
- constructor(shakaPlayer, eventCallback, stateMachine, mediaElement) {
10
- // super(shakaPlayer.getMediaElement(), eventCallback, stateMachine);
11
- super(mediaElement, eventCallback, stateMachine, Players.SHAKA);
12
-
13
- if (!shaka) {
14
- throw new Error('`shaka` lib is not installed (must be loaded before analytics module)');
15
- }
16
-
17
- /**
18
- * @public
19
- * @member {shaka.Player}
20
- */
21
- this.shakaPlayer = shakaPlayer;
22
- this.playerSoftwareName = Players.SHAKA;
23
- }
24
-
25
- getPlayerVersion() {
26
- return shaka.Player.version;
27
- }
28
-
29
- isLive() {
30
- return this.shakaPlayer ? this.shakaPlayer.isLive() : false;
31
- }
32
-
33
- /**
34
- * @override
35
- */
36
- getMIMEType() {
37
- // FIXME: Could be HLS too, Shaka probably has a method to find out
38
- return MIMETypes.DASH;
39
- }
40
-
41
- /**
42
- * @override
43
- */
44
- getStreamURL() {
45
- // return this.shakaPlayer ? this.shakaPlayer.getManifestUri() : null;
46
- return this.shakaPlayer ? this.shakaPlayer.getAssetUri() : null;
47
- }
48
-
49
- /**
50
- * Implemented by sub-class to deliver current quality-level info
51
- * specific to media-engine.
52
- * @override
53
- * @returns {QualityLevelInfo}
54
- */
55
- getCurrentQualityLevelInfo() {
56
- const variantTracks = this.shakaPlayer.getVariantTracks();
57
-
58
- const activeVideoTrack = variantTracks
59
- .filter((track) => track.active)
60
- .filter((track) => track.videoCodec || track.videoId !== undefined)[0];
61
-
62
- if (!activeVideoTrack) {
63
- // can only happen for audio-only streams
64
- return null;
65
- }
66
-
67
- const bitrate = activeVideoTrack.videoBandwidth || activeVideoTrack.bandwidth;
68
- const width = activeVideoTrack.width;
69
- const height = activeVideoTrack.height;
70
- const videoCodec = activeVideoTrack.videoCodec;
71
- const audioCodec = activeVideoTrack.audioCodec;
72
-
73
- return {
74
- bitrate,
75
- width,
76
- height,
77
- videoCodec,
78
- audioCodec
79
- };
80
- }
81
- }
@@ -1,455 +0,0 @@
1
- /* global videojs */
2
-
3
- import Events from '../enums/Events';
4
-
5
- const BUFFERING_TIMECHANGED_TIMEOUT = 1000;
6
-
7
- class VideoJsAdapter {
8
- constructor(player, eventCallback, stateMachine) {
9
- this.onBeforeUnLoadEvent = false;
10
- this.player = player;
11
- this.eventCallback = eventCallback;
12
- this.stateMachine = stateMachine;
13
- this.register();
14
- }
15
-
16
- getStreamType(url) {
17
- if (url.endsWith('.m3u8')) {
18
- return 'hls';
19
- }
20
- if (url.endsWith('.mpd')) {
21
- return 'dash';
22
- }
23
- return 'progressive';
24
- }
25
-
26
- // this seems very generic. one could put it in a helper
27
- // and use it in many adapter implementations.
28
- getStreamSources(url) {
29
- let mpdUrl = null;
30
- let m3u8Url = null;
31
- let progUrl = null;
32
- const streamType = this.getStreamType(url);
33
- switch (streamType) {
34
- case 'hls':
35
- m3u8Url = url;
36
- break;
37
- case 'dash':
38
- mpdUrl = url;
39
- break;
40
- default:
41
- progUrl = url;
42
- }
43
- return {
44
- mpdUrl,
45
- m3u8Url,
46
- progUrl
47
- };
48
- }
49
-
50
- getVideoWindowDimensions(player) {
51
- // return {
52
- // width : player.width(),
53
- // height: player.height()
54
- // };
55
- return {
56
- width : player.el_.clientWidth,
57
- height: player.el_.clientHeight
58
- }
59
- }
60
-
61
- getVideoSourceDimensions(tech) {
62
- return {
63
- videoWidth : tech.videoWidth(),
64
- videoHeight: tech.videoHeight()
65
- };
66
- }
67
-
68
- /**
69
- * @returns {string} 'native' | 'flash' | 'html5'
70
- */
71
- getVideojsSourceHandlerMode_() {
72
- const tech = this.player.tech({IWillNotUseThisInPlugins: true});
73
-
74
- if (!tech.sourceHandler_) {
75
- return 'native';
76
- } else {
77
- return tech.sourceHandler_.options_.mode;
78
- }
79
- }
80
-
81
- register() {
82
- const that = this;
83
- this.player.on('loadedmetadata', function() {
84
- const streamType = that.getStreamType(this.currentSrc());
85
- const sources = that.getStreamSources(this.currentSrc());
86
- const mode = that.getVideojsSourceHandlerMode_();
87
- const info = {
88
- isLive : this.duration() === Infinity,
89
- version : videojs.VERSION,
90
- type : mode,
91
- duration : this.duration(),
92
- streamType,
93
- autoplay : this.autoplay(),
94
- ...sources,
95
- ...that.getVideoWindowDimensions(this),
96
- videoWindowWidth : this.videoWidth(),
97
- videoWindowHeight: this.videoHeight(),
98
- muted : this.muted()
99
- };
100
- that.stateMachine.updateMetadata(info);
101
- that.eventCallback(Events.SOURCE_LOADED, info);
102
- });
103
-
104
- this.player.on('loadeddata', function() {
105
- });
106
-
107
- this.player.ready(function() {
108
- const streamType = that.getStreamType(this.currentSrc());
109
- const sources = that.getStreamSources(this.currentSrc());
110
- const mode = that.getVideojsSourceHandlerMode_();
111
- let playerDimensions = that.getVideoWindowDimensions(this);
112
-
113
- let currentVideoData = {width:null, height:null, bitrate:null};
114
- if (this.tech_.hls) {
115
- const selectedPlaylist = this.tech_.hls.playlists.media();
116
- if (selectedPlaylist) {
117
- const {attributes} = selectedPlaylist;
118
- currentVideoData['bitrate'] = attributes.BANDWIDTH;
119
- currentVideoData['width'] = attributes.RESOLUTION.width;
120
- currentVideoData['height'] = attributes.RESOLUTION.height;
121
- currentVideoData['videoCodec'] = attributes.CODECS.split(",")[0];
122
- currentVideoData['audioCodec'] = attributes.CODECS.split(",")[1];
123
- }
124
- }
125
-
126
-
127
-
128
- const info = {
129
- isLive : false,
130
- version : videojs.VERSION,
131
- type : mode,
132
- duration : this.duration(),
133
- streamType,
134
- autoplay : this.autoplay(),
135
- ...sources,
136
- ...that.getVideoWindowDimensions(this),
137
- // videoWindowWidth : this.videoWidth(),
138
- // videoWindowHeight: this.videoHeight(),
139
- videoWindowWidth : playerDimensions.width,
140
- videoWindowHeight: playerDimensions.height,
141
- muted : this.muted(),
142
- currentVideoData: currentVideoData
143
- };
144
- that.eventCallback(Events.READY, info);
145
- });
146
-
147
- this.player.on('play', function() {
148
- let currentVideoData = {width:null, height:null, bitrate:null};
149
- if (this.tech_.hls) {
150
- const selectedPlaylist = this.tech_.hls.playlists.media();
151
- if (selectedPlaylist) {
152
- const {attributes} = selectedPlaylist;
153
- currentVideoData['bitrate'] = attributes.BANDWIDTH;
154
- currentVideoData['width'] = attributes.RESOLUTION.width;
155
- currentVideoData['height'] = attributes.RESOLUTION.height;
156
- currentVideoData['videoCodec'] = attributes.CODECS.split(",")[0];
157
- currentVideoData['audioCodec'] = attributes.CODECS.split(",")[1];
158
- }
159
- }
160
-
161
- that.eventCallback(Events.PLAY, {
162
- currentTime: this.currentTime(),
163
- currentVideoData: currentVideoData
164
- });
165
- });
166
-
167
- this.player.on('pause', function() {
168
- let currentVideoData = {width:null, height:null, bitrate:null};
169
- if (this.tech_.hls) {
170
- const selectedPlaylist = this.tech_.hls.playlists.media();
171
- if (selectedPlaylist) {
172
- const {attributes} = selectedPlaylist;
173
- currentVideoData['bitrate'] = attributes.BANDWIDTH;
174
- currentVideoData['width'] = attributes.RESOLUTION.width;
175
- currentVideoData['height'] = attributes.RESOLUTION.height;
176
- currentVideoData['videoCodec'] = attributes.CODECS.split(",")[0];
177
- currentVideoData['audioCodec'] = attributes.CODECS.split(",")[1];
178
- }
179
- }
180
-
181
- that.eventCallback(Events.PAUSE, {
182
- currentTime: this.currentTime(),
183
- currentVideoData: currentVideoData
184
- });
185
- });
186
- this.player.on('ended', function() {
187
- let currentVideoData = {width:null, height:null, bitrate:null};
188
- if (this.tech_.hls) {
189
- const selectedPlaylist = this.tech_.hls.playlists.media();
190
- if (selectedPlaylist) {
191
- const {attributes} = selectedPlaylist;
192
- currentVideoData['bitrate'] = attributes.BANDWIDTH;
193
- currentVideoData['width'] = attributes.RESOLUTION.width;
194
- currentVideoData['height'] = attributes.RESOLUTION.height;
195
- currentVideoData['videoCodec'] = attributes.CODECS.split(",")[0];
196
- currentVideoData['audioCodec'] = attributes.CODECS.split(",")[1];
197
- }
198
- }
199
-
200
- that.eventCallback(Events.END, {
201
- currentTime: this.currentTime()
202
- });
203
- });
204
- this.player.on('error', function() {
205
- let currentVideoData = {width:null, height:null, bitrate:null};
206
- if (this.tech_.hls) {
207
- const selectedPlaylist = this.tech_.hls.playlists.media();
208
- if (selectedPlaylist) {
209
- const {attributes} = selectedPlaylist;
210
- currentVideoData['bitrate'] = attributes.BANDWIDTH;
211
- currentVideoData['width'] = attributes.RESOLUTION.width;
212
- currentVideoData['height'] = attributes.RESOLUTION.height;
213
- }
214
- }
215
-
216
- const error = this.error();
217
- that.eventCallback(Events.ERROR, {
218
- currentTime: this.currentTime(),
219
- code : error.code,
220
- message : error.message
221
- });
222
- });
223
- this.player.on('volumechange', function() {
224
- let currentVideoData = {width:null, height:null, bitrate:null};
225
- if (this.tech_.hls) {
226
- const selectedPlaylist = this.tech_.hls.playlists.media();
227
- if (selectedPlaylist) {
228
- const {attributes} = selectedPlaylist;
229
- currentVideoData['bitrate'] = attributes.BANDWIDTH;
230
- currentVideoData['width'] = attributes.RESOLUTION.width;
231
- currentVideoData['height'] = attributes.RESOLUTION.height;
232
- currentVideoData['videoCodec'] = attributes.CODECS.split(",")[0];
233
- currentVideoData['audioCodec'] = attributes.CODECS.split(",")[1];
234
- }
235
- }
236
-
237
- const muted = this.muted();
238
- if (muted) {
239
- that.eventCallback(Events.MUTE, {
240
- currentTime: this.currentTime(),
241
- currentVideoData: currentVideoData
242
- });
243
- } else {
244
- that.eventCallback(Events.UN_MUTE, {
245
- currentTime: this.currentTime(),
246
- currentVideoData: currentVideoData
247
- });
248
- }
249
- });
250
- this.player.on('seeking', function () {
251
- let currentVideoData = {width:null, height:null, bitrate:null};
252
- if (this.tech_.hls) {
253
- const selectedPlaylist = this.tech_.hls.playlists.media();
254
- if (selectedPlaylist) {
255
- const {attributes} = selectedPlaylist;
256
- currentVideoData['bitrate'] = attributes.BANDWIDTH;
257
- currentVideoData['width'] = attributes.RESOLUTION.width;
258
- currentVideoData['height'] = attributes.RESOLUTION.height;
259
- currentVideoData['videoCodec'] = attributes.CODECS.split(",")[0];
260
- currentVideoData['audioCodec'] = attributes.CODECS.split(",")[1];
261
- }
262
- }
263
-
264
- that.eventCallback(Events.SEEK, {
265
- currentTime: this.currentTime(),
266
- droppedFrames: 0,
267
- currentVideoData: currentVideoData
268
- });
269
- });
270
- this.player.on('seeked', function () {
271
- let currentVideoData = {width:null, height:null, bitrate:null};
272
- if (this.tech_.hls) {
273
- const selectedPlaylist = this.tech_.hls.playlists.media();
274
- if (selectedPlaylist) {
275
- const {attributes} = selectedPlaylist;
276
- currentVideoData['bitrate'] = attributes.BANDWIDTH;
277
- currentVideoData['width'] = attributes.RESOLUTION.width;
278
- currentVideoData['height'] = attributes.RESOLUTION.height;
279
- currentVideoData['videoCodec'] = attributes.CODECS.split(",")[0];
280
- currentVideoData['audioCodec'] = attributes.CODECS.split(",")[1];
281
- }
282
- }
283
-
284
- that.eventCallback(Events.SEEKED, {
285
- currentTime: this.currentTime(),
286
- droppedFrames: 0,
287
- currentVideoData: currentVideoData
288
- });
289
- });
290
-
291
- let analyticsBitrate;
292
- let bufferingTimeout;
293
- // eslint-disable-next-line
294
- let lastTimeupdate = Date.now();
295
- let isStalling = false;
296
-
297
- this.player.on('timeupdate', function() {
298
- clearTimeout(bufferingTimeout);
299
- isStalling = false;
300
- lastTimeupdate = Date.now();
301
-
302
- let currentVideoData = {width:null, height:null, bitrate:null};
303
- let selectedPlaylist = null;
304
- if (this.tech_.hls) {
305
- selectedPlaylist = this.tech_.hls.playlists.media();
306
- if (selectedPlaylist) {
307
- const {attributes} = selectedPlaylist;
308
- currentVideoData['bitrate'] = attributes.BANDWIDTH;
309
- currentVideoData['width'] = attributes.RESOLUTION.width;
310
- currentVideoData['height'] = attributes.RESOLUTION.height;
311
- currentVideoData['videoCodec'] = attributes.CODECS.split(",")[0];
312
- currentVideoData['audioCodec'] = attributes.CODECS.split(",")[1];
313
- }
314
- }
315
-
316
- that.eventCallback(Events.TIMECHANGED, {
317
- currentTime: this.currentTime(),
318
- currentVideoData: currentVideoData
319
- });
320
-
321
- // // that is not the quality that is currently being played.
322
- // // for more accuracy one can use the segment-metadata cue tracking:
323
- // // https://github.com/videojs/videojs-contrib-hls#segment-metadata
324
- // const selectedPlaylist = this.tech_.hls.playlists.media();
325
- if (!selectedPlaylist) {
326
- return;
327
- }
328
- //
329
- const {attributes} = selectedPlaylist;
330
- const bitrate = attributes.BANDWIDTH;
331
- const width = attributes.RESOLUTION.width;
332
- const height = attributes.RESOLUTION.height;
333
- const videoCodec = attributes.CODECS.split(",")[0];
334
- const audioCodec = attributes.CODECS.split(",")[1];
335
-
336
- // let currentVideoData = {width:null, height:null, bitrate:null}
337
- // if (selectedPlaylist) {
338
- // const {attributes} = selectedPlaylist;
339
- // currentVideoData['bitrate'] = bitrate;
340
- // currentVideoData['width'] = width;
341
- // currentVideoData['height'] = height;
342
- // }
343
-
344
- if (analyticsBitrate !== bitrate) {
345
- const eventObject = {
346
- width,
347
- height,
348
- bitrate,
349
- videoCodec,
350
- audioCodec,
351
- currentTime: this.currentTime(),
352
- currentVideoData: currentVideoData
353
- };
354
-
355
- that.eventCallback(Events.VIDEO_CHANGE, eventObject);
356
- analyticsBitrate = bitrate;
357
- }
358
-
359
- bufferingTimeout = setTimeout(() => {
360
- if ((this.paused() || this.ended()) && !isStalling) {
361
- return;
362
- }
363
-
364
- that.eventCallback(Events.START_BUFFERING, {
365
- currentTime: this.currentTime()
366
- });
367
- }, BUFFERING_TIMECHANGED_TIMEOUT);
368
-
369
- // Check for HLS source-handler (videojs-contrib-hls)
370
- // When we just use Videojs without any specific source-handler (not using MSE API based engine)
371
- // but just native technology (HTML5/Flash) to do for example "progressive download" with plain Webm/Mp4
372
- // or use native HLS on Safari this may not not be present. In that case Videojs is just
373
- // a wrapper around the respective playback tech (HTML or Flash).
374
-
375
- const tech = this.tech({IWillNotUseThisInPlugins: true});
376
- if (tech.hls) {
377
-
378
- // From here we are going onto Videojs-HLS source-handler specific API
379
- //
380
- const hls = this.tech_.hls;
381
-
382
- // Maybe we have the HLS source-handler initialized, but it is
383
- // not actually activated and used (just wrapping HTML5 built-in HLS playback like in Safari)
384
- if (!hls.playlists || typeof hls.playlists.media !== 'function') {
385
- return;
386
- }
387
-
388
- // Check for current media playlist
389
- const selectedPlaylist = hls.playlists.media();
390
- if (!selectedPlaylist) {
391
- return;
392
- }
393
-
394
- const {attributes} = selectedPlaylist;
395
- const bitrate = attributes.BANDWIDTH;
396
- const width = attributes.RESOLUTION.width;
397
- const height = attributes.RESOLUTION.height;
398
- const videoCodec = attributes.CODECS.split(",")[0];
399
- const audioCodec = attributes.CODECS.split(",")[1];
400
-
401
- let currentVideoData = {
402
- width:width,
403
- height:height,
404
- bitrate:bitrate,
405
- videoCodec:videoCodec,
406
- audioCodec:audioCodec
407
- }
408
-
409
- // update actual bitrate
410
- if (isNaN(analyticsBitrate) || analyticsBitrate !== bitrate) {
411
- const eventObject = {
412
- width,
413
- height,
414
- bitrate,
415
- currentTime: this.currentTime(),
416
- currentVideoData: currentVideoData
417
- };
418
-
419
- that.eventCallback(Events.VIDEO_CHANGE, eventObject);
420
- analyticsBitrate = bitrate;
421
- }
422
- }
423
-
424
- });
425
-
426
- this.player.on('stalled', function() {
427
- isStalling = true;
428
- });
429
-
430
- if (typeof window !== "undefined")
431
- {
432
- window.onunload = window.onbeforeunload = () => {
433
- if (!this.onBeforeUnLoadEvent) {
434
- this.onBeforeUnLoadEvent = true;
435
- this.eventCallback(Events.UNLOAD, {
436
- currentTime: this.player.currentTime()
437
-
438
- });
439
- }
440
- };
441
- }
442
- else
443
- {
444
- if (!this.onBeforeUnLoadEvent) {
445
- this.onBeforeUnLoadEvent = true;
446
- this.eventCallback(Events.UNLOAD, {
447
- currentTime: this.player.currentTime()
448
- });
449
- }
450
- }
451
-
452
- }
453
- }
454
-
455
- export default VideoJsAdapter;