@gumlet/insights-js-core 1.1.4 → 1.1.5
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/build/release/gumlet-insights.min.js +2 -0
- package/build/release/gumlet-insights.min.js.LICENSE.txt +10 -0
- package/build/release/package.json +1 -0
- package/package.json +3 -2
- package/.github/workflows/main.yml +0 -87
- package/.gitlab-ci.yml +0 -54
- package/bitbucket-pipelines.yml +0 -35
- package/docs/payload-documentation.md +0 -72
- package/html/bitmovin.html +0 -82
- package/html/dashjs.html +0 -55
- package/html/hlsjs.html +0 -72
- package/html/html5.html +0 -59
- package/html/shaka.html +0 -102
- package/html/videojs.html +0 -67
- package/index.html +0 -73
- package/jest.config.js +0 -187
- package/js/adapters/Bitmovin7Adapter.js +0 -352
- package/js/adapters/BitmovinAdapter.js +0 -198
- package/js/adapters/DashjsAdapter.js +0 -140
- package/js/adapters/HTML5Adapter.js +0 -774
- package/js/adapters/HlsjsAdapter.js +0 -152
- package/js/adapters/ShakaAdapter.js +0 -81
- package/js/adapters/VideoJsAdapter.js +0 -455
- package/js/analyticsStateMachines/Bitmovin7AnalyticsStateMachine.js +0 -471
- package/js/analyticsStateMachines/BitmovinAnalyticsStateMachine.js +0 -299
- package/js/analyticsStateMachines/HTML5AnalyticsStateMachine.js +0 -443
- package/js/analyticsStateMachines/VideoJsAnalyticsStateMachine.js +0 -503
- package/js/cast/CastClient.js +0 -50
- package/js/cast/CastReceiver.js +0 -37
- package/js/core/AdapterFactory.js +0 -41
- package/js/core/Analytics.js +0 -1367
- package/js/core/AnalyticsStateMachineFactory.js +0 -36
- package/js/core/GumletInsightsExport.js +0 -81
- package/js/enums/CDNProviders.js +0 -11
- package/js/enums/Events.js +0 -32
- package/js/enums/GumletEnum.js +0 -19
- package/js/enums/MIMETypes.js +0 -30
- package/js/enums/Players.js +0 -11
- package/js/enums/StreamTypes.js +0 -15
- package/js/utils/EventsCall.js +0 -22
- package/js/utils/HttpCall.js +0 -57
- package/js/utils/LicenseCall.js +0 -18
- package/js/utils/Logger.js +0 -40
- package/js/utils/PlayerDetector.js +0 -75
- package/js/utils/PlayerInitCall.js +0 -22
- package/js/utils/SessionCreationCall.js +0 -22
- package/js/utils/Settings.js +0 -3
- package/js/utils/Utils.js +0 -195
- package/precommit.bash +0 -8
- package/tests/stage1.test.js +0 -50
- package/webpack.config.debug.js +0 -34
- package/webpack.config.js +0 -40
- 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;
|