@arcware-cloud/pixelstreaming-websdk 1.2.14 → 1.2.15
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/index.cjs.js +343 -2
- package/index.esm.js +364 -20
- package/index.umd.js +343 -2
- package/package.json +2 -2
package/index.cjs.js
CHANGED
|
@@ -23351,7 +23351,7 @@ class ArcwareConfig extends lib_pixelstreamingfrontend_ue5_5_1.Config {
|
|
|
23351
23351
|
if (!config.initialSettings.ss)
|
|
23352
23352
|
config.initialSettings.ss = exports.DefaultUrl;
|
|
23353
23353
|
super(config);
|
|
23354
|
-
this.VERSION = "1.2.
|
|
23354
|
+
this.VERSION = "1.2.15";
|
|
23355
23355
|
this.settings = settings;
|
|
23356
23356
|
this.session = new Session_1.Session();
|
|
23357
23357
|
this._initialSettings = config.initialSettings;
|
|
@@ -23492,6 +23492,7 @@ exports.ArcwareInit = ArcwareInit;
|
|
|
23492
23492
|
|
|
23493
23493
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
23494
23494
|
exports.ArcwarePixelStreaming = void 0;
|
|
23495
|
+
const tslib_1 = __webpack_require__(655);
|
|
23495
23496
|
const shared_pixelstreaming_websdk_1 = __webpack_require__(7910);
|
|
23496
23497
|
const lib_pixelstreamingfrontend_ue5_5_1 = __webpack_require__(693);
|
|
23497
23498
|
const ApplyUrlHack_1 = __webpack_require__(4790);
|
|
@@ -23502,6 +23503,7 @@ const LoveLetters_1 = __webpack_require__(4572);
|
|
|
23502
23503
|
const ArcwareLogoLoader_1 = __webpack_require__(6469);
|
|
23503
23504
|
const MicrophoneOverlay_1 = __webpack_require__(3613);
|
|
23504
23505
|
const ConnectionIdentifier_1 = __webpack_require__(5999);
|
|
23506
|
+
const DiagnosticsCollector_1 = __webpack_require__(6478);
|
|
23505
23507
|
class ArcwarePixelStreaming extends lib_pixelstreamingfrontend_ue5_5_1.PixelStreaming {
|
|
23506
23508
|
/** Returns a list of WebSocketStates of all PixelStreaming Instances generated. */
|
|
23507
23509
|
get WebsocketStates() {
|
|
@@ -23549,6 +23551,9 @@ class ArcwarePixelStreaming extends lib_pixelstreamingfrontend_ue5_5_1.PixelStre
|
|
|
23549
23551
|
this.config = config;
|
|
23550
23552
|
this.loveLettersList = [];
|
|
23551
23553
|
this.microphoneOverlay = new MicrophoneOverlay_1.MicrophoneOverlay(this);
|
|
23554
|
+
this.diagnosticsCollector = new DiagnosticsCollector_1.DiagnosticsCollector({
|
|
23555
|
+
enableBandwidthProbe: false,
|
|
23556
|
+
});
|
|
23552
23557
|
// this.loveLettersContainer = null;
|
|
23553
23558
|
this.wrapWebSocketOnCloseHandler();
|
|
23554
23559
|
// Bind the event listener function to the class instance
|
|
@@ -23607,7 +23612,10 @@ class ArcwarePixelStreaming extends lib_pixelstreamingfrontend_ue5_5_1.PixelStre
|
|
|
23607
23612
|
*/
|
|
23608
23613
|
/** On version requested, the version of the WebSDK would be returned. */
|
|
23609
23614
|
onVersion(message) {
|
|
23610
|
-
|
|
23615
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
23616
|
+
const diagnostics = yield this.diagnosticsCollector.collect();
|
|
23617
|
+
this.send({ type: "version", version: this.config.VERSION, diagnostics });
|
|
23618
|
+
});
|
|
23611
23619
|
}
|
|
23612
23620
|
/** On ping the session creation timestamp will be updated. */
|
|
23613
23621
|
onPing(message) {
|
|
@@ -23939,6 +23947,339 @@ class ArcwarePixelStreaming extends lib_pixelstreamingfrontend_ue5_5_1.PixelStre
|
|
|
23939
23947
|
exports.ArcwarePixelStreaming = ArcwarePixelStreaming;
|
|
23940
23948
|
|
|
23941
23949
|
|
|
23950
|
+
/***/ }),
|
|
23951
|
+
|
|
23952
|
+
/***/ 6478:
|
|
23953
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
23954
|
+
|
|
23955
|
+
|
|
23956
|
+
/**
|
|
23957
|
+
* DiagnosticsCollector.ts
|
|
23958
|
+
* Lightweight, privacy-aware client diagnostics for troubleshooting + analytics.
|
|
23959
|
+
* WebRTC collection intentionally omitted (to add later).
|
|
23960
|
+
*
|
|
23961
|
+
* Notes:
|
|
23962
|
+
* - Some fields are best-effort due to browser restrictions; they're nullable.
|
|
23963
|
+
* - Bandwidth probe requires a small binary served with:
|
|
23964
|
+
* Content-Type: application/octet-stream
|
|
23965
|
+
* Content-Encoding: identity
|
|
23966
|
+
* Cache-Control: no-store
|
|
23967
|
+
* Default location: /diag/probe.bin
|
|
23968
|
+
*/
|
|
23969
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
23970
|
+
exports.DiagnosticsCollector = void 0;
|
|
23971
|
+
const tslib_1 = __webpack_require__(655);
|
|
23972
|
+
/**
|
|
23973
|
+
* DiagnosticsCollector
|
|
23974
|
+
*/
|
|
23975
|
+
class DiagnosticsCollector {
|
|
23976
|
+
constructor(opts = {}) {
|
|
23977
|
+
var _a, _b, _c, _d;
|
|
23978
|
+
this.opts = {
|
|
23979
|
+
enableBandwidthProbe: (_a = opts.enableBandwidthProbe) !== null && _a !== void 0 ? _a : true,
|
|
23980
|
+
probeUrl: (_b = opts.probeUrl) !== null && _b !== void 0 ? _b : '/diag/probe.bin',
|
|
23981
|
+
respectSaveData: (_c = opts.respectSaveData) !== null && _c !== void 0 ? _c : true,
|
|
23982
|
+
sampleRate: Math.max(0, Math.min(1, (_d = opts.sampleRate) !== null && _d !== void 0 ? _d : 1))
|
|
23983
|
+
};
|
|
23984
|
+
}
|
|
23985
|
+
/**
|
|
23986
|
+
* Collect the diagnostics payload.
|
|
23987
|
+
*/
|
|
23988
|
+
collect() {
|
|
23989
|
+
var _a, _b;
|
|
23990
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
23991
|
+
if (!this.shouldSample()) {
|
|
23992
|
+
return {
|
|
23993
|
+
device: { type: 'desktop', touchSupport: false },
|
|
23994
|
+
runtime: { browser: { family: 'Unknown', version: null }, os: { family: 'Unknown', version: null } },
|
|
23995
|
+
powerHints: { saveData: null, prefersReducedData: null, prefersReducedMotion: null },
|
|
23996
|
+
network: { type: null, effectiveType: null, downlinkMbps: null, rttMs: null, measuredDownlinkMbps: null },
|
|
23997
|
+
timestamps: { collectedAt: Date.now() }
|
|
23998
|
+
};
|
|
23999
|
+
}
|
|
24000
|
+
const collectedAt = Date.now();
|
|
24001
|
+
const [uaInfo, codecSupport, measuredDownlinkMbps] = yield Promise.all([
|
|
24002
|
+
this.getUAInfo(),
|
|
24003
|
+
this.getCodecSupport(),
|
|
24004
|
+
this.maybeMeasureBandwidth()
|
|
24005
|
+
]);
|
|
24006
|
+
return {
|
|
24007
|
+
device: {
|
|
24008
|
+
type: this.inferDeviceType(),
|
|
24009
|
+
vendor: null,
|
|
24010
|
+
model: uaInfo.model,
|
|
24011
|
+
architecture: uaInfo.architecture,
|
|
24012
|
+
bitness: uaInfo.bitness,
|
|
24013
|
+
touchSupport: this.hasTouch(),
|
|
24014
|
+
hardwareConcurrency: (_a = navigator.hardwareConcurrency) !== null && _a !== void 0 ? _a : null,
|
|
24015
|
+
deviceMemory: (_b = navigator.deviceMemory) !== null && _b !== void 0 ? _b : null,
|
|
24016
|
+
orientation: this.getOrientation(),
|
|
24017
|
+
webgl: this.hasWebGL(),
|
|
24018
|
+
codecs: codecSupport
|
|
24019
|
+
},
|
|
24020
|
+
runtime: {
|
|
24021
|
+
browser: { family: uaInfo.browserFamily, version: uaInfo.browserVersion },
|
|
24022
|
+
os: { family: uaInfo.osFamily, version: uaInfo.osVersion }
|
|
24023
|
+
},
|
|
24024
|
+
powerHints: this.getPowerHints(),
|
|
24025
|
+
network: this.getNetworkInfo(measuredDownlinkMbps),
|
|
24026
|
+
timestamps: { collectedAt }
|
|
24027
|
+
};
|
|
24028
|
+
});
|
|
24029
|
+
}
|
|
24030
|
+
/**
|
|
24031
|
+
* Collect a safe subset of WebRTC stats once PC is connected.
|
|
24032
|
+
*/
|
|
24033
|
+
collectWebRTC(pc) {
|
|
24034
|
+
var _a, _b, _c, _d, _e, _f;
|
|
24035
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
24036
|
+
try {
|
|
24037
|
+
const stats = yield pc.getStats();
|
|
24038
|
+
let selected, transport, local, remote;
|
|
24039
|
+
stats.forEach((r) => {
|
|
24040
|
+
if (r.type === 'transport' && r.selectedCandidatePairId)
|
|
24041
|
+
transport = r;
|
|
24042
|
+
if (r.type === 'candidate-pair' && (r.selected || r.nominated))
|
|
24043
|
+
selected = r;
|
|
24044
|
+
});
|
|
24045
|
+
if (selected) {
|
|
24046
|
+
local = stats.get(selected.localCandidateId);
|
|
24047
|
+
remote = stats.get(selected.remoteCandidateId);
|
|
24048
|
+
}
|
|
24049
|
+
return {
|
|
24050
|
+
candidatePairId: (_a = selected === null || selected === void 0 ? void 0 : selected.id) !== null && _a !== void 0 ? _a : null,
|
|
24051
|
+
localCandidateType: (_b = local === null || local === void 0 ? void 0 : local.candidateType) !== null && _b !== void 0 ? _b : null,
|
|
24052
|
+
remoteCandidateType: (_c = remote === null || remote === void 0 ? void 0 : remote.candidateType) !== null && _c !== void 0 ? _c : null,
|
|
24053
|
+
protocol: (_d = local === null || local === void 0 ? void 0 : local.protocol) !== null && _d !== void 0 ? _d : null,
|
|
24054
|
+
networkType: (_e = local === null || local === void 0 ? void 0 : local.networkType) !== null && _e !== void 0 ? _e : null,
|
|
24055
|
+
dtlsCipher: (_f = transport === null || transport === void 0 ? void 0 : transport.dtlsCipher) !== null && _f !== void 0 ? _f : null
|
|
24056
|
+
};
|
|
24057
|
+
}
|
|
24058
|
+
catch (_g) {
|
|
24059
|
+
return {};
|
|
24060
|
+
}
|
|
24061
|
+
});
|
|
24062
|
+
}
|
|
24063
|
+
/**
|
|
24064
|
+
* Helper to embed diagnostics in a hello envelope.
|
|
24065
|
+
*/
|
|
24066
|
+
buildHelloEnvelope(base, pc) {
|
|
24067
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
24068
|
+
const diag = yield this.collect();
|
|
24069
|
+
const webrtc = pc ? yield this.collectWebRTC(pc) : undefined;
|
|
24070
|
+
const ext = webrtc ? { diag: Object.assign(Object.assign({}, diag), { webrtc }) } : { diag };
|
|
24071
|
+
return Object.assign(Object.assign({}, base), { ext });
|
|
24072
|
+
});
|
|
24073
|
+
}
|
|
24074
|
+
// ---------- Internals ----------
|
|
24075
|
+
shouldSample() {
|
|
24076
|
+
if (this.opts.sampleRate >= 1)
|
|
24077
|
+
return true;
|
|
24078
|
+
return Math.random() < this.opts.sampleRate;
|
|
24079
|
+
}
|
|
24080
|
+
hasTouch() {
|
|
24081
|
+
var _a;
|
|
24082
|
+
const nav = navigator;
|
|
24083
|
+
return 'ontouchstart' in window || ((_a = nav.maxTouchPoints) !== null && _a !== void 0 ? _a : 0) > 0;
|
|
24084
|
+
}
|
|
24085
|
+
getOrientation() {
|
|
24086
|
+
var _a;
|
|
24087
|
+
try {
|
|
24088
|
+
if ((_a = screen.orientation) === null || _a === void 0 ? void 0 : _a.type) {
|
|
24089
|
+
return screen.orientation.type.startsWith('portrait') ? 'portrait' : 'landscape';
|
|
24090
|
+
}
|
|
24091
|
+
if (window.matchMedia) {
|
|
24092
|
+
return window.matchMedia('(orientation: portrait)').matches ? 'portrait' : 'landscape';
|
|
24093
|
+
}
|
|
24094
|
+
}
|
|
24095
|
+
catch (_b) { }
|
|
24096
|
+
return null;
|
|
24097
|
+
}
|
|
24098
|
+
hasWebGL() {
|
|
24099
|
+
try {
|
|
24100
|
+
const canvas = document.createElement('canvas');
|
|
24101
|
+
return !!(canvas.getContext('webgl') || canvas.getContext('experimental-webgl'));
|
|
24102
|
+
}
|
|
24103
|
+
catch (_a) {
|
|
24104
|
+
return false;
|
|
24105
|
+
}
|
|
24106
|
+
}
|
|
24107
|
+
/**
|
|
24108
|
+
* Heuristic device type: best-effort only.
|
|
24109
|
+
*/
|
|
24110
|
+
inferDeviceType() {
|
|
24111
|
+
const uaData = navigator.userAgentData;
|
|
24112
|
+
const isMobileCH = (uaData === null || uaData === void 0 ? void 0 : uaData.mobile) === true;
|
|
24113
|
+
const minDim = Math.min(screen.width, screen.height);
|
|
24114
|
+
if (isMobileCH && minDim >= 600)
|
|
24115
|
+
return 'tablet';
|
|
24116
|
+
if (isMobileCH)
|
|
24117
|
+
return 'mobile';
|
|
24118
|
+
if (/\b(iPad|Tablet)\b/i.test(navigator.userAgent))
|
|
24119
|
+
return 'tablet';
|
|
24120
|
+
if (('ontouchstart' in window) && minDim >= 600 && minDim <= 1100)
|
|
24121
|
+
return 'tablet';
|
|
24122
|
+
return 'desktop';
|
|
24123
|
+
}
|
|
24124
|
+
getPowerHints() {
|
|
24125
|
+
const conn = navigator.connection;
|
|
24126
|
+
const saveData = typeof (conn === null || conn === void 0 ? void 0 : conn.saveData) === 'boolean' ? conn.saveData : null;
|
|
24127
|
+
let prefersReducedData = null;
|
|
24128
|
+
let prefersReducedMotion = null;
|
|
24129
|
+
if (typeof window.matchMedia === 'function') {
|
|
24130
|
+
try {
|
|
24131
|
+
const mqData = window.matchMedia('(prefers-reduced-data: reduce)');
|
|
24132
|
+
if (typeof mqData.matches === 'boolean') {
|
|
24133
|
+
prefersReducedData = mqData.matches;
|
|
24134
|
+
}
|
|
24135
|
+
}
|
|
24136
|
+
catch (_a) { }
|
|
24137
|
+
try {
|
|
24138
|
+
const mqMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
|
|
24139
|
+
if (typeof mqMotion.matches === 'boolean') {
|
|
24140
|
+
prefersReducedMotion = mqMotion.matches;
|
|
24141
|
+
}
|
|
24142
|
+
}
|
|
24143
|
+
catch (_b) { }
|
|
24144
|
+
}
|
|
24145
|
+
return { saveData, prefersReducedData, prefersReducedMotion };
|
|
24146
|
+
}
|
|
24147
|
+
getNetworkInfo(measuredDownlinkMbps) {
|
|
24148
|
+
const conn = navigator.connection;
|
|
24149
|
+
return {
|
|
24150
|
+
type: (typeof (conn === null || conn === void 0 ? void 0 : conn.type) === 'string') ? conn.type : null,
|
|
24151
|
+
effectiveType: (typeof (conn === null || conn === void 0 ? void 0 : conn.effectiveType) === 'string') ? conn.effectiveType : null,
|
|
24152
|
+
downlinkMbps: (typeof (conn === null || conn === void 0 ? void 0 : conn.downlink) === 'number') ? conn.downlink : null,
|
|
24153
|
+
rttMs: (typeof (conn === null || conn === void 0 ? void 0 : conn.rtt) === 'number') ? conn.rtt : null,
|
|
24154
|
+
measuredDownlinkMbps
|
|
24155
|
+
};
|
|
24156
|
+
}
|
|
24157
|
+
maybeMeasureBandwidth() {
|
|
24158
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
24159
|
+
const conn = navigator.connection;
|
|
24160
|
+
const saveData = (conn === null || conn === void 0 ? void 0 : conn.saveData) === true;
|
|
24161
|
+
if (!this.opts.enableBandwidthProbe)
|
|
24162
|
+
return null;
|
|
24163
|
+
if (this.opts.respectSaveData && saveData)
|
|
24164
|
+
return null;
|
|
24165
|
+
try {
|
|
24166
|
+
const t0 = performance.now();
|
|
24167
|
+
const res = yield fetch(this.withCacheBuster(this.opts.probeUrl), {
|
|
24168
|
+
cache: 'no-store',
|
|
24169
|
+
credentials: 'omit'
|
|
24170
|
+
});
|
|
24171
|
+
const buf = yield res.arrayBuffer();
|
|
24172
|
+
const t1 = performance.now();
|
|
24173
|
+
const bits = buf.byteLength * 8;
|
|
24174
|
+
const seconds = (t1 - t0) / 1000;
|
|
24175
|
+
if (seconds <= 0.05)
|
|
24176
|
+
return null; // ignore unstable samples
|
|
24177
|
+
return +((bits / seconds) / 1000000).toFixed(2);
|
|
24178
|
+
}
|
|
24179
|
+
catch (_a) {
|
|
24180
|
+
return null;
|
|
24181
|
+
}
|
|
24182
|
+
});
|
|
24183
|
+
}
|
|
24184
|
+
withCacheBuster(url) {
|
|
24185
|
+
var _a, _b;
|
|
24186
|
+
const u = new URL(url, location.origin);
|
|
24187
|
+
const token = (_b = (_a = crypto === null || crypto === void 0 ? void 0 : crypto.randomUUID) === null || _a === void 0 ? void 0 : _a.call(crypto)) !== null && _b !== void 0 ? _b : String(Date.now());
|
|
24188
|
+
u.searchParams.set('cb', token);
|
|
24189
|
+
return u.toString();
|
|
24190
|
+
}
|
|
24191
|
+
getCodecSupport() {
|
|
24192
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
24193
|
+
const [h264, hevc] = yield Promise.all([
|
|
24194
|
+
this.supportsCodec('video/mp4; codecs="avc1.42E01E"'),
|
|
24195
|
+
this.supportsCodec('video/mp4; codecs="hvc1.1.6.L93.B0"')
|
|
24196
|
+
]);
|
|
24197
|
+
return { h264, hevc };
|
|
24198
|
+
});
|
|
24199
|
+
}
|
|
24200
|
+
supportsCodec(mime) {
|
|
24201
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
24202
|
+
try {
|
|
24203
|
+
if ('mediaCapabilities' in navigator) {
|
|
24204
|
+
// @ts-ignore
|
|
24205
|
+
const res = yield navigator.mediaCapabilities.decodingInfo({
|
|
24206
|
+
type: 'file',
|
|
24207
|
+
video: { contentType: mime, width: 1920, height: 1080, bitrate: 5000000, framerate: 30 }
|
|
24208
|
+
});
|
|
24209
|
+
return !!(res === null || res === void 0 ? void 0 : res.supported);
|
|
24210
|
+
}
|
|
24211
|
+
}
|
|
24212
|
+
catch (_a) { }
|
|
24213
|
+
try {
|
|
24214
|
+
const v = document.createElement('video');
|
|
24215
|
+
return v.canPlayType(mime) !== '';
|
|
24216
|
+
}
|
|
24217
|
+
catch (_b) {
|
|
24218
|
+
return false;
|
|
24219
|
+
}
|
|
24220
|
+
});
|
|
24221
|
+
}
|
|
24222
|
+
getUAInfo() {
|
|
24223
|
+
var _a, _b;
|
|
24224
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
24225
|
+
const nav = navigator;
|
|
24226
|
+
const uaData = nav.userAgentData;
|
|
24227
|
+
let browserFamily = 'Unknown', browserVersion = null;
|
|
24228
|
+
let osFamily = 'Unknown', osVersion = null;
|
|
24229
|
+
let model = null, architecture = null, bitness = null;
|
|
24230
|
+
if (uaData === null || uaData === void 0 ? void 0 : uaData.getHighEntropyValues) {
|
|
24231
|
+
try {
|
|
24232
|
+
const high = yield uaData.getHighEntropyValues([
|
|
24233
|
+
'platform', 'platformVersion', 'model', 'architecture', 'bitness', 'fullVersionList'
|
|
24234
|
+
]);
|
|
24235
|
+
osFamily = high.platform || 'Unknown';
|
|
24236
|
+
osVersion = high.platformVersion || null;
|
|
24237
|
+
model = high.model || null;
|
|
24238
|
+
architecture = high.architecture || null;
|
|
24239
|
+
bitness = high.bitness || null;
|
|
24240
|
+
const brands = high.fullVersionList || uaData.brands || [];
|
|
24241
|
+
const real = brands.find(b => b.brand && !/Chromium|Not:?A-?Brand/i.test(b.brand));
|
|
24242
|
+
browserFamily = (real === null || real === void 0 ? void 0 : real.brand) || ((_a = brands[0]) === null || _a === void 0 ? void 0 : _a.brand) || 'Unknown';
|
|
24243
|
+
browserVersion = (real === null || real === void 0 ? void 0 : real.version) || ((_b = brands[0]) === null || _b === void 0 ? void 0 : _b.version) || null;
|
|
24244
|
+
}
|
|
24245
|
+
catch (_c) { }
|
|
24246
|
+
}
|
|
24247
|
+
if (browserFamily === 'Unknown') {
|
|
24248
|
+
const ua = navigator.userAgent;
|
|
24249
|
+
if (/Firefox\/(\S+)/.test(ua)) {
|
|
24250
|
+
browserFamily = 'Firefox';
|
|
24251
|
+
browserVersion = RegExp.$1;
|
|
24252
|
+
}
|
|
24253
|
+
else if (/Edg\/(\S+)/.test(ua)) {
|
|
24254
|
+
browserFamily = 'Edge';
|
|
24255
|
+
browserVersion = RegExp.$1;
|
|
24256
|
+
}
|
|
24257
|
+
else if (/Chrome\/(\S+)/.test(ua)) {
|
|
24258
|
+
browserFamily = 'Chrome';
|
|
24259
|
+
browserVersion = RegExp.$1;
|
|
24260
|
+
}
|
|
24261
|
+
else if (/Version\/(\S+).*Safari/.test(ua)) {
|
|
24262
|
+
browserFamily = 'Safari';
|
|
24263
|
+
browserVersion = RegExp.$1;
|
|
24264
|
+
}
|
|
24265
|
+
if (/Windows/.test(ua))
|
|
24266
|
+
osFamily = 'Windows';
|
|
24267
|
+
else if (/Mac OS X/.test(ua))
|
|
24268
|
+
osFamily = 'macOS';
|
|
24269
|
+
else if (/Android/.test(ua))
|
|
24270
|
+
osFamily = 'Android';
|
|
24271
|
+
else if (/iPhone|iPad|iPod/.test(ua))
|
|
24272
|
+
osFamily = 'iOS';
|
|
24273
|
+
else if (/Linux/.test(ua))
|
|
24274
|
+
osFamily = 'Linux';
|
|
24275
|
+
}
|
|
24276
|
+
return { browserFamily, browserVersion, osFamily, osVersion, model, architecture, bitness };
|
|
24277
|
+
});
|
|
24278
|
+
}
|
|
24279
|
+
}
|
|
24280
|
+
exports.DiagnosticsCollector = DiagnosticsCollector;
|
|
24281
|
+
|
|
24282
|
+
|
|
23942
24283
|
/***/ }),
|
|
23943
24284
|
|
|
23944
24285
|
/***/ 5602:
|
package/index.esm.js
CHANGED
|
@@ -23356,7 +23356,7 @@ class ArcwareConfig extends _epicgames_ps_lib_pixelstreamingfrontend_ue5_5__WEBP
|
|
|
23356
23356
|
if (!config.initialSettings.ss)
|
|
23357
23357
|
config.initialSettings.ss = DefaultUrl;
|
|
23358
23358
|
super(config);
|
|
23359
|
-
this.VERSION = "1.2.
|
|
23359
|
+
this.VERSION = "1.2.15";
|
|
23360
23360
|
this.settings = settings;
|
|
23361
23361
|
this.session = new _domain_Session__WEBPACK_IMPORTED_MODULE_0__.Session();
|
|
23362
23362
|
this._initialSettings = config.initialSettings;
|
|
@@ -23500,18 +23500,22 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
23500
23500
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
23501
23501
|
/* harmony export */ "ArcwarePixelStreaming": () => (/* binding */ ArcwarePixelStreaming)
|
|
23502
23502
|
/* harmony export */ });
|
|
23503
|
+
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(655);
|
|
23503
23504
|
/* harmony import */ var _arcware_cloud_shared_pixelstreaming_websdk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(7910);
|
|
23504
23505
|
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_5__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(516);
|
|
23505
|
-
/* harmony import */ var
|
|
23506
|
-
/* harmony import */ var
|
|
23506
|
+
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_5__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(7800);
|
|
23507
|
+
/* harmony import */ var _epicgames_ps_lib_pixelstreamingfrontend_ue5_5__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(7463);
|
|
23507
23508
|
/* harmony import */ var _ApplyUrlHack__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(4790);
|
|
23508
23509
|
/* harmony import */ var _domain_EventHandler__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(3379);
|
|
23509
23510
|
/* harmony import */ var _domain_Stats__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(9764);
|
|
23510
|
-
/* harmony import */ var
|
|
23511
|
-
/* harmony import */ var
|
|
23512
|
-
/* harmony import */ var
|
|
23511
|
+
/* harmony import */ var _domain_debounce__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(9580);
|
|
23512
|
+
/* harmony import */ var _ui_LoveLetters__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(4572);
|
|
23513
|
+
/* harmony import */ var _ui_ArcwareLogoLoader__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(6469);
|
|
23513
23514
|
/* harmony import */ var _ui_MicrophoneOverlay__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(3613);
|
|
23514
23515
|
/* harmony import */ var _domain_ConnectionIdentifier__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5999);
|
|
23516
|
+
/* harmony import */ var _DiagnosticsCollector__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(6478);
|
|
23517
|
+
|
|
23518
|
+
|
|
23515
23519
|
|
|
23516
23520
|
|
|
23517
23521
|
|
|
@@ -23569,6 +23573,9 @@ class ArcwarePixelStreaming extends _epicgames_ps_lib_pixelstreamingfrontend_ue5
|
|
|
23569
23573
|
this.config = config;
|
|
23570
23574
|
this.loveLettersList = [];
|
|
23571
23575
|
this.microphoneOverlay = new _ui_MicrophoneOverlay__WEBPACK_IMPORTED_MODULE_6__.MicrophoneOverlay(this);
|
|
23576
|
+
this.diagnosticsCollector = new _DiagnosticsCollector__WEBPACK_IMPORTED_MODULE_7__.DiagnosticsCollector({
|
|
23577
|
+
enableBandwidthProbe: false,
|
|
23578
|
+
});
|
|
23572
23579
|
// this.loveLettersContainer = null;
|
|
23573
23580
|
this.wrapWebSocketOnCloseHandler();
|
|
23574
23581
|
// Bind the event listener function to the class instance
|
|
@@ -23582,7 +23589,7 @@ class ArcwarePixelStreaming extends _epicgames_ps_lib_pixelstreamingfrontend_ue5
|
|
|
23582
23589
|
this.addMessageHandler("queue", _arcware_cloud_shared_pixelstreaming_websdk__WEBPACK_IMPORTED_MODULE_0__.Messages.ZQueue, this.onQueue);
|
|
23583
23590
|
this.addMessageHandler("version", _arcware_cloud_shared_pixelstreaming_websdk__WEBPACK_IMPORTED_MODULE_0__.Messages.ZVersion, this.onVersion);
|
|
23584
23591
|
// Create a debounced version of the handleResolutionChange function
|
|
23585
|
-
const debouncedResolutionChange = (0,
|
|
23592
|
+
const debouncedResolutionChange = (0,_domain_debounce__WEBPACK_IMPORTED_MODULE_8__["default"])(() => {
|
|
23586
23593
|
this.handleResolutionChange();
|
|
23587
23594
|
}, 0);
|
|
23588
23595
|
// Register event listeners.
|
|
@@ -23627,7 +23634,10 @@ class ArcwarePixelStreaming extends _epicgames_ps_lib_pixelstreamingfrontend_ue5
|
|
|
23627
23634
|
*/
|
|
23628
23635
|
/** On version requested, the version of the WebSDK would be returned. */
|
|
23629
23636
|
onVersion(message) {
|
|
23630
|
-
|
|
23637
|
+
return (0,tslib__WEBPACK_IMPORTED_MODULE_9__.__awaiter)(this, void 0, void 0, function* () {
|
|
23638
|
+
const diagnostics = yield this.diagnosticsCollector.collect();
|
|
23639
|
+
this.send({ type: "version", version: this.config.VERSION, diagnostics });
|
|
23640
|
+
});
|
|
23631
23641
|
}
|
|
23632
23642
|
/** On ping the session creation timestamp will be updated. */
|
|
23633
23643
|
onPing(message) {
|
|
@@ -23641,7 +23651,7 @@ class ArcwarePixelStreaming extends _epicgames_ps_lib_pixelstreamingfrontend_ue5
|
|
|
23641
23651
|
// public readonly streamInfoHandler = new EventHandler<never>();
|
|
23642
23652
|
onStreamInfo(streamInfo) {
|
|
23643
23653
|
var _a, _b, _c, _d;
|
|
23644
|
-
|
|
23654
|
+
_epicgames_ps_lib_pixelstreamingfrontend_ue5_5__WEBPACK_IMPORTED_MODULE_10__.Logger.Info(`StreamInfo received.`);
|
|
23645
23655
|
// Save the streamInfo to the instance variable
|
|
23646
23656
|
this.streamInfo = streamInfo;
|
|
23647
23657
|
// By setting this hidden flag, the evaluation of the streamInfo can be cut off.
|
|
@@ -23649,8 +23659,8 @@ class ArcwarePixelStreaming extends _epicgames_ps_lib_pixelstreamingfrontend_ue5
|
|
|
23649
23659
|
if (!((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.settings) === null || _b === void 0 ? void 0 : _b["do-not-eval-streamInfo"])) {
|
|
23650
23660
|
const { afk } = streamInfo.streamInfo;
|
|
23651
23661
|
if (afk) {
|
|
23652
|
-
this.config.setFlagEnabled(
|
|
23653
|
-
this.config.setNumericSetting(
|
|
23662
|
+
this.config.setFlagEnabled(_epicgames_ps_lib_pixelstreamingfrontend_ue5_5__WEBPACK_IMPORTED_MODULE_11__.Flags.AFKDetection, afk.enabled);
|
|
23663
|
+
this.config.setNumericSetting(_epicgames_ps_lib_pixelstreamingfrontend_ue5_5__WEBPACK_IMPORTED_MODULE_11__.NumericParameters.AFKTimeoutSecs, afk.warn + afk.error);
|
|
23654
23664
|
// Hack
|
|
23655
23665
|
const { afkController } = this.webRtcController;
|
|
23656
23666
|
afkController.countDown = afk.action;
|
|
@@ -23673,11 +23683,11 @@ class ArcwarePixelStreaming extends _epicgames_ps_lib_pixelstreamingfrontend_ue5
|
|
|
23673
23683
|
// EventHandler.Emit(this.streamInfoHandler, undefined as never);
|
|
23674
23684
|
}
|
|
23675
23685
|
onQueue(message) {
|
|
23676
|
-
|
|
23686
|
+
_epicgames_ps_lib_pixelstreamingfrontend_ue5_5__WEBPACK_IMPORTED_MODULE_10__.Logger.Info(`QueueInfo received.`);
|
|
23677
23687
|
_domain_EventHandler__WEBPACK_IMPORTED_MODULE_5__.EventHandler.Emit(this.queueHandler, message);
|
|
23678
23688
|
}
|
|
23679
23689
|
onError(error) {
|
|
23680
|
-
|
|
23690
|
+
_epicgames_ps_lib_pixelstreamingfrontend_ue5_5__WEBPACK_IMPORTED_MODULE_10__.Logger.Error(error.type);
|
|
23681
23691
|
_domain_EventHandler__WEBPACK_IMPORTED_MODULE_5__.EventHandler.Emit(this.errorHandler, error);
|
|
23682
23692
|
}
|
|
23683
23693
|
onLoveLetter(loveLetter) {
|
|
@@ -23688,7 +23698,7 @@ class ArcwarePixelStreaming extends _epicgames_ps_lib_pixelstreamingfrontend_ue5
|
|
|
23688
23698
|
this.pushLetter(loveLetter.reason);
|
|
23689
23699
|
}
|
|
23690
23700
|
onSessionId(message) {
|
|
23691
|
-
|
|
23701
|
+
_epicgames_ps_lib_pixelstreamingfrontend_ue5_5__WEBPACK_IMPORTED_MODULE_10__.Logger.Info(message.sessionId);
|
|
23692
23702
|
// console.info(`Session: ${message.sessionId}`);
|
|
23693
23703
|
this.session.set(message.sessionId);
|
|
23694
23704
|
_domain_EventHandler__WEBPACK_IMPORTED_MODULE_5__.EventHandler.Emit(this.sessionIdHandler, message.sessionId);
|
|
@@ -23714,7 +23724,7 @@ class ArcwarePixelStreaming extends _epicgames_ps_lib_pixelstreamingfrontend_ue5
|
|
|
23714
23724
|
// This cast has to be done, since Frontend does not use typescript-strict setting.
|
|
23715
23725
|
const parsedError = parsed;
|
|
23716
23726
|
const error = new Error(`Unexpected message content. Event:'${type}', ZodError: ${parsedError.error.message}`);
|
|
23717
|
-
|
|
23727
|
+
_epicgames_ps_lib_pixelstreamingfrontend_ue5_5__WEBPACK_IMPORTED_MODULE_10__.Logger.Error(error.message);
|
|
23718
23728
|
}
|
|
23719
23729
|
if (type === "error") {
|
|
23720
23730
|
this.disconnect();
|
|
@@ -23739,7 +23749,7 @@ class ArcwarePixelStreaming extends _epicgames_ps_lib_pixelstreamingfrontend_ue5
|
|
|
23739
23749
|
else {
|
|
23740
23750
|
// This cast has to be done, since Frontend does not use typescript-strict setting.
|
|
23741
23751
|
const parsedError = result;
|
|
23742
|
-
|
|
23752
|
+
_epicgames_ps_lib_pixelstreamingfrontend_ue5_5__WEBPACK_IMPORTED_MODULE_10__.Logger.Error(`Failed to send. ${parsedError.error}`);
|
|
23743
23753
|
}
|
|
23744
23754
|
}
|
|
23745
23755
|
else {
|
|
@@ -23816,7 +23826,7 @@ class ArcwarePixelStreaming extends _epicgames_ps_lib_pixelstreamingfrontend_ue5
|
|
|
23816
23826
|
}
|
|
23817
23827
|
initLoveLettersContainer() {
|
|
23818
23828
|
var _a;
|
|
23819
|
-
const logoLoader = new
|
|
23829
|
+
const logoLoader = new _ui_ArcwareLogoLoader__WEBPACK_IMPORTED_MODULE_12__.ArcwareLogoLoader();
|
|
23820
23830
|
if (!this.loveLettersContainer) {
|
|
23821
23831
|
const loveLettersContainer = document === null || document === void 0 ? void 0 : document.createElement("div");
|
|
23822
23832
|
const { videoPlayer } = this === null || this === void 0 ? void 0 : this.webRtcController;
|
|
@@ -23857,7 +23867,7 @@ class ArcwarePixelStreaming extends _epicgames_ps_lib_pixelstreamingfrontend_ue5
|
|
|
23857
23867
|
if (letter !== undefined) {
|
|
23858
23868
|
const formattedLoveLetter = letter === null || letter === void 0 ? void 0 : letter.replace(/LL: |\.$/g, "");
|
|
23859
23869
|
(_a = this === null || this === void 0 ? void 0 : this.loveLettersList) === null || _a === void 0 ? void 0 : _a.push(formattedLoveLetter);
|
|
23860
|
-
const loveLettersBox = new
|
|
23870
|
+
const loveLettersBox = new _ui_LoveLetters__WEBPACK_IMPORTED_MODULE_13__.LoveLetters();
|
|
23861
23871
|
loveLettersBox === null || loveLettersBox === void 0 ? void 0 : loveLettersBox.addLetter(formattedLoveLetter, (_b = this === null || this === void 0 ? void 0 : this.loveLettersList) === null || _b === void 0 ? void 0 : _b.length);
|
|
23862
23872
|
// Process the next item in the queue after a delay
|
|
23863
23873
|
setTimeout(() => {
|
|
@@ -23902,7 +23912,7 @@ class ArcwarePixelStreaming extends _epicgames_ps_lib_pixelstreamingfrontend_ue5
|
|
|
23902
23912
|
}
|
|
23903
23913
|
toggleMic(enable, isDefault) {
|
|
23904
23914
|
var _a, _b;
|
|
23905
|
-
(_a = this === null || this === void 0 ? void 0 : this.config) === null || _a === void 0 ? void 0 : _a.setFlagEnabled(
|
|
23915
|
+
(_a = this === null || this === void 0 ? void 0 : this.config) === null || _a === void 0 ? void 0 : _a.setFlagEnabled(_epicgames_ps_lib_pixelstreamingfrontend_ue5_5__WEBPACK_IMPORTED_MODULE_11__.Flags.UseMic, enable);
|
|
23906
23916
|
if (!isDefault) {
|
|
23907
23917
|
(_b = this === null || this === void 0 ? void 0 : this.microphoneOverlay) === null || _b === void 0 ? void 0 : _b.toggleMessage(enable);
|
|
23908
23918
|
setTimeout(() => {
|
|
@@ -23939,7 +23949,7 @@ class ArcwarePixelStreaming extends _epicgames_ps_lib_pixelstreamingfrontend_ue5
|
|
|
23939
23949
|
removeXRIconIfDisabled() {
|
|
23940
23950
|
var _a, _b, _c, _d, _e;
|
|
23941
23951
|
if (!((_b = (_a = this === null || this === void 0 ? void 0 : this.config) === null || _a === void 0 ? void 0 : _a.initialSettings) === null || _b === void 0 ? void 0 : _b.XRControllerInput)) {
|
|
23942
|
-
(_c = this === null || this === void 0 ? void 0 : this.config) === null || _c === void 0 ? void 0 : _c.setFlagEnabled(
|
|
23952
|
+
(_c = this === null || this === void 0 ? void 0 : this.config) === null || _c === void 0 ? void 0 : _c.setFlagEnabled(_epicgames_ps_lib_pixelstreamingfrontend_ue5_5__WEBPACK_IMPORTED_MODULE_11__.Flags.XRControllerInput, false);
|
|
23943
23953
|
if (this.videoElementParent) {
|
|
23944
23954
|
if ((_d = this === null || this === void 0 ? void 0 : this.videoElementParent) === null || _d === void 0 ? void 0 : _d.parentElement) {
|
|
23945
23955
|
const xrBtn = (_e = this === null || this === void 0 ? void 0 : this.videoElementParent) === null || _e === void 0 ? void 0 : _e.parentElement.querySelector("#xrBtn");
|
|
@@ -23958,6 +23968,340 @@ class ArcwarePixelStreaming extends _epicgames_ps_lib_pixelstreamingfrontend_ue5
|
|
|
23958
23968
|
}
|
|
23959
23969
|
|
|
23960
23970
|
|
|
23971
|
+
/***/ }),
|
|
23972
|
+
|
|
23973
|
+
/***/ 6478:
|
|
23974
|
+
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
23975
|
+
|
|
23976
|
+
__webpack_require__.r(__webpack_exports__);
|
|
23977
|
+
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
23978
|
+
/* harmony export */ "DiagnosticsCollector": () => (/* binding */ DiagnosticsCollector)
|
|
23979
|
+
/* harmony export */ });
|
|
23980
|
+
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(655);
|
|
23981
|
+
/**
|
|
23982
|
+
* DiagnosticsCollector.ts
|
|
23983
|
+
* Lightweight, privacy-aware client diagnostics for troubleshooting + analytics.
|
|
23984
|
+
* WebRTC collection intentionally omitted (to add later).
|
|
23985
|
+
*
|
|
23986
|
+
* Notes:
|
|
23987
|
+
* - Some fields are best-effort due to browser restrictions; they're nullable.
|
|
23988
|
+
* - Bandwidth probe requires a small binary served with:
|
|
23989
|
+
* Content-Type: application/octet-stream
|
|
23990
|
+
* Content-Encoding: identity
|
|
23991
|
+
* Cache-Control: no-store
|
|
23992
|
+
* Default location: /diag/probe.bin
|
|
23993
|
+
*/
|
|
23994
|
+
|
|
23995
|
+
/**
|
|
23996
|
+
* DiagnosticsCollector
|
|
23997
|
+
*/
|
|
23998
|
+
class DiagnosticsCollector {
|
|
23999
|
+
constructor(opts = {}) {
|
|
24000
|
+
var _a, _b, _c, _d;
|
|
24001
|
+
this.opts = {
|
|
24002
|
+
enableBandwidthProbe: (_a = opts.enableBandwidthProbe) !== null && _a !== void 0 ? _a : true,
|
|
24003
|
+
probeUrl: (_b = opts.probeUrl) !== null && _b !== void 0 ? _b : '/diag/probe.bin',
|
|
24004
|
+
respectSaveData: (_c = opts.respectSaveData) !== null && _c !== void 0 ? _c : true,
|
|
24005
|
+
sampleRate: Math.max(0, Math.min(1, (_d = opts.sampleRate) !== null && _d !== void 0 ? _d : 1))
|
|
24006
|
+
};
|
|
24007
|
+
}
|
|
24008
|
+
/**
|
|
24009
|
+
* Collect the diagnostics payload.
|
|
24010
|
+
*/
|
|
24011
|
+
collect() {
|
|
24012
|
+
var _a, _b;
|
|
24013
|
+
return (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__awaiter)(this, void 0, void 0, function* () {
|
|
24014
|
+
if (!this.shouldSample()) {
|
|
24015
|
+
return {
|
|
24016
|
+
device: { type: 'desktop', touchSupport: false },
|
|
24017
|
+
runtime: { browser: { family: 'Unknown', version: null }, os: { family: 'Unknown', version: null } },
|
|
24018
|
+
powerHints: { saveData: null, prefersReducedData: null, prefersReducedMotion: null },
|
|
24019
|
+
network: { type: null, effectiveType: null, downlinkMbps: null, rttMs: null, measuredDownlinkMbps: null },
|
|
24020
|
+
timestamps: { collectedAt: Date.now() }
|
|
24021
|
+
};
|
|
24022
|
+
}
|
|
24023
|
+
const collectedAt = Date.now();
|
|
24024
|
+
const [uaInfo, codecSupport, measuredDownlinkMbps] = yield Promise.all([
|
|
24025
|
+
this.getUAInfo(),
|
|
24026
|
+
this.getCodecSupport(),
|
|
24027
|
+
this.maybeMeasureBandwidth()
|
|
24028
|
+
]);
|
|
24029
|
+
return {
|
|
24030
|
+
device: {
|
|
24031
|
+
type: this.inferDeviceType(),
|
|
24032
|
+
vendor: null,
|
|
24033
|
+
model: uaInfo.model,
|
|
24034
|
+
architecture: uaInfo.architecture,
|
|
24035
|
+
bitness: uaInfo.bitness,
|
|
24036
|
+
touchSupport: this.hasTouch(),
|
|
24037
|
+
hardwareConcurrency: (_a = navigator.hardwareConcurrency) !== null && _a !== void 0 ? _a : null,
|
|
24038
|
+
deviceMemory: (_b = navigator.deviceMemory) !== null && _b !== void 0 ? _b : null,
|
|
24039
|
+
orientation: this.getOrientation(),
|
|
24040
|
+
webgl: this.hasWebGL(),
|
|
24041
|
+
codecs: codecSupport
|
|
24042
|
+
},
|
|
24043
|
+
runtime: {
|
|
24044
|
+
browser: { family: uaInfo.browserFamily, version: uaInfo.browserVersion },
|
|
24045
|
+
os: { family: uaInfo.osFamily, version: uaInfo.osVersion }
|
|
24046
|
+
},
|
|
24047
|
+
powerHints: this.getPowerHints(),
|
|
24048
|
+
network: this.getNetworkInfo(measuredDownlinkMbps),
|
|
24049
|
+
timestamps: { collectedAt }
|
|
24050
|
+
};
|
|
24051
|
+
});
|
|
24052
|
+
}
|
|
24053
|
+
/**
|
|
24054
|
+
* Collect a safe subset of WebRTC stats once PC is connected.
|
|
24055
|
+
*/
|
|
24056
|
+
collectWebRTC(pc) {
|
|
24057
|
+
var _a, _b, _c, _d, _e, _f;
|
|
24058
|
+
return (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__awaiter)(this, void 0, void 0, function* () {
|
|
24059
|
+
try {
|
|
24060
|
+
const stats = yield pc.getStats();
|
|
24061
|
+
let selected, transport, local, remote;
|
|
24062
|
+
stats.forEach((r) => {
|
|
24063
|
+
if (r.type === 'transport' && r.selectedCandidatePairId)
|
|
24064
|
+
transport = r;
|
|
24065
|
+
if (r.type === 'candidate-pair' && (r.selected || r.nominated))
|
|
24066
|
+
selected = r;
|
|
24067
|
+
});
|
|
24068
|
+
if (selected) {
|
|
24069
|
+
local = stats.get(selected.localCandidateId);
|
|
24070
|
+
remote = stats.get(selected.remoteCandidateId);
|
|
24071
|
+
}
|
|
24072
|
+
return {
|
|
24073
|
+
candidatePairId: (_a = selected === null || selected === void 0 ? void 0 : selected.id) !== null && _a !== void 0 ? _a : null,
|
|
24074
|
+
localCandidateType: (_b = local === null || local === void 0 ? void 0 : local.candidateType) !== null && _b !== void 0 ? _b : null,
|
|
24075
|
+
remoteCandidateType: (_c = remote === null || remote === void 0 ? void 0 : remote.candidateType) !== null && _c !== void 0 ? _c : null,
|
|
24076
|
+
protocol: (_d = local === null || local === void 0 ? void 0 : local.protocol) !== null && _d !== void 0 ? _d : null,
|
|
24077
|
+
networkType: (_e = local === null || local === void 0 ? void 0 : local.networkType) !== null && _e !== void 0 ? _e : null,
|
|
24078
|
+
dtlsCipher: (_f = transport === null || transport === void 0 ? void 0 : transport.dtlsCipher) !== null && _f !== void 0 ? _f : null
|
|
24079
|
+
};
|
|
24080
|
+
}
|
|
24081
|
+
catch (_g) {
|
|
24082
|
+
return {};
|
|
24083
|
+
}
|
|
24084
|
+
});
|
|
24085
|
+
}
|
|
24086
|
+
/**
|
|
24087
|
+
* Helper to embed diagnostics in a hello envelope.
|
|
24088
|
+
*/
|
|
24089
|
+
buildHelloEnvelope(base, pc) {
|
|
24090
|
+
return (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__awaiter)(this, void 0, void 0, function* () {
|
|
24091
|
+
const diag = yield this.collect();
|
|
24092
|
+
const webrtc = pc ? yield this.collectWebRTC(pc) : undefined;
|
|
24093
|
+
const ext = webrtc ? { diag: Object.assign(Object.assign({}, diag), { webrtc }) } : { diag };
|
|
24094
|
+
return Object.assign(Object.assign({}, base), { ext });
|
|
24095
|
+
});
|
|
24096
|
+
}
|
|
24097
|
+
// ---------- Internals ----------
|
|
24098
|
+
shouldSample() {
|
|
24099
|
+
if (this.opts.sampleRate >= 1)
|
|
24100
|
+
return true;
|
|
24101
|
+
return Math.random() < this.opts.sampleRate;
|
|
24102
|
+
}
|
|
24103
|
+
hasTouch() {
|
|
24104
|
+
var _a;
|
|
24105
|
+
const nav = navigator;
|
|
24106
|
+
return 'ontouchstart' in window || ((_a = nav.maxTouchPoints) !== null && _a !== void 0 ? _a : 0) > 0;
|
|
24107
|
+
}
|
|
24108
|
+
getOrientation() {
|
|
24109
|
+
var _a;
|
|
24110
|
+
try {
|
|
24111
|
+
if ((_a = screen.orientation) === null || _a === void 0 ? void 0 : _a.type) {
|
|
24112
|
+
return screen.orientation.type.startsWith('portrait') ? 'portrait' : 'landscape';
|
|
24113
|
+
}
|
|
24114
|
+
if (window.matchMedia) {
|
|
24115
|
+
return window.matchMedia('(orientation: portrait)').matches ? 'portrait' : 'landscape';
|
|
24116
|
+
}
|
|
24117
|
+
}
|
|
24118
|
+
catch (_b) { }
|
|
24119
|
+
return null;
|
|
24120
|
+
}
|
|
24121
|
+
hasWebGL() {
|
|
24122
|
+
try {
|
|
24123
|
+
const canvas = document.createElement('canvas');
|
|
24124
|
+
return !!(canvas.getContext('webgl') || canvas.getContext('experimental-webgl'));
|
|
24125
|
+
}
|
|
24126
|
+
catch (_a) {
|
|
24127
|
+
return false;
|
|
24128
|
+
}
|
|
24129
|
+
}
|
|
24130
|
+
/**
|
|
24131
|
+
* Heuristic device type: best-effort only.
|
|
24132
|
+
*/
|
|
24133
|
+
inferDeviceType() {
|
|
24134
|
+
const uaData = navigator.userAgentData;
|
|
24135
|
+
const isMobileCH = (uaData === null || uaData === void 0 ? void 0 : uaData.mobile) === true;
|
|
24136
|
+
const minDim = Math.min(screen.width, screen.height);
|
|
24137
|
+
if (isMobileCH && minDim >= 600)
|
|
24138
|
+
return 'tablet';
|
|
24139
|
+
if (isMobileCH)
|
|
24140
|
+
return 'mobile';
|
|
24141
|
+
if (/\b(iPad|Tablet)\b/i.test(navigator.userAgent))
|
|
24142
|
+
return 'tablet';
|
|
24143
|
+
if (('ontouchstart' in window) && minDim >= 600 && minDim <= 1100)
|
|
24144
|
+
return 'tablet';
|
|
24145
|
+
return 'desktop';
|
|
24146
|
+
}
|
|
24147
|
+
getPowerHints() {
|
|
24148
|
+
const conn = navigator.connection;
|
|
24149
|
+
const saveData = typeof (conn === null || conn === void 0 ? void 0 : conn.saveData) === 'boolean' ? conn.saveData : null;
|
|
24150
|
+
let prefersReducedData = null;
|
|
24151
|
+
let prefersReducedMotion = null;
|
|
24152
|
+
if (typeof window.matchMedia === 'function') {
|
|
24153
|
+
try {
|
|
24154
|
+
const mqData = window.matchMedia('(prefers-reduced-data: reduce)');
|
|
24155
|
+
if (typeof mqData.matches === 'boolean') {
|
|
24156
|
+
prefersReducedData = mqData.matches;
|
|
24157
|
+
}
|
|
24158
|
+
}
|
|
24159
|
+
catch (_a) { }
|
|
24160
|
+
try {
|
|
24161
|
+
const mqMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
|
|
24162
|
+
if (typeof mqMotion.matches === 'boolean') {
|
|
24163
|
+
prefersReducedMotion = mqMotion.matches;
|
|
24164
|
+
}
|
|
24165
|
+
}
|
|
24166
|
+
catch (_b) { }
|
|
24167
|
+
}
|
|
24168
|
+
return { saveData, prefersReducedData, prefersReducedMotion };
|
|
24169
|
+
}
|
|
24170
|
+
getNetworkInfo(measuredDownlinkMbps) {
|
|
24171
|
+
const conn = navigator.connection;
|
|
24172
|
+
return {
|
|
24173
|
+
type: (typeof (conn === null || conn === void 0 ? void 0 : conn.type) === 'string') ? conn.type : null,
|
|
24174
|
+
effectiveType: (typeof (conn === null || conn === void 0 ? void 0 : conn.effectiveType) === 'string') ? conn.effectiveType : null,
|
|
24175
|
+
downlinkMbps: (typeof (conn === null || conn === void 0 ? void 0 : conn.downlink) === 'number') ? conn.downlink : null,
|
|
24176
|
+
rttMs: (typeof (conn === null || conn === void 0 ? void 0 : conn.rtt) === 'number') ? conn.rtt : null,
|
|
24177
|
+
measuredDownlinkMbps
|
|
24178
|
+
};
|
|
24179
|
+
}
|
|
24180
|
+
maybeMeasureBandwidth() {
|
|
24181
|
+
return (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__awaiter)(this, void 0, void 0, function* () {
|
|
24182
|
+
const conn = navigator.connection;
|
|
24183
|
+
const saveData = (conn === null || conn === void 0 ? void 0 : conn.saveData) === true;
|
|
24184
|
+
if (!this.opts.enableBandwidthProbe)
|
|
24185
|
+
return null;
|
|
24186
|
+
if (this.opts.respectSaveData && saveData)
|
|
24187
|
+
return null;
|
|
24188
|
+
try {
|
|
24189
|
+
const t0 = performance.now();
|
|
24190
|
+
const res = yield fetch(this.withCacheBuster(this.opts.probeUrl), {
|
|
24191
|
+
cache: 'no-store',
|
|
24192
|
+
credentials: 'omit'
|
|
24193
|
+
});
|
|
24194
|
+
const buf = yield res.arrayBuffer();
|
|
24195
|
+
const t1 = performance.now();
|
|
24196
|
+
const bits = buf.byteLength * 8;
|
|
24197
|
+
const seconds = (t1 - t0) / 1000;
|
|
24198
|
+
if (seconds <= 0.05)
|
|
24199
|
+
return null; // ignore unstable samples
|
|
24200
|
+
return +((bits / seconds) / 1000000).toFixed(2);
|
|
24201
|
+
}
|
|
24202
|
+
catch (_a) {
|
|
24203
|
+
return null;
|
|
24204
|
+
}
|
|
24205
|
+
});
|
|
24206
|
+
}
|
|
24207
|
+
withCacheBuster(url) {
|
|
24208
|
+
var _a, _b;
|
|
24209
|
+
const u = new URL(url, location.origin);
|
|
24210
|
+
const token = (_b = (_a = crypto === null || crypto === void 0 ? void 0 : crypto.randomUUID) === null || _a === void 0 ? void 0 : _a.call(crypto)) !== null && _b !== void 0 ? _b : String(Date.now());
|
|
24211
|
+
u.searchParams.set('cb', token);
|
|
24212
|
+
return u.toString();
|
|
24213
|
+
}
|
|
24214
|
+
getCodecSupport() {
|
|
24215
|
+
return (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__awaiter)(this, void 0, void 0, function* () {
|
|
24216
|
+
const [h264, hevc] = yield Promise.all([
|
|
24217
|
+
this.supportsCodec('video/mp4; codecs="avc1.42E01E"'),
|
|
24218
|
+
this.supportsCodec('video/mp4; codecs="hvc1.1.6.L93.B0"')
|
|
24219
|
+
]);
|
|
24220
|
+
return { h264, hevc };
|
|
24221
|
+
});
|
|
24222
|
+
}
|
|
24223
|
+
supportsCodec(mime) {
|
|
24224
|
+
return (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__awaiter)(this, void 0, void 0, function* () {
|
|
24225
|
+
try {
|
|
24226
|
+
if ('mediaCapabilities' in navigator) {
|
|
24227
|
+
// @ts-ignore
|
|
24228
|
+
const res = yield navigator.mediaCapabilities.decodingInfo({
|
|
24229
|
+
type: 'file',
|
|
24230
|
+
video: { contentType: mime, width: 1920, height: 1080, bitrate: 5000000, framerate: 30 }
|
|
24231
|
+
});
|
|
24232
|
+
return !!(res === null || res === void 0 ? void 0 : res.supported);
|
|
24233
|
+
}
|
|
24234
|
+
}
|
|
24235
|
+
catch (_a) { }
|
|
24236
|
+
try {
|
|
24237
|
+
const v = document.createElement('video');
|
|
24238
|
+
return v.canPlayType(mime) !== '';
|
|
24239
|
+
}
|
|
24240
|
+
catch (_b) {
|
|
24241
|
+
return false;
|
|
24242
|
+
}
|
|
24243
|
+
});
|
|
24244
|
+
}
|
|
24245
|
+
getUAInfo() {
|
|
24246
|
+
var _a, _b;
|
|
24247
|
+
return (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__awaiter)(this, void 0, void 0, function* () {
|
|
24248
|
+
const nav = navigator;
|
|
24249
|
+
const uaData = nav.userAgentData;
|
|
24250
|
+
let browserFamily = 'Unknown', browserVersion = null;
|
|
24251
|
+
let osFamily = 'Unknown', osVersion = null;
|
|
24252
|
+
let model = null, architecture = null, bitness = null;
|
|
24253
|
+
if (uaData === null || uaData === void 0 ? void 0 : uaData.getHighEntropyValues) {
|
|
24254
|
+
try {
|
|
24255
|
+
const high = yield uaData.getHighEntropyValues([
|
|
24256
|
+
'platform', 'platformVersion', 'model', 'architecture', 'bitness', 'fullVersionList'
|
|
24257
|
+
]);
|
|
24258
|
+
osFamily = high.platform || 'Unknown';
|
|
24259
|
+
osVersion = high.platformVersion || null;
|
|
24260
|
+
model = high.model || null;
|
|
24261
|
+
architecture = high.architecture || null;
|
|
24262
|
+
bitness = high.bitness || null;
|
|
24263
|
+
const brands = high.fullVersionList || uaData.brands || [];
|
|
24264
|
+
const real = brands.find(b => b.brand && !/Chromium|Not:?A-?Brand/i.test(b.brand));
|
|
24265
|
+
browserFamily = (real === null || real === void 0 ? void 0 : real.brand) || ((_a = brands[0]) === null || _a === void 0 ? void 0 : _a.brand) || 'Unknown';
|
|
24266
|
+
browserVersion = (real === null || real === void 0 ? void 0 : real.version) || ((_b = brands[0]) === null || _b === void 0 ? void 0 : _b.version) || null;
|
|
24267
|
+
}
|
|
24268
|
+
catch (_c) { }
|
|
24269
|
+
}
|
|
24270
|
+
if (browserFamily === 'Unknown') {
|
|
24271
|
+
const ua = navigator.userAgent;
|
|
24272
|
+
if (/Firefox\/(\S+)/.test(ua)) {
|
|
24273
|
+
browserFamily = 'Firefox';
|
|
24274
|
+
browserVersion = RegExp.$1;
|
|
24275
|
+
}
|
|
24276
|
+
else if (/Edg\/(\S+)/.test(ua)) {
|
|
24277
|
+
browserFamily = 'Edge';
|
|
24278
|
+
browserVersion = RegExp.$1;
|
|
24279
|
+
}
|
|
24280
|
+
else if (/Chrome\/(\S+)/.test(ua)) {
|
|
24281
|
+
browserFamily = 'Chrome';
|
|
24282
|
+
browserVersion = RegExp.$1;
|
|
24283
|
+
}
|
|
24284
|
+
else if (/Version\/(\S+).*Safari/.test(ua)) {
|
|
24285
|
+
browserFamily = 'Safari';
|
|
24286
|
+
browserVersion = RegExp.$1;
|
|
24287
|
+
}
|
|
24288
|
+
if (/Windows/.test(ua))
|
|
24289
|
+
osFamily = 'Windows';
|
|
24290
|
+
else if (/Mac OS X/.test(ua))
|
|
24291
|
+
osFamily = 'macOS';
|
|
24292
|
+
else if (/Android/.test(ua))
|
|
24293
|
+
osFamily = 'Android';
|
|
24294
|
+
else if (/iPhone|iPad|iPod/.test(ua))
|
|
24295
|
+
osFamily = 'iOS';
|
|
24296
|
+
else if (/Linux/.test(ua))
|
|
24297
|
+
osFamily = 'Linux';
|
|
24298
|
+
}
|
|
24299
|
+
return { browserFamily, browserVersion, osFamily, osVersion, model, architecture, bitness };
|
|
24300
|
+
});
|
|
24301
|
+
}
|
|
24302
|
+
}
|
|
24303
|
+
|
|
24304
|
+
|
|
23961
24305
|
/***/ }),
|
|
23962
24306
|
|
|
23963
24307
|
/***/ 5602:
|
package/index.umd.js
CHANGED
|
@@ -23361,7 +23361,7 @@ class ArcwareConfig extends lib_pixelstreamingfrontend_ue5_5_1.Config {
|
|
|
23361
23361
|
if (!config.initialSettings.ss)
|
|
23362
23362
|
config.initialSettings.ss = exports.DefaultUrl;
|
|
23363
23363
|
super(config);
|
|
23364
|
-
this.VERSION = "1.2.
|
|
23364
|
+
this.VERSION = "1.2.15";
|
|
23365
23365
|
this.settings = settings;
|
|
23366
23366
|
this.session = new Session_1.Session();
|
|
23367
23367
|
this._initialSettings = config.initialSettings;
|
|
@@ -23502,6 +23502,7 @@ exports.ArcwareInit = ArcwareInit;
|
|
|
23502
23502
|
|
|
23503
23503
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
23504
23504
|
exports.ArcwarePixelStreaming = void 0;
|
|
23505
|
+
const tslib_1 = __webpack_require__(655);
|
|
23505
23506
|
const shared_pixelstreaming_websdk_1 = __webpack_require__(7910);
|
|
23506
23507
|
const lib_pixelstreamingfrontend_ue5_5_1 = __webpack_require__(693);
|
|
23507
23508
|
const ApplyUrlHack_1 = __webpack_require__(4790);
|
|
@@ -23512,6 +23513,7 @@ const LoveLetters_1 = __webpack_require__(4572);
|
|
|
23512
23513
|
const ArcwareLogoLoader_1 = __webpack_require__(6469);
|
|
23513
23514
|
const MicrophoneOverlay_1 = __webpack_require__(3613);
|
|
23514
23515
|
const ConnectionIdentifier_1 = __webpack_require__(5999);
|
|
23516
|
+
const DiagnosticsCollector_1 = __webpack_require__(6478);
|
|
23515
23517
|
class ArcwarePixelStreaming extends lib_pixelstreamingfrontend_ue5_5_1.PixelStreaming {
|
|
23516
23518
|
/** Returns a list of WebSocketStates of all PixelStreaming Instances generated. */
|
|
23517
23519
|
get WebsocketStates() {
|
|
@@ -23559,6 +23561,9 @@ class ArcwarePixelStreaming extends lib_pixelstreamingfrontend_ue5_5_1.PixelStre
|
|
|
23559
23561
|
this.config = config;
|
|
23560
23562
|
this.loveLettersList = [];
|
|
23561
23563
|
this.microphoneOverlay = new MicrophoneOverlay_1.MicrophoneOverlay(this);
|
|
23564
|
+
this.diagnosticsCollector = new DiagnosticsCollector_1.DiagnosticsCollector({
|
|
23565
|
+
enableBandwidthProbe: false,
|
|
23566
|
+
});
|
|
23562
23567
|
// this.loveLettersContainer = null;
|
|
23563
23568
|
this.wrapWebSocketOnCloseHandler();
|
|
23564
23569
|
// Bind the event listener function to the class instance
|
|
@@ -23617,7 +23622,10 @@ class ArcwarePixelStreaming extends lib_pixelstreamingfrontend_ue5_5_1.PixelStre
|
|
|
23617
23622
|
*/
|
|
23618
23623
|
/** On version requested, the version of the WebSDK would be returned. */
|
|
23619
23624
|
onVersion(message) {
|
|
23620
|
-
|
|
23625
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
23626
|
+
const diagnostics = yield this.diagnosticsCollector.collect();
|
|
23627
|
+
this.send({ type: "version", version: this.config.VERSION, diagnostics });
|
|
23628
|
+
});
|
|
23621
23629
|
}
|
|
23622
23630
|
/** On ping the session creation timestamp will be updated. */
|
|
23623
23631
|
onPing(message) {
|
|
@@ -23949,6 +23957,339 @@ class ArcwarePixelStreaming extends lib_pixelstreamingfrontend_ue5_5_1.PixelStre
|
|
|
23949
23957
|
exports.ArcwarePixelStreaming = ArcwarePixelStreaming;
|
|
23950
23958
|
|
|
23951
23959
|
|
|
23960
|
+
/***/ }),
|
|
23961
|
+
|
|
23962
|
+
/***/ 6478:
|
|
23963
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
23964
|
+
|
|
23965
|
+
|
|
23966
|
+
/**
|
|
23967
|
+
* DiagnosticsCollector.ts
|
|
23968
|
+
* Lightweight, privacy-aware client diagnostics for troubleshooting + analytics.
|
|
23969
|
+
* WebRTC collection intentionally omitted (to add later).
|
|
23970
|
+
*
|
|
23971
|
+
* Notes:
|
|
23972
|
+
* - Some fields are best-effort due to browser restrictions; they're nullable.
|
|
23973
|
+
* - Bandwidth probe requires a small binary served with:
|
|
23974
|
+
* Content-Type: application/octet-stream
|
|
23975
|
+
* Content-Encoding: identity
|
|
23976
|
+
* Cache-Control: no-store
|
|
23977
|
+
* Default location: /diag/probe.bin
|
|
23978
|
+
*/
|
|
23979
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
23980
|
+
exports.DiagnosticsCollector = void 0;
|
|
23981
|
+
const tslib_1 = __webpack_require__(655);
|
|
23982
|
+
/**
|
|
23983
|
+
* DiagnosticsCollector
|
|
23984
|
+
*/
|
|
23985
|
+
class DiagnosticsCollector {
|
|
23986
|
+
constructor(opts = {}) {
|
|
23987
|
+
var _a, _b, _c, _d;
|
|
23988
|
+
this.opts = {
|
|
23989
|
+
enableBandwidthProbe: (_a = opts.enableBandwidthProbe) !== null && _a !== void 0 ? _a : true,
|
|
23990
|
+
probeUrl: (_b = opts.probeUrl) !== null && _b !== void 0 ? _b : '/diag/probe.bin',
|
|
23991
|
+
respectSaveData: (_c = opts.respectSaveData) !== null && _c !== void 0 ? _c : true,
|
|
23992
|
+
sampleRate: Math.max(0, Math.min(1, (_d = opts.sampleRate) !== null && _d !== void 0 ? _d : 1))
|
|
23993
|
+
};
|
|
23994
|
+
}
|
|
23995
|
+
/**
|
|
23996
|
+
* Collect the diagnostics payload.
|
|
23997
|
+
*/
|
|
23998
|
+
collect() {
|
|
23999
|
+
var _a, _b;
|
|
24000
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
24001
|
+
if (!this.shouldSample()) {
|
|
24002
|
+
return {
|
|
24003
|
+
device: { type: 'desktop', touchSupport: false },
|
|
24004
|
+
runtime: { browser: { family: 'Unknown', version: null }, os: { family: 'Unknown', version: null } },
|
|
24005
|
+
powerHints: { saveData: null, prefersReducedData: null, prefersReducedMotion: null },
|
|
24006
|
+
network: { type: null, effectiveType: null, downlinkMbps: null, rttMs: null, measuredDownlinkMbps: null },
|
|
24007
|
+
timestamps: { collectedAt: Date.now() }
|
|
24008
|
+
};
|
|
24009
|
+
}
|
|
24010
|
+
const collectedAt = Date.now();
|
|
24011
|
+
const [uaInfo, codecSupport, measuredDownlinkMbps] = yield Promise.all([
|
|
24012
|
+
this.getUAInfo(),
|
|
24013
|
+
this.getCodecSupport(),
|
|
24014
|
+
this.maybeMeasureBandwidth()
|
|
24015
|
+
]);
|
|
24016
|
+
return {
|
|
24017
|
+
device: {
|
|
24018
|
+
type: this.inferDeviceType(),
|
|
24019
|
+
vendor: null,
|
|
24020
|
+
model: uaInfo.model,
|
|
24021
|
+
architecture: uaInfo.architecture,
|
|
24022
|
+
bitness: uaInfo.bitness,
|
|
24023
|
+
touchSupport: this.hasTouch(),
|
|
24024
|
+
hardwareConcurrency: (_a = navigator.hardwareConcurrency) !== null && _a !== void 0 ? _a : null,
|
|
24025
|
+
deviceMemory: (_b = navigator.deviceMemory) !== null && _b !== void 0 ? _b : null,
|
|
24026
|
+
orientation: this.getOrientation(),
|
|
24027
|
+
webgl: this.hasWebGL(),
|
|
24028
|
+
codecs: codecSupport
|
|
24029
|
+
},
|
|
24030
|
+
runtime: {
|
|
24031
|
+
browser: { family: uaInfo.browserFamily, version: uaInfo.browserVersion },
|
|
24032
|
+
os: { family: uaInfo.osFamily, version: uaInfo.osVersion }
|
|
24033
|
+
},
|
|
24034
|
+
powerHints: this.getPowerHints(),
|
|
24035
|
+
network: this.getNetworkInfo(measuredDownlinkMbps),
|
|
24036
|
+
timestamps: { collectedAt }
|
|
24037
|
+
};
|
|
24038
|
+
});
|
|
24039
|
+
}
|
|
24040
|
+
/**
|
|
24041
|
+
* Collect a safe subset of WebRTC stats once PC is connected.
|
|
24042
|
+
*/
|
|
24043
|
+
collectWebRTC(pc) {
|
|
24044
|
+
var _a, _b, _c, _d, _e, _f;
|
|
24045
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
24046
|
+
try {
|
|
24047
|
+
const stats = yield pc.getStats();
|
|
24048
|
+
let selected, transport, local, remote;
|
|
24049
|
+
stats.forEach((r) => {
|
|
24050
|
+
if (r.type === 'transport' && r.selectedCandidatePairId)
|
|
24051
|
+
transport = r;
|
|
24052
|
+
if (r.type === 'candidate-pair' && (r.selected || r.nominated))
|
|
24053
|
+
selected = r;
|
|
24054
|
+
});
|
|
24055
|
+
if (selected) {
|
|
24056
|
+
local = stats.get(selected.localCandidateId);
|
|
24057
|
+
remote = stats.get(selected.remoteCandidateId);
|
|
24058
|
+
}
|
|
24059
|
+
return {
|
|
24060
|
+
candidatePairId: (_a = selected === null || selected === void 0 ? void 0 : selected.id) !== null && _a !== void 0 ? _a : null,
|
|
24061
|
+
localCandidateType: (_b = local === null || local === void 0 ? void 0 : local.candidateType) !== null && _b !== void 0 ? _b : null,
|
|
24062
|
+
remoteCandidateType: (_c = remote === null || remote === void 0 ? void 0 : remote.candidateType) !== null && _c !== void 0 ? _c : null,
|
|
24063
|
+
protocol: (_d = local === null || local === void 0 ? void 0 : local.protocol) !== null && _d !== void 0 ? _d : null,
|
|
24064
|
+
networkType: (_e = local === null || local === void 0 ? void 0 : local.networkType) !== null && _e !== void 0 ? _e : null,
|
|
24065
|
+
dtlsCipher: (_f = transport === null || transport === void 0 ? void 0 : transport.dtlsCipher) !== null && _f !== void 0 ? _f : null
|
|
24066
|
+
};
|
|
24067
|
+
}
|
|
24068
|
+
catch (_g) {
|
|
24069
|
+
return {};
|
|
24070
|
+
}
|
|
24071
|
+
});
|
|
24072
|
+
}
|
|
24073
|
+
/**
|
|
24074
|
+
* Helper to embed diagnostics in a hello envelope.
|
|
24075
|
+
*/
|
|
24076
|
+
buildHelloEnvelope(base, pc) {
|
|
24077
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
24078
|
+
const diag = yield this.collect();
|
|
24079
|
+
const webrtc = pc ? yield this.collectWebRTC(pc) : undefined;
|
|
24080
|
+
const ext = webrtc ? { diag: Object.assign(Object.assign({}, diag), { webrtc }) } : { diag };
|
|
24081
|
+
return Object.assign(Object.assign({}, base), { ext });
|
|
24082
|
+
});
|
|
24083
|
+
}
|
|
24084
|
+
// ---------- Internals ----------
|
|
24085
|
+
shouldSample() {
|
|
24086
|
+
if (this.opts.sampleRate >= 1)
|
|
24087
|
+
return true;
|
|
24088
|
+
return Math.random() < this.opts.sampleRate;
|
|
24089
|
+
}
|
|
24090
|
+
hasTouch() {
|
|
24091
|
+
var _a;
|
|
24092
|
+
const nav = navigator;
|
|
24093
|
+
return 'ontouchstart' in window || ((_a = nav.maxTouchPoints) !== null && _a !== void 0 ? _a : 0) > 0;
|
|
24094
|
+
}
|
|
24095
|
+
getOrientation() {
|
|
24096
|
+
var _a;
|
|
24097
|
+
try {
|
|
24098
|
+
if ((_a = screen.orientation) === null || _a === void 0 ? void 0 : _a.type) {
|
|
24099
|
+
return screen.orientation.type.startsWith('portrait') ? 'portrait' : 'landscape';
|
|
24100
|
+
}
|
|
24101
|
+
if (window.matchMedia) {
|
|
24102
|
+
return window.matchMedia('(orientation: portrait)').matches ? 'portrait' : 'landscape';
|
|
24103
|
+
}
|
|
24104
|
+
}
|
|
24105
|
+
catch (_b) { }
|
|
24106
|
+
return null;
|
|
24107
|
+
}
|
|
24108
|
+
hasWebGL() {
|
|
24109
|
+
try {
|
|
24110
|
+
const canvas = document.createElement('canvas');
|
|
24111
|
+
return !!(canvas.getContext('webgl') || canvas.getContext('experimental-webgl'));
|
|
24112
|
+
}
|
|
24113
|
+
catch (_a) {
|
|
24114
|
+
return false;
|
|
24115
|
+
}
|
|
24116
|
+
}
|
|
24117
|
+
/**
|
|
24118
|
+
* Heuristic device type: best-effort only.
|
|
24119
|
+
*/
|
|
24120
|
+
inferDeviceType() {
|
|
24121
|
+
const uaData = navigator.userAgentData;
|
|
24122
|
+
const isMobileCH = (uaData === null || uaData === void 0 ? void 0 : uaData.mobile) === true;
|
|
24123
|
+
const minDim = Math.min(screen.width, screen.height);
|
|
24124
|
+
if (isMobileCH && minDim >= 600)
|
|
24125
|
+
return 'tablet';
|
|
24126
|
+
if (isMobileCH)
|
|
24127
|
+
return 'mobile';
|
|
24128
|
+
if (/\b(iPad|Tablet)\b/i.test(navigator.userAgent))
|
|
24129
|
+
return 'tablet';
|
|
24130
|
+
if (('ontouchstart' in window) && minDim >= 600 && minDim <= 1100)
|
|
24131
|
+
return 'tablet';
|
|
24132
|
+
return 'desktop';
|
|
24133
|
+
}
|
|
24134
|
+
getPowerHints() {
|
|
24135
|
+
const conn = navigator.connection;
|
|
24136
|
+
const saveData = typeof (conn === null || conn === void 0 ? void 0 : conn.saveData) === 'boolean' ? conn.saveData : null;
|
|
24137
|
+
let prefersReducedData = null;
|
|
24138
|
+
let prefersReducedMotion = null;
|
|
24139
|
+
if (typeof window.matchMedia === 'function') {
|
|
24140
|
+
try {
|
|
24141
|
+
const mqData = window.matchMedia('(prefers-reduced-data: reduce)');
|
|
24142
|
+
if (typeof mqData.matches === 'boolean') {
|
|
24143
|
+
prefersReducedData = mqData.matches;
|
|
24144
|
+
}
|
|
24145
|
+
}
|
|
24146
|
+
catch (_a) { }
|
|
24147
|
+
try {
|
|
24148
|
+
const mqMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
|
|
24149
|
+
if (typeof mqMotion.matches === 'boolean') {
|
|
24150
|
+
prefersReducedMotion = mqMotion.matches;
|
|
24151
|
+
}
|
|
24152
|
+
}
|
|
24153
|
+
catch (_b) { }
|
|
24154
|
+
}
|
|
24155
|
+
return { saveData, prefersReducedData, prefersReducedMotion };
|
|
24156
|
+
}
|
|
24157
|
+
getNetworkInfo(measuredDownlinkMbps) {
|
|
24158
|
+
const conn = navigator.connection;
|
|
24159
|
+
return {
|
|
24160
|
+
type: (typeof (conn === null || conn === void 0 ? void 0 : conn.type) === 'string') ? conn.type : null,
|
|
24161
|
+
effectiveType: (typeof (conn === null || conn === void 0 ? void 0 : conn.effectiveType) === 'string') ? conn.effectiveType : null,
|
|
24162
|
+
downlinkMbps: (typeof (conn === null || conn === void 0 ? void 0 : conn.downlink) === 'number') ? conn.downlink : null,
|
|
24163
|
+
rttMs: (typeof (conn === null || conn === void 0 ? void 0 : conn.rtt) === 'number') ? conn.rtt : null,
|
|
24164
|
+
measuredDownlinkMbps
|
|
24165
|
+
};
|
|
24166
|
+
}
|
|
24167
|
+
maybeMeasureBandwidth() {
|
|
24168
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
24169
|
+
const conn = navigator.connection;
|
|
24170
|
+
const saveData = (conn === null || conn === void 0 ? void 0 : conn.saveData) === true;
|
|
24171
|
+
if (!this.opts.enableBandwidthProbe)
|
|
24172
|
+
return null;
|
|
24173
|
+
if (this.opts.respectSaveData && saveData)
|
|
24174
|
+
return null;
|
|
24175
|
+
try {
|
|
24176
|
+
const t0 = performance.now();
|
|
24177
|
+
const res = yield fetch(this.withCacheBuster(this.opts.probeUrl), {
|
|
24178
|
+
cache: 'no-store',
|
|
24179
|
+
credentials: 'omit'
|
|
24180
|
+
});
|
|
24181
|
+
const buf = yield res.arrayBuffer();
|
|
24182
|
+
const t1 = performance.now();
|
|
24183
|
+
const bits = buf.byteLength * 8;
|
|
24184
|
+
const seconds = (t1 - t0) / 1000;
|
|
24185
|
+
if (seconds <= 0.05)
|
|
24186
|
+
return null; // ignore unstable samples
|
|
24187
|
+
return +((bits / seconds) / 1000000).toFixed(2);
|
|
24188
|
+
}
|
|
24189
|
+
catch (_a) {
|
|
24190
|
+
return null;
|
|
24191
|
+
}
|
|
24192
|
+
});
|
|
24193
|
+
}
|
|
24194
|
+
withCacheBuster(url) {
|
|
24195
|
+
var _a, _b;
|
|
24196
|
+
const u = new URL(url, location.origin);
|
|
24197
|
+
const token = (_b = (_a = crypto === null || crypto === void 0 ? void 0 : crypto.randomUUID) === null || _a === void 0 ? void 0 : _a.call(crypto)) !== null && _b !== void 0 ? _b : String(Date.now());
|
|
24198
|
+
u.searchParams.set('cb', token);
|
|
24199
|
+
return u.toString();
|
|
24200
|
+
}
|
|
24201
|
+
getCodecSupport() {
|
|
24202
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
24203
|
+
const [h264, hevc] = yield Promise.all([
|
|
24204
|
+
this.supportsCodec('video/mp4; codecs="avc1.42E01E"'),
|
|
24205
|
+
this.supportsCodec('video/mp4; codecs="hvc1.1.6.L93.B0"')
|
|
24206
|
+
]);
|
|
24207
|
+
return { h264, hevc };
|
|
24208
|
+
});
|
|
24209
|
+
}
|
|
24210
|
+
supportsCodec(mime) {
|
|
24211
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
24212
|
+
try {
|
|
24213
|
+
if ('mediaCapabilities' in navigator) {
|
|
24214
|
+
// @ts-ignore
|
|
24215
|
+
const res = yield navigator.mediaCapabilities.decodingInfo({
|
|
24216
|
+
type: 'file',
|
|
24217
|
+
video: { contentType: mime, width: 1920, height: 1080, bitrate: 5000000, framerate: 30 }
|
|
24218
|
+
});
|
|
24219
|
+
return !!(res === null || res === void 0 ? void 0 : res.supported);
|
|
24220
|
+
}
|
|
24221
|
+
}
|
|
24222
|
+
catch (_a) { }
|
|
24223
|
+
try {
|
|
24224
|
+
const v = document.createElement('video');
|
|
24225
|
+
return v.canPlayType(mime) !== '';
|
|
24226
|
+
}
|
|
24227
|
+
catch (_b) {
|
|
24228
|
+
return false;
|
|
24229
|
+
}
|
|
24230
|
+
});
|
|
24231
|
+
}
|
|
24232
|
+
getUAInfo() {
|
|
24233
|
+
var _a, _b;
|
|
24234
|
+
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
24235
|
+
const nav = navigator;
|
|
24236
|
+
const uaData = nav.userAgentData;
|
|
24237
|
+
let browserFamily = 'Unknown', browserVersion = null;
|
|
24238
|
+
let osFamily = 'Unknown', osVersion = null;
|
|
24239
|
+
let model = null, architecture = null, bitness = null;
|
|
24240
|
+
if (uaData === null || uaData === void 0 ? void 0 : uaData.getHighEntropyValues) {
|
|
24241
|
+
try {
|
|
24242
|
+
const high = yield uaData.getHighEntropyValues([
|
|
24243
|
+
'platform', 'platformVersion', 'model', 'architecture', 'bitness', 'fullVersionList'
|
|
24244
|
+
]);
|
|
24245
|
+
osFamily = high.platform || 'Unknown';
|
|
24246
|
+
osVersion = high.platformVersion || null;
|
|
24247
|
+
model = high.model || null;
|
|
24248
|
+
architecture = high.architecture || null;
|
|
24249
|
+
bitness = high.bitness || null;
|
|
24250
|
+
const brands = high.fullVersionList || uaData.brands || [];
|
|
24251
|
+
const real = brands.find(b => b.brand && !/Chromium|Not:?A-?Brand/i.test(b.brand));
|
|
24252
|
+
browserFamily = (real === null || real === void 0 ? void 0 : real.brand) || ((_a = brands[0]) === null || _a === void 0 ? void 0 : _a.brand) || 'Unknown';
|
|
24253
|
+
browserVersion = (real === null || real === void 0 ? void 0 : real.version) || ((_b = brands[0]) === null || _b === void 0 ? void 0 : _b.version) || null;
|
|
24254
|
+
}
|
|
24255
|
+
catch (_c) { }
|
|
24256
|
+
}
|
|
24257
|
+
if (browserFamily === 'Unknown') {
|
|
24258
|
+
const ua = navigator.userAgent;
|
|
24259
|
+
if (/Firefox\/(\S+)/.test(ua)) {
|
|
24260
|
+
browserFamily = 'Firefox';
|
|
24261
|
+
browserVersion = RegExp.$1;
|
|
24262
|
+
}
|
|
24263
|
+
else if (/Edg\/(\S+)/.test(ua)) {
|
|
24264
|
+
browserFamily = 'Edge';
|
|
24265
|
+
browserVersion = RegExp.$1;
|
|
24266
|
+
}
|
|
24267
|
+
else if (/Chrome\/(\S+)/.test(ua)) {
|
|
24268
|
+
browserFamily = 'Chrome';
|
|
24269
|
+
browserVersion = RegExp.$1;
|
|
24270
|
+
}
|
|
24271
|
+
else if (/Version\/(\S+).*Safari/.test(ua)) {
|
|
24272
|
+
browserFamily = 'Safari';
|
|
24273
|
+
browserVersion = RegExp.$1;
|
|
24274
|
+
}
|
|
24275
|
+
if (/Windows/.test(ua))
|
|
24276
|
+
osFamily = 'Windows';
|
|
24277
|
+
else if (/Mac OS X/.test(ua))
|
|
24278
|
+
osFamily = 'macOS';
|
|
24279
|
+
else if (/Android/.test(ua))
|
|
24280
|
+
osFamily = 'Android';
|
|
24281
|
+
else if (/iPhone|iPad|iPod/.test(ua))
|
|
24282
|
+
osFamily = 'iOS';
|
|
24283
|
+
else if (/Linux/.test(ua))
|
|
24284
|
+
osFamily = 'Linux';
|
|
24285
|
+
}
|
|
24286
|
+
return { browserFamily, browserVersion, osFamily, osVersion, model, architecture, bitness };
|
|
24287
|
+
});
|
|
24288
|
+
}
|
|
24289
|
+
}
|
|
24290
|
+
exports.DiagnosticsCollector = DiagnosticsCollector;
|
|
24291
|
+
|
|
24292
|
+
|
|
23952
24293
|
/***/ }),
|
|
23953
24294
|
|
|
23954
24295
|
/***/ 5602:
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@arcware-cloud/pixelstreaming-websdk",
|
|
3
3
|
"description": "WebSDK for easy implementation of pixel streaming with Arcware Cloud Services. Heavily based on the '@epicgames-ps' library.",
|
|
4
|
-
"version": "1.2.
|
|
4
|
+
"version": "1.2.15",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./index.umd.js",
|
|
7
7
|
"module": "./index.umd.js",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
],
|
|
16
16
|
"author": {
|
|
17
17
|
"name": "Arcware GmbH",
|
|
18
|
-
"email": "
|
|
18
|
+
"email": "info@arcware.com",
|
|
19
19
|
"url": "https://www.arcware.com"
|
|
20
20
|
},
|
|
21
21
|
"license": "MIT",
|