@stormstreaming/stormstreamer 0.9.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/README.md +31 -0
- package/dist/amd/index.js +3448 -0
- package/dist/cjs/index.js +14 -0
- package/dist/esm/index.js +14 -0
- package/dist/iife/index.js +14 -0
- package/dist/types/StormStreamer.d.ts +75 -0
- package/dist/types/config/AudioData.d.ts +16 -0
- package/dist/types/config/ConfigManager.d.ts +18 -0
- package/dist/types/config/DebugData.d.ts +33 -0
- package/dist/types/config/IConfig.d.ts +4 -0
- package/dist/types/config/SettingsData.d.ts +37 -0
- package/dist/types/config/StorageData.d.ts +16 -0
- package/dist/types/config/StreamData.d.ts +25 -0
- package/dist/types/config/VideoData.d.ts +40 -0
- package/dist/types/config/enum/LogType.d.ts +7 -0
- package/dist/types/config/enum/ProtocolType.d.ts +7 -0
- package/dist/types/config/enum/ScalingType.d.ts +6 -0
- package/dist/types/config/enum/SecurityType.d.ts +4 -0
- package/dist/types/config/enum/SizeCalculationType.d.ts +5 -0
- package/dist/types/events/EventDispatcher.d.ts +15 -0
- package/dist/types/events/StormStreamerEvent.d.ts +128 -0
- package/dist/types/events/StormStreamerListener.d.ts +2 -0
- package/dist/types/index.amd.d.ts +10 -0
- package/dist/types/index.cjs.d.ts +10 -0
- package/dist/types/index.esm.d.ts +10 -0
- package/dist/types/index.iife.d.ts +3 -0
- package/dist/types/index.umd.d.ts +10 -0
- package/dist/types/logger/Logger.d.ts +25 -0
- package/dist/types/model/AbstractSourceItem.d.ts +9 -0
- package/dist/types/model/ClientUser.d.ts +6 -0
- package/dist/types/model/GatewayServerItem.d.ts +17 -0
- package/dist/types/model/IServerItem.d.ts +9 -0
- package/dist/types/model/ISourceItem.d.ts +8 -0
- package/dist/types/model/IStreamItem.d.ts +8 -0
- package/dist/types/model/QualityItem.d.ts +17 -0
- package/dist/types/model/RTMPSourceItem.d.ts +17 -0
- package/dist/types/model/RTSPSourceItem.d.ts +17 -0
- package/dist/types/model/StormMetaDataItem.d.ts +44 -0
- package/dist/types/model/StormServerItem.d.ts +17 -0
- package/dist/types/model/StormSourceItem.d.ts +11 -0
- package/dist/types/model/StreamInfo.d.ts +17 -0
- package/dist/types/network/AbstractSocket.d.ts +26 -0
- package/dist/types/network/NetworkController.d.ts +20 -0
- package/dist/types/network/StormPacket.d.ts +93 -0
- package/dist/types/network/WowzaConnection.d.ts +22 -0
- package/dist/types/playback/CooldownMonitor.d.ts +9 -0
- package/dist/types/playback/PlaybackController.d.ts +54 -0
- package/dist/types/playback/SoundMeter.d.ts +17 -0
- package/dist/types/playback/enum/ConnectionState.d.ts +8 -0
- package/dist/types/playback/enum/InputType.d.ts +4 -0
- package/dist/types/playback/enum/PublishState.d.ts +10 -0
- package/dist/types/playback/enum/TaskType.d.ts +7 -0
- package/dist/types/playback/model/InputDevice.d.ts +14 -0
- package/dist/types/playback/model/InputDeviceList.d.ts +9 -0
- package/dist/types/playback/player/AbstractPlayer.d.ts +11 -0
- package/dist/types/playback/player/IPlayer.d.ts +3 -0
- package/dist/types/playback/task/IPlaybackTask.d.ts +4 -0
- package/dist/types/playback/task/PauseTask.d.ts +8 -0
- package/dist/types/playback/task/PlayTask.d.ts +8 -0
- package/dist/types/playback/task/SubscribeTask.d.ts +8 -0
- package/dist/types/playback/task/UnsubscribeTask.d.ts +6 -0
- package/dist/types/stage/ScreenElement.d.ts +19 -0
- package/dist/types/stage/StageController.d.ts +46 -0
- package/dist/types/storage/StorageManager.d.ts +10 -0
- package/dist/types/types/AudioConfig.d.ts +4 -0
- package/dist/types/types/DebugConfig.d.ts +15 -0
- package/dist/types/types/ServerListConfig.d.ts +6 -0
- package/dist/types/types/SettingsConfig.d.ts +15 -0
- package/dist/types/types/SourceListConfig.d.ts +9 -0
- package/dist/types/types/StorageConfig.d.ts +4 -0
- package/dist/types/types/StreamConfig.d.ts +5 -0
- package/dist/types/types/StreamInfoConfig.d.ts +6 -0
- package/dist/types/types/StreamerConfig.d.ts +7 -0
- package/dist/types/types/VideoConfig.d.ts +9 -0
- package/dist/types/utilities/DomUtilities.d.ts +6 -0
- package/dist/types/utilities/MungeData.d.ts +18 -0
- package/dist/types/utilities/MungeSDP.d.ts +16 -0
- package/dist/types/utilities/NumberUtilities.d.ts +9 -0
- package/dist/types/utilities/UserCapabilities.d.ts +19 -0
- package/dist/umd/index.js +14 -0
- package/package.json +102 -0
|
@@ -0,0 +1,3448 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* StormStreaming JavaScript Streamer
|
|
3
|
+
* Copyright © 2021-2024 Web-Anatomy s.c. All rights reserved.
|
|
4
|
+
* contact@stormstreaming.com
|
|
5
|
+
* https://stormstreaming.com
|
|
6
|
+
*
|
|
7
|
+
* Version: 0.9.0-beta.0
|
|
8
|
+
* Version: 11/28/2024, 9:22:54 AM
|
|
9
|
+
*
|
|
10
|
+
* LEGAL NOTICE:
|
|
11
|
+
* This software is subject to the terms and conditions defined in
|
|
12
|
+
* separate license conditions ('LICENSE.txt')
|
|
13
|
+
*
|
|
14
|
+
*/define(['exports'], (function (exports) { 'use strict';
|
|
15
|
+
|
|
16
|
+
class StormServerItem {
|
|
17
|
+
constructor(host, application, port = 443, isSSL = true) {
|
|
18
|
+
this.host = host;
|
|
19
|
+
this.application = application;
|
|
20
|
+
this.port = port;
|
|
21
|
+
this.isSSL = isSSL;
|
|
22
|
+
this.hasFaild = false;
|
|
23
|
+
}
|
|
24
|
+
getHost() {
|
|
25
|
+
return this.host;
|
|
26
|
+
}
|
|
27
|
+
getApplication() {
|
|
28
|
+
return this.application;
|
|
29
|
+
}
|
|
30
|
+
getPort() {
|
|
31
|
+
return this.port;
|
|
32
|
+
}
|
|
33
|
+
getIfSSL() {
|
|
34
|
+
return this.isSSL;
|
|
35
|
+
}
|
|
36
|
+
getIfFaild() {
|
|
37
|
+
return this.hasFaild;
|
|
38
|
+
}
|
|
39
|
+
setAsFaild(value) {
|
|
40
|
+
this.hasFaild = value;
|
|
41
|
+
}
|
|
42
|
+
getData() {
|
|
43
|
+
return {
|
|
44
|
+
serverURL: this.getHost(),
|
|
45
|
+
application: this.getHost(),
|
|
46
|
+
serverPort: this.getPort(),
|
|
47
|
+
isSSL: this.getIfSSL()
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
toString() {
|
|
51
|
+
return "host: " + this.host + " | application: " + this.application + " | port: " + this.port + " | isSSL: " + this.isSSL;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
class StreamData {
|
|
56
|
+
constructor(streamConfig) {
|
|
57
|
+
this._serverList = new Array();
|
|
58
|
+
this._sourceList = new Array();
|
|
59
|
+
this._streamKey = null;
|
|
60
|
+
this.parse(streamConfig);
|
|
61
|
+
}
|
|
62
|
+
parse(streamConfig) {
|
|
63
|
+
var _a, _b, _c;
|
|
64
|
+
this._streamConfig = streamConfig;
|
|
65
|
+
if (!this._streamConfig) throw new Error("Stream configuration is missing. Please check stream config!");
|
|
66
|
+
if (this._streamConfig.serverList !== undefined && this._streamConfig.serverList !== null) {
|
|
67
|
+
if (this._streamConfig.serverList.length !== 0) {
|
|
68
|
+
for (let i = 0; i < this._streamConfig.serverList.length; i++) {
|
|
69
|
+
let host;
|
|
70
|
+
let application;
|
|
71
|
+
if (this._streamConfig.serverList[i].host != null) host = this._streamConfig.serverList[i].host;else throw new Error("Error while parsing server object (\"host\" field is missing). Please check player config!");
|
|
72
|
+
if (this._streamConfig.serverList[i].application != null) application = this._streamConfig.serverList[i].application;else throw new Error("Error while parsing server object (\"application\" field is missing). Please check player config!");
|
|
73
|
+
const port = (_a = this._streamConfig.serverList[i].port) !== null && _a !== void 0 ? _a : StreamData.DEFAULT_CONNECTION_PORT;
|
|
74
|
+
const isSSL = (_b = this._streamConfig.serverList[i].ssl) !== null && _b !== void 0 ? _b : StreamData.IS_SSL_BY_DEFAULT;
|
|
75
|
+
this._serverList.push(new StormServerItem(host, application, port, isSSL));
|
|
76
|
+
}
|
|
77
|
+
} else throw new Error("StormLibrary: Server list configuration is empty. Please check the config!");
|
|
78
|
+
} else throw new Error("StormLibrary: Server list configuration is missing. Please check the config!");
|
|
79
|
+
this._streamKey = (_c = this._streamConfig.streamKey) !== null && _c !== void 0 ? _c : this._streamKey;
|
|
80
|
+
}
|
|
81
|
+
getServerList() {
|
|
82
|
+
return this._serverList;
|
|
83
|
+
}
|
|
84
|
+
getSourceList() {
|
|
85
|
+
return this._sourceList;
|
|
86
|
+
}
|
|
87
|
+
get streamKey() {
|
|
88
|
+
return this._streamKey;
|
|
89
|
+
}
|
|
90
|
+
set streamKey(newValue) {
|
|
91
|
+
this._streamKey = newValue;
|
|
92
|
+
}
|
|
93
|
+
set serverList(serverList) {
|
|
94
|
+
this._serverList = serverList;
|
|
95
|
+
}
|
|
96
|
+
set sourceList(sourceList) {
|
|
97
|
+
this._sourceList = sourceList;
|
|
98
|
+
}
|
|
99
|
+
clearSourceList() {
|
|
100
|
+
this._sourceList = new Array();
|
|
101
|
+
}
|
|
102
|
+
clearServerList() {
|
|
103
|
+
this._serverList = new Array();
|
|
104
|
+
}
|
|
105
|
+
print(logger, force = false) {
|
|
106
|
+
if (StreamData.PRINT_ON_STARTUP || force) {
|
|
107
|
+
logger.info(this, "Server List:");
|
|
108
|
+
for (let i = 0; i < this._serverList.length; i++) {
|
|
109
|
+
logger.info(this, "=> [" + i + "] " + this._serverList[i].toString());
|
|
110
|
+
}
|
|
111
|
+
logger.info(this, "StreamKey: " + this._streamKey);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
StreamData.PRINT_ON_STARTUP = true;
|
|
116
|
+
StreamData.DEFAULT_CONNECTION_PORT = 443;
|
|
117
|
+
StreamData.IS_SSL_BY_DEFAULT = true;
|
|
118
|
+
|
|
119
|
+
var ScalingType;
|
|
120
|
+
(function (ScalingType) {
|
|
121
|
+
ScalingType["FILL"] = "fill";
|
|
122
|
+
ScalingType["LETTER_BOX"] = "letterbox";
|
|
123
|
+
ScalingType["CROP"] = "crop";
|
|
124
|
+
ScalingType["ORIGINAL"] = "original";
|
|
125
|
+
})(ScalingType || (ScalingType = {}));
|
|
126
|
+
|
|
127
|
+
var SizeCalculationType;
|
|
128
|
+
(function (SizeCalculationType) {
|
|
129
|
+
SizeCalculationType["CLIENT_DIMENSIONS"] = "clientDimensions";
|
|
130
|
+
SizeCalculationType["BOUNDING_BOX"] = "boundingBox";
|
|
131
|
+
SizeCalculationType["FULL_BOX"] = "fullBox";
|
|
132
|
+
})(SizeCalculationType || (SizeCalculationType = {}));
|
|
133
|
+
|
|
134
|
+
class VideoData {
|
|
135
|
+
constructor(videoConfig) {
|
|
136
|
+
this._scalingMode = ScalingType.LETTER_BOX;
|
|
137
|
+
this._aspectRatio = "none";
|
|
138
|
+
this._videoWidthValue = 100;
|
|
139
|
+
this._isVideoWidthInPixels = false;
|
|
140
|
+
this._wasVideoWidthProvided = false;
|
|
141
|
+
this._videoHeightValue = 100;
|
|
142
|
+
this._isVideoHeightInPixels = false;
|
|
143
|
+
this._wasVideoHeightProvided = false;
|
|
144
|
+
this._resizeDebounce = 250;
|
|
145
|
+
this._parentSizeCalculationMethod = SizeCalculationType.CLIENT_DIMENSIONS;
|
|
146
|
+
this.parse(videoConfig);
|
|
147
|
+
}
|
|
148
|
+
parse(config) {
|
|
149
|
+
var _a, _b;
|
|
150
|
+
this.videoConfig = config;
|
|
151
|
+
if (this.videoConfig != null) {
|
|
152
|
+
if (this.videoConfig.aspectRatio != null) {
|
|
153
|
+
const aspectRatioRegexString = '^[0-9]*\\.?[0-9]+:[0-9]*\\.?[0-9]+$';
|
|
154
|
+
const aspectRatioRegex = new RegExp(aspectRatioRegexString);
|
|
155
|
+
let tempAspectRatio = this.videoConfig.aspectRatio;
|
|
156
|
+
if (aspectRatioRegex.test(tempAspectRatio)) {
|
|
157
|
+
this._aspectRatio = tempAspectRatio;
|
|
158
|
+
} else throw new Error("Parameter \"aspectRatio\" - must match \"number:number\" pattern ");
|
|
159
|
+
this._aspectRatio = this.videoConfig.aspectRatio;
|
|
160
|
+
}
|
|
161
|
+
if (this.videoConfig.scalingMode != null) {
|
|
162
|
+
let newScalingMode = this.videoConfig.scalingMode;
|
|
163
|
+
switch (newScalingMode.toLowerCase()) {
|
|
164
|
+
case "fill":
|
|
165
|
+
this._scalingMode = ScalingType.FILL;
|
|
166
|
+
break;
|
|
167
|
+
case "letterbox":
|
|
168
|
+
this._scalingMode = ScalingType.LETTER_BOX;
|
|
169
|
+
break;
|
|
170
|
+
case "crop":
|
|
171
|
+
this._scalingMode = ScalingType.CROP;
|
|
172
|
+
break;
|
|
173
|
+
case "original":
|
|
174
|
+
this._scalingMode = ScalingType.ORIGINAL;
|
|
175
|
+
break;
|
|
176
|
+
default:
|
|
177
|
+
throw new Error("Unknown video scaling mode. Please check player config!");
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
if (this.videoConfig.width !== undefined) {
|
|
181
|
+
if (this.videoConfig.width !== null) {
|
|
182
|
+
if (typeof this.videoConfig.width === "number") {
|
|
183
|
+
this._videoWidthValue = this.videoConfig.width;
|
|
184
|
+
this._isVideoWidthInPixels = true;
|
|
185
|
+
} else if (typeof this.videoConfig.width === "string") {
|
|
186
|
+
if (this.videoConfig.width.toLowerCase().endsWith('px')) {
|
|
187
|
+
this._videoWidthValue = parseInt(this.videoConfig.width);
|
|
188
|
+
this._isVideoWidthInPixels = true;
|
|
189
|
+
} else if (this.videoConfig.width.toLowerCase().endsWith('%')) {
|
|
190
|
+
this._videoWidthValue = parseInt(this.videoConfig.width);
|
|
191
|
+
this._isVideoWidthInPixels = false;
|
|
192
|
+
}
|
|
193
|
+
} else throw new Error("Unknown type for parameter \"width\" - it must be a number or a string! ");
|
|
194
|
+
this._wasVideoWidthProvided = true;
|
|
195
|
+
} else throw new Error("Parameter \"width\" cannot be empty");
|
|
196
|
+
}
|
|
197
|
+
if (this.videoConfig.height !== undefined) {
|
|
198
|
+
if (this.videoConfig.height !== null) {
|
|
199
|
+
if (typeof this.videoConfig.height === "number") {
|
|
200
|
+
this._videoHeightValue = this.videoConfig.height;
|
|
201
|
+
this._isVideoHeightInPixels = true;
|
|
202
|
+
} else if (typeof this.videoConfig.height === "string") {
|
|
203
|
+
if (this.videoConfig.height.toLowerCase().endsWith('px')) {
|
|
204
|
+
this._videoHeightValue = parseInt(this.videoConfig.height);
|
|
205
|
+
this._isVideoHeightInPixels = true;
|
|
206
|
+
} else if (this.videoConfig.height.toLowerCase().endsWith('%')) {
|
|
207
|
+
this._videoHeightValue = parseInt(this.videoConfig.height);
|
|
208
|
+
this._isVideoHeightInPixels = false;
|
|
209
|
+
}
|
|
210
|
+
} else throw new Error("Unknown type for parameter \"height\" - it must be a number or a string!");
|
|
211
|
+
this._wasVideoHeightProvided = true;
|
|
212
|
+
} else throw new Error("Parameter \"height\" cannot be empty");
|
|
213
|
+
}
|
|
214
|
+
if (this.videoConfig.sizeCalculationMethod !== undefined) {
|
|
215
|
+
if (this.videoConfig.sizeCalculationMethod !== null) {
|
|
216
|
+
switch (this.videoConfig.sizeCalculationMethod) {
|
|
217
|
+
case "clientDimensions":
|
|
218
|
+
this._parentSizeCalculationMethod = SizeCalculationType.CLIENT_DIMENSIONS;
|
|
219
|
+
break;
|
|
220
|
+
case "boundingBox":
|
|
221
|
+
this._parentSizeCalculationMethod = SizeCalculationType.BOUNDING_BOX;
|
|
222
|
+
break;
|
|
223
|
+
case "fullBox":
|
|
224
|
+
this._parentSizeCalculationMethod = SizeCalculationType.FULL_BOX;
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
this._containerID = (_a = this.videoConfig.containerID) !== null && _a !== void 0 ? _a : null;
|
|
230
|
+
this._resizeDebounce = (_b = this.videoConfig.resizeDebounce) !== null && _b !== void 0 ? _b : this._resizeDebounce;
|
|
231
|
+
} else throw new Error("Missing video configuration. Please check player config!");
|
|
232
|
+
}
|
|
233
|
+
get scalingMode() {
|
|
234
|
+
return this._scalingMode;
|
|
235
|
+
}
|
|
236
|
+
get containerID() {
|
|
237
|
+
return this._containerID;
|
|
238
|
+
}
|
|
239
|
+
get videoWidthValue() {
|
|
240
|
+
return this._videoWidthValue;
|
|
241
|
+
}
|
|
242
|
+
get videoWidthInPixels() {
|
|
243
|
+
return this._isVideoWidthInPixels;
|
|
244
|
+
}
|
|
245
|
+
get videoWidthProvided() {
|
|
246
|
+
return this._wasVideoWidthProvided;
|
|
247
|
+
}
|
|
248
|
+
get videoHeightValue() {
|
|
249
|
+
return this._videoHeightValue;
|
|
250
|
+
}
|
|
251
|
+
get videoHeightInPixels() {
|
|
252
|
+
return this._isVideoHeightInPixels;
|
|
253
|
+
}
|
|
254
|
+
get videoHeightProvided() {
|
|
255
|
+
return this._wasVideoHeightProvided;
|
|
256
|
+
}
|
|
257
|
+
get aspectRatio() {
|
|
258
|
+
return this._aspectRatio;
|
|
259
|
+
}
|
|
260
|
+
get resizeDebounce() {
|
|
261
|
+
return this._resizeDebounce;
|
|
262
|
+
}
|
|
263
|
+
set resizeDebounce(newValue) {
|
|
264
|
+
this._resizeDebounce = newValue;
|
|
265
|
+
}
|
|
266
|
+
set videoWidthValue(newWidth) {
|
|
267
|
+
this._videoWidthValue = newWidth;
|
|
268
|
+
}
|
|
269
|
+
set videoWidthInPixels(value) {
|
|
270
|
+
this._isVideoWidthInPixels = value;
|
|
271
|
+
}
|
|
272
|
+
set videoHeightValue(newHeight) {
|
|
273
|
+
this._videoHeightValue = newHeight;
|
|
274
|
+
}
|
|
275
|
+
set videoHeightInPixels(value) {
|
|
276
|
+
this._isVideoHeightInPixels = value;
|
|
277
|
+
}
|
|
278
|
+
set containerID(newContainerID) {
|
|
279
|
+
this._containerID = newContainerID;
|
|
280
|
+
}
|
|
281
|
+
set scalingMode(newScalingMode) {
|
|
282
|
+
switch (newScalingMode.toLowerCase()) {
|
|
283
|
+
case "fill":
|
|
284
|
+
this._scalingMode = ScalingType.FILL;
|
|
285
|
+
break;
|
|
286
|
+
case "letterbox":
|
|
287
|
+
this._scalingMode = ScalingType.LETTER_BOX;
|
|
288
|
+
break;
|
|
289
|
+
case "crop":
|
|
290
|
+
this._scalingMode = ScalingType.CROP;
|
|
291
|
+
break;
|
|
292
|
+
case "original":
|
|
293
|
+
this._scalingMode = ScalingType.ORIGINAL;
|
|
294
|
+
break;
|
|
295
|
+
default:
|
|
296
|
+
throw new Error("Unknown video scaling mode. Please check player config!");
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
get parentSizeCalculationMethod() {
|
|
300
|
+
return this._parentSizeCalculationMethod;
|
|
301
|
+
}
|
|
302
|
+
print(logger) {
|
|
303
|
+
let scalingMode = "";
|
|
304
|
+
switch (this._scalingMode) {
|
|
305
|
+
case ScalingType.FILL:
|
|
306
|
+
scalingMode = "fill";
|
|
307
|
+
break;
|
|
308
|
+
case ScalingType.LETTER_BOX:
|
|
309
|
+
scalingMode = "letterbox";
|
|
310
|
+
break;
|
|
311
|
+
case ScalingType.CROP:
|
|
312
|
+
scalingMode = "crop";
|
|
313
|
+
break;
|
|
314
|
+
case ScalingType.ORIGINAL:
|
|
315
|
+
scalingMode = "original";
|
|
316
|
+
break;
|
|
317
|
+
}
|
|
318
|
+
logger.info(this, "VideoConfig :: containerID: " + this._containerID);
|
|
319
|
+
logger.info(this, "VideoConfig :: scalingMode: " + scalingMode);
|
|
320
|
+
logger.info(this, "VideoConfig :: width: " + this._videoWidthValue + (this._isVideoWidthInPixels ? "px" : "%") + (this._wasVideoWidthProvided ? " (provided)" : " (default)"));
|
|
321
|
+
logger.info(this, "VideoConfig :: height: " + this._videoHeightValue + (this._isVideoHeightInPixels ? "px" : "%") + (this._wasVideoHeightProvided ? " (provided)" : " (default)"));
|
|
322
|
+
logger.info(this, "VideoConfig :: aspectRatio: " + this._aspectRatio);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
var LogType;
|
|
327
|
+
(function (LogType) {
|
|
328
|
+
LogType[LogType["TRACE"] = 0] = "TRACE";
|
|
329
|
+
LogType[LogType["INFO"] = 1] = "INFO";
|
|
330
|
+
LogType[LogType["SUCCESS"] = 2] = "SUCCESS";
|
|
331
|
+
LogType[LogType["WARNING"] = 3] = "WARNING";
|
|
332
|
+
LogType[LogType["ERROR"] = 4] = "ERROR";
|
|
333
|
+
})(LogType || (LogType = {}));
|
|
334
|
+
|
|
335
|
+
class DebugData {
|
|
336
|
+
constructor(debugConfig) {
|
|
337
|
+
this._consoleLogEnabled = false;
|
|
338
|
+
this._enabledConsoleTypes = [LogType.INFO, LogType.ERROR, LogType.SUCCESS, LogType.TRACE, LogType.WARNING];
|
|
339
|
+
this._consoleMonoColor = false;
|
|
340
|
+
this._containerLogEnabled = false;
|
|
341
|
+
this._enabledContainerTypes = [LogType.INFO, LogType.ERROR, LogType.SUCCESS, LogType.TRACE, LogType.WARNING];
|
|
342
|
+
this._containerLogMonoColor = false;
|
|
343
|
+
this.parse(debugConfig);
|
|
344
|
+
}
|
|
345
|
+
parse(debugConfig) {
|
|
346
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
|
|
347
|
+
this._debugConfig = debugConfig;
|
|
348
|
+
if (this._debugConfig) {
|
|
349
|
+
this._consoleLogEnabled = (_c = (_b = (_a = this._debugConfig) === null || _a === void 0 ? void 0 : _a.console) === null || _b === void 0 ? void 0 : _b.enabled) !== null && _c !== void 0 ? _c : this._consoleLogEnabled;
|
|
350
|
+
this._consoleMonoColor = (_f = (_e = (_d = this._debugConfig) === null || _d === void 0 ? void 0 : _d.console) === null || _e === void 0 ? void 0 : _e.monoColor) !== null && _f !== void 0 ? _f : this._consoleMonoColor;
|
|
351
|
+
this._enabledConsoleTypes = (_j = this.parseLogTypes((_h = (_g = this._debugConfig) === null || _g === void 0 ? void 0 : _g.console) === null || _h === void 0 ? void 0 : _h.logTypes)) !== null && _j !== void 0 ? _j : this._enabledConsoleTypes;
|
|
352
|
+
this._containerLogEnabled = (_m = (_l = (_k = this._debugConfig) === null || _k === void 0 ? void 0 : _k.container) === null || _l === void 0 ? void 0 : _l.enabled) !== null && _m !== void 0 ? _m : this._containerLogEnabled;
|
|
353
|
+
this._containerLogMonoColor = (_q = (_p = (_o = this._debugConfig) === null || _o === void 0 ? void 0 : _o.container) === null || _p === void 0 ? void 0 : _p.monoColor) !== null && _q !== void 0 ? _q : this._containerLogMonoColor;
|
|
354
|
+
this._enabledContainerTypes = (_t = this.parseLogTypes((_s = (_r = this._debugConfig) === null || _r === void 0 ? void 0 : _r.container) === null || _s === void 0 ? void 0 : _s.logTypes)) !== null && _t !== void 0 ? _t : this._enabledContainerTypes;
|
|
355
|
+
this._containerID = (_w = (_v = (_u = this._debugConfig) === null || _u === void 0 ? void 0 : _u.container) === null || _v === void 0 ? void 0 : _v.containerID) !== null && _w !== void 0 ? _w : this._containerID;
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
parseLogTypes(logTypes) {
|
|
359
|
+
return logTypes === null || logTypes === void 0 ? void 0 : logTypes.map(type => {
|
|
360
|
+
switch (type.toLowerCase()) {
|
|
361
|
+
case 'info':
|
|
362
|
+
return LogType.INFO;
|
|
363
|
+
case 'error':
|
|
364
|
+
return LogType.ERROR;
|
|
365
|
+
case 'warning':
|
|
366
|
+
return LogType.WARNING;
|
|
367
|
+
case 'success':
|
|
368
|
+
return LogType.SUCCESS;
|
|
369
|
+
case 'trace':
|
|
370
|
+
return LogType.TRACE;
|
|
371
|
+
default:
|
|
372
|
+
throw new Error(`Unsupported log type: ${type}`);
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
get consoleLogEnabled() {
|
|
377
|
+
return this._consoleLogEnabled;
|
|
378
|
+
}
|
|
379
|
+
set consoleLogEnabled(newValue) {
|
|
380
|
+
this._consoleLogEnabled = newValue;
|
|
381
|
+
}
|
|
382
|
+
get enabledConsoleTypes() {
|
|
383
|
+
return this._enabledConsoleTypes;
|
|
384
|
+
}
|
|
385
|
+
set enabledConsoleTypes(newValue) {
|
|
386
|
+
this._enabledConsoleTypes = new Array();
|
|
387
|
+
for (let i = 0; i < newValue.length; i++) {
|
|
388
|
+
switch (newValue[i].toLowerCase()) {
|
|
389
|
+
case "info":
|
|
390
|
+
this._enabledConsoleTypes.push(LogType.INFO);
|
|
391
|
+
break;
|
|
392
|
+
case "error":
|
|
393
|
+
this._enabledConsoleTypes.push(LogType.ERROR);
|
|
394
|
+
break;
|
|
395
|
+
case "warning":
|
|
396
|
+
this._enabledConsoleTypes.push(LogType.WARNING);
|
|
397
|
+
break;
|
|
398
|
+
case "success":
|
|
399
|
+
this._enabledConsoleTypes.push(LogType.SUCCESS);
|
|
400
|
+
break;
|
|
401
|
+
case "trace":
|
|
402
|
+
this._enabledConsoleTypes.push(LogType.TRACE);
|
|
403
|
+
break;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
get containerLogEnabled() {
|
|
408
|
+
return this._containerLogEnabled;
|
|
409
|
+
}
|
|
410
|
+
set containerLogEnabled(newValue) {
|
|
411
|
+
this._consoleLogEnabled = newValue;
|
|
412
|
+
}
|
|
413
|
+
get consoleLogMonoColor() {
|
|
414
|
+
return this._consoleMonoColor;
|
|
415
|
+
}
|
|
416
|
+
set consoleLogMonoColor(newValue) {
|
|
417
|
+
this._consoleMonoColor = newValue;
|
|
418
|
+
}
|
|
419
|
+
get enabledContainerTypes() {
|
|
420
|
+
return this._enabledContainerTypes;
|
|
421
|
+
}
|
|
422
|
+
set enabledContainerTypes(newValue) {
|
|
423
|
+
this._enabledContainerTypes = new Array();
|
|
424
|
+
for (let i = 0; i < newValue.length; i++) {
|
|
425
|
+
switch (newValue[i].toLowerCase()) {
|
|
426
|
+
case "info":
|
|
427
|
+
this._enabledContainerTypes.push(LogType.INFO);
|
|
428
|
+
break;
|
|
429
|
+
case "error":
|
|
430
|
+
this._enabledContainerTypes.push(LogType.ERROR);
|
|
431
|
+
break;
|
|
432
|
+
case "warning":
|
|
433
|
+
this._enabledContainerTypes.push(LogType.WARNING);
|
|
434
|
+
break;
|
|
435
|
+
case "success":
|
|
436
|
+
this._enabledContainerTypes.push(LogType.SUCCESS);
|
|
437
|
+
break;
|
|
438
|
+
case "trace":
|
|
439
|
+
this._enabledContainerTypes.push(LogType.TRACE);
|
|
440
|
+
break;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
get containerID() {
|
|
445
|
+
return this._containerID;
|
|
446
|
+
}
|
|
447
|
+
set containerID(object) {
|
|
448
|
+
this._containerID = object;
|
|
449
|
+
}
|
|
450
|
+
get containerLogMonoColor() {
|
|
451
|
+
return this._containerLogMonoColor;
|
|
452
|
+
}
|
|
453
|
+
set containerLogMonoColor(newValue) {
|
|
454
|
+
this._containerLogMonoColor = newValue;
|
|
455
|
+
}
|
|
456
|
+
print(logger, force = false) {
|
|
457
|
+
if (DebugData.PRINT_ON_STARTUP || force) {
|
|
458
|
+
let consoleLogTypes = "";
|
|
459
|
+
for (let i = 0; i < this._enabledConsoleTypes.length; i++) {
|
|
460
|
+
switch (this._enabledConsoleTypes[i]) {
|
|
461
|
+
case LogType.TRACE:
|
|
462
|
+
consoleLogTypes += "TRACE, ";
|
|
463
|
+
break;
|
|
464
|
+
case LogType.SUCCESS:
|
|
465
|
+
consoleLogTypes += "SUCCESS, ";
|
|
466
|
+
break;
|
|
467
|
+
case LogType.WARNING:
|
|
468
|
+
consoleLogTypes += "WARNING, ";
|
|
469
|
+
break;
|
|
470
|
+
case LogType.INFO:
|
|
471
|
+
consoleLogTypes += "INFO, ";
|
|
472
|
+
break;
|
|
473
|
+
case LogType.ERROR:
|
|
474
|
+
consoleLogTypes += "ERROR, ";
|
|
475
|
+
break;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
logger.info(this, "Console:: enabled: " + this._consoleLogEnabled);
|
|
479
|
+
logger.info(this, "Console:: logTypes: " + consoleLogTypes);
|
|
480
|
+
logger.info(this, "Console:: monoColor: " + this._consoleMonoColor);
|
|
481
|
+
let containerLogTypes = "";
|
|
482
|
+
for (let i = 0; i < this._enabledContainerTypes.length; i++) {
|
|
483
|
+
switch (this._enabledContainerTypes[i]) {
|
|
484
|
+
case LogType.TRACE:
|
|
485
|
+
containerLogTypes += "TRACE, ";
|
|
486
|
+
break;
|
|
487
|
+
case LogType.SUCCESS:
|
|
488
|
+
containerLogTypes += "SUCCESS, ";
|
|
489
|
+
break;
|
|
490
|
+
case LogType.WARNING:
|
|
491
|
+
containerLogTypes += "WARNING, ";
|
|
492
|
+
break;
|
|
493
|
+
case LogType.INFO:
|
|
494
|
+
containerLogTypes += "INFO, ";
|
|
495
|
+
break;
|
|
496
|
+
case LogType.ERROR:
|
|
497
|
+
containerLogTypes += "ERROR, ";
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
logger.info(this, "Container:: enabled: " + this._containerLogEnabled);
|
|
502
|
+
logger.info(this, "Container:: logTypes: " + containerLogTypes);
|
|
503
|
+
logger.info(this, "Container:: containerID: " + this._containerID);
|
|
504
|
+
logger.info(this, "Container:: monoColor: " + this._consoleMonoColor);
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
DebugData.PRINT_ON_STARTUP = true;
|
|
509
|
+
|
|
510
|
+
class AudioData {
|
|
511
|
+
constructor(volumeConfig) {
|
|
512
|
+
this._startVolume = 100;
|
|
513
|
+
this._isMuted = false;
|
|
514
|
+
this.parse(volumeConfig);
|
|
515
|
+
}
|
|
516
|
+
parse(config) {
|
|
517
|
+
var _a, _b, _c, _d;
|
|
518
|
+
this._audioConfig = config;
|
|
519
|
+
if (this._audioConfig) {
|
|
520
|
+
this._startVolume = (_b = (_a = this._audioConfig) === null || _a === void 0 ? void 0 : _a.startVolume) !== null && _b !== void 0 ? _b : this._startVolume;
|
|
521
|
+
this._isMuted = (_d = (_c = this._audioConfig) === null || _c === void 0 ? void 0 : _c.muted) !== null && _d !== void 0 ? _d : this._isMuted;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
get startVolume() {
|
|
525
|
+
return this._startVolume;
|
|
526
|
+
}
|
|
527
|
+
set startVolume(newValue) {
|
|
528
|
+
this._startVolume = newValue;
|
|
529
|
+
}
|
|
530
|
+
get muted() {
|
|
531
|
+
return this._isMuted;
|
|
532
|
+
}
|
|
533
|
+
set muted(newValue) {
|
|
534
|
+
this._isMuted = newValue;
|
|
535
|
+
}
|
|
536
|
+
print(logger, force = false) {
|
|
537
|
+
if (AudioData.PRINT_ON_STARTUP || force) logger.info(this, "Audio :: startVolume: " + this._startVolume + " | isMuted: " + this._isMuted);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
AudioData.PRINT_ON_STARTUP = true;
|
|
541
|
+
|
|
542
|
+
class StorageData {
|
|
543
|
+
constructor(storageConfig) {
|
|
544
|
+
this._enabled = true;
|
|
545
|
+
this._prefix = "storm";
|
|
546
|
+
this.parse(storageConfig);
|
|
547
|
+
}
|
|
548
|
+
parse(config) {
|
|
549
|
+
var _a, _b, _c, _d;
|
|
550
|
+
this._storageConfig = config;
|
|
551
|
+
this._enabled = (_b = (_a = this._storageConfig) === null || _a === void 0 ? void 0 : _a.enabled) !== null && _b !== void 0 ? _b : this._enabled;
|
|
552
|
+
this._prefix = (_d = (_c = this._storageConfig) === null || _c === void 0 ? void 0 : _c.prefix) !== null && _d !== void 0 ? _d : this._prefix;
|
|
553
|
+
}
|
|
554
|
+
get enabled() {
|
|
555
|
+
return this._enabled;
|
|
556
|
+
}
|
|
557
|
+
set enabled(newValue) {
|
|
558
|
+
this._enabled = newValue;
|
|
559
|
+
}
|
|
560
|
+
get prefix() {
|
|
561
|
+
return this._prefix;
|
|
562
|
+
}
|
|
563
|
+
set prefix(newValue) {
|
|
564
|
+
this._prefix = newValue;
|
|
565
|
+
}
|
|
566
|
+
print(logger, force = false) {
|
|
567
|
+
if (StorageData.PRINT_ON_STARTUP || force) logger.info(this, "Storage :: startVolume: " + this._enabled + " | prefix: " + this._prefix);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
StorageData.PRINT_ON_STARTUP = true;
|
|
571
|
+
|
|
572
|
+
class SettingsData {
|
|
573
|
+
constructor(config) {
|
|
574
|
+
this._restartOnError = true;
|
|
575
|
+
this._reconnectTime = 1;
|
|
576
|
+
this._autoStart = false;
|
|
577
|
+
this._autoConnect = true;
|
|
578
|
+
this.startOnDOMReady = false;
|
|
579
|
+
this.iOSOnDomReadyFix = true;
|
|
580
|
+
this._restartOnFocus = true;
|
|
581
|
+
this.parse(config);
|
|
582
|
+
}
|
|
583
|
+
parse(config) {
|
|
584
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
585
|
+
this._settingsConfig = config;
|
|
586
|
+
this._autoConnect = (_a = this._settingsConfig.autoConnect) !== null && _a !== void 0 ? _a : this._autoConnect;
|
|
587
|
+
this._autoStart = (_b = this._settingsConfig.autoStart) !== null && _b !== void 0 ? _b : this._autoStart;
|
|
588
|
+
this._restartOnFocus = (_c = this._settingsConfig.restartOnFocus) !== null && _c !== void 0 ? _c : this._restartOnFocus;
|
|
589
|
+
this._restartOnError = (_d = this._settingsConfig.restartOnError) !== null && _d !== void 0 ? _d : this._restartOnError;
|
|
590
|
+
this._reconnectTime = (_e = this._settingsConfig.reconnectTime) !== null && _e !== void 0 ? _e : this._reconnectTime;
|
|
591
|
+
this._videoData = new VideoData((_f = this._settingsConfig.video) !== null && _f !== void 0 ? _f : null);
|
|
592
|
+
this._audioData = new AudioData((_g = this._settingsConfig.audio) !== null && _g !== void 0 ? _g : null);
|
|
593
|
+
this._storageData = new StorageData((_h = this._settingsConfig.storage) !== null && _h !== void 0 ? _h : null);
|
|
594
|
+
this._debugData = new DebugData((_j = this._settingsConfig.debug) !== null && _j !== void 0 ? _j : null);
|
|
595
|
+
}
|
|
596
|
+
getAudioData() {
|
|
597
|
+
return this._audioData;
|
|
598
|
+
}
|
|
599
|
+
getVideoData() {
|
|
600
|
+
return this._videoData;
|
|
601
|
+
}
|
|
602
|
+
getStorageData() {
|
|
603
|
+
return this._storageData;
|
|
604
|
+
}
|
|
605
|
+
getIfRestartOnError() {
|
|
606
|
+
return this._restartOnError;
|
|
607
|
+
}
|
|
608
|
+
getReconnectTime() {
|
|
609
|
+
return this._reconnectTime;
|
|
610
|
+
}
|
|
611
|
+
get autoStart() {
|
|
612
|
+
return this._autoStart;
|
|
613
|
+
}
|
|
614
|
+
set autoStart(newValue) {
|
|
615
|
+
this._autoStart = newValue;
|
|
616
|
+
}
|
|
617
|
+
get autoConnect() {
|
|
618
|
+
return this._autoConnect;
|
|
619
|
+
}
|
|
620
|
+
get restartOnFocus() {
|
|
621
|
+
return this._restartOnFocus;
|
|
622
|
+
}
|
|
623
|
+
getDebugData() {
|
|
624
|
+
return this._debugData;
|
|
625
|
+
}
|
|
626
|
+
getIfStartOnDOMReadyEnabled() {
|
|
627
|
+
return this.startOnDOMReady;
|
|
628
|
+
}
|
|
629
|
+
getIfIOSOnDomStartFixEnabled() {
|
|
630
|
+
return this.iOSOnDomReadyFix;
|
|
631
|
+
}
|
|
632
|
+
print(logger, force = false) {
|
|
633
|
+
if (SettingsData.PRINT_ON_STARTUP || force) {
|
|
634
|
+
let enabledProtocols = "";
|
|
635
|
+
logger.info(this, "SettingsConfig :: autoConnect: " + this._autoConnect);
|
|
636
|
+
logger.info(this, "SettingsConfig :: autoStart: " + this._autoStart);
|
|
637
|
+
logger.info(this, "SettingsConfig :: restartOnError: " + this._restartOnError);
|
|
638
|
+
logger.info(this, "SettingsConfig :: reconnectTime: " + this._reconnectTime);
|
|
639
|
+
logger.info(this, "SettingsConfig :: enabledProtocols: " + enabledProtocols);
|
|
640
|
+
this._videoData.print(logger);
|
|
641
|
+
this._audioData.print(logger);
|
|
642
|
+
this._debugData.print(logger);
|
|
643
|
+
this._debugData.print(logger);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
SettingsData.PRINT_ON_STARTUP = true;
|
|
648
|
+
|
|
649
|
+
class ConfigManager {
|
|
650
|
+
constructor(config) {
|
|
651
|
+
this.PRINT_ON_STARTUP = true;
|
|
652
|
+
this.demoMode = false;
|
|
653
|
+
this.parse(config);
|
|
654
|
+
}
|
|
655
|
+
parse(config) {
|
|
656
|
+
var _a, _b;
|
|
657
|
+
this.configTemplate = config;
|
|
658
|
+
if (this.configTemplate.stream == null) throw new Error("No stream field was provided. Please check your player config!");
|
|
659
|
+
this.streamData = new StreamData(this.configTemplate.stream);
|
|
660
|
+
this.settingsData = new SettingsData((_a = this.configTemplate.settings) !== null && _a !== void 0 ? _a : null);
|
|
661
|
+
this.demoMode = (_b = this.configTemplate.demoMode) !== null && _b !== void 0 ? _b : false;
|
|
662
|
+
}
|
|
663
|
+
getStreamData() {
|
|
664
|
+
return this.streamData;
|
|
665
|
+
}
|
|
666
|
+
getSettingsData() {
|
|
667
|
+
return this.settingsData;
|
|
668
|
+
}
|
|
669
|
+
getIfDemoMode() {
|
|
670
|
+
return this.demoMode;
|
|
671
|
+
}
|
|
672
|
+
print(logger, force = false) {
|
|
673
|
+
if (this.PRINT_ON_STARTUP || force) {
|
|
674
|
+
this.streamData.print(logger);
|
|
675
|
+
this.settingsData.print(logger);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
class EventDispatcher {
|
|
681
|
+
constructor() {
|
|
682
|
+
this._isRemoved = false;
|
|
683
|
+
this._listeners = {};
|
|
684
|
+
}
|
|
685
|
+
addEventListener(eventName, listener, removable = true) {
|
|
686
|
+
if (!this._listeners[eventName]) this._listeners[eventName] = [];
|
|
687
|
+
let elementFound = false;
|
|
688
|
+
if (this._listeners[eventName] != undefined) {
|
|
689
|
+
if (this._listeners[eventName].length > 0) {
|
|
690
|
+
for (let i = 0; i < this._listeners[eventName].length; i++) {
|
|
691
|
+
let element = this._listeners[eventName][i];
|
|
692
|
+
if (element[1] == listener) {
|
|
693
|
+
elementFound = true;
|
|
694
|
+
break;
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
this._logger.success(this, "Registering a new event: " + eventName);
|
|
700
|
+
if (!elementFound) {
|
|
701
|
+
this._listeners[eventName].push([eventName, listener, removable]);
|
|
702
|
+
return true;
|
|
703
|
+
} else return false;
|
|
704
|
+
}
|
|
705
|
+
removeEventListener(eventName, listener) {
|
|
706
|
+
let elementFound = false;
|
|
707
|
+
if (this._listeners[eventName] != undefined) {
|
|
708
|
+
if (this._listeners[eventName].length > 0) {
|
|
709
|
+
for (let i = 0; i < this._listeners[eventName].length; i++) {
|
|
710
|
+
let element = this._listeners[eventName][i];
|
|
711
|
+
if (listener) {
|
|
712
|
+
if (element[1] == listener) {
|
|
713
|
+
if (element[2] == true) {
|
|
714
|
+
elementFound = true;
|
|
715
|
+
this._listeners[eventName].splice(i, 1);
|
|
716
|
+
break;
|
|
717
|
+
} else break;
|
|
718
|
+
}
|
|
719
|
+
} else {
|
|
720
|
+
elementFound = true;
|
|
721
|
+
if (element[2] == true) {
|
|
722
|
+
this._listeners[eventName].splice(i, 1);
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
this._logger.success(this, "Removing listener: " + eventName);
|
|
729
|
+
return elementFound;
|
|
730
|
+
}
|
|
731
|
+
removeAllEventListeners() {
|
|
732
|
+
this._logger.success(this, "Removing all listeners!");
|
|
733
|
+
for (const eventName in this._listeners) {
|
|
734
|
+
const typedEventName = eventName;
|
|
735
|
+
const branch = this._listeners[typedEventName];
|
|
736
|
+
if (branch && branch.length > 0) {
|
|
737
|
+
for (let i = branch.length - 1; i >= 0; i--) {
|
|
738
|
+
const element = branch[i];
|
|
739
|
+
if (element[2] === true) {
|
|
740
|
+
branch.splice(i, 1);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
dispatchEvent(eventName, event) {
|
|
747
|
+
if (this._isRemoved) return;
|
|
748
|
+
if (this._listeners[eventName] != undefined) {
|
|
749
|
+
if (this._listeners[eventName].length > 0) {
|
|
750
|
+
for (let i = 0; i < this._listeners[eventName].length; i++) {
|
|
751
|
+
let element = this._listeners[eventName][i];
|
|
752
|
+
element[1].call(this, event);
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
class NumberUtilities {
|
|
760
|
+
static addLeadingZero(number) {
|
|
761
|
+
if (number < 10) {
|
|
762
|
+
return "0" + number;
|
|
763
|
+
} else {
|
|
764
|
+
return String(number);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
static isNear(currentBuffer, target, targetMargin) {
|
|
768
|
+
return Math.abs(currentBuffer - target) <= targetMargin;
|
|
769
|
+
}
|
|
770
|
+
static generateUniqueString(length) {
|
|
771
|
+
let result = '';
|
|
772
|
+
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
773
|
+
const charactersLength = characters.length;
|
|
774
|
+
for (let i = 0; i < length; i++) {
|
|
775
|
+
result += characters.charAt(Math.floor(Math.random() * charactersLength));
|
|
776
|
+
}
|
|
777
|
+
return result;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
NumberUtilities.parseValue = value => {
|
|
781
|
+
if (typeof value === 'string') {
|
|
782
|
+
const isPixels = value.toLowerCase().endsWith('px');
|
|
783
|
+
const numericValue = parseInt(value, 10);
|
|
784
|
+
return {
|
|
785
|
+
value: numericValue,
|
|
786
|
+
isPixels: isPixels
|
|
787
|
+
};
|
|
788
|
+
} else {
|
|
789
|
+
return {
|
|
790
|
+
value: value,
|
|
791
|
+
isPixels: true
|
|
792
|
+
};
|
|
793
|
+
}
|
|
794
|
+
};
|
|
795
|
+
|
|
796
|
+
class Logger {
|
|
797
|
+
constructor(config, stormStreamer) {
|
|
798
|
+
this.colorOrder = ["red", "green", "blue", "orange", "black", "violet"];
|
|
799
|
+
this._logMemory = [];
|
|
800
|
+
this._streamerInstanceID = -1;
|
|
801
|
+
this._debugConfig = config;
|
|
802
|
+
this._stormStreamer = stormStreamer;
|
|
803
|
+
this._streamerInstanceID = this._stormStreamer.getStreamerID();
|
|
804
|
+
let colorID = this.colorOrder.length < stormStreamer.getStreamerID() ? this.colorOrder.length - 1 : stormStreamer.getStreamerID();
|
|
805
|
+
this._monoColor = this.colorOrder[colorID];
|
|
806
|
+
}
|
|
807
|
+
info(objectName, message) {
|
|
808
|
+
let output = this.logData(objectName, message);
|
|
809
|
+
if (this._debugConfig.consoleLogEnabled) {
|
|
810
|
+
if (this._debugConfig.enabledConsoleTypes.indexOf(LogType.INFO) >= 0) {
|
|
811
|
+
let consoleColor = this._debugConfig.consoleLogMonoColor ? this._monoColor : Logger.INFO_COLOR;
|
|
812
|
+
console.log('%c ' + output, 'color: ' + consoleColor);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
if (this._debugConfig.containerLogEnabled) {
|
|
816
|
+
if (this._debugConfig.enabledContainerTypes.indexOf(LogType.INFO) >= 0) {
|
|
817
|
+
let containerColor = this._debugConfig.containerLogMonoColor ? this._monoColor : Logger.INFO_COLOR;
|
|
818
|
+
this.writeToContainer(output, containerColor);
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
warning(objectName, message) {
|
|
823
|
+
let output = this.logData(objectName, message);
|
|
824
|
+
if (this._debugConfig.consoleLogEnabled) {
|
|
825
|
+
if (this._debugConfig.enabledConsoleTypes.indexOf(LogType.WARNING) >= 0) {
|
|
826
|
+
let consoleColor = this._debugConfig.consoleLogMonoColor ? this._monoColor : Logger.WARNING_COLOR;
|
|
827
|
+
console.log('%c ' + output, 'color: ' + consoleColor);
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
if (this._debugConfig.containerLogEnabled) {
|
|
831
|
+
if (this._debugConfig.enabledContainerTypes.indexOf(LogType.WARNING) >= 0) {
|
|
832
|
+
let containerColor = this._debugConfig.containerLogMonoColor ? this._monoColor : Logger.WARNING_COLOR;
|
|
833
|
+
this.writeToContainer(output, containerColor);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
error(objectName, message) {
|
|
838
|
+
let output = this.logData(objectName, message);
|
|
839
|
+
if (this._debugConfig.consoleLogEnabled) {
|
|
840
|
+
if (this._debugConfig.enabledConsoleTypes.indexOf(LogType.ERROR) >= 0) {
|
|
841
|
+
let consoleColor = this._debugConfig.consoleLogMonoColor ? this._monoColor : Logger.ERROR_COLOR;
|
|
842
|
+
console.log('%c ' + output, 'color: ' + consoleColor);
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
if (this._debugConfig.containerLogEnabled) {
|
|
846
|
+
if (this._debugConfig.enabledContainerTypes.indexOf(LogType.ERROR) >= 0) {
|
|
847
|
+
let containerColor = this._debugConfig.containerLogMonoColor ? this._monoColor : Logger.ERROR_COLOR;
|
|
848
|
+
this.writeToContainer(output, containerColor);
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
success(objectName, message) {
|
|
853
|
+
let output = this.logData(objectName, message);
|
|
854
|
+
if (this._debugConfig.consoleLogEnabled) {
|
|
855
|
+
if (this._debugConfig.enabledConsoleTypes.indexOf(LogType.SUCCESS) >= 0) {
|
|
856
|
+
let consoleColor = this._debugConfig.consoleLogMonoColor ? this._monoColor : Logger.SUCCESS_COLOR;
|
|
857
|
+
console.log('%c ' + output, 'color: ' + consoleColor);
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
if (this._debugConfig.containerLogEnabled) {
|
|
861
|
+
if (this._debugConfig.enabledContainerTypes.indexOf(LogType.SUCCESS) >= 0) {
|
|
862
|
+
let containerColor = this._debugConfig.containerLogMonoColor ? this._monoColor : Logger.SUCCESS_COLOR;
|
|
863
|
+
this.writeToContainer(output, containerColor);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
866
|
+
}
|
|
867
|
+
trace(objectName, message) {
|
|
868
|
+
let output = this.logData(objectName, message);
|
|
869
|
+
if (this._debugConfig.consoleLogEnabled) {
|
|
870
|
+
if (this._debugConfig.enabledConsoleTypes.indexOf(LogType.TRACE) >= 0) {
|
|
871
|
+
let consoleColor = this._debugConfig.consoleLogMonoColor ? this._monoColor : Logger.TRACE_COLOR;
|
|
872
|
+
console.log('%c ' + output, 'color: ' + consoleColor);
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
if (this._debugConfig.containerLogEnabled) {
|
|
876
|
+
if (this._debugConfig.enabledContainerTypes.indexOf(LogType.TRACE) >= 0) {
|
|
877
|
+
let containerColor = this._debugConfig.containerLogMonoColor ? this._monoColor : Logger.TRACE_COLOR;
|
|
878
|
+
this.writeToContainer(output, containerColor);
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
logData(_objectName, message) {
|
|
883
|
+
let date = new Date();
|
|
884
|
+
let hour = NumberUtilities.addLeadingZero(date.getHours());
|
|
885
|
+
let minutes = NumberUtilities.addLeadingZero(date.getMinutes());
|
|
886
|
+
let seconds = NumberUtilities.addLeadingZero(date.getSeconds());
|
|
887
|
+
let label = String(this._streamerInstanceID);
|
|
888
|
+
if (this._streamerInstanceID >= 0) label += "|" + this._streamerInstanceID;
|
|
889
|
+
let finalString = "[Storm-ID:" + label + "] [" + hour + ":" + minutes + ":" + seconds + "] :: " + message;
|
|
890
|
+
this._logMemory.push(finalString);
|
|
891
|
+
return finalString;
|
|
892
|
+
}
|
|
893
|
+
writeToContainer(message, color) {
|
|
894
|
+
let containerName = this._debugConfig.containerID;
|
|
895
|
+
if (containerName) {
|
|
896
|
+
let container = document.getElementById(containerName);
|
|
897
|
+
let log = document.createElement('span');
|
|
898
|
+
log.innerText = message;
|
|
899
|
+
log.style.color = color;
|
|
900
|
+
container.appendChild(log);
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
setPlayerID(playerID) {
|
|
904
|
+
this._streamerInstanceID = playerID;
|
|
905
|
+
}
|
|
906
|
+
getAllLogs() {
|
|
907
|
+
return this._logMemory;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
Logger.INFO_COLOR = "blue";
|
|
911
|
+
Logger.WARNING_COLOR = "orange";
|
|
912
|
+
Logger.ERROR_COLOR = "red";
|
|
913
|
+
Logger.SUCCESS_COLOR = "green";
|
|
914
|
+
Logger.TRACE_COLOR = "black";
|
|
915
|
+
|
|
916
|
+
class ClientUser {
|
|
917
|
+
constructor() {
|
|
918
|
+
this.bandwidthCapabilities = 0;
|
|
919
|
+
}
|
|
920
|
+
setBandwidthCapabilities(newCapabilities) {
|
|
921
|
+
this.bandwidthCapabilities = newCapabilities;
|
|
922
|
+
}
|
|
923
|
+
getBandwidthCapabilities() {
|
|
924
|
+
return this.bandwidthCapabilities;
|
|
925
|
+
}
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
class UserCapabilities {
|
|
929
|
+
static hasWebSocketsSupport() {
|
|
930
|
+
return window.WebSocket != null;
|
|
931
|
+
}
|
|
932
|
+
static isMobile() {
|
|
933
|
+
const mobileCheckString = "Mobile|mini|Fennec|Android|iP(ad|od|hone)";
|
|
934
|
+
const mobileCheckRegExp = new RegExp(mobileCheckString);
|
|
935
|
+
return mobileCheckRegExp.test(navigator.userAgent);
|
|
936
|
+
}
|
|
937
|
+
static isCookieEnabled() {
|
|
938
|
+
let cookieEnabled = navigator.cookieEnabled ? true : false;
|
|
939
|
+
if (typeof navigator.cookieEnabled == 'undefined' && !cookieEnabled) {
|
|
940
|
+
document.cookie = 'testcookie';
|
|
941
|
+
cookieEnabled = document.cookie.indexOf('testcookie') != -1 ? true : false;
|
|
942
|
+
}
|
|
943
|
+
return cookieEnabled;
|
|
944
|
+
}
|
|
945
|
+
static getOSVersion() {
|
|
946
|
+
let osVersion = "Unknown version";
|
|
947
|
+
let os = UserCapabilities.getOS();
|
|
948
|
+
if (os != null) {
|
|
949
|
+
const windowsCheckString = "Windows";
|
|
950
|
+
const windowsCheckRegExp = new RegExp(windowsCheckString);
|
|
951
|
+
if (windowsCheckRegExp.test(os)) {
|
|
952
|
+
const windowsExecString = "Windows (.*)";
|
|
953
|
+
const windowsExecRegExp = new RegExp(windowsExecString);
|
|
954
|
+
osVersion = windowsExecRegExp.exec(os)[1] != null ? windowsExecRegExp.exec(os)[1] : osVersion;
|
|
955
|
+
os = 'Windows';
|
|
956
|
+
}
|
|
957
|
+
switch (os) {
|
|
958
|
+
case 'Mac OS':
|
|
959
|
+
case 'Mac OS X':
|
|
960
|
+
case 'Android':
|
|
961
|
+
const versionExecString = "(?:Android|Mac OS|Mac OS X|MacPPC|MacIntel|Mac_PowerPC|Macintosh) ([\\.\\_\\d]+)";
|
|
962
|
+
const versionExecRegExp = new RegExp(versionExecString);
|
|
963
|
+
osVersion = versionExecRegExp.exec(navigator.userAgent)[1];
|
|
964
|
+
break;
|
|
965
|
+
case 'iOS':
|
|
966
|
+
const iOSExecString = "OS (\\d+)_(\\d+)_?(\\d+)?";
|
|
967
|
+
const iOSExecRegExp = new RegExp(iOSExecString);
|
|
968
|
+
osVersion = iOSExecRegExp.exec(navigator.userAgent);
|
|
969
|
+
osVersion = osVersion[1] + '.' + osVersion[2] + '.' + (osVersion[3] | 0);
|
|
970
|
+
break;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
return osVersion;
|
|
974
|
+
}
|
|
975
|
+
static getBrowserName() {
|
|
976
|
+
return UserCapabilities.getFullBrowser().name;
|
|
977
|
+
}
|
|
978
|
+
static getBrowserVersion() {
|
|
979
|
+
return UserCapabilities.getFullBrowser().version;
|
|
980
|
+
}
|
|
981
|
+
static getFullBrowser() {
|
|
982
|
+
let nAgt = navigator.userAgent;
|
|
983
|
+
let browser = navigator.appName;
|
|
984
|
+
let version = '' + parseFloat(navigator.appVersion);
|
|
985
|
+
let majorVersion = parseInt(navigator.appVersion, 10);
|
|
986
|
+
let nameOffset, verOffset, ix;
|
|
987
|
+
if ((verOffset = nAgt.indexOf('Opera')) != -1) {
|
|
988
|
+
browser = 'Opera';
|
|
989
|
+
version = nAgt.substring(verOffset + 6);
|
|
990
|
+
if ((verOffset = nAgt.indexOf('Version')) != -1) {
|
|
991
|
+
version = nAgt.substring(verOffset + 8);
|
|
992
|
+
}
|
|
993
|
+
} else if ((verOffset = nAgt.indexOf('MSIE')) != -1) {
|
|
994
|
+
browser = 'Microsoft Internet Explorer';
|
|
995
|
+
version = nAgt.substring(verOffset + 5);
|
|
996
|
+
} else if (browser == 'Netscape' && nAgt.indexOf('Trident/') != -1) {
|
|
997
|
+
browser = 'Microsoft Internet Explorer';
|
|
998
|
+
version = nAgt.substring(verOffset + 5);
|
|
999
|
+
if ((verOffset = nAgt.indexOf('rv:')) != -1) {
|
|
1000
|
+
version = nAgt.substring(verOffset + 3);
|
|
1001
|
+
}
|
|
1002
|
+
} else if ((verOffset = nAgt.indexOf('Chrome')) != -1) {
|
|
1003
|
+
browser = 'Chrome';
|
|
1004
|
+
if (nAgt.indexOf("FBAV") > -1 || nAgt.indexOf("FBAN") > -1) browser = 'Facebook';
|
|
1005
|
+
if (nAgt.indexOf("OPR") > -1) browser = 'Opera';
|
|
1006
|
+
if (nAgt.indexOf("SamsungBrowser") > -1) browser = 'Samsung';
|
|
1007
|
+
version = nAgt.substring(verOffset + 7);
|
|
1008
|
+
} else if ((verOffset = nAgt.indexOf('Safari')) != -1) {
|
|
1009
|
+
browser = 'Safari';
|
|
1010
|
+
version = nAgt.substring(verOffset + 7);
|
|
1011
|
+
if ((verOffset = nAgt.indexOf('Version')) != -1) {
|
|
1012
|
+
version = nAgt.substring(verOffset + 8);
|
|
1013
|
+
}
|
|
1014
|
+
if (nAgt.indexOf('CriOS') != -1) {
|
|
1015
|
+
browser = 'Chrome';
|
|
1016
|
+
}
|
|
1017
|
+
if (nAgt.indexOf('FxiOS') != -1) {
|
|
1018
|
+
browser = "Firefox";
|
|
1019
|
+
}
|
|
1020
|
+
} else if ((verOffset = nAgt.indexOf('Firefox')) != -1) {
|
|
1021
|
+
browser = 'Firefox';
|
|
1022
|
+
version = nAgt.substring(verOffset + 8);
|
|
1023
|
+
} else if ((nameOffset = nAgt.lastIndexOf(' ') + 1) < (verOffset = nAgt.lastIndexOf('/'))) {
|
|
1024
|
+
browser = nAgt.substring(nameOffset, verOffset);
|
|
1025
|
+
version = nAgt.substring(verOffset + 1);
|
|
1026
|
+
if (browser.toLowerCase() == browser.toUpperCase()) {
|
|
1027
|
+
browser = navigator.appName;
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
if ((ix = version.indexOf(';')) != -1) version = version.substring(0, ix);
|
|
1031
|
+
if ((ix = version.indexOf(' ')) != -1) version = version.substring(0, ix);
|
|
1032
|
+
if ((ix = version.indexOf(')')) != -1) version = version.substring(0, ix);
|
|
1033
|
+
majorVersion = parseInt('' + version, 10);
|
|
1034
|
+
if (isNaN(majorVersion)) {
|
|
1035
|
+
version = '' + parseFloat(navigator.appVersion);
|
|
1036
|
+
majorVersion = parseInt(navigator.appVersion, 10);
|
|
1037
|
+
}
|
|
1038
|
+
return {
|
|
1039
|
+
"name": browser,
|
|
1040
|
+
"fullVersion": version,
|
|
1041
|
+
"version": majorVersion
|
|
1042
|
+
};
|
|
1043
|
+
}
|
|
1044
|
+
static getOS() {
|
|
1045
|
+
let os = "Unknown OS";
|
|
1046
|
+
let oscodes = [{
|
|
1047
|
+
"os": 'Windows 10',
|
|
1048
|
+
"code": "(Windows 10.0|Windows NT 10.0)"
|
|
1049
|
+
}, {
|
|
1050
|
+
"os": 'Windows 8.1',
|
|
1051
|
+
"code": "(Windows 8.1|Windows NT 6.3)"
|
|
1052
|
+
}, {
|
|
1053
|
+
"os": 'Windows 8',
|
|
1054
|
+
"code": "(Windows 8|Windows NT 6.2)"
|
|
1055
|
+
}, {
|
|
1056
|
+
"os": 'Windows 7',
|
|
1057
|
+
"code": "(Windows 7|Windows NT 6.1)"
|
|
1058
|
+
}, {
|
|
1059
|
+
"os": 'Windows Vista',
|
|
1060
|
+
"code": "Windows NT 6.0"
|
|
1061
|
+
}, {
|
|
1062
|
+
"os": 'Windows Server 2003',
|
|
1063
|
+
"code": "Windows NT 5.2"
|
|
1064
|
+
}, {
|
|
1065
|
+
"os": 'Windows XP',
|
|
1066
|
+
"code": "(Windows NT 5.1|Windows XP)"
|
|
1067
|
+
}, {
|
|
1068
|
+
"os": 'Windows 2000',
|
|
1069
|
+
"code": "(Windows NT 5.0|Windows 2000)"
|
|
1070
|
+
}, {
|
|
1071
|
+
"os": 'Windows ME',
|
|
1072
|
+
"code": "(Win 9x 4.90|Windows ME)"
|
|
1073
|
+
}, {
|
|
1074
|
+
"os": 'Windows 98',
|
|
1075
|
+
"code": "(Windows 98|Win98)"
|
|
1076
|
+
}, {
|
|
1077
|
+
"os": 'Windows 95',
|
|
1078
|
+
"code": "(Windows 95|Win95|Windows_95)"
|
|
1079
|
+
}, {
|
|
1080
|
+
"os": 'Windows NT 4.0',
|
|
1081
|
+
"code": "(Windows NT 4.0|WinNT4.0|WinNT|Windows NT)"
|
|
1082
|
+
}, {
|
|
1083
|
+
"os": 'Windows CE',
|
|
1084
|
+
"code": "Windows CE"
|
|
1085
|
+
}, {
|
|
1086
|
+
"os": 'Windows 3.11',
|
|
1087
|
+
"code": "Win16"
|
|
1088
|
+
}, {
|
|
1089
|
+
"os": 'Android',
|
|
1090
|
+
"code": "Android"
|
|
1091
|
+
}, {
|
|
1092
|
+
"os": 'Open BSD',
|
|
1093
|
+
"code": "OpenBSD"
|
|
1094
|
+
}, {
|
|
1095
|
+
"os": 'Sun OS',
|
|
1096
|
+
"code": "SunOS"
|
|
1097
|
+
}, {
|
|
1098
|
+
"os": 'Chrome OS',
|
|
1099
|
+
"code": "CrOS"
|
|
1100
|
+
}, {
|
|
1101
|
+
"os": 'Linux',
|
|
1102
|
+
"code": "(Linux|X11(?!.*CrOS))"
|
|
1103
|
+
}, {
|
|
1104
|
+
"os": 'iOS',
|
|
1105
|
+
"code": "(iPhone|iPad|iPod)"
|
|
1106
|
+
}, {
|
|
1107
|
+
"os": 'Mac OS X',
|
|
1108
|
+
"code": "Mac OS X"
|
|
1109
|
+
}, {
|
|
1110
|
+
"os": 'Mac OS',
|
|
1111
|
+
"code": "(Mac OS|MacPPC|MacIntel|Mac_PowerPC|Macintosh)"
|
|
1112
|
+
}, {
|
|
1113
|
+
"os": 'QNX',
|
|
1114
|
+
"code": "QNX"
|
|
1115
|
+
}, {
|
|
1116
|
+
"os": 'UNIX',
|
|
1117
|
+
"code": "UNIX"
|
|
1118
|
+
}, {
|
|
1119
|
+
"os": 'BeOS',
|
|
1120
|
+
"code": "BeOS"
|
|
1121
|
+
}, {
|
|
1122
|
+
"os": 'OS/2',
|
|
1123
|
+
"code": "OS\\/2"
|
|
1124
|
+
}, {
|
|
1125
|
+
"os": 'Search Bot',
|
|
1126
|
+
"code": "(nuhk|Googlebot|Yammybot|Openbot|Slurp|MSNBot|Ask Jeeves\\/Teoma|ia_archiver)"
|
|
1127
|
+
}];
|
|
1128
|
+
for (var id in oscodes) {
|
|
1129
|
+
var cs = oscodes[id];
|
|
1130
|
+
var re = new RegExp(cs.code);
|
|
1131
|
+
if (re.test(navigator.userAgent)) {
|
|
1132
|
+
os = cs.os;
|
|
1133
|
+
break;
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
return os;
|
|
1137
|
+
}
|
|
1138
|
+
static hasWebRTCSupport() {
|
|
1139
|
+
let isSupported = false;
|
|
1140
|
+
try {
|
|
1141
|
+
let webrtc = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || window.RTCPeerConnection;
|
|
1142
|
+
isSupported = true;
|
|
1143
|
+
} catch (error) {
|
|
1144
|
+
isSupported = false;
|
|
1145
|
+
}
|
|
1146
|
+
return isSupported;
|
|
1147
|
+
}
|
|
1148
|
+
static hasHLSSupport(videoObject) {
|
|
1149
|
+
if (videoObject !== null) {
|
|
1150
|
+
return Boolean(videoObject.canPlayType('application/vnd.apple.mpegURL') || videoObject.canPlayType('audio/mpegurl'));
|
|
1151
|
+
} else return false;
|
|
1152
|
+
}
|
|
1153
|
+
static hasMSESupport() {
|
|
1154
|
+
const mediaSource = window.MediaSource = window.MediaSource || window.WebKitMediaSource;
|
|
1155
|
+
window.SourceBuffer = window.SourceBuffer || window.WebKitSourceBuffer;
|
|
1156
|
+
return mediaSource && typeof mediaSource.isTypeSupported === 'function';
|
|
1157
|
+
}
|
|
1158
|
+
static hasMMSSupport() {
|
|
1159
|
+
return window.ManagedMediaSource;
|
|
1160
|
+
}
|
|
1161
|
+
static isSSL() {
|
|
1162
|
+
if (location.protocol === 'https:') return true;else return false;
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
class StorageManager {
|
|
1167
|
+
constructor(main) {
|
|
1168
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1169
|
+
this.LOG_ACTIVITY = false;
|
|
1170
|
+
this.isEnabled = true;
|
|
1171
|
+
this.prefix = "";
|
|
1172
|
+
this.logger = main.getLogger();
|
|
1173
|
+
this.isEnabled = (_c = (_b = (_a = main.getConfigManager()) === null || _a === void 0 ? void 0 : _a.getSettingsData()) === null || _b === void 0 ? void 0 : _b.getStorageData().enabled) !== null && _c !== void 0 ? _c : this.isEnabled;
|
|
1174
|
+
this.prefix = (_f = (_e = (_d = main.getConfigManager()) === null || _d === void 0 ? void 0 : _d.getSettingsData()) === null || _e === void 0 ? void 0 : _e.getStorageData().prefix) !== null && _f !== void 0 ? _f : this.prefix;
|
|
1175
|
+
if (this.LOG_ACTIVITY) this.logger.info(this, "Creating new StorageManager");
|
|
1176
|
+
}
|
|
1177
|
+
saveField(name, value) {
|
|
1178
|
+
if (this.isEnabled == true) {
|
|
1179
|
+
if (this.LOG_ACTIVITY) this.logger.info(this, "Saving data: " + name + " | " + value);
|
|
1180
|
+
localStorage.setItem(this.prefix + name, value);
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
getField(name) {
|
|
1184
|
+
if (this.isEnabled == true) {
|
|
1185
|
+
const value = localStorage.getItem(this.prefix + name);
|
|
1186
|
+
if (this.LOG_ACTIVITY) this.logger.info(this, "Grabbing data: " + name + " | " + value);
|
|
1187
|
+
return value;
|
|
1188
|
+
} else return null;
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
1193
|
+
|
|
1194
|
+
function getDefaultExportFromCjs (x) {
|
|
1195
|
+
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
/**
|
|
1199
|
+
* lodash (Custom Build) <https://lodash.com/>
|
|
1200
|
+
* Build: `lodash modularize exports="npm" -o ./`
|
|
1201
|
+
* Copyright jQuery Foundation and other contributors <https://jquery.org/>
|
|
1202
|
+
* Released under MIT license <https://lodash.com/license>
|
|
1203
|
+
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
|
|
1204
|
+
* Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
|
|
1205
|
+
*/
|
|
1206
|
+
|
|
1207
|
+
/** Used as the `TypeError` message for "Functions" methods. */
|
|
1208
|
+
var FUNC_ERROR_TEXT = 'Expected a function';
|
|
1209
|
+
|
|
1210
|
+
/** Used as references for various `Number` constants. */
|
|
1211
|
+
var NAN = 0 / 0;
|
|
1212
|
+
|
|
1213
|
+
/** `Object#toString` result references. */
|
|
1214
|
+
var symbolTag = '[object Symbol]';
|
|
1215
|
+
|
|
1216
|
+
/** Used to match leading and trailing whitespace. */
|
|
1217
|
+
var reTrim = /^\s+|\s+$/g;
|
|
1218
|
+
|
|
1219
|
+
/** Used to detect bad signed hexadecimal string values. */
|
|
1220
|
+
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
|
|
1221
|
+
|
|
1222
|
+
/** Used to detect binary string values. */
|
|
1223
|
+
var reIsBinary = /^0b[01]+$/i;
|
|
1224
|
+
|
|
1225
|
+
/** Used to detect octal string values. */
|
|
1226
|
+
var reIsOctal = /^0o[0-7]+$/i;
|
|
1227
|
+
|
|
1228
|
+
/** Built-in method references without a dependency on `root`. */
|
|
1229
|
+
var freeParseInt = parseInt;
|
|
1230
|
+
|
|
1231
|
+
/** Detect free variable `global` from Node.js. */
|
|
1232
|
+
var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
|
|
1233
|
+
|
|
1234
|
+
/** Detect free variable `self`. */
|
|
1235
|
+
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
|
|
1236
|
+
|
|
1237
|
+
/** Used as a reference to the global object. */
|
|
1238
|
+
var root = freeGlobal || freeSelf || Function('return this')();
|
|
1239
|
+
|
|
1240
|
+
/** Used for built-in method references. */
|
|
1241
|
+
var objectProto = Object.prototype;
|
|
1242
|
+
|
|
1243
|
+
/**
|
|
1244
|
+
* Used to resolve the
|
|
1245
|
+
* [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
|
|
1246
|
+
* of values.
|
|
1247
|
+
*/
|
|
1248
|
+
var objectToString = objectProto.toString;
|
|
1249
|
+
|
|
1250
|
+
/* Built-in method references for those with the same name as other `lodash` methods. */
|
|
1251
|
+
var nativeMax = Math.max,
|
|
1252
|
+
nativeMin = Math.min;
|
|
1253
|
+
|
|
1254
|
+
/**
|
|
1255
|
+
* Gets the timestamp of the number of milliseconds that have elapsed since
|
|
1256
|
+
* the Unix epoch (1 January 1970 00:00:00 UTC).
|
|
1257
|
+
*
|
|
1258
|
+
* @static
|
|
1259
|
+
* @memberOf _
|
|
1260
|
+
* @since 2.4.0
|
|
1261
|
+
* @category Date
|
|
1262
|
+
* @returns {number} Returns the timestamp.
|
|
1263
|
+
* @example
|
|
1264
|
+
*
|
|
1265
|
+
* _.defer(function(stamp) {
|
|
1266
|
+
* console.log(_.now() - stamp);
|
|
1267
|
+
* }, _.now());
|
|
1268
|
+
* // => Logs the number of milliseconds it took for the deferred invocation.
|
|
1269
|
+
*/
|
|
1270
|
+
var now = function() {
|
|
1271
|
+
return root.Date.now();
|
|
1272
|
+
};
|
|
1273
|
+
|
|
1274
|
+
/**
|
|
1275
|
+
* Creates a debounced function that delays invoking `func` until after `wait`
|
|
1276
|
+
* milliseconds have elapsed since the last time the debounced function was
|
|
1277
|
+
* invoked. The debounced function comes with a `cancel` method to cancel
|
|
1278
|
+
* delayed `func` invocations and a `flush` method to immediately invoke them.
|
|
1279
|
+
* Provide `options` to indicate whether `func` should be invoked on the
|
|
1280
|
+
* leading and/or trailing edge of the `wait` timeout. The `func` is invoked
|
|
1281
|
+
* with the last arguments provided to the debounced function. Subsequent
|
|
1282
|
+
* calls to the debounced function return the result of the last `func`
|
|
1283
|
+
* invocation.
|
|
1284
|
+
*
|
|
1285
|
+
* **Note:** If `leading` and `trailing` options are `true`, `func` is
|
|
1286
|
+
* invoked on the trailing edge of the timeout only if the debounced function
|
|
1287
|
+
* is invoked more than once during the `wait` timeout.
|
|
1288
|
+
*
|
|
1289
|
+
* If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
|
|
1290
|
+
* until to the next tick, similar to `setTimeout` with a timeout of `0`.
|
|
1291
|
+
*
|
|
1292
|
+
* See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
|
|
1293
|
+
* for details over the differences between `_.debounce` and `_.throttle`.
|
|
1294
|
+
*
|
|
1295
|
+
* @static
|
|
1296
|
+
* @memberOf _
|
|
1297
|
+
* @since 0.1.0
|
|
1298
|
+
* @category Function
|
|
1299
|
+
* @param {Function} func The function to debounce.
|
|
1300
|
+
* @param {number} [wait=0] The number of milliseconds to delay.
|
|
1301
|
+
* @param {Object} [options={}] The options object.
|
|
1302
|
+
* @param {boolean} [options.leading=false]
|
|
1303
|
+
* Specify invoking on the leading edge of the timeout.
|
|
1304
|
+
* @param {number} [options.maxWait]
|
|
1305
|
+
* The maximum time `func` is allowed to be delayed before it's invoked.
|
|
1306
|
+
* @param {boolean} [options.trailing=true]
|
|
1307
|
+
* Specify invoking on the trailing edge of the timeout.
|
|
1308
|
+
* @returns {Function} Returns the new debounced function.
|
|
1309
|
+
* @example
|
|
1310
|
+
*
|
|
1311
|
+
* // Avoid costly calculations while the window size is in flux.
|
|
1312
|
+
* jQuery(window).on('resize', _.debounce(calculateLayout, 150));
|
|
1313
|
+
*
|
|
1314
|
+
* // Invoke `sendMail` when clicked, debouncing subsequent calls.
|
|
1315
|
+
* jQuery(element).on('click', _.debounce(sendMail, 300, {
|
|
1316
|
+
* 'leading': true,
|
|
1317
|
+
* 'trailing': false
|
|
1318
|
+
* }));
|
|
1319
|
+
*
|
|
1320
|
+
* // Ensure `batchLog` is invoked once after 1 second of debounced calls.
|
|
1321
|
+
* var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
|
|
1322
|
+
* var source = new EventSource('/stream');
|
|
1323
|
+
* jQuery(source).on('message', debounced);
|
|
1324
|
+
*
|
|
1325
|
+
* // Cancel the trailing debounced invocation.
|
|
1326
|
+
* jQuery(window).on('popstate', debounced.cancel);
|
|
1327
|
+
*/
|
|
1328
|
+
function debounce(func, wait, options) {
|
|
1329
|
+
var lastArgs,
|
|
1330
|
+
lastThis,
|
|
1331
|
+
maxWait,
|
|
1332
|
+
result,
|
|
1333
|
+
timerId,
|
|
1334
|
+
lastCallTime,
|
|
1335
|
+
lastInvokeTime = 0,
|
|
1336
|
+
leading = false,
|
|
1337
|
+
maxing = false,
|
|
1338
|
+
trailing = true;
|
|
1339
|
+
|
|
1340
|
+
if (typeof func != 'function') {
|
|
1341
|
+
throw new TypeError(FUNC_ERROR_TEXT);
|
|
1342
|
+
}
|
|
1343
|
+
wait = toNumber(wait) || 0;
|
|
1344
|
+
if (isObject(options)) {
|
|
1345
|
+
leading = !!options.leading;
|
|
1346
|
+
maxing = 'maxWait' in options;
|
|
1347
|
+
maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
|
|
1348
|
+
trailing = 'trailing' in options ? !!options.trailing : trailing;
|
|
1349
|
+
}
|
|
1350
|
+
|
|
1351
|
+
function invokeFunc(time) {
|
|
1352
|
+
var args = lastArgs,
|
|
1353
|
+
thisArg = lastThis;
|
|
1354
|
+
|
|
1355
|
+
lastArgs = lastThis = undefined;
|
|
1356
|
+
lastInvokeTime = time;
|
|
1357
|
+
result = func.apply(thisArg, args);
|
|
1358
|
+
return result;
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
function leadingEdge(time) {
|
|
1362
|
+
// Reset any `maxWait` timer.
|
|
1363
|
+
lastInvokeTime = time;
|
|
1364
|
+
// Start the timer for the trailing edge.
|
|
1365
|
+
timerId = setTimeout(timerExpired, wait);
|
|
1366
|
+
// Invoke the leading edge.
|
|
1367
|
+
return leading ? invokeFunc(time) : result;
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
function remainingWait(time) {
|
|
1371
|
+
var timeSinceLastCall = time - lastCallTime,
|
|
1372
|
+
timeSinceLastInvoke = time - lastInvokeTime,
|
|
1373
|
+
result = wait - timeSinceLastCall;
|
|
1374
|
+
|
|
1375
|
+
return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
function shouldInvoke(time) {
|
|
1379
|
+
var timeSinceLastCall = time - lastCallTime,
|
|
1380
|
+
timeSinceLastInvoke = time - lastInvokeTime;
|
|
1381
|
+
|
|
1382
|
+
// Either this is the first call, activity has stopped and we're at the
|
|
1383
|
+
// trailing edge, the system time has gone backwards and we're treating
|
|
1384
|
+
// it as the trailing edge, or we've hit the `maxWait` limit.
|
|
1385
|
+
return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
|
|
1386
|
+
(timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
function timerExpired() {
|
|
1390
|
+
var time = now();
|
|
1391
|
+
if (shouldInvoke(time)) {
|
|
1392
|
+
return trailingEdge(time);
|
|
1393
|
+
}
|
|
1394
|
+
// Restart the timer.
|
|
1395
|
+
timerId = setTimeout(timerExpired, remainingWait(time));
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
function trailingEdge(time) {
|
|
1399
|
+
timerId = undefined;
|
|
1400
|
+
|
|
1401
|
+
// Only invoke if we have `lastArgs` which means `func` has been
|
|
1402
|
+
// debounced at least once.
|
|
1403
|
+
if (trailing && lastArgs) {
|
|
1404
|
+
return invokeFunc(time);
|
|
1405
|
+
}
|
|
1406
|
+
lastArgs = lastThis = undefined;
|
|
1407
|
+
return result;
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
function cancel() {
|
|
1411
|
+
if (timerId !== undefined) {
|
|
1412
|
+
clearTimeout(timerId);
|
|
1413
|
+
}
|
|
1414
|
+
lastInvokeTime = 0;
|
|
1415
|
+
lastArgs = lastCallTime = lastThis = timerId = undefined;
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
function flush() {
|
|
1419
|
+
return timerId === undefined ? result : trailingEdge(now());
|
|
1420
|
+
}
|
|
1421
|
+
|
|
1422
|
+
function debounced() {
|
|
1423
|
+
var time = now(),
|
|
1424
|
+
isInvoking = shouldInvoke(time);
|
|
1425
|
+
|
|
1426
|
+
lastArgs = arguments;
|
|
1427
|
+
lastThis = this;
|
|
1428
|
+
lastCallTime = time;
|
|
1429
|
+
|
|
1430
|
+
if (isInvoking) {
|
|
1431
|
+
if (timerId === undefined) {
|
|
1432
|
+
return leadingEdge(lastCallTime);
|
|
1433
|
+
}
|
|
1434
|
+
if (maxing) {
|
|
1435
|
+
// Handle invocations in a tight loop.
|
|
1436
|
+
timerId = setTimeout(timerExpired, wait);
|
|
1437
|
+
return invokeFunc(lastCallTime);
|
|
1438
|
+
}
|
|
1439
|
+
}
|
|
1440
|
+
if (timerId === undefined) {
|
|
1441
|
+
timerId = setTimeout(timerExpired, wait);
|
|
1442
|
+
}
|
|
1443
|
+
return result;
|
|
1444
|
+
}
|
|
1445
|
+
debounced.cancel = cancel;
|
|
1446
|
+
debounced.flush = flush;
|
|
1447
|
+
return debounced;
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
/**
|
|
1451
|
+
* Checks if `value` is the
|
|
1452
|
+
* [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
|
|
1453
|
+
* of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
|
|
1454
|
+
*
|
|
1455
|
+
* @static
|
|
1456
|
+
* @memberOf _
|
|
1457
|
+
* @since 0.1.0
|
|
1458
|
+
* @category Lang
|
|
1459
|
+
* @param {*} value The value to check.
|
|
1460
|
+
* @returns {boolean} Returns `true` if `value` is an object, else `false`.
|
|
1461
|
+
* @example
|
|
1462
|
+
*
|
|
1463
|
+
* _.isObject({});
|
|
1464
|
+
* // => true
|
|
1465
|
+
*
|
|
1466
|
+
* _.isObject([1, 2, 3]);
|
|
1467
|
+
* // => true
|
|
1468
|
+
*
|
|
1469
|
+
* _.isObject(_.noop);
|
|
1470
|
+
* // => true
|
|
1471
|
+
*
|
|
1472
|
+
* _.isObject(null);
|
|
1473
|
+
* // => false
|
|
1474
|
+
*/
|
|
1475
|
+
function isObject(value) {
|
|
1476
|
+
var type = typeof value;
|
|
1477
|
+
return !!value && (type == 'object' || type == 'function');
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
/**
|
|
1481
|
+
* Checks if `value` is object-like. A value is object-like if it's not `null`
|
|
1482
|
+
* and has a `typeof` result of "object".
|
|
1483
|
+
*
|
|
1484
|
+
* @static
|
|
1485
|
+
* @memberOf _
|
|
1486
|
+
* @since 4.0.0
|
|
1487
|
+
* @category Lang
|
|
1488
|
+
* @param {*} value The value to check.
|
|
1489
|
+
* @returns {boolean} Returns `true` if `value` is object-like, else `false`.
|
|
1490
|
+
* @example
|
|
1491
|
+
*
|
|
1492
|
+
* _.isObjectLike({});
|
|
1493
|
+
* // => true
|
|
1494
|
+
*
|
|
1495
|
+
* _.isObjectLike([1, 2, 3]);
|
|
1496
|
+
* // => true
|
|
1497
|
+
*
|
|
1498
|
+
* _.isObjectLike(_.noop);
|
|
1499
|
+
* // => false
|
|
1500
|
+
*
|
|
1501
|
+
* _.isObjectLike(null);
|
|
1502
|
+
* // => false
|
|
1503
|
+
*/
|
|
1504
|
+
function isObjectLike(value) {
|
|
1505
|
+
return !!value && typeof value == 'object';
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
/**
|
|
1509
|
+
* Checks if `value` is classified as a `Symbol` primitive or object.
|
|
1510
|
+
*
|
|
1511
|
+
* @static
|
|
1512
|
+
* @memberOf _
|
|
1513
|
+
* @since 4.0.0
|
|
1514
|
+
* @category Lang
|
|
1515
|
+
* @param {*} value The value to check.
|
|
1516
|
+
* @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
|
|
1517
|
+
* @example
|
|
1518
|
+
*
|
|
1519
|
+
* _.isSymbol(Symbol.iterator);
|
|
1520
|
+
* // => true
|
|
1521
|
+
*
|
|
1522
|
+
* _.isSymbol('abc');
|
|
1523
|
+
* // => false
|
|
1524
|
+
*/
|
|
1525
|
+
function isSymbol(value) {
|
|
1526
|
+
return typeof value == 'symbol' ||
|
|
1527
|
+
(isObjectLike(value) && objectToString.call(value) == symbolTag);
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1530
|
+
/**
|
|
1531
|
+
* Converts `value` to a number.
|
|
1532
|
+
*
|
|
1533
|
+
* @static
|
|
1534
|
+
* @memberOf _
|
|
1535
|
+
* @since 4.0.0
|
|
1536
|
+
* @category Lang
|
|
1537
|
+
* @param {*} value The value to process.
|
|
1538
|
+
* @returns {number} Returns the number.
|
|
1539
|
+
* @example
|
|
1540
|
+
*
|
|
1541
|
+
* _.toNumber(3.2);
|
|
1542
|
+
* // => 3.2
|
|
1543
|
+
*
|
|
1544
|
+
* _.toNumber(Number.MIN_VALUE);
|
|
1545
|
+
* // => 5e-324
|
|
1546
|
+
*
|
|
1547
|
+
* _.toNumber(Infinity);
|
|
1548
|
+
* // => Infinity
|
|
1549
|
+
*
|
|
1550
|
+
* _.toNumber('3.2');
|
|
1551
|
+
* // => 3.2
|
|
1552
|
+
*/
|
|
1553
|
+
function toNumber(value) {
|
|
1554
|
+
if (typeof value == 'number') {
|
|
1555
|
+
return value;
|
|
1556
|
+
}
|
|
1557
|
+
if (isSymbol(value)) {
|
|
1558
|
+
return NAN;
|
|
1559
|
+
}
|
|
1560
|
+
if (isObject(value)) {
|
|
1561
|
+
var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
|
|
1562
|
+
value = isObject(other) ? (other + '') : other;
|
|
1563
|
+
}
|
|
1564
|
+
if (typeof value != 'string') {
|
|
1565
|
+
return value === 0 ? value : +value;
|
|
1566
|
+
}
|
|
1567
|
+
value = value.replace(reTrim, '');
|
|
1568
|
+
var isBinary = reIsBinary.test(value);
|
|
1569
|
+
return (isBinary || reIsOctal.test(value))
|
|
1570
|
+
? freeParseInt(value.slice(2), isBinary ? 2 : 8)
|
|
1571
|
+
: (reIsBadHex.test(value) ? NAN : +value);
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
var lodash_debounce = debounce;
|
|
1575
|
+
|
|
1576
|
+
var debounce$1 = /*@__PURE__*/getDefaultExportFromCjs(lodash_debounce);
|
|
1577
|
+
|
|
1578
|
+
class ScreenElement {
|
|
1579
|
+
constructor(main) {
|
|
1580
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1581
|
+
this.LOG_ACTIVITY = true;
|
|
1582
|
+
this._volume = 100;
|
|
1583
|
+
this._isMuted = false;
|
|
1584
|
+
this._isMutedByBrowser = false;
|
|
1585
|
+
this.onForceMute = () => {
|
|
1586
|
+
this._isMuted = true;
|
|
1587
|
+
this._isMutedByBrowser = true;
|
|
1588
|
+
this.dispatchVolumeEvent();
|
|
1589
|
+
};
|
|
1590
|
+
this._main = main;
|
|
1591
|
+
this._logger = main.getLogger();
|
|
1592
|
+
this._videoElement = document.createElement('video');
|
|
1593
|
+
this._main.addEventListener("playbackForceMute", this.onForceMute, false);
|
|
1594
|
+
let startVolume = (_b = (_a = this._main.getConfigManager()) === null || _a === void 0 ? void 0 : _a.getSettingsData().getAudioData().startVolume) !== null && _b !== void 0 ? _b : 100;
|
|
1595
|
+
let isMuted = (_d = (_c = this._main.getConfigManager()) === null || _c === void 0 ? void 0 : _c.getSettingsData().getAudioData().muted) !== null && _d !== void 0 ? _d : false;
|
|
1596
|
+
if (((_e = this._main.getStorageManager()) === null || _e === void 0 ? void 0 : _e.getField("volume")) != null) startVolume = Number(this._main.getStorageManager().getField("volume"));
|
|
1597
|
+
if (((_f = this._main.getStorageManager()) === null || _f === void 0 ? void 0 : _f.getField("muted")) != null) {
|
|
1598
|
+
const savedValue = this._main.getStorageManager().getField("muted") == "true";
|
|
1599
|
+
if (savedValue) {
|
|
1600
|
+
isMuted = true;
|
|
1601
|
+
this._isMutedByBrowser = true;
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
this._volume = startVolume;
|
|
1605
|
+
this._isMuted = isMuted;
|
|
1606
|
+
if (this.LOG_ACTIVITY) this._logger.info(this, "VideoElement :: Start Volume: " + this._volume + " | Muted: " + this._isMuted);
|
|
1607
|
+
this._videoElement.volume = this._volume / 100;
|
|
1608
|
+
this._videoElement.muted = this._isMuted;
|
|
1609
|
+
this._videoElement.setAttribute('playsinline', 'playsinline');
|
|
1610
|
+
this._videoElement.setAttribute('webkit-playsinline', 'webkit-playsinline');
|
|
1611
|
+
this._main.dispatchEvent("videoElementCreate", {
|
|
1612
|
+
ref: this._main,
|
|
1613
|
+
videoElement: this._videoElement
|
|
1614
|
+
});
|
|
1615
|
+
this.initialize();
|
|
1616
|
+
}
|
|
1617
|
+
initialize() {
|
|
1618
|
+
this._videoElement.onload = function (event) {};
|
|
1619
|
+
this._videoElement.onstalled = event => {
|
|
1620
|
+
this._logger.info(this, "VideoElement :: onstalled");
|
|
1621
|
+
};
|
|
1622
|
+
this._videoElement.onerror = event => {
|
|
1623
|
+
this._logger.info(this, "VideoElement :: onerror :: " + JSON.stringify(event));
|
|
1624
|
+
};
|
|
1625
|
+
this._videoElement.onvolumechange = () => {
|
|
1626
|
+
this.dispatchVolumeEvent();
|
|
1627
|
+
};
|
|
1628
|
+
this._videoElement.onpause = () => {};
|
|
1629
|
+
this._videoElement.ontimeupdate = function (event) {};
|
|
1630
|
+
this._videoElement.onended = event => {
|
|
1631
|
+
this._logger.info(this, "VideoElement :: onended");
|
|
1632
|
+
};
|
|
1633
|
+
this._videoElement.onplay = () => {};
|
|
1634
|
+
}
|
|
1635
|
+
setVolume(value) {
|
|
1636
|
+
if (this._isMuted && value > 0) this.setMuted(false);
|
|
1637
|
+
this._volume = value;
|
|
1638
|
+
this._videoElement.volume = value / 100;
|
|
1639
|
+
this._main.getStorageManager().saveField("volume", String(value));
|
|
1640
|
+
if (value == 0) this.setMuted(true);
|
|
1641
|
+
}
|
|
1642
|
+
getVolume() {
|
|
1643
|
+
return this._volume;
|
|
1644
|
+
}
|
|
1645
|
+
setMuted(isMuted) {
|
|
1646
|
+
this._isMuted = isMuted;
|
|
1647
|
+
this._videoElement.muted = isMuted;
|
|
1648
|
+
this._isMutedByBrowser = false;
|
|
1649
|
+
this._main.getStorageManager().saveField("muted", String(isMuted));
|
|
1650
|
+
if (this.getVolume() == 0 && !isMuted) this.setVolume(100);
|
|
1651
|
+
}
|
|
1652
|
+
getIfMuted() {
|
|
1653
|
+
return this._isMuted;
|
|
1654
|
+
}
|
|
1655
|
+
dispatchVolumeEvent() {
|
|
1656
|
+
const action = !this._isMutedByBrowser ? "user" : "browser";
|
|
1657
|
+
const eventObj = {
|
|
1658
|
+
volume: this._volume,
|
|
1659
|
+
isMuted: this._isMuted,
|
|
1660
|
+
type: action
|
|
1661
|
+
};
|
|
1662
|
+
if (this.LOG_ACTIVITY) this._logger.info(this, "ScreenElement :: Event: onVolumeChange: " + JSON.stringify(eventObj));
|
|
1663
|
+
this._main.dispatchEvent("volumeChange", {
|
|
1664
|
+
ref: this._main,
|
|
1665
|
+
volume: this._volume,
|
|
1666
|
+
muted: this._isMuted,
|
|
1667
|
+
invokedBy: action
|
|
1668
|
+
});
|
|
1669
|
+
}
|
|
1670
|
+
getVideoElement() {
|
|
1671
|
+
return this._videoElement;
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
class DomUtilities {
|
|
1676
|
+
static calculateDimensionsWithMargins(element) {
|
|
1677
|
+
const style = window.getComputedStyle(element);
|
|
1678
|
+
const rect = element.getBoundingClientRect();
|
|
1679
|
+
const paddingLeft = parseFloat(style.paddingLeft);
|
|
1680
|
+
const paddingRight = parseFloat(style.paddingRight);
|
|
1681
|
+
const paddingTop = parseFloat(style.paddingTop);
|
|
1682
|
+
const paddingBottom = parseFloat(style.paddingBottom);
|
|
1683
|
+
const borderLeft = parseFloat(style.borderLeftWidth);
|
|
1684
|
+
const borderRight = parseFloat(style.borderRightWidth);
|
|
1685
|
+
const borderTop = parseFloat(style.borderTopWidth);
|
|
1686
|
+
const borderBottom = parseFloat(style.borderBottomWidth);
|
|
1687
|
+
const width = rect.width - paddingLeft - paddingRight - borderLeft - borderRight;
|
|
1688
|
+
const height = rect.height - paddingTop - paddingBottom - borderTop - borderBottom;
|
|
1689
|
+
return {
|
|
1690
|
+
width,
|
|
1691
|
+
height
|
|
1692
|
+
};
|
|
1693
|
+
}
|
|
1694
|
+
}
|
|
1695
|
+
|
|
1696
|
+
class StageController {
|
|
1697
|
+
constructor(main) {
|
|
1698
|
+
this._containerWidth = 0;
|
|
1699
|
+
this._tempContainerWidth = 0;
|
|
1700
|
+
this._containerHeight = 0;
|
|
1701
|
+
this._tempContainerHeight = 0;
|
|
1702
|
+
this._videoWidth = 0;
|
|
1703
|
+
this._videoHeight = 0;
|
|
1704
|
+
this._scalingMode = ScalingType.FILL;
|
|
1705
|
+
this.isInFullScreenMode = false;
|
|
1706
|
+
this._autoResizeEnabled = true;
|
|
1707
|
+
this.onFullScreenChange = () => {
|
|
1708
|
+
if (document.fullscreenElement == null) {
|
|
1709
|
+
this.isInFullScreenMode = false;
|
|
1710
|
+
this._logger.info(this, "The library has exited FullScreen mode!");
|
|
1711
|
+
this._main.dispatchEvent("fullScreenExit", {
|
|
1712
|
+
ref: this._main
|
|
1713
|
+
});
|
|
1714
|
+
} else {
|
|
1715
|
+
this.isInFullScreenMode = true;
|
|
1716
|
+
this._logger.info(this, "The library has entered FullScreen mode!");
|
|
1717
|
+
this._main.dispatchEvent("fullScreenEnter", {
|
|
1718
|
+
ref: this._main
|
|
1719
|
+
});
|
|
1720
|
+
}
|
|
1721
|
+
};
|
|
1722
|
+
this.onResize = () => {
|
|
1723
|
+
if (this._parentElement != null) {
|
|
1724
|
+
const calcMethod = this._main.getConfigManager().getSettingsData().getVideoData().parentSizeCalculationMethod;
|
|
1725
|
+
this._videoContainer.style.display = "none";
|
|
1726
|
+
switch (calcMethod) {
|
|
1727
|
+
case SizeCalculationType.CLIENT_DIMENSIONS:
|
|
1728
|
+
this._tempContainerWidth = this._parentElement.clientWidth;
|
|
1729
|
+
this._tempContainerHeight = this._parentElement.clientHeight;
|
|
1730
|
+
break;
|
|
1731
|
+
case SizeCalculationType.BOUNDING_BOX:
|
|
1732
|
+
this._tempContainerWidth = this._parentElement.getBoundingClientRect().width;
|
|
1733
|
+
this._tempContainerHeight = this._parentElement.getBoundingClientRect().height;
|
|
1734
|
+
break;
|
|
1735
|
+
case SizeCalculationType.FULL_BOX:
|
|
1736
|
+
this._tempContainerWidth = DomUtilities.calculateDimensionsWithMargins(this._parentElement).width;
|
|
1737
|
+
this._tempContainerHeight = DomUtilities.calculateDimensionsWithMargins(this._parentElement).height;
|
|
1738
|
+
break;
|
|
1739
|
+
}
|
|
1740
|
+
this._logger.info(this, "onResize called: " + this._tempContainerWidth + "x" + this._tempContainerHeight + " (" + calcMethod + ")");
|
|
1741
|
+
this.resizeVideoContainer();
|
|
1742
|
+
this.scaleVideo();
|
|
1743
|
+
this._videoContainer.style.display = "block";
|
|
1744
|
+
this._main.dispatchEvent("resizeUpdate", {
|
|
1745
|
+
ref: this._main,
|
|
1746
|
+
width: this._tempContainerWidth,
|
|
1747
|
+
height: this._tempContainerHeight
|
|
1748
|
+
});
|
|
1749
|
+
}
|
|
1750
|
+
};
|
|
1751
|
+
this._main = main;
|
|
1752
|
+
this._logger = main.getLogger();
|
|
1753
|
+
this._logger.info(this, "Creating new StageController");
|
|
1754
|
+
this.initialize();
|
|
1755
|
+
}
|
|
1756
|
+
initialize() {
|
|
1757
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1758
|
+
const containerID = (_d = (_c = (_b = (_a = this._main.getConfigManager()) === null || _a === void 0 ? void 0 : _a.getSettingsData()) === null || _b === void 0 ? void 0 : _b.getVideoData()) === null || _c === void 0 ? void 0 : _c.containerID) !== null && _d !== void 0 ? _d : null;
|
|
1759
|
+
this._scalingMode = (_f = (_e = this._main.getConfigManager()) === null || _e === void 0 ? void 0 : _e.getSettingsData().getVideoData().scalingMode) !== null && _f !== void 0 ? _f : ScalingType.FILL;
|
|
1760
|
+
this._videoContainer = document.createElement('div');
|
|
1761
|
+
this._videoContainer.setAttribute("id", "stormLibrary_" + this._main.getStreamerID());
|
|
1762
|
+
this._videoContainer.style.overflow = "hidden";
|
|
1763
|
+
this._videoContainer.style.position = "relative";
|
|
1764
|
+
this._videoContainer.classList.add("stormLibrary");
|
|
1765
|
+
this._screenElement = new ScreenElement(this._main);
|
|
1766
|
+
this._videoContainer.appendChild(this._screenElement.getVideoElement());
|
|
1767
|
+
const debounceValue = this._main.getConfigManager().getSettingsData().getVideoData().resizeDebounce;
|
|
1768
|
+
if (debounceValue > 0) {
|
|
1769
|
+
this._resizeObserver = new ResizeObserver(debounce$1(() => () => {
|
|
1770
|
+
if (this._autoResizeEnabled) this.onResize();
|
|
1771
|
+
}, debounceValue, {
|
|
1772
|
+
leading: false,
|
|
1773
|
+
trailing: true
|
|
1774
|
+
}));
|
|
1775
|
+
} else {
|
|
1776
|
+
this._resizeObserver = new ResizeObserver(() => {
|
|
1777
|
+
if (this._autoResizeEnabled) this.onResize();
|
|
1778
|
+
});
|
|
1779
|
+
}
|
|
1780
|
+
document.addEventListener('fullscreenchange', this.onFullScreenChange, false);
|
|
1781
|
+
document.addEventListener('webkitfullscreenchange', this.onFullScreenChange, false);
|
|
1782
|
+
document.addEventListener('mozfullscreenchange', this.onFullScreenChange, false);
|
|
1783
|
+
document.addEventListener('webkitendfullscreen', this.onFullScreenChange, false);
|
|
1784
|
+
this._screenElement.getVideoElement().addEventListener('webkitendfullscreen', this.onFullScreenChange, false);
|
|
1785
|
+
if (containerID) {
|
|
1786
|
+
this.attachToParent(containerID);
|
|
1787
|
+
} else this._logger.warning(this, `Could not create HTMLObject for the library - "containerID" was not provided`);
|
|
1788
|
+
}
|
|
1789
|
+
attachToParent(container) {
|
|
1790
|
+
let result = false;
|
|
1791
|
+
let tempParentElement = null;
|
|
1792
|
+
if (typeof container === "string") {
|
|
1793
|
+
this._logger.info(this, "Attaching container to ID: " + container);
|
|
1794
|
+
tempParentElement = document.getElementById(container);
|
|
1795
|
+
} else if (container instanceof HTMLElement) {
|
|
1796
|
+
this._logger.info(this, "Attaching container to HTMLElement: " + container);
|
|
1797
|
+
tempParentElement = container;
|
|
1798
|
+
}
|
|
1799
|
+
if (tempParentElement === this._parentElement) {
|
|
1800
|
+
this._logger.warning(this, "attachToParent :: container is the same");
|
|
1801
|
+
return false;
|
|
1802
|
+
}
|
|
1803
|
+
if (tempParentElement && this._videoContainer) {
|
|
1804
|
+
this._parentElement = tempParentElement;
|
|
1805
|
+
this._parentElement.appendChild(this._videoContainer);
|
|
1806
|
+
this._resizeObserver.observe(this._parentElement);
|
|
1807
|
+
this._parentElement.addEventListener("transitionend", () => {
|
|
1808
|
+
this.onResize();
|
|
1809
|
+
});
|
|
1810
|
+
this._main.dispatchEvent("containerChange", {
|
|
1811
|
+
ref: this._main,
|
|
1812
|
+
container: this._parentElement
|
|
1813
|
+
});
|
|
1814
|
+
this.onResize();
|
|
1815
|
+
result = true;
|
|
1816
|
+
} else {
|
|
1817
|
+
this._logger.warning(this, "attachToParent :: container was not found");
|
|
1818
|
+
}
|
|
1819
|
+
return result;
|
|
1820
|
+
}
|
|
1821
|
+
detachFromParent() {
|
|
1822
|
+
let result = false;
|
|
1823
|
+
if (this._parentElement != null && this._videoContainer != null) {
|
|
1824
|
+
this._logger.info(this, "Detaching from parent: " + this._videoContainer);
|
|
1825
|
+
this._parentElement.removeChild(this._videoContainer);
|
|
1826
|
+
if (this._resizeObserver) {
|
|
1827
|
+
this._resizeObserver.unobserve(this._parentElement);
|
|
1828
|
+
this._resizeObserver.disconnect();
|
|
1829
|
+
}
|
|
1830
|
+
if (this._autoResizeEnabled) this._parentElement.removeEventListener("transitionend", this.onResize);
|
|
1831
|
+
this._main.dispatchEvent("containerChange", {
|
|
1832
|
+
ref: this._main,
|
|
1833
|
+
container: null
|
|
1834
|
+
});
|
|
1835
|
+
result = true;
|
|
1836
|
+
} else {
|
|
1837
|
+
this._logger.info(this, "Failed detaching from parent!");
|
|
1838
|
+
}
|
|
1839
|
+
this._parentElement = null;
|
|
1840
|
+
return result;
|
|
1841
|
+
}
|
|
1842
|
+
resizeVideoContainer() {
|
|
1843
|
+
const isWidthInPX = this._main.getConfigManager().getSettingsData().getVideoData().videoWidthInPixels;
|
|
1844
|
+
const isHeightInPX = this._main.getConfigManager().getSettingsData().getVideoData().videoHeightInPixels;
|
|
1845
|
+
const videoWidthVal = this._main.getConfigManager().getSettingsData().getVideoData().videoWidthValue;
|
|
1846
|
+
const videoHeightVal = this._main.getConfigManager().getSettingsData().getVideoData().videoHeightValue;
|
|
1847
|
+
const aspectRatio = this._main.getConfigManager().getSettingsData().getVideoData().aspectRatio;
|
|
1848
|
+
let finalVideoWidth = 0;
|
|
1849
|
+
let finalVideoHeight = 0;
|
|
1850
|
+
let aspectWRatio = Number(aspectRatio.split(":")[0]);
|
|
1851
|
+
let aspectHRatio = Number(aspectRatio.split(":")[1]);
|
|
1852
|
+
if (aspectRatio == "none") {
|
|
1853
|
+
if (isWidthInPX) {
|
|
1854
|
+
finalVideoWidth = videoWidthVal;
|
|
1855
|
+
} else {
|
|
1856
|
+
if (this._parentElement != null) finalVideoWidth = this._tempContainerWidth * videoWidthVal / 100;
|
|
1857
|
+
}
|
|
1858
|
+
if (isHeightInPX) {
|
|
1859
|
+
finalVideoHeight = videoHeightVal;
|
|
1860
|
+
} else {
|
|
1861
|
+
if (this._parentElement != null) {
|
|
1862
|
+
finalVideoHeight = this._tempContainerHeight * videoHeightVal / 100;
|
|
1863
|
+
if (finalVideoHeight == 0 && this._videoHeight != 0 && this._videoWidth != 0) finalVideoHeight = this._videoHeight * finalVideoWidth / this._videoWidth;
|
|
1864
|
+
}
|
|
1865
|
+
}
|
|
1866
|
+
} else {
|
|
1867
|
+
if (isWidthInPX) {
|
|
1868
|
+
finalVideoWidth = videoWidthVal;
|
|
1869
|
+
} else {
|
|
1870
|
+
if (this._parentElement != null) finalVideoWidth = this._tempContainerWidth * videoWidthVal / 100;
|
|
1871
|
+
}
|
|
1872
|
+
finalVideoHeight = finalVideoWidth * aspectHRatio / aspectWRatio;
|
|
1873
|
+
}
|
|
1874
|
+
this._containerWidth = Math.ceil(finalVideoWidth);
|
|
1875
|
+
this._containerHeight = Math.ceil(finalVideoHeight);
|
|
1876
|
+
this._videoWidth = this._containerWidth;
|
|
1877
|
+
this._videoHeight = this._containerHeight;
|
|
1878
|
+
if (this._videoContainer !== null) {
|
|
1879
|
+
this._videoContainer.style.width = this._containerWidth + "px";
|
|
1880
|
+
this._videoContainer.style.height = this._containerHeight + "px";
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
scaleVideo() {
|
|
1884
|
+
if (this._screenElement !== null) {
|
|
1885
|
+
let videoX = 0;
|
|
1886
|
+
let videoY = 0;
|
|
1887
|
+
let videoWidth = 0;
|
|
1888
|
+
let videoHeight = 0;
|
|
1889
|
+
switch (this._scalingMode) {
|
|
1890
|
+
case ScalingType.FILL:
|
|
1891
|
+
{
|
|
1892
|
+
videoWidth = this._containerWidth;
|
|
1893
|
+
videoHeight = this._containerHeight;
|
|
1894
|
+
}
|
|
1895
|
+
break;
|
|
1896
|
+
case ScalingType.CROP:
|
|
1897
|
+
{
|
|
1898
|
+
videoWidth = this._containerWidth;
|
|
1899
|
+
videoHeight = this._videoHeight * this._containerWidth / this._videoWidth;
|
|
1900
|
+
if (videoHeight >= this._containerHeight) {
|
|
1901
|
+
videoX = 0;
|
|
1902
|
+
videoY = (videoHeight - this._containerHeight) / 2 * -1;
|
|
1903
|
+
} else {
|
|
1904
|
+
videoHeight = this._containerHeight;
|
|
1905
|
+
videoWidth = this._videoWidth * this._containerHeight / this._videoHeight;
|
|
1906
|
+
videoY = 0;
|
|
1907
|
+
videoX = (videoWidth - this._containerWidth) / 2 * -1;
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
break;
|
|
1911
|
+
case ScalingType.LETTER_BOX:
|
|
1912
|
+
{
|
|
1913
|
+
videoWidth = this._containerWidth;
|
|
1914
|
+
videoHeight = this._videoHeight * this._containerWidth / this._videoWidth;
|
|
1915
|
+
if (videoHeight <= this._containerHeight) {
|
|
1916
|
+
videoX = 0;
|
|
1917
|
+
videoY = (videoHeight - this._containerHeight) / 2 * -1;
|
|
1918
|
+
if (videoHeight > this._containerHeight) {
|
|
1919
|
+
videoHeight = this._containerHeight;
|
|
1920
|
+
videoWidth = this._videoWidth * this._containerHeight / this._videoHeight;
|
|
1921
|
+
videoY = 0;
|
|
1922
|
+
videoX = (videoWidth - this._containerWidth) / 2 * -1;
|
|
1923
|
+
}
|
|
1924
|
+
} else {
|
|
1925
|
+
videoHeight = this._containerHeight;
|
|
1926
|
+
videoWidth = this._videoWidth * this._containerHeight / this._videoHeight;
|
|
1927
|
+
videoY = 0;
|
|
1928
|
+
videoX = (videoWidth - this._containerWidth) / 2 * -1;
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
break;
|
|
1932
|
+
case ScalingType.ORIGINAL:
|
|
1933
|
+
{
|
|
1934
|
+
videoWidth = this._videoWidth;
|
|
1935
|
+
videoHeight = this._videoHeight;
|
|
1936
|
+
videoX = (this._videoWidth - this._containerWidth) / -2;
|
|
1937
|
+
videoY = (this._videoHeight - this._containerHeight) / -2;
|
|
1938
|
+
break;
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1941
|
+
this._screenElement.getVideoElement().style.left = Math.floor(videoX) + "px";
|
|
1942
|
+
this._screenElement.getVideoElement().style.top = Math.floor(videoY) + "px";
|
|
1943
|
+
this._screenElement.getVideoElement().style.width = Math.ceil(videoWidth) + "px";
|
|
1944
|
+
this._screenElement.getVideoElement().style.height = Math.ceil(videoHeight) + "px";
|
|
1945
|
+
this._screenElement.getVideoElement().style.position = "absolute";
|
|
1946
|
+
this._screenElement.getVideoElement().style.objectFit = "fill";
|
|
1947
|
+
}
|
|
1948
|
+
}
|
|
1949
|
+
enterFullScreen() {
|
|
1950
|
+
var _a, _b, _c;
|
|
1951
|
+
if ((_a = this._screenElement) === null || _a === void 0 ? void 0 : _a.getVideoElement().webkitEnterFullScreen) {
|
|
1952
|
+
(_b = this._screenElement) === null || _b === void 0 ? void 0 : _b.getVideoElement().webkitEnterFullScreen();
|
|
1953
|
+
} else {
|
|
1954
|
+
(_c = this._screenElement) === null || _c === void 0 ? void 0 : _c.getVideoElement().requestFullscreen();
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1957
|
+
exitFullScreen() {
|
|
1958
|
+
var _a;
|
|
1959
|
+
if ((_a = this._screenElement) === null || _a === void 0 ? void 0 : _a.getVideoElement().webkitExitFullscreen) {
|
|
1960
|
+
document.webkitExitFullscreen();
|
|
1961
|
+
} else {
|
|
1962
|
+
document.exitFullscreen();
|
|
1963
|
+
}
|
|
1964
|
+
}
|
|
1965
|
+
isFullScreenMode() {
|
|
1966
|
+
return this.isInFullScreenMode;
|
|
1967
|
+
}
|
|
1968
|
+
setDimension(key, value) {
|
|
1969
|
+
const dimensionKey = key === 'width' ? 'videoWidth' : 'videoHeight';
|
|
1970
|
+
let valueInPixels;
|
|
1971
|
+
let numericValue;
|
|
1972
|
+
if (typeof value === "number") {
|
|
1973
|
+
numericValue = value;
|
|
1974
|
+
valueInPixels = true;
|
|
1975
|
+
} else if (typeof value === "string") {
|
|
1976
|
+
numericValue = parseInt(value);
|
|
1977
|
+
valueInPixels = value.toLowerCase().endsWith('px');
|
|
1978
|
+
} else {
|
|
1979
|
+
throw new Error(`Unknown value for parameter "${key}" - it must be a number or a string!`);
|
|
1980
|
+
}
|
|
1981
|
+
this._main.getConfigManager().getSettingsData().getVideoData()[`${dimensionKey}Value`] = numericValue;
|
|
1982
|
+
this._main.getConfigManager().getSettingsData().getVideoData()[`${dimensionKey}InPixels`] = valueInPixels;
|
|
1983
|
+
this.resizeVideoContainer();
|
|
1984
|
+
this.scaleVideo();
|
|
1985
|
+
}
|
|
1986
|
+
setSize(width, height) {
|
|
1987
|
+
this.setDimension('width', width);
|
|
1988
|
+
this.setDimension('height', height);
|
|
1989
|
+
}
|
|
1990
|
+
setWidth(width) {
|
|
1991
|
+
this.setDimension('width', width);
|
|
1992
|
+
}
|
|
1993
|
+
setHeight(height) {
|
|
1994
|
+
this.setDimension('height', height);
|
|
1995
|
+
}
|
|
1996
|
+
getParentElement() {
|
|
1997
|
+
return this._parentElement;
|
|
1998
|
+
}
|
|
1999
|
+
setScalingMode(newMode) {
|
|
2000
|
+
switch (newMode.toLowerCase()) {
|
|
2001
|
+
case "fill":
|
|
2002
|
+
this._scalingMode = ScalingType.FILL;
|
|
2003
|
+
break;
|
|
2004
|
+
case "crop":
|
|
2005
|
+
this._scalingMode = ScalingType.CROP;
|
|
2006
|
+
break;
|
|
2007
|
+
case "letterbox":
|
|
2008
|
+
this._scalingMode = ScalingType.LETTER_BOX;
|
|
2009
|
+
break;
|
|
2010
|
+
case "original":
|
|
2011
|
+
this._scalingMode = ScalingType.ORIGINAL;
|
|
2012
|
+
break;
|
|
2013
|
+
}
|
|
2014
|
+
this.scaleVideo();
|
|
2015
|
+
}
|
|
2016
|
+
getContainerWidth() {
|
|
2017
|
+
return this._containerWidth;
|
|
2018
|
+
}
|
|
2019
|
+
getContainerHeight() {
|
|
2020
|
+
return this._containerHeight;
|
|
2021
|
+
}
|
|
2022
|
+
getScalingModeAsString() {
|
|
2023
|
+
let scalingName = "";
|
|
2024
|
+
switch (this._scalingMode) {
|
|
2025
|
+
case ScalingType.FILL:
|
|
2026
|
+
scalingName = "fill";
|
|
2027
|
+
break;
|
|
2028
|
+
case ScalingType.CROP:
|
|
2029
|
+
scalingName = "crop";
|
|
2030
|
+
break;
|
|
2031
|
+
case ScalingType.LETTER_BOX:
|
|
2032
|
+
scalingName = "letterbox";
|
|
2033
|
+
break;
|
|
2034
|
+
case ScalingType.ORIGINAL:
|
|
2035
|
+
scalingName = "original";
|
|
2036
|
+
break;
|
|
2037
|
+
}
|
|
2038
|
+
return scalingName;
|
|
2039
|
+
}
|
|
2040
|
+
getScalingMode() {
|
|
2041
|
+
return this._scalingMode;
|
|
2042
|
+
}
|
|
2043
|
+
getScreenElement() {
|
|
2044
|
+
return this._screenElement;
|
|
2045
|
+
}
|
|
2046
|
+
getContainer() {
|
|
2047
|
+
return this._videoContainer;
|
|
2048
|
+
}
|
|
2049
|
+
destroy() {
|
|
2050
|
+
this.detachFromParent();
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
StageController.LOG_ACTIVITY = true;
|
|
2054
|
+
|
|
2055
|
+
class MungeSDP {
|
|
2056
|
+
constructor() {}
|
|
2057
|
+
addAudio(sdpStr, audioLine) {
|
|
2058
|
+
const sdpLines = sdpStr.split(/\r\n/);
|
|
2059
|
+
let sdpSection = '';
|
|
2060
|
+
let sdpStrRet = '';
|
|
2061
|
+
let done = false;
|
|
2062
|
+
for (const sdpLine of sdpLines) {
|
|
2063
|
+
if (sdpLine.length <= 0) continue;
|
|
2064
|
+
if (sdpLine.indexOf('m=audio') === 0) {
|
|
2065
|
+
sdpSection = 'audio';
|
|
2066
|
+
} else if (sdpLine.indexOf('m=video') === 0) {
|
|
2067
|
+
sdpSection = 'video';
|
|
2068
|
+
}
|
|
2069
|
+
sdpStrRet += sdpLine;
|
|
2070
|
+
sdpStrRet += '\r\n';
|
|
2071
|
+
if (sdpSection === 'audio') {
|
|
2072
|
+
if ('a=rtcp-mux'.localeCompare(sdpLine) === 0 && !done) {
|
|
2073
|
+
sdpStrRet += audioLine;
|
|
2074
|
+
done = true;
|
|
2075
|
+
}
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
return sdpStrRet;
|
|
2079
|
+
}
|
|
2080
|
+
addVideo(sdpStr, videoLine) {
|
|
2081
|
+
const sdpLines = sdpStr.split(/\r\n/);
|
|
2082
|
+
let sdpStrRet = '';
|
|
2083
|
+
let done = false;
|
|
2084
|
+
let rtcpSize = false;
|
|
2085
|
+
for (const sdpLine of sdpLines) {
|
|
2086
|
+
if (sdpLine.length <= 0) continue;
|
|
2087
|
+
if (sdpLine.includes("a=rtcp-rsize")) {
|
|
2088
|
+
rtcpSize = true;
|
|
2089
|
+
}
|
|
2090
|
+
if (sdpLine.includes("a=rtcp-mux")) ;
|
|
2091
|
+
}
|
|
2092
|
+
let foundMVideo = false;
|
|
2093
|
+
for (const sdpLine of sdpLines) {
|
|
2094
|
+
if (sdpLine.startsWith("m=video")) {
|
|
2095
|
+
foundMVideo = true;
|
|
2096
|
+
}
|
|
2097
|
+
sdpStrRet += sdpLine;
|
|
2098
|
+
sdpStrRet += '\r\n';
|
|
2099
|
+
if (foundMVideo) {
|
|
2100
|
+
if ('a=rtcp-rsize'.localeCompare(sdpLine) === 0 && !done && rtcpSize) {
|
|
2101
|
+
sdpStrRet += videoLine;
|
|
2102
|
+
done = true;
|
|
2103
|
+
}
|
|
2104
|
+
if ('a=rtcp-mux'.localeCompare(sdpLine) === 0 && done && !rtcpSize) {
|
|
2105
|
+
sdpStrRet += videoLine;
|
|
2106
|
+
done = true;
|
|
2107
|
+
}
|
|
2108
|
+
if ('a=rtcp-mux'.localeCompare(sdpLine) === 0 && !done && !rtcpSize) {
|
|
2109
|
+
done = true;
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
return sdpStrRet;
|
|
2114
|
+
}
|
|
2115
|
+
deliverCheckLine(profile, type) {
|
|
2116
|
+
for (const line in MungeSDP.SDPOutput) {
|
|
2117
|
+
const lineInUse = MungeSDP.SDPOutput[line];
|
|
2118
|
+
if (lineInUse.includes(profile)) {
|
|
2119
|
+
if (profile.includes("VP9") || profile.includes("VP8")) {
|
|
2120
|
+
let output = "";
|
|
2121
|
+
const outputs = lineInUse.split(/\r\n/);
|
|
2122
|
+
for (const transport of outputs) {
|
|
2123
|
+
output += transport;
|
|
2124
|
+
output += "\r\n";
|
|
2125
|
+
}
|
|
2126
|
+
if (type.includes("audio")) {
|
|
2127
|
+
MungeSDP.audioIndex = parseInt(line);
|
|
2128
|
+
}
|
|
2129
|
+
if (type.includes("video")) {
|
|
2130
|
+
MungeSDP.videoIndex = parseInt(line);
|
|
2131
|
+
}
|
|
2132
|
+
return output;
|
|
2133
|
+
}
|
|
2134
|
+
if (type.includes("audio")) {
|
|
2135
|
+
MungeSDP.audioIndex = parseInt(line);
|
|
2136
|
+
}
|
|
2137
|
+
if (type.includes("video")) {
|
|
2138
|
+
MungeSDP.videoIndex = parseInt(line);
|
|
2139
|
+
}
|
|
2140
|
+
return lineInUse;
|
|
2141
|
+
}
|
|
2142
|
+
}
|
|
2143
|
+
return '';
|
|
2144
|
+
}
|
|
2145
|
+
checkLine(line) {
|
|
2146
|
+
if (line.startsWith("a=rtpmap") || line.startsWith("a=rtcp-fb") || line.startsWith("a=fmtp")) {
|
|
2147
|
+
const res = line.split(":");
|
|
2148
|
+
if (res.length > 1) {
|
|
2149
|
+
const number = res[1].split(" ");
|
|
2150
|
+
if (!isNaN(parseInt(number[0]))) {
|
|
2151
|
+
if (!number[1].startsWith("http") && !number[1].startsWith("ur")) {
|
|
2152
|
+
let currentString = MungeSDP.SDPOutput[number[0]];
|
|
2153
|
+
if (!currentString) {
|
|
2154
|
+
currentString = "";
|
|
2155
|
+
}
|
|
2156
|
+
currentString += line + "\r\n";
|
|
2157
|
+
MungeSDP.SDPOutput[number[0]] = currentString;
|
|
2158
|
+
return false;
|
|
2159
|
+
}
|
|
2160
|
+
}
|
|
2161
|
+
}
|
|
2162
|
+
}
|
|
2163
|
+
return true;
|
|
2164
|
+
}
|
|
2165
|
+
getrtpMapID(line) {
|
|
2166
|
+
const findid = new RegExp('a=rtpmap:(\\d+) (\\w+)/(\\d+)');
|
|
2167
|
+
const found = line.match(findid);
|
|
2168
|
+
return found && found.length >= 3 ? found : null;
|
|
2169
|
+
}
|
|
2170
|
+
mungeSDPPublish(sdpStr, mungeData) {
|
|
2171
|
+
MungeSDP.SDPOutput = {};
|
|
2172
|
+
MungeSDP.videoChoice = "42e01f";
|
|
2173
|
+
MungeSDP.audioChoice = "opus";
|
|
2174
|
+
MungeSDP.videoIndex = -1;
|
|
2175
|
+
MungeSDP.audioIndex = -1;
|
|
2176
|
+
const sdpLines = sdpStr.split(/\r\n/);
|
|
2177
|
+
let sdpSection = 'header';
|
|
2178
|
+
let hitMID = false;
|
|
2179
|
+
let sdpStrRet = '';
|
|
2180
|
+
if (mungeData.videoCodec != null && mungeData.videoCodec !== '') MungeSDP.videoChoice = mungeData.videoCodec;
|
|
2181
|
+
if (mungeData.audioCodec != null && mungeData.audioCodec !== '') MungeSDP.audioChoice = mungeData.audioCodec;
|
|
2182
|
+
for (const sdpLine of sdpLines) {
|
|
2183
|
+
if (sdpLine.length <= 0) continue;
|
|
2184
|
+
const doneCheck = this.checkLine(sdpLine);
|
|
2185
|
+
if (!doneCheck) continue;
|
|
2186
|
+
sdpStrRet += sdpLine;
|
|
2187
|
+
sdpStrRet += '\r\n';
|
|
2188
|
+
}
|
|
2189
|
+
sdpStrRet = this.addAudio(sdpStrRet, this.deliverCheckLine(MungeSDP.audioChoice, "audio"));
|
|
2190
|
+
sdpStrRet = this.addVideo(sdpStrRet, this.deliverCheckLine(MungeSDP.videoChoice, "video"));
|
|
2191
|
+
const newSdpLines = sdpStrRet.split(/\r\n/);
|
|
2192
|
+
sdpStrRet = '';
|
|
2193
|
+
for (const sdpLine of newSdpLines) {
|
|
2194
|
+
if (sdpLine.length <= 0) continue;
|
|
2195
|
+
let audioMLines;
|
|
2196
|
+
if (sdpLine.indexOf("m=audio") === 0 && MungeSDP.audioIndex !== -1) {
|
|
2197
|
+
audioMLines = sdpLine.split(" ");
|
|
2198
|
+
sdpStrRet += audioMLines[0] + " " + audioMLines[1] + " " + audioMLines[2] + " " + MungeSDP.audioIndex + "\r\n";
|
|
2199
|
+
sdpSection = 'audio';
|
|
2200
|
+
hitMID = false;
|
|
2201
|
+
continue;
|
|
2202
|
+
}
|
|
2203
|
+
if (sdpLine.indexOf("m=video") === 0 && MungeSDP.videoIndex !== -1) {
|
|
2204
|
+
audioMLines = sdpLine.split(" ");
|
|
2205
|
+
sdpStrRet += audioMLines[0] + " " + audioMLines[1] + " " + audioMLines[2] + " " + MungeSDP.videoIndex + "\r\n";
|
|
2206
|
+
sdpSection = 'video';
|
|
2207
|
+
hitMID = false;
|
|
2208
|
+
continue;
|
|
2209
|
+
}
|
|
2210
|
+
sdpStrRet += sdpLine;
|
|
2211
|
+
if (sdpLine.indexOf("a=rtpmap") === 0) {
|
|
2212
|
+
sdpSection = 'bandwidth';
|
|
2213
|
+
hitMID = false;
|
|
2214
|
+
}
|
|
2215
|
+
if (UserCapabilities.getBrowserName().toLowerCase() === 'chrome' || UserCapabilities.getBrowserName().toLowerCase() === 'safari') {
|
|
2216
|
+
if (sdpLine.indexOf("a=mid:") === 0 || sdpLine.indexOf("a=rtpmap") === 0) {
|
|
2217
|
+
if (!hitMID) {
|
|
2218
|
+
if ('audio'.localeCompare(sdpSection) === 0) {
|
|
2219
|
+
if (mungeData.audioBitrate !== undefined && mungeData.audioBitrate !== '') {
|
|
2220
|
+
sdpStrRet += '\r\nb=CT:' + mungeData.audioBitrate;
|
|
2221
|
+
sdpStrRet += '\r\nb=AS:' + mungeData.audioBitrate;
|
|
2222
|
+
}
|
|
2223
|
+
hitMID = true;
|
|
2224
|
+
} else if ('video'.localeCompare(sdpSection) === 0) {
|
|
2225
|
+
if (mungeData.videoBitrate !== undefined && mungeData.videoBitrate !== '') {
|
|
2226
|
+
sdpStrRet += '\r\nb=CT:' + mungeData.videoBitrate;
|
|
2227
|
+
sdpStrRet += '\r\nb=AS:' + mungeData.videoBitrate;
|
|
2228
|
+
if (mungeData.videoFrameRate !== undefined) {
|
|
2229
|
+
sdpStrRet += '\r\na=framerate:' + mungeData.videoFrameRate;
|
|
2230
|
+
}
|
|
2231
|
+
}
|
|
2232
|
+
hitMID = true;
|
|
2233
|
+
} else if (UserCapabilities.getBrowserName().toLowerCase() === 'chrome' && 'bandwidth'.localeCompare(sdpSection) === 0) {
|
|
2234
|
+
const rtpmapID = this.getrtpMapID(sdpLine);
|
|
2235
|
+
if (rtpmapID !== null) {
|
|
2236
|
+
const match = rtpmapID[2].toLowerCase();
|
|
2237
|
+
if ('vp9'.localeCompare(match) === 0 || 'vp8'.localeCompare(match) === 0 || 'h264'.localeCompare(match) === 0 || 'red'.localeCompare(match) === 0 || 'ulpfec'.localeCompare(match) === 0 || 'rtx'.localeCompare(match) === 0) {
|
|
2238
|
+
if (mungeData.videoBitrate !== undefined) {
|
|
2239
|
+
sdpStrRet += '\r\na=fmtp:' + rtpmapID[1] + ' x-google-min-bitrate=' + mungeData.videoBitrate + ';x-google-max-bitrate=' + mungeData.videoBitrate;
|
|
2240
|
+
}
|
|
2241
|
+
}
|
|
2242
|
+
if ('opus'.localeCompare(match) === 0 || 'isac'.localeCompare(match) === 0 || 'g722'.localeCompare(match) === 0 || 'pcmu'.localeCompare(match) === 0 || 'pcma'.localeCompare(match) === 0 || 'cn'.localeCompare(match) === 0) {
|
|
2243
|
+
if (mungeData.audioBitrate !== undefined) {
|
|
2244
|
+
sdpStrRet += '\r\na=fmtp:' + rtpmapID[1] + ' x-google-min-bitrate=' + mungeData.audioBitrate + ';x-google-max-bitrate=' + mungeData.audioBitrate;
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
}
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2250
|
+
}
|
|
2251
|
+
}
|
|
2252
|
+
if (UserCapabilities.getBrowserName().toLowerCase() === 'firefox') {
|
|
2253
|
+
if (sdpLine.indexOf("c=IN") === 0) {
|
|
2254
|
+
if ('audio'.localeCompare(sdpSection) === 0) {
|
|
2255
|
+
if (mungeData.audioBitrate !== '') {
|
|
2256
|
+
if (typeof mungeData.audioBitrate === "string") {
|
|
2257
|
+
const audioBitrate = parseInt(mungeData.audioBitrate);
|
|
2258
|
+
const audioBitrateTIAS = audioBitrate * 1000 * 0.95 - 50 * 40 * 8;
|
|
2259
|
+
sdpStrRet += "\r\nb=TIAS:" + audioBitrateTIAS + "\r\n";
|
|
2260
|
+
sdpStrRet += "b=AS:" + audioBitrate + "\r\n";
|
|
2261
|
+
sdpStrRet += "b=CT:" + audioBitrate + "\r\n";
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
|
+
continue;
|
|
2265
|
+
}
|
|
2266
|
+
if ('video'.localeCompare(sdpSection) === 0) {
|
|
2267
|
+
if (mungeData.videoBitrate !== '') {
|
|
2268
|
+
if (typeof mungeData.videoBitrate === "string") {
|
|
2269
|
+
const videoBitrate = parseInt(mungeData.videoBitrate);
|
|
2270
|
+
const videoBitrateTIAS = videoBitrate * 1000 * 0.95 - 50 * 40 * 8;
|
|
2271
|
+
sdpStrRet += "\r\nb=TIAS:" + videoBitrateTIAS * 1000 + "\r\n";
|
|
2272
|
+
sdpStrRet += "b=AS:" + videoBitrate + "\r\n";
|
|
2273
|
+
sdpStrRet += "b=CT:" + videoBitrate + "\r\n";
|
|
2274
|
+
}
|
|
2275
|
+
}
|
|
2276
|
+
continue;
|
|
2277
|
+
}
|
|
2278
|
+
}
|
|
2279
|
+
}
|
|
2280
|
+
sdpStrRet += '\r\n';
|
|
2281
|
+
}
|
|
2282
|
+
return sdpStrRet;
|
|
2283
|
+
}
|
|
2284
|
+
mungeSDPPlay(sdpStr) {
|
|
2285
|
+
const sdpLines = sdpStr.split(/\r\n/);
|
|
2286
|
+
let sdpStrRet = '';
|
|
2287
|
+
for (const sdpLine of sdpLines) {
|
|
2288
|
+
if (sdpLine.length === 0) continue;
|
|
2289
|
+
if (sdpLine.includes("profile-level-id")) {
|
|
2290
|
+
let profileLevelId = sdpLine.substr(sdpLine.indexOf("profile-level-id") + 17, 6);
|
|
2291
|
+
let profile = Number('0x' + profileLevelId.substr(0, 2));
|
|
2292
|
+
let constraint = Number('0x' + profileLevelId.substr(2, 2));
|
|
2293
|
+
let level = Number('0x' + profileLevelId.substr(4, 2));
|
|
2294
|
+
if (profile > 0x42) {
|
|
2295
|
+
profile = 0x42;
|
|
2296
|
+
constraint = 0xE0;
|
|
2297
|
+
level = 0x1F;
|
|
2298
|
+
}
|
|
2299
|
+
if (constraint === 0x00) {
|
|
2300
|
+
constraint = 0xE0;
|
|
2301
|
+
}
|
|
2302
|
+
const newProfileLevelId = ("00" + profile.toString(16)).slice(-2).toLowerCase() + ("00" + constraint.toString(16)).slice(-2).toLowerCase() + ("00" + level.toString(16)).slice(-2).toLowerCase();
|
|
2303
|
+
sdpStrRet += sdpLine.replace(profileLevelId, newProfileLevelId);
|
|
2304
|
+
} else {
|
|
2305
|
+
sdpStrRet += sdpLine;
|
|
2306
|
+
}
|
|
2307
|
+
sdpStrRet += '\r\n';
|
|
2308
|
+
}
|
|
2309
|
+
return sdpStrRet;
|
|
2310
|
+
}
|
|
2311
|
+
}
|
|
2312
|
+
MungeSDP.SDPOutput = {};
|
|
2313
|
+
|
|
2314
|
+
var InputType;
|
|
2315
|
+
(function (InputType) {
|
|
2316
|
+
InputType[InputType["VIDEO_INPUT"] = 0] = "VIDEO_INPUT";
|
|
2317
|
+
InputType[InputType["AUDIO_INPUT"] = 1] = "AUDIO_INPUT";
|
|
2318
|
+
})(InputType || (InputType = {}));
|
|
2319
|
+
|
|
2320
|
+
class InputDevice {
|
|
2321
|
+
constructor(inputDevice, number) {
|
|
2322
|
+
this._groupID = "";
|
|
2323
|
+
this._isSelected = false;
|
|
2324
|
+
if (inputDevice !== undefined && inputDevice !== null) {
|
|
2325
|
+
if (inputDevice.deviceId !== undefined && inputDevice.deviceId !== null) this._id = inputDevice.deviceId;else throw new Error("no deviceID");
|
|
2326
|
+
if (inputDevice.kind !== undefined && inputDevice.kind !== null) {
|
|
2327
|
+
switch (inputDevice.kind) {
|
|
2328
|
+
case "videoinput":
|
|
2329
|
+
this._inputType = InputType.VIDEO_INPUT;
|
|
2330
|
+
break;
|
|
2331
|
+
case "audioinput":
|
|
2332
|
+
this._inputType = InputType.AUDIO_INPUT;
|
|
2333
|
+
break;
|
|
2334
|
+
default:
|
|
2335
|
+
throw new Error("incorrect kind");
|
|
2336
|
+
}
|
|
2337
|
+
} else throw new Error("no device kind");
|
|
2338
|
+
if (inputDevice.label !== null && inputDevice.label !== "") {
|
|
2339
|
+
this._label = this.cleanLabel(inputDevice.label);
|
|
2340
|
+
} else this._label = this._inputType == InputType.VIDEO_INPUT ? "Camera " + number : "Microphone " + number;
|
|
2341
|
+
if (inputDevice.groupId !== undefined && inputDevice.groupId !== null) this._groupID = inputDevice.groupId;
|
|
2342
|
+
} else throw new Error("no input device");
|
|
2343
|
+
}
|
|
2344
|
+
cleanLabel(label) {
|
|
2345
|
+
return label;
|
|
2346
|
+
}
|
|
2347
|
+
getLabel() {
|
|
2348
|
+
return this._label;
|
|
2349
|
+
}
|
|
2350
|
+
getID() {
|
|
2351
|
+
return this._id;
|
|
2352
|
+
}
|
|
2353
|
+
getGroupID() {
|
|
2354
|
+
return this._groupID;
|
|
2355
|
+
}
|
|
2356
|
+
getIfSelected() {
|
|
2357
|
+
return this._isSelected;
|
|
2358
|
+
}
|
|
2359
|
+
setSelected(isSelected) {
|
|
2360
|
+
this._isSelected = isSelected;
|
|
2361
|
+
}
|
|
2362
|
+
}
|
|
2363
|
+
|
|
2364
|
+
class InputDeviceList {
|
|
2365
|
+
constructor() {
|
|
2366
|
+
this._internalList = new Array();
|
|
2367
|
+
}
|
|
2368
|
+
push(item) {
|
|
2369
|
+
let alreadyExists = false;
|
|
2370
|
+
if (this._internalList.length > 0) {
|
|
2371
|
+
for (let i = 0; i < this._internalList.length; i++) {
|
|
2372
|
+
if (this._internalList[i].getGroupID() !== "") {
|
|
2373
|
+
if (this._internalList[i].getGroupID() == item.getGroupID()) {
|
|
2374
|
+
alreadyExists = true;
|
|
2375
|
+
this._internalList[i] = item;
|
|
2376
|
+
}
|
|
2377
|
+
}
|
|
2378
|
+
}
|
|
2379
|
+
if (alreadyExists == false) return this._internalList.push(item);else return this._internalList.length;
|
|
2380
|
+
} else return this._internalList.push(item);
|
|
2381
|
+
}
|
|
2382
|
+
get(id) {
|
|
2383
|
+
return this._internalList[id];
|
|
2384
|
+
}
|
|
2385
|
+
getSize() {
|
|
2386
|
+
return this._internalList.length;
|
|
2387
|
+
}
|
|
2388
|
+
getArray() {
|
|
2389
|
+
return this._internalList;
|
|
2390
|
+
}
|
|
2391
|
+
}
|
|
2392
|
+
|
|
2393
|
+
exports.PublishState = void 0;
|
|
2394
|
+
(function (PublishState) {
|
|
2395
|
+
PublishState["NOT_INITIALIZED"] = "NOT_INITIALIZED";
|
|
2396
|
+
PublishState["INITIALIZED"] = "INITIALIZED";
|
|
2397
|
+
PublishState["CONNECTING"] = "CONNECTING";
|
|
2398
|
+
PublishState["PUBLISHED"] = "PUBLISHED";
|
|
2399
|
+
PublishState["UNPUBLISHED"] = "UNPUBLISHED";
|
|
2400
|
+
PublishState["STOPPED"] = "STOPPED";
|
|
2401
|
+
PublishState["UNKNOWN"] = "UNKNOWN";
|
|
2402
|
+
PublishState["ERROR"] = "ERROR";
|
|
2403
|
+
})(exports.PublishState || (exports.PublishState = {}));
|
|
2404
|
+
|
|
2405
|
+
class SoundMeter {
|
|
2406
|
+
constructor(main) {
|
|
2407
|
+
this._instant = 0.0;
|
|
2408
|
+
this._slow = 0.0;
|
|
2409
|
+
this.clip = 0.0;
|
|
2410
|
+
this._main = main;
|
|
2411
|
+
}
|
|
2412
|
+
attach(stream) {
|
|
2413
|
+
this._stream = stream;
|
|
2414
|
+
this.audioContext = new AudioContext();
|
|
2415
|
+
this.microphone = this.audioContext.createMediaStreamSource(stream);
|
|
2416
|
+
this.processor = this.audioContext.createScriptProcessor(2048, 1, 1);
|
|
2417
|
+
this.microphone.connect(this.processor);
|
|
2418
|
+
this.processor.connect(this.audioContext.destination);
|
|
2419
|
+
this.processor.onaudioprocess = event => {
|
|
2420
|
+
this.onAudioProcess(event);
|
|
2421
|
+
};
|
|
2422
|
+
}
|
|
2423
|
+
detach() {
|
|
2424
|
+
if (this.microphone !== null) this.microphone.disconnect();
|
|
2425
|
+
if (this.processor !== null) this.processor.disconnect();
|
|
2426
|
+
}
|
|
2427
|
+
clear() {
|
|
2428
|
+
this._instant = 0;
|
|
2429
|
+
this._slow = 0;
|
|
2430
|
+
this.clip = 0;
|
|
2431
|
+
}
|
|
2432
|
+
onAudioProcess(event) {
|
|
2433
|
+
const input = event.inputBuffer.getChannelData(0);
|
|
2434
|
+
let i;
|
|
2435
|
+
let sum = 0.0;
|
|
2436
|
+
let clipcount = 0;
|
|
2437
|
+
for (i = 0; i < input.length; ++i) {
|
|
2438
|
+
sum += input[i] * input[i];
|
|
2439
|
+
if (Math.abs(input[i]) > 0.99) {
|
|
2440
|
+
clipcount += 1;
|
|
2441
|
+
}
|
|
2442
|
+
}
|
|
2443
|
+
this._instant = Math.sqrt(sum / input.length);
|
|
2444
|
+
this._slow = 0.05 * this._instant + 0.95 * this._slow;
|
|
2445
|
+
this.clip = clipcount / input.length;
|
|
2446
|
+
console.log("sound", this._instant, this._slow);
|
|
2447
|
+
this._main.dispatchEvent("soundMeter", {
|
|
2448
|
+
ref: this._main,
|
|
2449
|
+
high: this._instant,
|
|
2450
|
+
low: this._slow
|
|
2451
|
+
});
|
|
2452
|
+
}
|
|
2453
|
+
}
|
|
2454
|
+
|
|
2455
|
+
class PlaybackController {
|
|
2456
|
+
constructor(main) {
|
|
2457
|
+
this._isWindowActive = true;
|
|
2458
|
+
this._peerConnectionConfig = {
|
|
2459
|
+
'iceServers': []
|
|
2460
|
+
};
|
|
2461
|
+
this._isMicrophoneMuted = false;
|
|
2462
|
+
this._constraints = {
|
|
2463
|
+
video: {
|
|
2464
|
+
width: {
|
|
2465
|
+
min: "640",
|
|
2466
|
+
ideal: "1024",
|
|
2467
|
+
max: "1024"
|
|
2468
|
+
},
|
|
2469
|
+
height: {
|
|
2470
|
+
min: "360",
|
|
2471
|
+
ideal: "576",
|
|
2472
|
+
max: "576"
|
|
2473
|
+
},
|
|
2474
|
+
frameRate: {
|
|
2475
|
+
min: 24,
|
|
2476
|
+
ideal: 30,
|
|
2477
|
+
max: 30
|
|
2478
|
+
}
|
|
2479
|
+
},
|
|
2480
|
+
audio: true
|
|
2481
|
+
};
|
|
2482
|
+
this._publishState = exports.PublishState.NOT_INITIALIZED;
|
|
2483
|
+
this.onServerDisconnect = () => {};
|
|
2484
|
+
this.onServerConnect = () => {
|
|
2485
|
+
this._peerConnection = new RTCPeerConnection(this._peerConnectionConfig);
|
|
2486
|
+
this._peerConnection.onicecandidate = event => {
|
|
2487
|
+
this.onIceCandidate(event);
|
|
2488
|
+
};
|
|
2489
|
+
this._peerConnection.onconnectionstatechange = event => {
|
|
2490
|
+
this.onConnectionStateChange(event);
|
|
2491
|
+
};
|
|
2492
|
+
this._peerConnection.onnegotiationneeded = event => {
|
|
2493
|
+
this._peerConnection.createOffer(description => {
|
|
2494
|
+
this.onDescriptionSuccess(description);
|
|
2495
|
+
}, error => {
|
|
2496
|
+
this.onDescriptionError(error);
|
|
2497
|
+
}).catch(reason => {
|
|
2498
|
+
console.log(reason);
|
|
2499
|
+
});
|
|
2500
|
+
};
|
|
2501
|
+
let localTracks = this._stream.getTracks();
|
|
2502
|
+
for (let localTrack in localTracks) {
|
|
2503
|
+
this._peerConnection.addTrack(localTracks[localTrack], this._stream);
|
|
2504
|
+
}
|
|
2505
|
+
};
|
|
2506
|
+
this.onDescriptionSuccess = description => {
|
|
2507
|
+
var _a, _b, _c;
|
|
2508
|
+
const streamInfo = {
|
|
2509
|
+
applicationName: (_b = (_a = this._main.getNetworkController()) === null || _a === void 0 ? void 0 : _a.getConnection().getCurrentServer()) === null || _b === void 0 ? void 0 : _b.getApplication(),
|
|
2510
|
+
streamName: (_c = this._main.getConfigManager()) === null || _c === void 0 ? void 0 : _c.getStreamData().streamKey,
|
|
2511
|
+
sessionId: "[empty]"
|
|
2512
|
+
};
|
|
2513
|
+
description.sdp = this._mungeSDP.mungeSDPPublish(description.sdp, {
|
|
2514
|
+
audioBitrate: "64",
|
|
2515
|
+
videoBitrate: "1500",
|
|
2516
|
+
videoFrameRate: 30,
|
|
2517
|
+
videoCodec: "42e01f",
|
|
2518
|
+
audioCodec: "opus"
|
|
2519
|
+
});
|
|
2520
|
+
this._peerConnection.setLocalDescription(description).then(() => {
|
|
2521
|
+
var _a;
|
|
2522
|
+
(_a = this._main.getNetworkController()) === null || _a === void 0 ? void 0 : _a.sendMessage('{"direction":"publish", "command":"sendOffer", "streamInfo":' + JSON.stringify(streamInfo) + ', "sdp":' + JSON.stringify(description) + '}');
|
|
2523
|
+
}).catch(error => {
|
|
2524
|
+
console.log(error);
|
|
2525
|
+
});
|
|
2526
|
+
};
|
|
2527
|
+
this.visibilityChange = () => {
|
|
2528
|
+
if (document.visibilityState === 'hidden') {
|
|
2529
|
+
this.onWindowBlur();
|
|
2530
|
+
} else if (document.visibilityState === 'visible') {
|
|
2531
|
+
this.onWindowFocus();
|
|
2532
|
+
}
|
|
2533
|
+
};
|
|
2534
|
+
this.onWindowBlur = () => {
|
|
2535
|
+
if (this._isWindowActive) {
|
|
2536
|
+
this._logger.warning(this, "Player window is no longer in focus!");
|
|
2537
|
+
}
|
|
2538
|
+
this._isWindowActive = false;
|
|
2539
|
+
};
|
|
2540
|
+
this.onWindowFocus = () => {
|
|
2541
|
+
if (!this._isWindowActive) {
|
|
2542
|
+
this._logger.info(this, "Player window is focused again!");
|
|
2543
|
+
}
|
|
2544
|
+
this._isWindowActive = true;
|
|
2545
|
+
};
|
|
2546
|
+
this._main = main;
|
|
2547
|
+
this._logger = main.getLogger();
|
|
2548
|
+
this._logger.info(this, "Creating new PlaybackController");
|
|
2549
|
+
this._mungeSDP = new MungeSDP();
|
|
2550
|
+
this._soundMeter = new SoundMeter(this._main);
|
|
2551
|
+
this.initialize();
|
|
2552
|
+
}
|
|
2553
|
+
initialize() {
|
|
2554
|
+
var _a, _b, _c;
|
|
2555
|
+
this._main.addEventListener("serverConnect", this.onServerConnect, false);
|
|
2556
|
+
this._main.addEventListener("serverDisconnect", this.onServerDisconnect, false);
|
|
2557
|
+
document.addEventListener("visibilitychange", this.visibilityChange);
|
|
2558
|
+
window.addEventListener("blur", this.onWindowBlur);
|
|
2559
|
+
window.addEventListener("focus", this.onWindowFocus);
|
|
2560
|
+
if ((_a = this._main.getConfigManager()) === null || _a === void 0 ? void 0 : _a.getSettingsData().autoConnect) {
|
|
2561
|
+
this._logger.info(this, "Initializing NetworkController (autoConnect is true)");
|
|
2562
|
+
(_b = this._main.getNetworkController()) === null || _b === void 0 ? void 0 : _b.initialize();
|
|
2563
|
+
} else this._logger.warning(this, "Warning - autoConnect is set to false, switching to standby mode!");
|
|
2564
|
+
if (((_c = this._main.getConfigManager()) === null || _c === void 0 ? void 0 : _c.getStreamData().streamKey) != null) this.startWebRTC();
|
|
2565
|
+
}
|
|
2566
|
+
startWebRTC() {
|
|
2567
|
+
try {
|
|
2568
|
+
if (navigator.mediaDevices.getUserMedia) {
|
|
2569
|
+
navigator.mediaDevices.getUserMedia(this._constraints).then(stream => {
|
|
2570
|
+
this.onUserMediaSuccess(stream);
|
|
2571
|
+
}).catch(error => {
|
|
2572
|
+
this.onUserMediaError(error);
|
|
2573
|
+
});
|
|
2574
|
+
} else {
|
|
2575
|
+
this._logger.error(this, "WebRTCStreamer :: Browser does not support WebRTC");
|
|
2576
|
+
this._main.dispatchEvent("compatibilityError", {
|
|
2577
|
+
ref: this._main,
|
|
2578
|
+
message: "WebRTC is not supported"
|
|
2579
|
+
});
|
|
2580
|
+
}
|
|
2581
|
+
} catch (error) {
|
|
2582
|
+
this.onUserMediaError(error);
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2585
|
+
publish(streamKey) {
|
|
2586
|
+
if (this._publishState == exports.PublishState.PUBLISHED) this.closeStream();
|
|
2587
|
+
this._main.getConfigManager().getStreamData().streamKey = streamKey;
|
|
2588
|
+
this.startWebRTC();
|
|
2589
|
+
}
|
|
2590
|
+
unpublish() {
|
|
2591
|
+
this.closeStream();
|
|
2592
|
+
}
|
|
2593
|
+
onUserMediaSuccess(stream) {
|
|
2594
|
+
var _a;
|
|
2595
|
+
this._logger.success(this, "WebRTCStreamer :: WebRTC UserMedia successfully retrieved");
|
|
2596
|
+
this._stream = stream;
|
|
2597
|
+
this._soundMeter.attach(this._stream);
|
|
2598
|
+
this.setPublishState(exports.PublishState.INITIALIZED);
|
|
2599
|
+
if (this._cameraList == null || this._microphoneList == null) this.grabDevices();
|
|
2600
|
+
const videoElement = this._main.getStageController().getScreenElement().getVideoElement();
|
|
2601
|
+
videoElement.srcObject = stream;
|
|
2602
|
+
videoElement.autoplay = true;
|
|
2603
|
+
videoElement.playsInline = true;
|
|
2604
|
+
(_a = this._main.getNetworkController()) === null || _a === void 0 ? void 0 : _a.start();
|
|
2605
|
+
}
|
|
2606
|
+
onUserMediaError(error) {
|
|
2607
|
+
switch (error.message) {
|
|
2608
|
+
case "Permission denied":
|
|
2609
|
+
this._logger.warning(this, "WebRTCStreamer :: No permission to access camera & microphone");
|
|
2610
|
+
this._main.dispatchEvent("inputDeviceDenied", {
|
|
2611
|
+
ref: this._main
|
|
2612
|
+
});
|
|
2613
|
+
break;
|
|
2614
|
+
case "The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.":
|
|
2615
|
+
this._logger.warning(this, "WebRTCStreamer :: No permission to access camera & microphone");
|
|
2616
|
+
this._main.dispatchEvent("inputDeviceDenied", {
|
|
2617
|
+
ref: this._main
|
|
2618
|
+
});
|
|
2619
|
+
break;
|
|
2620
|
+
case "The request is not allowed by the user agent or the platform in the current context.":
|
|
2621
|
+
this._logger.warning(this, "WebRTCStreamer :: No permission to access camera & microphone");
|
|
2622
|
+
this._main.dispatchEvent("inputDeviceDenied", {
|
|
2623
|
+
ref: this._main
|
|
2624
|
+
});
|
|
2625
|
+
break;
|
|
2626
|
+
case "The object can not be found here.":
|
|
2627
|
+
this._logger.warning(this, "WebRTCStreamer :: Could not access camera or microphone");
|
|
2628
|
+
this._main.dispatchEvent("inputDeviceError", {
|
|
2629
|
+
ref: this._main
|
|
2630
|
+
});
|
|
2631
|
+
break;
|
|
2632
|
+
case "Requested device not found":
|
|
2633
|
+
this._logger.warning(this, "WebRTCStreamer :: Could not access camera or microphone");
|
|
2634
|
+
this._main.dispatchEvent("inputDeviceError", {
|
|
2635
|
+
ref: this._main
|
|
2636
|
+
});
|
|
2637
|
+
break;
|
|
2638
|
+
default:
|
|
2639
|
+
this._logger.warning(this, "WebRTCStreamer :: Unsupported onUserMediaError: " + error.message);
|
|
2640
|
+
break;
|
|
2641
|
+
}
|
|
2642
|
+
}
|
|
2643
|
+
onSocketMessage(data) {
|
|
2644
|
+
let msgJSON = JSON.parse(data);
|
|
2645
|
+
let msgStatus = Number(msgJSON["status"]);
|
|
2646
|
+
switch (msgStatus) {
|
|
2647
|
+
case 200:
|
|
2648
|
+
let sdpData = msgJSON['sdp'];
|
|
2649
|
+
if (sdpData !== undefined) {
|
|
2650
|
+
this._peerConnection.setRemoteDescription(new RTCSessionDescription(sdpData), () => {}, () => {});
|
|
2651
|
+
}
|
|
2652
|
+
let iceCandidates = msgJSON['iceCandidates'];
|
|
2653
|
+
if (iceCandidates !== undefined) {
|
|
2654
|
+
for (let index in iceCandidates) {
|
|
2655
|
+
this._peerConnection.addIceCandidate(new RTCIceCandidate(iceCandidates[index]));
|
|
2656
|
+
}
|
|
2657
|
+
}
|
|
2658
|
+
break;
|
|
2659
|
+
case 503:
|
|
2660
|
+
this._main.dispatchEvent("streamKeyInUse", {
|
|
2661
|
+
ref: this._main,
|
|
2662
|
+
streamKey: this._main.getConfigManager().getStreamData().streamKey
|
|
2663
|
+
});
|
|
2664
|
+
this.setPublishState(exports.PublishState.ERROR);
|
|
2665
|
+
break;
|
|
2666
|
+
}
|
|
2667
|
+
}
|
|
2668
|
+
onConnectionStateChange(event) {
|
|
2669
|
+
if (event !== null) {
|
|
2670
|
+
switch (event.currentTarget.connectionState) {
|
|
2671
|
+
case "connecting":
|
|
2672
|
+
this._logger.info(this, "WebRTCStreamer :: Event: onStreamerConnecting");
|
|
2673
|
+
this.setPublishState(exports.PublishState.CONNECTING);
|
|
2674
|
+
break;
|
|
2675
|
+
case "connected":
|
|
2676
|
+
this._logger.info(this, "WebRTCStreamer :: Event: onStreamerConnected");
|
|
2677
|
+
this.setPublishState(exports.PublishState.PUBLISHED);
|
|
2678
|
+
if (this._isMicrophoneMuted == true) this.muteMicrophone(false);
|
|
2679
|
+
break;
|
|
2680
|
+
case "disconnected":
|
|
2681
|
+
this._logger.info(this, "WebRTCStreamer :: Event: onStreamerDisconnected");
|
|
2682
|
+
this.setPublishState(exports.PublishState.UNPUBLISHED);
|
|
2683
|
+
break;
|
|
2684
|
+
case "failed":
|
|
2685
|
+
this._logger.info(this, "WebRTCStreamer :: Event: onPlayerFailed");
|
|
2686
|
+
this.setPublishState(exports.PublishState.ERROR);
|
|
2687
|
+
break;
|
|
2688
|
+
default:
|
|
2689
|
+
this._logger.info(this, "WebRTCStreamer :: Unsupported onConnectionStateChange: " + event.currentTarget.connectionState);
|
|
2690
|
+
break;
|
|
2691
|
+
}
|
|
2692
|
+
}
|
|
2693
|
+
}
|
|
2694
|
+
grabDevices() {
|
|
2695
|
+
navigator.mediaDevices.enumerateDevices().then(devices => {
|
|
2696
|
+
this._cameraList = new InputDeviceList();
|
|
2697
|
+
this._microphoneList = new InputDeviceList();
|
|
2698
|
+
for (let i = 0; i < devices.length; i++) {
|
|
2699
|
+
try {
|
|
2700
|
+
if (devices[i].kind === 'videoinput') {
|
|
2701
|
+
let device = new InputDevice(devices[i], i);
|
|
2702
|
+
this._cameraList.push(device);
|
|
2703
|
+
} else if (devices[i].kind === 'audioinput') {
|
|
2704
|
+
let device = new InputDevice(devices[i], i);
|
|
2705
|
+
this._microphoneList.push(device);
|
|
2706
|
+
}
|
|
2707
|
+
} catch (error) {
|
|
2708
|
+
this._logger.error(this, "WebRTCStreamer :: Input Device Error: " + error);
|
|
2709
|
+
}
|
|
2710
|
+
}
|
|
2711
|
+
if (this._cameraList.getSize() == 0) {
|
|
2712
|
+
this._main.dispatchEvent("noCameraFound", {
|
|
2713
|
+
ref: this._main
|
|
2714
|
+
});
|
|
2715
|
+
} else if (this._microphoneList.getSize() == 0) {
|
|
2716
|
+
this._main.dispatchEvent("noCameraFound", {
|
|
2717
|
+
ref: this._main
|
|
2718
|
+
});
|
|
2719
|
+
} else {
|
|
2720
|
+
this._logger.info(this, "Camera list:");
|
|
2721
|
+
for (let i = 0; i < this._cameraList.getSize(); i++) this._logger.info(this, "=> [" + i + "] InputDevice: " + this._cameraList.get(i).getLabel());
|
|
2722
|
+
this._logger.info(this, "Microphone list:");
|
|
2723
|
+
for (let k = 0; k < this._microphoneList.getSize(); k++) this._logger.info(this, "=> [" + k + "] InputDevice: " + this._microphoneList.get(k).getLabel());
|
|
2724
|
+
this._selectedCamera = this.pickCamera();
|
|
2725
|
+
this._selectedMicrophone = this.pickMicrophone();
|
|
2726
|
+
}
|
|
2727
|
+
}).catch(() => {
|
|
2728
|
+
this._main.dispatchEvent("inputDeviceError", {
|
|
2729
|
+
ref: this._main
|
|
2730
|
+
});
|
|
2731
|
+
});
|
|
2732
|
+
}
|
|
2733
|
+
selectCamera(cameraID) {
|
|
2734
|
+
var _a;
|
|
2735
|
+
for (let i = 0; i < this._cameraList.getSize(); i++) {
|
|
2736
|
+
if (this._cameraList.get(i).getID() == cameraID) {
|
|
2737
|
+
this._selectedCamera = this._cameraList.get(i);
|
|
2738
|
+
(_a = this._main.getStorageManager()) === null || _a === void 0 ? void 0 : _a.saveField("cameraID", this._selectedCamera.getID());
|
|
2739
|
+
break;
|
|
2740
|
+
}
|
|
2741
|
+
}
|
|
2742
|
+
this.closeStream();
|
|
2743
|
+
this._constraints.video.deviceId = this._selectedCamera.getID();
|
|
2744
|
+
this.startWebRTC();
|
|
2745
|
+
}
|
|
2746
|
+
selectMicrophone(micID) {
|
|
2747
|
+
var _a;
|
|
2748
|
+
for (let i = 0; i < this._microphoneList.getSize(); i++) {
|
|
2749
|
+
if (this._microphoneList.get(i).getID() == micID) {
|
|
2750
|
+
this._selectedMicrophone = this._microphoneList.get(i);
|
|
2751
|
+
(_a = this._main.getStorageManager()) === null || _a === void 0 ? void 0 : _a.saveField("microphoneID", this._selectedMicrophone.getID());
|
|
2752
|
+
break;
|
|
2753
|
+
}
|
|
2754
|
+
}
|
|
2755
|
+
this.closeStream();
|
|
2756
|
+
this._constraints.audio = {
|
|
2757
|
+
deviceId: this._selectedMicrophone.getID()
|
|
2758
|
+
};
|
|
2759
|
+
this.startWebRTC();
|
|
2760
|
+
}
|
|
2761
|
+
pickCamera() {
|
|
2762
|
+
var _a, _b;
|
|
2763
|
+
for (let i = 0; i < this._cameraList.getSize(); i++) this._cameraList.get(i).setSelected(false);
|
|
2764
|
+
let savedCameraID = (_b = (_a = this._main.getStorageManager()) === null || _a === void 0 ? void 0 : _a.getField("cameraID")) !== null && _b !== void 0 ? _b : null;
|
|
2765
|
+
if (this._selectedCamera == null || savedCameraID == null) this._selectedCamera = this._cameraList.get(0);else this.selectCamera(savedCameraID);
|
|
2766
|
+
this._selectedCamera.setSelected(true);
|
|
2767
|
+
this._main.dispatchEvent("deviceListUpdate", {
|
|
2768
|
+
ref: this._main,
|
|
2769
|
+
cameraList: this._cameraList.getArray(),
|
|
2770
|
+
microphoneList: this._microphoneList.getArray()
|
|
2771
|
+
});
|
|
2772
|
+
return this._selectedCamera;
|
|
2773
|
+
}
|
|
2774
|
+
pickMicrophone() {
|
|
2775
|
+
var _a, _b;
|
|
2776
|
+
for (let i = 0; i < this._microphoneList.getSize(); i++) this._microphoneList.get(i).setSelected(false);
|
|
2777
|
+
let savedMicID = (_b = (_a = this._main.getStorageManager()) === null || _a === void 0 ? void 0 : _a.getField("microphoneID")) !== null && _b !== void 0 ? _b : null;
|
|
2778
|
+
if (this._selectedMicrophone == null || savedMicID == null) this._selectedMicrophone = this._microphoneList.get(0);else this.selectMicrophone(savedMicID);
|
|
2779
|
+
this._selectedMicrophone.setSelected(true);
|
|
2780
|
+
this._main.dispatchEvent("deviceListUpdate", {
|
|
2781
|
+
ref: this._main,
|
|
2782
|
+
cameraList: this._cameraList.getArray(),
|
|
2783
|
+
microphoneList: this._microphoneList.getArray()
|
|
2784
|
+
});
|
|
2785
|
+
return this._selectedMicrophone;
|
|
2786
|
+
}
|
|
2787
|
+
muteMicrophone(microphoneState) {
|
|
2788
|
+
if (this._publishState == exports.PublishState.PUBLISHED) {
|
|
2789
|
+
if (this._stream !== null) {
|
|
2790
|
+
if (microphoneState) {
|
|
2791
|
+
this._logger.success(this, "WebRTCStreamer :: Unmuting microphone");
|
|
2792
|
+
} else {
|
|
2793
|
+
this._logger.success(this, "WebRTCStreamer :: Muting microphone");
|
|
2794
|
+
}
|
|
2795
|
+
for (let i = 0; i < this._stream.getAudioTracks().length; i++) this._stream.getAudioTracks()[i].enabled = microphoneState;
|
|
2796
|
+
this._isMicrophoneMuted = !microphoneState;
|
|
2797
|
+
} else {
|
|
2798
|
+
this._logger.warning(this, "WebRTCStreamer :: Stream object not present!");
|
|
2799
|
+
}
|
|
2800
|
+
} else {
|
|
2801
|
+
this._logger.warning(this, "WebRTCStreamer :: Not ready to change microphone");
|
|
2802
|
+
}
|
|
2803
|
+
}
|
|
2804
|
+
onDescriptionError(error) {
|
|
2805
|
+
this._logger.info(this, "WebRTCStreamer :: onDescriptionError: " + JSON.stringify(error));
|
|
2806
|
+
}
|
|
2807
|
+
onIceCandidate(event) {
|
|
2808
|
+
if (event.candidate !== null) ;
|
|
2809
|
+
}
|
|
2810
|
+
closeStream() {
|
|
2811
|
+
if (this._stream) {
|
|
2812
|
+
this._stream.getTracks().forEach(function (track) {
|
|
2813
|
+
track.stop();
|
|
2814
|
+
});
|
|
2815
|
+
}
|
|
2816
|
+
this._soundMeter.detach();
|
|
2817
|
+
if (this._peerConnection !== undefined && this._peerConnection !== null) this._peerConnection.close();
|
|
2818
|
+
this.setPublishState(exports.PublishState.UNPUBLISHED);
|
|
2819
|
+
}
|
|
2820
|
+
getCurrentCamera() {
|
|
2821
|
+
return this._selectedCamera;
|
|
2822
|
+
}
|
|
2823
|
+
getCurrentMicrophone() {
|
|
2824
|
+
return this._selectedMicrophone;
|
|
2825
|
+
}
|
|
2826
|
+
setPublishState(newState) {
|
|
2827
|
+
this._publishState = newState;
|
|
2828
|
+
this._main.dispatchEvent("publishStateChange", {
|
|
2829
|
+
ref: this._main,
|
|
2830
|
+
state: this._publishState
|
|
2831
|
+
});
|
|
2832
|
+
}
|
|
2833
|
+
getCameraList() {
|
|
2834
|
+
return this._cameraList.getArray();
|
|
2835
|
+
}
|
|
2836
|
+
getMicrophoneList() {
|
|
2837
|
+
return this._microphoneList.getArray();
|
|
2838
|
+
}
|
|
2839
|
+
getPlayer() {
|
|
2840
|
+
return this._selectedPlayer;
|
|
2841
|
+
}
|
|
2842
|
+
destroy() {
|
|
2843
|
+
var _a;
|
|
2844
|
+
this.closeStream();
|
|
2845
|
+
(_a = this._selectedPlayer) === null || _a === void 0 ? void 0 : _a.clear();
|
|
2846
|
+
this._selectedPlayer = null;
|
|
2847
|
+
this._main.removeEventListener("serverConnect", this.onServerConnect);
|
|
2848
|
+
document.removeEventListener("visibilitychange", this.visibilityChange);
|
|
2849
|
+
window.removeEventListener("blur", this.onWindowBlur);
|
|
2850
|
+
window.removeEventListener("focus", this.onWindowFocus);
|
|
2851
|
+
}
|
|
2852
|
+
}
|
|
2853
|
+
|
|
2854
|
+
var ConnectionState;
|
|
2855
|
+
(function (ConnectionState) {
|
|
2856
|
+
ConnectionState[ConnectionState["NOT_INITIALIZED"] = 0] = "NOT_INITIALIZED";
|
|
2857
|
+
ConnectionState[ConnectionState["STARTED"] = 1] = "STARTED";
|
|
2858
|
+
ConnectionState[ConnectionState["CONNECTING"] = 2] = "CONNECTING";
|
|
2859
|
+
ConnectionState[ConnectionState["CONNECTED"] = 3] = "CONNECTED";
|
|
2860
|
+
ConnectionState[ConnectionState["CLOSED"] = 4] = "CLOSED";
|
|
2861
|
+
ConnectionState[ConnectionState["FAILED"] = 5] = "FAILED";
|
|
2862
|
+
})(ConnectionState || (ConnectionState = {}));
|
|
2863
|
+
|
|
2864
|
+
class AbstractSocket {
|
|
2865
|
+
constructor() {
|
|
2866
|
+
this.CONNECTION_TIMEOUT = 5;
|
|
2867
|
+
this.isBinary = true;
|
|
2868
|
+
this._connectionState = ConnectionState.NOT_INITIALIZED;
|
|
2869
|
+
this._messageCount = 0;
|
|
2870
|
+
this._disconnectedByUser = false;
|
|
2871
|
+
this._isConnected = false;
|
|
2872
|
+
this._sequenceNumber = -1;
|
|
2873
|
+
}
|
|
2874
|
+
startConnection() {
|
|
2875
|
+
this._disconnectedByUser = false;
|
|
2876
|
+
this._messageCount = 0;
|
|
2877
|
+
this._isConnected = false;
|
|
2878
|
+
this._disconnectedByUser = false;
|
|
2879
|
+
this._connectionState = ConnectionState.CONNECTING;
|
|
2880
|
+
this.socket = new WebSocket(this.socketURL);
|
|
2881
|
+
if (this.isBinary) this.socket.binaryType = "arraybuffer";
|
|
2882
|
+
this.socket.onopen = event => {
|
|
2883
|
+
clearTimeout(this._connectionTimeout);
|
|
2884
|
+
this._sequenceNumber++;
|
|
2885
|
+
this._connectionState = ConnectionState.CONNECTED;
|
|
2886
|
+
this.onSocketOpen(event);
|
|
2887
|
+
};
|
|
2888
|
+
this.socket.onmessage = event => {
|
|
2889
|
+
this._messageCount++;
|
|
2890
|
+
this.onSocketMessage(event);
|
|
2891
|
+
};
|
|
2892
|
+
this.socket.onclose = event => {
|
|
2893
|
+
clearTimeout(this._connectionTimeout);
|
|
2894
|
+
if (this._connectionState == ConnectionState.CONNECTED) {
|
|
2895
|
+
this._connectionState = ConnectionState.CLOSED;
|
|
2896
|
+
this.onSocketClose(event);
|
|
2897
|
+
} else {
|
|
2898
|
+
this._connectionState = ConnectionState.FAILED;
|
|
2899
|
+
}
|
|
2900
|
+
};
|
|
2901
|
+
this.socket.onerror = event => {
|
|
2902
|
+
clearTimeout(this._connectionTimeout);
|
|
2903
|
+
if (this._connectionState == ConnectionState.CONNECTING) this.onSocketError(event);
|
|
2904
|
+
if (this._connectionState == ConnectionState.CONNECTED) {
|
|
2905
|
+
try {
|
|
2906
|
+
this.socket.close();
|
|
2907
|
+
} catch (error) {}
|
|
2908
|
+
}
|
|
2909
|
+
};
|
|
2910
|
+
this._connectionTimeout = setTimeout(() => {
|
|
2911
|
+
try {
|
|
2912
|
+
this.socket.close();
|
|
2913
|
+
} catch (error) {}
|
|
2914
|
+
if (this._connectionState == ConnectionState.CONNECTING) {
|
|
2915
|
+
this._connectionState = ConnectionState.FAILED;
|
|
2916
|
+
this.onSocketError(new ErrorEvent("connectionTimeout"));
|
|
2917
|
+
}
|
|
2918
|
+
}, this.CONNECTION_TIMEOUT * 1000);
|
|
2919
|
+
}
|
|
2920
|
+
onSocketOpen(event) {}
|
|
2921
|
+
onSocketClose(event) {}
|
|
2922
|
+
onSocketMessage(event) {}
|
|
2923
|
+
onSocketError(event) {}
|
|
2924
|
+
onError(error) {}
|
|
2925
|
+
sendData(data) {
|
|
2926
|
+
if (this._connectionState == ConnectionState.CONNECTED) {
|
|
2927
|
+
if (this.socket !== null) {
|
|
2928
|
+
if (data !== undefined && data !== null) {
|
|
2929
|
+
this.socket.send(data);
|
|
2930
|
+
return;
|
|
2931
|
+
} else this.onError("no data to send");
|
|
2932
|
+
}
|
|
2933
|
+
}
|
|
2934
|
+
this.onError("socket not connected");
|
|
2935
|
+
}
|
|
2936
|
+
getConnectionState() {
|
|
2937
|
+
return this._connectionState;
|
|
2938
|
+
}
|
|
2939
|
+
disconnect(byUser = true) {
|
|
2940
|
+
this._isConnected = false;
|
|
2941
|
+
this._connectionState = ConnectionState.CLOSED;
|
|
2942
|
+
if (byUser) {
|
|
2943
|
+
this._logger.warning(this, "Disconnected by user");
|
|
2944
|
+
this._disconnectedByUser = byUser;
|
|
2945
|
+
}
|
|
2946
|
+
if (this.socket != null) {
|
|
2947
|
+
this.socket.onopen = null;
|
|
2948
|
+
this.socket.onmessage = null;
|
|
2949
|
+
this.socket.onclose = null;
|
|
2950
|
+
this.socket.onerror = null;
|
|
2951
|
+
this.socket.close();
|
|
2952
|
+
}
|
|
2953
|
+
}
|
|
2954
|
+
destroy() {
|
|
2955
|
+
if (this.socket !== undefined && this.socket !== null) {
|
|
2956
|
+
this.socket.onopen = null;
|
|
2957
|
+
this.socket.onmessage = null;
|
|
2958
|
+
this.socket.onclose = null;
|
|
2959
|
+
this.socket.onerror = null;
|
|
2960
|
+
this.socket.close();
|
|
2961
|
+
}
|
|
2962
|
+
this._connectionState = ConnectionState.CLOSED;
|
|
2963
|
+
}
|
|
2964
|
+
getSocketURL() {
|
|
2965
|
+
return this.socketURL;
|
|
2966
|
+
}
|
|
2967
|
+
}
|
|
2968
|
+
|
|
2969
|
+
class WowzaConnection extends AbstractSocket {
|
|
2970
|
+
constructor(main, networkController) {
|
|
2971
|
+
super();
|
|
2972
|
+
this._logger = main.getLogger();
|
|
2973
|
+
this._main = main;
|
|
2974
|
+
this._networkController = networkController;
|
|
2975
|
+
this.initialize();
|
|
2976
|
+
}
|
|
2977
|
+
initialize() {
|
|
2978
|
+
this._logger.info(this, "Starting new connection with a storm server");
|
|
2979
|
+
this.pickServerFromList(this._main.getConfigManager().getStreamData().getServerList());
|
|
2980
|
+
if (this._currServer != null) {
|
|
2981
|
+
this.socketURL = this.createURL(this._currServer);
|
|
2982
|
+
this._logger.info(this, `Starting WebSocket connection with: ${this.socketURL}`);
|
|
2983
|
+
this._main.dispatchEvent("serverConnectionInitiate", {
|
|
2984
|
+
ref: this._main,
|
|
2985
|
+
serverURL: this.socketURL
|
|
2986
|
+
});
|
|
2987
|
+
if (this._main.getConfigManager().getIfDemoMode()) {
|
|
2988
|
+
this._logger.warning(this, "Player is in demo mode, and will not connect with a server!");
|
|
2989
|
+
this._main.dispatchEvent("authorizationComplete", {
|
|
2990
|
+
ref: this._main
|
|
2991
|
+
});
|
|
2992
|
+
return;
|
|
2993
|
+
}
|
|
2994
|
+
this.startConnection();
|
|
2995
|
+
} else this._logger.error(this, "Connection with the server could not be initialized!");
|
|
2996
|
+
}
|
|
2997
|
+
onSocketOpen(event) {
|
|
2998
|
+
this._logger.success(this, `Connection with the server has been established!`);
|
|
2999
|
+
this._main.dispatchEvent("serverConnect", {
|
|
3000
|
+
ref: this._main,
|
|
3001
|
+
serverURL: this.socketURL,
|
|
3002
|
+
sequenceNum: this._sequenceNumber
|
|
3003
|
+
});
|
|
3004
|
+
this._isConnected = true;
|
|
3005
|
+
}
|
|
3006
|
+
onSocketError(event) {
|
|
3007
|
+
this._isConnected = false;
|
|
3008
|
+
if (!this._disconnectedByUser) {
|
|
3009
|
+
this._logger.error(this, `Connection with the server failed`);
|
|
3010
|
+
this._main.dispatchEvent("serverConnectionError", {
|
|
3011
|
+
ref: this._main,
|
|
3012
|
+
serverURL: this.socketURL,
|
|
3013
|
+
restart: this._main.getConfigManager().getSettingsData().getIfRestartOnError(),
|
|
3014
|
+
sequenceNum: this._sequenceNumber
|
|
3015
|
+
});
|
|
3016
|
+
if (this._isConnected == false) {
|
|
3017
|
+
this._currServer.setAsFaild(true);
|
|
3018
|
+
this.initiateReconnect();
|
|
3019
|
+
}
|
|
3020
|
+
}
|
|
3021
|
+
}
|
|
3022
|
+
onSocketClose(event) {
|
|
3023
|
+
this._isConnected = false;
|
|
3024
|
+
if (!this._disconnectedByUser) {
|
|
3025
|
+
this._logger.error(this, `Connection with the server has been closed`);
|
|
3026
|
+
this._main.dispatchEvent("serverDisconnect", {
|
|
3027
|
+
ref: this._main,
|
|
3028
|
+
serverURL: this.socketURL,
|
|
3029
|
+
restart: this._main.getConfigManager().getSettingsData().getIfRestartOnError(),
|
|
3030
|
+
sequenceNum: this._sequenceNumber
|
|
3031
|
+
});
|
|
3032
|
+
this.initiateReconnect();
|
|
3033
|
+
} else this._logger.warning(this, `Force disconnect from server!`);
|
|
3034
|
+
}
|
|
3035
|
+
onSocketMessage(event) {
|
|
3036
|
+
this._networkController.onMessage(event);
|
|
3037
|
+
}
|
|
3038
|
+
createURL(serverItem) {
|
|
3039
|
+
let url = "";
|
|
3040
|
+
url += serverItem.getIfSSL() ? "wss://" : "ws://";
|
|
3041
|
+
url += serverItem.getHost();
|
|
3042
|
+
url += ":" + serverItem.getPort();
|
|
3043
|
+
url += "/webrtc-session.json";
|
|
3044
|
+
return url;
|
|
3045
|
+
}
|
|
3046
|
+
initiateReconnect() {
|
|
3047
|
+
const shouldReconnect = this._main.getConfigManager().getSettingsData().getIfRestartOnError();
|
|
3048
|
+
const reconnectTime = this._main.getConfigManager().getSettingsData().getReconnectTime();
|
|
3049
|
+
if (this._disconnectedByUser) {
|
|
3050
|
+
return;
|
|
3051
|
+
}
|
|
3052
|
+
if (shouldReconnect) {
|
|
3053
|
+
if (this._reconnectTimer != null) clearTimeout(this._reconnectTimer);
|
|
3054
|
+
this._reconnectTimer = setTimeout(() => {
|
|
3055
|
+
this.pickServerFromList(this._main.getConfigManager().getStreamData().getServerList());
|
|
3056
|
+
if (this._currServer != null) {
|
|
3057
|
+
this._logger.info(this, `Will reconnect to the server in ${reconnectTime} seconds...`);
|
|
3058
|
+
this.socketURL = this.createURL(this._currServer);
|
|
3059
|
+
this._logger.info(this, `Starting WebSocket connection with: ${this.socketURL}`);
|
|
3060
|
+
this._main.dispatchEvent("serverConnectionInitiate", {
|
|
3061
|
+
ref: this._main,
|
|
3062
|
+
serverURL: this.socketURL
|
|
3063
|
+
});
|
|
3064
|
+
this.startConnection();
|
|
3065
|
+
}
|
|
3066
|
+
}, reconnectTime * 1000);
|
|
3067
|
+
}
|
|
3068
|
+
}
|
|
3069
|
+
pickServerFromList(serverList) {
|
|
3070
|
+
let server = null;
|
|
3071
|
+
for (let i = 0; i < serverList.length; i++) {
|
|
3072
|
+
if (!serverList[i].getIfFaild()) {
|
|
3073
|
+
server = serverList[i];
|
|
3074
|
+
break;
|
|
3075
|
+
}
|
|
3076
|
+
}
|
|
3077
|
+
if (server == null) {
|
|
3078
|
+
this._logger.error(this, "All connections failed!");
|
|
3079
|
+
this._main.dispatchEvent("allConnectionsFailed", {
|
|
3080
|
+
ref: this._main,
|
|
3081
|
+
mode: "none"
|
|
3082
|
+
});
|
|
3083
|
+
this._currServer = null;
|
|
3084
|
+
return;
|
|
3085
|
+
} else {
|
|
3086
|
+
this._currServer = server;
|
|
3087
|
+
}
|
|
3088
|
+
}
|
|
3089
|
+
isConnectionActive() {
|
|
3090
|
+
return this._isConnected;
|
|
3091
|
+
}
|
|
3092
|
+
getCurrentServer() {
|
|
3093
|
+
return this._currServer;
|
|
3094
|
+
}
|
|
3095
|
+
destroy() {
|
|
3096
|
+
super.destroy();
|
|
3097
|
+
if (this._reconnectTimer != null) clearTimeout(this._reconnectTimer);
|
|
3098
|
+
}
|
|
3099
|
+
}
|
|
3100
|
+
|
|
3101
|
+
class NetworkController {
|
|
3102
|
+
constructor(main) {
|
|
3103
|
+
this._currentStreamKey = "none";
|
|
3104
|
+
this._lastState = "";
|
|
3105
|
+
this.onServerConnect = () => {};
|
|
3106
|
+
this.onServerDisconnect = () => {
|
|
3107
|
+
this._lastState = "none";
|
|
3108
|
+
};
|
|
3109
|
+
this.onMessage = event => {
|
|
3110
|
+
var _a;
|
|
3111
|
+
(_a = this._main.getPlaybackController()) === null || _a === void 0 ? void 0 : _a.onSocketMessage(event.data);
|
|
3112
|
+
};
|
|
3113
|
+
this._main = main;
|
|
3114
|
+
this._logger = main.getLogger();
|
|
3115
|
+
this._main.addEventListener("serverConnect", this.onServerConnect, false);
|
|
3116
|
+
this._main.addEventListener("serverDisconnect", this.onServerDisconnect, false);
|
|
3117
|
+
}
|
|
3118
|
+
initialize() {
|
|
3119
|
+
if (this._connection != null) {
|
|
3120
|
+
if (this._connection.getConnectionState() == ConnectionState.CONNECTING || this._connection.getConnectionState() == ConnectionState.CONNECTED) {
|
|
3121
|
+
this._logger.info(this, "Connection is alive, not doing anything!");
|
|
3122
|
+
} else {
|
|
3123
|
+
this._logger.info(this, "Connection is dead, restarting!");
|
|
3124
|
+
this._connection.startConnection();
|
|
3125
|
+
}
|
|
3126
|
+
}
|
|
3127
|
+
}
|
|
3128
|
+
start() {
|
|
3129
|
+
this._connection = new WowzaConnection(this._main, this);
|
|
3130
|
+
}
|
|
3131
|
+
stop() {
|
|
3132
|
+
this._connection.disconnect(true);
|
|
3133
|
+
this._lastState = "";
|
|
3134
|
+
}
|
|
3135
|
+
sendMessage(message) {
|
|
3136
|
+
if (this._connection.isConnectionActive()) {
|
|
3137
|
+
this._connection.sendData(message);
|
|
3138
|
+
}
|
|
3139
|
+
}
|
|
3140
|
+
getConnection() {
|
|
3141
|
+
return this._connection;
|
|
3142
|
+
}
|
|
3143
|
+
getCurrentStreamKey() {
|
|
3144
|
+
return this._currentStreamKey;
|
|
3145
|
+
}
|
|
3146
|
+
}
|
|
3147
|
+
|
|
3148
|
+
class StormStreamer extends EventDispatcher {
|
|
3149
|
+
constructor(streamConfig, autoInitialize = false) {
|
|
3150
|
+
super();
|
|
3151
|
+
this.DEV_MODE = true;
|
|
3152
|
+
this.STREAMER_VERSION = "0.9.0-beta.0";
|
|
3153
|
+
this.COMPILE_DATE = "11/28/2024, 9:22:53 AM";
|
|
3154
|
+
this.STREAMER_BRANCH = "Experimental";
|
|
3155
|
+
this.STREAMER_PROTOCOL_VERSION = 1;
|
|
3156
|
+
this._initialized = false;
|
|
3157
|
+
if (typeof window === 'undefined' || !window.document || !window.document.createElement) {
|
|
3158
|
+
console.error(`StormLibrary Creation Error - No "window" element in the provided context!`);
|
|
3159
|
+
return;
|
|
3160
|
+
}
|
|
3161
|
+
if (this.DEV_MODE && !('StormStreamerArray' in window)) {
|
|
3162
|
+
window.StormStreamerArray = [];
|
|
3163
|
+
}
|
|
3164
|
+
window.StormStreamerArray.push(this);
|
|
3165
|
+
this._streamerID = StormStreamer.NEXT_STREAMER_ID++;
|
|
3166
|
+
if (streamConfig == null) return;
|
|
3167
|
+
this.setStreamConfig(streamConfig);
|
|
3168
|
+
if (autoInitialize) this.initialize();
|
|
3169
|
+
}
|
|
3170
|
+
initialize() {
|
|
3171
|
+
if (this._isRemoved) return;
|
|
3172
|
+
if (this._configManager == null) throw Error("Stream Config was not provided for this library! A properly configured object must be provided through the constructor or via the setConfig method before using the initialize() method.");
|
|
3173
|
+
this._storageManager = new StorageManager(this);
|
|
3174
|
+
this._stageController = new StageController(this);
|
|
3175
|
+
this._networkController = new NetworkController(this);
|
|
3176
|
+
this._playbackController = new PlaybackController(this);
|
|
3177
|
+
this._clientUser = new ClientUser();
|
|
3178
|
+
this._initialized = true;
|
|
3179
|
+
this.dispatchEvent("streamerReady", {
|
|
3180
|
+
ref: this
|
|
3181
|
+
});
|
|
3182
|
+
}
|
|
3183
|
+
setStreamConfig(streamConfig) {
|
|
3184
|
+
if (this._isRemoved) return;
|
|
3185
|
+
const copiedStreamConfig = JSON.parse(JSON.stringify(streamConfig));
|
|
3186
|
+
if (this._configManager == null) {
|
|
3187
|
+
this._configManager = new ConfigManager(copiedStreamConfig);
|
|
3188
|
+
this._logger = new Logger(this._configManager.getSettingsData().getDebugData(), this);
|
|
3189
|
+
this._logger.info(this, "StreamerID: " + this._streamerID);
|
|
3190
|
+
this._logger.info(this, "Version: " + this.STREAMER_VERSION + " | Compile Date: " + this.COMPILE_DATE + " | Branch: " + this.STREAMER_BRANCH);
|
|
3191
|
+
this._logger.info(this, "UserCapabilities :: Browser: " + UserCapabilities.getBrowserName() + " " + UserCapabilities.getBrowserVersion());
|
|
3192
|
+
this._logger.info(this, "UserCapabilities :: Operating System: " + UserCapabilities.getOS() + " " + UserCapabilities.getOSVersion());
|
|
3193
|
+
this._logger.info(this, "UserCapabilities :: isMobile: " + UserCapabilities.isMobile());
|
|
3194
|
+
this._logger.info(this, "UserCapabilities :: hasMSESupport: " + UserCapabilities.hasMSESupport());
|
|
3195
|
+
this._logger.info(this, "UserCapabilities :: hasWebSocketSupport: " + UserCapabilities.hasWebSocketsSupport());
|
|
3196
|
+
this._logger.info(this, "UserCapabilities :: hasWebRTCSupport: " + UserCapabilities.hasWebRTCSupport());
|
|
3197
|
+
this._configManager.print(this._logger);
|
|
3198
|
+
} else {
|
|
3199
|
+
this._logger.info(this, "StreamConfig has been overwritten, dispatching streamConfigChanged!");
|
|
3200
|
+
this._configManager = new ConfigManager(copiedStreamConfig);
|
|
3201
|
+
this._configManager.print(this._logger);
|
|
3202
|
+
this.dispatchEvent("streamConfigChange", {
|
|
3203
|
+
ref: this,
|
|
3204
|
+
newConfig: this._configManager
|
|
3205
|
+
});
|
|
3206
|
+
}
|
|
3207
|
+
}
|
|
3208
|
+
stop() {}
|
|
3209
|
+
isConnected() {
|
|
3210
|
+
var _a, _b;
|
|
3211
|
+
return (_b = (_a = this._networkController) === null || _a === void 0 ? void 0 : _a.getConnection().isConnectionActive()) !== null && _b !== void 0 ? _b : false;
|
|
3212
|
+
}
|
|
3213
|
+
attachToContainer(container) {
|
|
3214
|
+
var _a, _b;
|
|
3215
|
+
let result = false;
|
|
3216
|
+
if (this._initialized) return (_b = (_a = this._stageController) === null || _a === void 0 ? void 0 : _a.attachToParent(container)) !== null && _b !== void 0 ? _b : false;
|
|
3217
|
+
return result;
|
|
3218
|
+
}
|
|
3219
|
+
detachFromContainer() {
|
|
3220
|
+
var _a, _b;
|
|
3221
|
+
let result = false;
|
|
3222
|
+
if (this._initialized) return (_b = (_a = this._stageController) === null || _a === void 0 ? void 0 : _a.detachFromParent()) !== null && _b !== void 0 ? _b : false;
|
|
3223
|
+
return result;
|
|
3224
|
+
}
|
|
3225
|
+
getContainer() {
|
|
3226
|
+
var _a, _b;
|
|
3227
|
+
return (_b = (_a = this._stageController) === null || _a === void 0 ? void 0 : _a.getParentElement()) !== null && _b !== void 0 ? _b : null;
|
|
3228
|
+
}
|
|
3229
|
+
mute() {
|
|
3230
|
+
if (this._stageController != null) {
|
|
3231
|
+
if (this._stageController.getScreenElement() != null) {
|
|
3232
|
+
this._stageController.getScreenElement().setMuted(true);
|
|
3233
|
+
return;
|
|
3234
|
+
}
|
|
3235
|
+
}
|
|
3236
|
+
this._configManager.getSettingsData().getAudioData().muted = true;
|
|
3237
|
+
}
|
|
3238
|
+
unmute() {
|
|
3239
|
+
if (this._stageController != null) {
|
|
3240
|
+
if (this._stageController.getScreenElement() != null) {
|
|
3241
|
+
this._stageController.getScreenElement().setMuted(false);
|
|
3242
|
+
return;
|
|
3243
|
+
}
|
|
3244
|
+
}
|
|
3245
|
+
this._configManager.getSettingsData().getAudioData().muted = false;
|
|
3246
|
+
}
|
|
3247
|
+
isMute() {
|
|
3248
|
+
var _a, _b, _c, _d;
|
|
3249
|
+
return (_d = (_c = (_b = (_a = this._stageController) === null || _a === void 0 ? void 0 : _a.getScreenElement()) === null || _b === void 0 ? void 0 : _b.getIfMuted()) !== null && _c !== void 0 ? _c : this._configManager.getSettingsData().getAudioData().muted) !== null && _d !== void 0 ? _d : false;
|
|
3250
|
+
}
|
|
3251
|
+
toggleMute() {
|
|
3252
|
+
const isMuted = this.isMute();
|
|
3253
|
+
if (isMuted) {
|
|
3254
|
+
this.unmute();
|
|
3255
|
+
} else {
|
|
3256
|
+
this.mute();
|
|
3257
|
+
}
|
|
3258
|
+
return !isMuted;
|
|
3259
|
+
}
|
|
3260
|
+
setVolume(newVolume) {
|
|
3261
|
+
var _a, _b;
|
|
3262
|
+
if (((_b = (_a = this._stageController) === null || _a === void 0 ? void 0 : _a.getScreenElement()) === null || _b === void 0 ? void 0 : _b.setVolume(newVolume)) !== undefined) {
|
|
3263
|
+
return;
|
|
3264
|
+
}
|
|
3265
|
+
this._configManager.getSettingsData().getAudioData().startVolume = newVolume;
|
|
3266
|
+
}
|
|
3267
|
+
getVolume() {
|
|
3268
|
+
var _a, _b, _c;
|
|
3269
|
+
return (_c = (_b = (_a = this._stageController) === null || _a === void 0 ? void 0 : _a.getScreenElement()) === null || _b === void 0 ? void 0 : _b.getVolume()) !== null && _c !== void 0 ? _c : this._configManager.getSettingsData().getAudioData().startVolume;
|
|
3270
|
+
}
|
|
3271
|
+
getCameraList() {
|
|
3272
|
+
var _a, _b;
|
|
3273
|
+
return (_b = (_a = this._playbackController) === null || _a === void 0 ? void 0 : _a.getCameraList()) !== null && _b !== void 0 ? _b : null;
|
|
3274
|
+
}
|
|
3275
|
+
getMicrophoneList() {
|
|
3276
|
+
var _a, _b;
|
|
3277
|
+
return (_b = (_a = this._playbackController) === null || _a === void 0 ? void 0 : _a.getMicrophoneList()) !== null && _b !== void 0 ? _b : null;
|
|
3278
|
+
}
|
|
3279
|
+
setCamera(cameraID) {
|
|
3280
|
+
var _a;
|
|
3281
|
+
(_a = this._playbackController) === null || _a === void 0 ? void 0 : _a.selectCamera(cameraID);
|
|
3282
|
+
}
|
|
3283
|
+
setMicrophone(microphoneID) {
|
|
3284
|
+
var _a;
|
|
3285
|
+
(_a = this._playbackController) === null || _a === void 0 ? void 0 : _a.selectMicrophone(microphoneID);
|
|
3286
|
+
}
|
|
3287
|
+
getCurrentCamera() {
|
|
3288
|
+
return this._playbackController.getCurrentCamera();
|
|
3289
|
+
}
|
|
3290
|
+
getCurrentMicrophone() {
|
|
3291
|
+
return this._playbackController.getCurrentMicrophone();
|
|
3292
|
+
}
|
|
3293
|
+
muteMicrophone(microphoneState) {
|
|
3294
|
+
var _a;
|
|
3295
|
+
(_a = this._playbackController) === null || _a === void 0 ? void 0 : _a.muteMicrophone(microphoneState);
|
|
3296
|
+
}
|
|
3297
|
+
publish(streamKey) {
|
|
3298
|
+
var _a;
|
|
3299
|
+
(_a = this._playbackController) === null || _a === void 0 ? void 0 : _a.publish(streamKey);
|
|
3300
|
+
}
|
|
3301
|
+
unpublish() {
|
|
3302
|
+
var _a;
|
|
3303
|
+
(_a = this._playbackController) === null || _a === void 0 ? void 0 : _a.unpublish();
|
|
3304
|
+
}
|
|
3305
|
+
setSize(width, height) {
|
|
3306
|
+
if (this._initialized) this._stageController.setSize(width, height);else {
|
|
3307
|
+
const parsedWidth = NumberUtilities.parseValue(width);
|
|
3308
|
+
const parsedHeight = NumberUtilities.parseValue(height);
|
|
3309
|
+
this._configManager.getSettingsData().getVideoData().videoWidthValue = parsedWidth.value;
|
|
3310
|
+
this._configManager.getSettingsData().getVideoData().videoWidthInPixels = parsedWidth.isPixels;
|
|
3311
|
+
this._configManager.getSettingsData().getVideoData().videoHeightValue = parsedHeight.value;
|
|
3312
|
+
this._configManager.getSettingsData().getVideoData().videoHeightInPixels = parsedHeight.isPixels;
|
|
3313
|
+
}
|
|
3314
|
+
}
|
|
3315
|
+
setWidth(width) {
|
|
3316
|
+
if (this._initialized) this._stageController.setWidth(width);else {
|
|
3317
|
+
const parsedWidth = NumberUtilities.parseValue(width);
|
|
3318
|
+
this._configManager.getSettingsData().getVideoData().videoWidthValue = parsedWidth.value;
|
|
3319
|
+
this._configManager.getSettingsData().getVideoData().videoWidthInPixels = parsedWidth.isPixels;
|
|
3320
|
+
}
|
|
3321
|
+
}
|
|
3322
|
+
setHeight(height) {
|
|
3323
|
+
if (this._initialized) this._stageController.setHeight(height);else {
|
|
3324
|
+
const parsedHeight = NumberUtilities.parseValue(height);
|
|
3325
|
+
this._configManager.getSettingsData().getVideoData().videoHeightValue = parsedHeight.value;
|
|
3326
|
+
this._configManager.getSettingsData().getVideoData().videoHeightInPixels = parsedHeight.isPixels;
|
|
3327
|
+
}
|
|
3328
|
+
}
|
|
3329
|
+
getWidth() {
|
|
3330
|
+
if (this._initialized) return this._stageController.getContainerWidth();else {
|
|
3331
|
+
if (this._configManager.getSettingsData().getVideoData().videoWidthInPixels) return this._configManager.getSettingsData().getVideoData().videoWidthValue;
|
|
3332
|
+
}
|
|
3333
|
+
return 0;
|
|
3334
|
+
}
|
|
3335
|
+
getHeight() {
|
|
3336
|
+
if (this._initialized) return this._stageController.getContainerHeight();else {
|
|
3337
|
+
if (this._configManager.getSettingsData().getVideoData().videoHeightInPixels) return this._configManager.getSettingsData().getVideoData().videoHeightValue;
|
|
3338
|
+
}
|
|
3339
|
+
return 0;
|
|
3340
|
+
}
|
|
3341
|
+
setScalingMode(newMode) {
|
|
3342
|
+
if (this._stageController) {
|
|
3343
|
+
this._stageController.setScalingMode(newMode);
|
|
3344
|
+
} else {
|
|
3345
|
+
this._configManager.getSettingsData().getVideoData().scalingMode = newMode;
|
|
3346
|
+
}
|
|
3347
|
+
}
|
|
3348
|
+
getScalingMode() {
|
|
3349
|
+
if (this._stageController) {
|
|
3350
|
+
return this._stageController.getScalingMode();
|
|
3351
|
+
} else {
|
|
3352
|
+
return this._configManager.getSettingsData().getVideoData().scalingMode;
|
|
3353
|
+
}
|
|
3354
|
+
}
|
|
3355
|
+
updateToSize() {
|
|
3356
|
+
if (this._initialized) {
|
|
3357
|
+
this._stageController.onResize();
|
|
3358
|
+
}
|
|
3359
|
+
}
|
|
3360
|
+
makeScreenshot() {
|
|
3361
|
+
let canvas = document.createElement('canvas');
|
|
3362
|
+
let context = canvas.getContext('2d');
|
|
3363
|
+
return new Promise(resolve => {
|
|
3364
|
+
if (this._stageController != null) {
|
|
3365
|
+
canvas.width = this._stageController.getScreenElement().getVideoElement().videoWidth;
|
|
3366
|
+
canvas.height = this._stageController.getScreenElement().getVideoElement().videoHeight;
|
|
3367
|
+
let element = this._stageController.getScreenElement().getVideoElement();
|
|
3368
|
+
if (context) {
|
|
3369
|
+
context.drawImage(element, 0, 0, canvas.width, canvas.height);
|
|
3370
|
+
canvas.toBlob(blob => {
|
|
3371
|
+
resolve(blob);
|
|
3372
|
+
}, 'image/png');
|
|
3373
|
+
} else {
|
|
3374
|
+
resolve(null);
|
|
3375
|
+
}
|
|
3376
|
+
} else {
|
|
3377
|
+
resolve(null);
|
|
3378
|
+
}
|
|
3379
|
+
});
|
|
3380
|
+
}
|
|
3381
|
+
enterFullScreen() {
|
|
3382
|
+
if (this._initialized && this._stageController) this._stageController.enterFullScreen();
|
|
3383
|
+
}
|
|
3384
|
+
exitFullScreen() {
|
|
3385
|
+
if (this._initialized && this._stageController) this._stageController.exitFullScreen();
|
|
3386
|
+
}
|
|
3387
|
+
isFullScreenMode() {
|
|
3388
|
+
if (this._initialized && this._stageController) return this._stageController.isFullScreenMode();
|
|
3389
|
+
return false;
|
|
3390
|
+
}
|
|
3391
|
+
getStreamerID() {
|
|
3392
|
+
return this._streamerID;
|
|
3393
|
+
}
|
|
3394
|
+
getLogger() {
|
|
3395
|
+
return this._logger;
|
|
3396
|
+
}
|
|
3397
|
+
getConfigManager() {
|
|
3398
|
+
return this._configManager;
|
|
3399
|
+
}
|
|
3400
|
+
getNetworkController() {
|
|
3401
|
+
return this._networkController;
|
|
3402
|
+
}
|
|
3403
|
+
getPlaybackController() {
|
|
3404
|
+
return this._playbackController;
|
|
3405
|
+
}
|
|
3406
|
+
getStageController() {
|
|
3407
|
+
return this._stageController;
|
|
3408
|
+
}
|
|
3409
|
+
getVideoElement() {
|
|
3410
|
+
var _a, _b, _c;
|
|
3411
|
+
return (_c = (_b = (_a = this._stageController) === null || _a === void 0 ? void 0 : _a.getScreenElement()) === null || _b === void 0 ? void 0 : _b.getVideoElement()) !== null && _c !== void 0 ? _c : null;
|
|
3412
|
+
}
|
|
3413
|
+
isInitialized() {
|
|
3414
|
+
return this._initialized;
|
|
3415
|
+
}
|
|
3416
|
+
getVersion() {
|
|
3417
|
+
return this.STREAMER_VERSION;
|
|
3418
|
+
}
|
|
3419
|
+
getBranch() {
|
|
3420
|
+
return this.STREAMER_BRANCH;
|
|
3421
|
+
}
|
|
3422
|
+
getStorageManager() {
|
|
3423
|
+
return this._storageManager;
|
|
3424
|
+
}
|
|
3425
|
+
dispatchEvent(eventName, event) {
|
|
3426
|
+
super.dispatchEvent(eventName, event);
|
|
3427
|
+
}
|
|
3428
|
+
destroy() {
|
|
3429
|
+
var _a, _b, _c;
|
|
3430
|
+
this._logger.warning(this, "Destroying library instance, bye, bye!");
|
|
3431
|
+
this._initialized = false;
|
|
3432
|
+
this._isRemoved = true;
|
|
3433
|
+
(_a = this._networkController) === null || _a === void 0 ? void 0 : _a.getConnection().destroy();
|
|
3434
|
+
(_b = this._stageController) === null || _b === void 0 ? void 0 : _b.destroy();
|
|
3435
|
+
(_c = this._playbackController) === null || _c === void 0 ? void 0 : _c.destroy();
|
|
3436
|
+
this.removeAllEventListeners();
|
|
3437
|
+
}
|
|
3438
|
+
}
|
|
3439
|
+
StormStreamer.NEXT_STREAMER_ID = 0;
|
|
3440
|
+
|
|
3441
|
+
function create(config) {
|
|
3442
|
+
return new StormStreamer(config);
|
|
3443
|
+
}
|
|
3444
|
+
|
|
3445
|
+
exports.StormStreamer = StormStreamer;
|
|
3446
|
+
exports.create = create;
|
|
3447
|
+
|
|
3448
|
+
}));
|