yjz-web-sdk 1.0.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.
@@ -0,0 +1,3872 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+ function _mergeNamespaces(n, m) {
5
+ for (var i = 0; i < m.length; i++) {
6
+ const e = m[i];
7
+ if (typeof e !== "string" && !Array.isArray(e)) {
8
+ for (const k in e) {
9
+ if (k !== "default" && !(k in n)) {
10
+ const d = Object.getOwnPropertyDescriptor(e, k);
11
+ if (d) {
12
+ Object.defineProperty(n, k, d.get ? d : {
13
+ enumerable: true,
14
+ get: () => e[k]
15
+ });
16
+ }
17
+ }
18
+ }
19
+ }
20
+ }
21
+ return Object.freeze(Object.defineProperty(n, Symbol.toStringTag, { value: "Module" }));
22
+ }
23
+ function getDefaultExportFromCjs(x) {
24
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
25
+ }
26
+ var eventemitter3 = { exports: {} };
27
+ var hasRequiredEventemitter3;
28
+ function requireEventemitter3() {
29
+ if (hasRequiredEventemitter3) return eventemitter3.exports;
30
+ hasRequiredEventemitter3 = 1;
31
+ (function(module) {
32
+ var has = Object.prototype.hasOwnProperty, prefix = "~";
33
+ function Events() {
34
+ }
35
+ if (Object.create) {
36
+ Events.prototype = /* @__PURE__ */ Object.create(null);
37
+ if (!new Events().__proto__) prefix = false;
38
+ }
39
+ function EE(fn, context, once) {
40
+ this.fn = fn;
41
+ this.context = context;
42
+ this.once = once || false;
43
+ }
44
+ function addListener(emitter, event, fn, context, once) {
45
+ if (typeof fn !== "function") {
46
+ throw new TypeError("The listener must be a function");
47
+ }
48
+ var listener = new EE(fn, context || emitter, once), evt = prefix ? prefix + event : event;
49
+ if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++;
50
+ else if (!emitter._events[evt].fn) emitter._events[evt].push(listener);
51
+ else emitter._events[evt] = [emitter._events[evt], listener];
52
+ return emitter;
53
+ }
54
+ function clearEvent(emitter, evt) {
55
+ if (--emitter._eventsCount === 0) emitter._events = new Events();
56
+ else delete emitter._events[evt];
57
+ }
58
+ function EventEmitter2() {
59
+ this._events = new Events();
60
+ this._eventsCount = 0;
61
+ }
62
+ EventEmitter2.prototype.eventNames = function eventNames() {
63
+ var names = [], events, name;
64
+ if (this._eventsCount === 0) return names;
65
+ for (name in events = this._events) {
66
+ if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);
67
+ }
68
+ if (Object.getOwnPropertySymbols) {
69
+ return names.concat(Object.getOwnPropertySymbols(events));
70
+ }
71
+ return names;
72
+ };
73
+ EventEmitter2.prototype.listeners = function listeners(event) {
74
+ var evt = prefix ? prefix + event : event, handlers = this._events[evt];
75
+ if (!handlers) return [];
76
+ if (handlers.fn) return [handlers.fn];
77
+ for (var i = 0, l = handlers.length, ee = new Array(l); i < l; i++) {
78
+ ee[i] = handlers[i].fn;
79
+ }
80
+ return ee;
81
+ };
82
+ EventEmitter2.prototype.listenerCount = function listenerCount(event) {
83
+ var evt = prefix ? prefix + event : event, listeners = this._events[evt];
84
+ if (!listeners) return 0;
85
+ if (listeners.fn) return 1;
86
+ return listeners.length;
87
+ };
88
+ EventEmitter2.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {
89
+ var evt = prefix ? prefix + event : event;
90
+ if (!this._events[evt]) return false;
91
+ var listeners = this._events[evt], len = arguments.length, args, i;
92
+ if (listeners.fn) {
93
+ if (listeners.once) this.removeListener(event, listeners.fn, void 0, true);
94
+ switch (len) {
95
+ case 1:
96
+ return listeners.fn.call(listeners.context), true;
97
+ case 2:
98
+ return listeners.fn.call(listeners.context, a1), true;
99
+ case 3:
100
+ return listeners.fn.call(listeners.context, a1, a2), true;
101
+ case 4:
102
+ return listeners.fn.call(listeners.context, a1, a2, a3), true;
103
+ case 5:
104
+ return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;
105
+ case 6:
106
+ return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;
107
+ }
108
+ for (i = 1, args = new Array(len - 1); i < len; i++) {
109
+ args[i - 1] = arguments[i];
110
+ }
111
+ listeners.fn.apply(listeners.context, args);
112
+ } else {
113
+ var length = listeners.length, j;
114
+ for (i = 0; i < length; i++) {
115
+ if (listeners[i].once) this.removeListener(event, listeners[i].fn, void 0, true);
116
+ switch (len) {
117
+ case 1:
118
+ listeners[i].fn.call(listeners[i].context);
119
+ break;
120
+ case 2:
121
+ listeners[i].fn.call(listeners[i].context, a1);
122
+ break;
123
+ case 3:
124
+ listeners[i].fn.call(listeners[i].context, a1, a2);
125
+ break;
126
+ case 4:
127
+ listeners[i].fn.call(listeners[i].context, a1, a2, a3);
128
+ break;
129
+ default:
130
+ if (!args) for (j = 1, args = new Array(len - 1); j < len; j++) {
131
+ args[j - 1] = arguments[j];
132
+ }
133
+ listeners[i].fn.apply(listeners[i].context, args);
134
+ }
135
+ }
136
+ }
137
+ return true;
138
+ };
139
+ EventEmitter2.prototype.on = function on(event, fn, context) {
140
+ return addListener(this, event, fn, context, false);
141
+ };
142
+ EventEmitter2.prototype.once = function once(event, fn, context) {
143
+ return addListener(this, event, fn, context, true);
144
+ };
145
+ EventEmitter2.prototype.removeListener = function removeListener(event, fn, context, once) {
146
+ var evt = prefix ? prefix + event : event;
147
+ if (!this._events[evt]) return this;
148
+ if (!fn) {
149
+ clearEvent(this, evt);
150
+ return this;
151
+ }
152
+ var listeners = this._events[evt];
153
+ if (listeners.fn) {
154
+ if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) {
155
+ clearEvent(this, evt);
156
+ }
157
+ } else {
158
+ for (var i = 0, events = [], length = listeners.length; i < length; i++) {
159
+ if (listeners[i].fn !== fn || once && !listeners[i].once || context && listeners[i].context !== context) {
160
+ events.push(listeners[i]);
161
+ }
162
+ }
163
+ if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;
164
+ else clearEvent(this, evt);
165
+ }
166
+ return this;
167
+ };
168
+ EventEmitter2.prototype.removeAllListeners = function removeAllListeners(event) {
169
+ var evt;
170
+ if (event) {
171
+ evt = prefix ? prefix + event : event;
172
+ if (this._events[evt]) clearEvent(this, evt);
173
+ } else {
174
+ this._events = new Events();
175
+ this._eventsCount = 0;
176
+ }
177
+ return this;
178
+ };
179
+ EventEmitter2.prototype.off = EventEmitter2.prototype.removeListener;
180
+ EventEmitter2.prototype.addListener = EventEmitter2.prototype.on;
181
+ EventEmitter2.prefixed = prefix;
182
+ EventEmitter2.EventEmitter = EventEmitter2;
183
+ {
184
+ module.exports = EventEmitter2;
185
+ }
186
+ })(eventemitter3);
187
+ return eventemitter3.exports;
188
+ }
189
+ var eventemitter3Exports = requireEventemitter3();
190
+ const EventEmitter = /* @__PURE__ */ getDefaultExportFromCjs(eventemitter3Exports);
191
+ var MessageType = /* @__PURE__ */ ((MessageType2) => {
192
+ MessageType2["Peers"] = "Peers";
193
+ MessageType2["Offer"] = "Offer";
194
+ MessageType2["Answer"] = "Answer";
195
+ MessageType2["IceCandidates"] = "IceCandidates";
196
+ MessageType2["SignOut"] = "SignOut";
197
+ MessageType2["NotAvailable"] = "NotAvailable";
198
+ MessageType2["Ping"] = "Ping";
199
+ MessageType2["Pong"] = "Pong";
200
+ return MessageType2;
201
+ })(MessageType || {});
202
+ var SendType = /* @__PURE__ */ ((SendType2) => {
203
+ SendType2["SignIn"] = "SignIn";
204
+ SendType2["SignOut"] = "SignOut";
205
+ SendType2["Answer"] = "Answer";
206
+ SendType2["Offer"] = "Offer";
207
+ SendType2["IceCandidates"] = "IceCandidates";
208
+ SendType2["Pong"] = "Pong";
209
+ SendType2["Identity"] = "Web";
210
+ return SendType2;
211
+ })(SendType || {});
212
+ var FailCode = /* @__PURE__ */ ((FailCode2) => {
213
+ FailCode2[FailCode2["SOCKET"] = 10001] = "SOCKET";
214
+ FailCode2[FailCode2["SOCKET_CLOSE"] = 10002] = "SOCKET_CLOSE";
215
+ FailCode2[FailCode2["CREATE_OFFER"] = 10003] = "CREATE_OFFER";
216
+ FailCode2[FailCode2["HANDLE_OFFER"] = 10004] = "HANDLE_OFFER";
217
+ FailCode2[FailCode2["CREATE_ANSWER"] = 10005] = "CREATE_ANSWER";
218
+ FailCode2[FailCode2["HANDLE_ANSWER"] = 10006] = "HANDLE_ANSWER";
219
+ FailCode2[FailCode2["LOCAL_DES"] = 10007] = "LOCAL_DES";
220
+ FailCode2[FailCode2["REMOTE_DES"] = 10008] = "REMOTE_DES";
221
+ FailCode2[FailCode2["HANDLE_ICE"] = 10009] = "HANDLE_ICE";
222
+ FailCode2[FailCode2["ICE_STATE"] = 10010] = "ICE_STATE";
223
+ FailCode2[FailCode2["CAMERA"] = 10011] = "CAMERA";
224
+ FailCode2[FailCode2["NOT_AVAILABLE"] = 10012] = "NOT_AVAILABLE";
225
+ FailCode2[FailCode2["DATACHANNEL_ERR"] = 10013] = "DATACHANNEL_ERR";
226
+ FailCode2[FailCode2["STREAM_STATE"] = 10014] = "STREAM_STATE";
227
+ return FailCode2;
228
+ })(FailCode || {});
229
+ const FailInfoMap = {
230
+ [
231
+ 10001
232
+ /* SOCKET */
233
+ ]: { type: "socket", description: "WebSocket连接失败" },
234
+ [
235
+ 10002
236
+ /* SOCKET_CLOSE */
237
+ ]: { type: "socket_close", description: "WebSocket已关闭" },
238
+ [
239
+ 10003
240
+ /* CREATE_OFFER */
241
+ ]: { type: "createOffer", description: "创建offer失败" },
242
+ [
243
+ 10004
244
+ /* HANDLE_OFFER */
245
+ ]: { type: "handleOffer", description: "处理offer失败" },
246
+ [
247
+ 10005
248
+ /* CREATE_ANSWER */
249
+ ]: { type: "createAnswer", description: "创建answer失败" },
250
+ [
251
+ 10006
252
+ /* HANDLE_ANSWER */
253
+ ]: { type: "handleAnswer", description: "处理answer失败" },
254
+ [
255
+ 10007
256
+ /* LOCAL_DES */
257
+ ]: { type: "setLocalDescription", description: "设置本地描述失败" },
258
+ [
259
+ 10008
260
+ /* REMOTE_DES */
261
+ ]: { type: "setRemoteDescription", description: "设置远端描述失败" },
262
+ [
263
+ 10009
264
+ /* HANDLE_ICE */
265
+ ]: { type: "handleICE", description: "处理 ICE 失败" },
266
+ [
267
+ 10010
268
+ /* ICE_STATE */
269
+ ]: { type: "iceState", description: "ICE 状态异常" },
270
+ [
271
+ 10011
272
+ /* CAMERA */
273
+ ]: { type: "camera", description: "摄像头异常" },
274
+ [
275
+ 10012
276
+ /* NOT_AVAILABLE */
277
+ ]: { type: "notAvailable", description: "云机已关机或者不存在" },
278
+ [
279
+ 10013
280
+ /* DATACHANNEL_ERR */
281
+ ]: { type: "datachannel_err", description: "信令通道错误" },
282
+ [
283
+ 10014
284
+ /* STREAM_STATE */
285
+ ]: { type: "stream_state", description: "webrtc统计信息获取失败" }
286
+ };
287
+ function createWebRtcError(code, rawError) {
288
+ const info = FailInfoMap[code];
289
+ return {
290
+ code,
291
+ type: info.type,
292
+ message: info.description,
293
+ rawError
294
+ };
295
+ }
296
+ var EmitType = /* @__PURE__ */ ((EmitType2) => {
297
+ EmitType2["signalMessage"] = "signalMessage";
298
+ EmitType2["webrtcError"] = "webrtcError";
299
+ EmitType2["sendAnswer"] = "sendAnswer";
300
+ EmitType2["sendOffer"] = "sendOffer";
301
+ EmitType2["sendICEMessage"] = "sendICEMessage";
302
+ EmitType2["streamTrack"] = "streamTrack";
303
+ EmitType2["iceConnectionState"] = "iceConnectionState";
304
+ EmitType2["cloudStatusChanged"] = "cloudStatusChanged";
305
+ EmitType2["statisticInfo"] = "statisticInfo";
306
+ return EmitType2;
307
+ })(EmitType || {});
308
+ class SignalingClient extends EventEmitter {
309
+ constructor(config) {
310
+ super();
311
+ // 私有属性 config,用于存储 WebRTC 配置信息
312
+ __publicField(this, "config");
313
+ // 根据实际情况替换为具体配置类型
314
+ // 私有属性 webSocket,用于存储 WebSocket 连接实例,初始值为 null
315
+ __publicField(this, "webSocket", null);
316
+ __publicField(this, "timeout", null);
317
+ this.config = config;
318
+ }
319
+ /**
320
+ * 启动 WebSocket 连接,并注册各事件处理
321
+ */
322
+ start() {
323
+ this.webSocket = new WebSocket(this.config.signalServerUrl);
324
+ this.webSocket.onopen = () => {
325
+ this.sendSignInMessage();
326
+ if (this.timeout === null) {
327
+ this.timeout = setTimeout(() => {
328
+ this.emit(EmitType.webrtcError, createWebRtcError(FailCode.NOT_AVAILABLE, ""));
329
+ this.timeout = null;
330
+ }, 4e3);
331
+ }
332
+ };
333
+ this.webSocket.onclose = () => {
334
+ this.webSocket = null;
335
+ };
336
+ this.webSocket.onerror = (event) => {
337
+ this.emit(EmitType.webrtcError, createWebRtcError(FailCode.SOCKET, event));
338
+ };
339
+ this.webSocket.onmessage = (event) => {
340
+ const message = JSON.parse(event.data);
341
+ if (message.type === MessageType.Offer) {
342
+ if (this.timeout) {
343
+ clearTimeout(this.timeout);
344
+ this.timeout = null;
345
+ }
346
+ }
347
+ this.emit(EmitType.signalMessage, message);
348
+ };
349
+ }
350
+ /**
351
+ * 关闭 WebSocket 连接,并通知外部
352
+ */
353
+ close() {
354
+ if (this.webSocket) {
355
+ this.webSocket.onopen = null;
356
+ this.webSocket.onmessage = null;
357
+ this.webSocket.onerror = null;
358
+ this.webSocket.onclose = null;
359
+ if (this.webSocket.readyState === WebSocket.OPEN || this.webSocket.readyState === WebSocket.CONNECTING) {
360
+ this.webSocket.close(1e3, "Normal Closure");
361
+ }
362
+ this.webSocket = null;
363
+ }
364
+ this.removeAllListeners();
365
+ }
366
+ /**
367
+ * 发送消息到服务端
368
+ * @param message - 消息字符串
369
+ */
370
+ sendMessage(message) {
371
+ if (this.webSocket && this.webSocket.readyState === WebSocket.OPEN) {
372
+ this.webSocket.send(message);
373
+ }
374
+ }
375
+ sendSignInMessage() {
376
+ const message = {
377
+ type: SendType.SignIn,
378
+ identity: SendType.Identity,
379
+ turnServerUri: this.config.turnServerUri,
380
+ roomId: this.config.roomId
381
+ };
382
+ const jsonMessage = JSON.stringify(message);
383
+ this.sendMessage(jsonMessage);
384
+ }
385
+ }
386
+ var ChannelDataType = /* @__PURE__ */ ((ChannelDataType2) => {
387
+ ChannelDataType2["ClickData"] = "ClickData";
388
+ ChannelDataType2["ClipboardData"] = "ClipboardData";
389
+ ChannelDataType2["ActionCommand"] = "ActionCommand";
390
+ ChannelDataType2["ActionInput"] = "ActionInput";
391
+ ChannelDataType2["ActionChinese"] = "ActionChinese";
392
+ ChannelDataType2["ActionRequestCloudDeviceInfo"] = "ActionRequestCloudDeviceInfo";
393
+ ChannelDataType2["ActionClarity"] = "ActionClarity";
394
+ return ChannelDataType2;
395
+ })(ChannelDataType || {});
396
+ const ActionType = Object.freeze({
397
+ ACTION_DOWN: 0,
398
+ ACTION_MOVE: 2,
399
+ ACTION_UP: 1
400
+ });
401
+ const StreamRotation = {
402
+ ROTATION_0: 0,
403
+ ROTATION_180: 2
404
+ };
405
+ const ContainerDirection = {
406
+ Vertical: 0,
407
+ Horizontal: 1
408
+ };
409
+ class TouchData {
410
+ constructor(action, p, x, y, offsetTime, type = "adb") {
411
+ __publicField(this, "action");
412
+ __publicField(this, "p");
413
+ __publicField(this, "x");
414
+ __publicField(this, "y");
415
+ __publicField(this, "offsetTime");
416
+ __publicField(this, "type");
417
+ this.action = action;
418
+ this.p = p;
419
+ this.x = x;
420
+ this.y = y;
421
+ this.offsetTime = offsetTime;
422
+ this.type = type;
423
+ }
424
+ }
425
+ class InputData {
426
+ constructor(text) {
427
+ __publicField(this, "text");
428
+ this.text = text;
429
+ }
430
+ }
431
+ class KeyEventData {
432
+ constructor(keyCode, meta) {
433
+ __publicField(this, "keyCode");
434
+ __publicField(this, "meta");
435
+ this.keyCode = keyCode;
436
+ this.meta = meta;
437
+ }
438
+ }
439
+ class ChannelData {
440
+ constructor(type, data = null) {
441
+ __publicField(this, "type");
442
+ __publicField(this, "data");
443
+ this.type = type;
444
+ this.data = data;
445
+ }
446
+ toString() {
447
+ return JSON.stringify({ type: this.type, data: this.data });
448
+ }
449
+ /**
450
+ * 格式化数据
451
+ * 如果数据已经是字符串,则直接返回;否则使用 JSON.stringify() 转换为字符串
452
+ * @param data 待转换数据
453
+ * @returns 格式化后的字符串
454
+ */
455
+ static formatData(data) {
456
+ return typeof data === "string" ? data : JSON.stringify(data);
457
+ }
458
+ /**
459
+ * 生成点击数据
460
+ * @param touchData 触摸数据,可以是任意类型
461
+ */
462
+ static click(touchData) {
463
+ return new ChannelData("ClickData", this.formatData(touchData));
464
+ }
465
+ /**
466
+ * 生成剪贴板数据
467
+ * @param data 剪贴板数据,可以是字符串或其他类型
468
+ */
469
+ static clipboard(data) {
470
+ return new ChannelData("ClipboardData", this.formatData(data));
471
+ }
472
+ /**
473
+ * 生成输入数据
474
+ * @param data 输入数据对象
475
+ */
476
+ static input(data) {
477
+ return new ChannelData("ActionInput", this.formatData(data));
478
+ }
479
+ /**
480
+ * 生成中文输入数据
481
+ * @param data 中文输入数据
482
+ */
483
+ static chinese(data) {
484
+ return new ChannelData("ActionChinese", this.formatData(data));
485
+ }
486
+ /**
487
+ * 生成请求云设备信息数据
488
+ */
489
+ static requestCloudDeviceInfo() {
490
+ return new ChannelData("ActionRequestCloudDeviceInfo", "");
491
+ }
492
+ /**
493
+ * 生成清晰度数据(clarity)
494
+ * @param data 清晰度数据
495
+ */
496
+ static clarity(data) {
497
+ return new ChannelData("ActionClarity", this.formatData(data));
498
+ }
499
+ }
500
+ class WebRTCConfig {
501
+ constructor(options = {}) {
502
+ __publicField(this, "signalServerUrl");
503
+ __publicField(this, "myId");
504
+ __publicField(this, "roomId");
505
+ __publicField(this, "targetId");
506
+ __publicField(this, "stunServerUri");
507
+ __publicField(this, "stunServerUriAli");
508
+ __publicField(this, "stunServerUriTel");
509
+ __publicField(this, "turnServerUri");
510
+ __publicField(this, "turnServerUserName");
511
+ __publicField(this, "turnServerPassword");
512
+ this.signalServerUrl = options.signalServerUrl || "";
513
+ this.myId = options.myId || "";
514
+ this.roomId = options.roomId || "";
515
+ this.targetId = options.targetId || "";
516
+ this.stunServerUri = options.stunServerUri || "stun:stun.l.google.com:19302";
517
+ this.stunServerUriAli = options.stunServerUriAli || "stun:stun.middle.aliyun.com:3478";
518
+ this.stunServerUriTel = options.stunServerUriTel || "stun:stun.qq.com:3478";
519
+ this.turnServerUri = options.turnServerUri || "turn:btweb.yajuzhen.com:3478";
520
+ this.turnServerUserName = options.turnServerUserName || "yangyj";
521
+ this.turnServerPassword = options.turnServerPassword || "hb@2025@168";
522
+ }
523
+ }
524
+ let logDisabled_ = true;
525
+ let deprecationWarnings_ = true;
526
+ function extractVersion(uastring, expr, pos) {
527
+ const match = uastring.match(expr);
528
+ return match && match.length >= pos && parseInt(match[pos], 10);
529
+ }
530
+ function wrapPeerConnectionEvent(window2, eventNameToWrap, wrapper) {
531
+ if (!window2.RTCPeerConnection) {
532
+ return;
533
+ }
534
+ const proto = window2.RTCPeerConnection.prototype;
535
+ const nativeAddEventListener = proto.addEventListener;
536
+ proto.addEventListener = function(nativeEventName, cb) {
537
+ if (nativeEventName !== eventNameToWrap) {
538
+ return nativeAddEventListener.apply(this, arguments);
539
+ }
540
+ const wrappedCallback = (e) => {
541
+ const modifiedEvent = wrapper(e);
542
+ if (modifiedEvent) {
543
+ if (cb.handleEvent) {
544
+ cb.handleEvent(modifiedEvent);
545
+ } else {
546
+ cb(modifiedEvent);
547
+ }
548
+ }
549
+ };
550
+ this._eventMap = this._eventMap || {};
551
+ if (!this._eventMap[eventNameToWrap]) {
552
+ this._eventMap[eventNameToWrap] = /* @__PURE__ */ new Map();
553
+ }
554
+ this._eventMap[eventNameToWrap].set(cb, wrappedCallback);
555
+ return nativeAddEventListener.apply(this, [
556
+ nativeEventName,
557
+ wrappedCallback
558
+ ]);
559
+ };
560
+ const nativeRemoveEventListener = proto.removeEventListener;
561
+ proto.removeEventListener = function(nativeEventName, cb) {
562
+ if (nativeEventName !== eventNameToWrap || !this._eventMap || !this._eventMap[eventNameToWrap]) {
563
+ return nativeRemoveEventListener.apply(this, arguments);
564
+ }
565
+ if (!this._eventMap[eventNameToWrap].has(cb)) {
566
+ return nativeRemoveEventListener.apply(this, arguments);
567
+ }
568
+ const unwrappedCb = this._eventMap[eventNameToWrap].get(cb);
569
+ this._eventMap[eventNameToWrap].delete(cb);
570
+ if (this._eventMap[eventNameToWrap].size === 0) {
571
+ delete this._eventMap[eventNameToWrap];
572
+ }
573
+ if (Object.keys(this._eventMap).length === 0) {
574
+ delete this._eventMap;
575
+ }
576
+ return nativeRemoveEventListener.apply(this, [
577
+ nativeEventName,
578
+ unwrappedCb
579
+ ]);
580
+ };
581
+ Object.defineProperty(proto, "on" + eventNameToWrap, {
582
+ get() {
583
+ return this["_on" + eventNameToWrap];
584
+ },
585
+ set(cb) {
586
+ if (this["_on" + eventNameToWrap]) {
587
+ this.removeEventListener(
588
+ eventNameToWrap,
589
+ this["_on" + eventNameToWrap]
590
+ );
591
+ delete this["_on" + eventNameToWrap];
592
+ }
593
+ if (cb) {
594
+ this.addEventListener(
595
+ eventNameToWrap,
596
+ this["_on" + eventNameToWrap] = cb
597
+ );
598
+ }
599
+ },
600
+ enumerable: true,
601
+ configurable: true
602
+ });
603
+ }
604
+ function disableLog(bool) {
605
+ if (typeof bool !== "boolean") {
606
+ return new Error("Argument type: " + typeof bool + ". Please use a boolean.");
607
+ }
608
+ logDisabled_ = bool;
609
+ return bool ? "adapter.js logging disabled" : "adapter.js logging enabled";
610
+ }
611
+ function disableWarnings(bool) {
612
+ if (typeof bool !== "boolean") {
613
+ return new Error("Argument type: " + typeof bool + ". Please use a boolean.");
614
+ }
615
+ deprecationWarnings_ = !bool;
616
+ return "adapter.js deprecation warnings " + (bool ? "disabled" : "enabled");
617
+ }
618
+ function log() {
619
+ if (typeof window === "object") {
620
+ if (logDisabled_) {
621
+ return;
622
+ }
623
+ if (typeof console !== "undefined" && typeof console.log === "function") {
624
+ console.log.apply(console, arguments);
625
+ }
626
+ }
627
+ }
628
+ function deprecated(oldMethod, newMethod) {
629
+ if (!deprecationWarnings_) {
630
+ return;
631
+ }
632
+ console.warn(oldMethod + " is deprecated, please use " + newMethod + " instead.");
633
+ }
634
+ function detectBrowser(window2) {
635
+ const result = { browser: null, version: null };
636
+ if (typeof window2 === "undefined" || !window2.navigator || !window2.navigator.userAgent) {
637
+ result.browser = "Not a browser.";
638
+ return result;
639
+ }
640
+ const { navigator: navigator2 } = window2;
641
+ if (navigator2.userAgentData && navigator2.userAgentData.brands) {
642
+ const chromium = navigator2.userAgentData.brands.find((brand) => {
643
+ return brand.brand === "Chromium";
644
+ });
645
+ if (chromium) {
646
+ return { browser: "chrome", version: parseInt(chromium.version, 10) };
647
+ }
648
+ }
649
+ if (navigator2.mozGetUserMedia) {
650
+ result.browser = "firefox";
651
+ result.version = extractVersion(
652
+ navigator2.userAgent,
653
+ /Firefox\/(\d+)\./,
654
+ 1
655
+ );
656
+ } else if (navigator2.webkitGetUserMedia || window2.isSecureContext === false && window2.webkitRTCPeerConnection) {
657
+ result.browser = "chrome";
658
+ result.version = extractVersion(
659
+ navigator2.userAgent,
660
+ /Chrom(e|ium)\/(\d+)\./,
661
+ 2
662
+ );
663
+ } else if (window2.RTCPeerConnection && navigator2.userAgent.match(/AppleWebKit\/(\d+)\./)) {
664
+ result.browser = "safari";
665
+ result.version = extractVersion(
666
+ navigator2.userAgent,
667
+ /AppleWebKit\/(\d+)\./,
668
+ 1
669
+ );
670
+ result.supportsUnifiedPlan = window2.RTCRtpTransceiver && "currentDirection" in window2.RTCRtpTransceiver.prototype;
671
+ } else {
672
+ result.browser = "Not a supported browser.";
673
+ return result;
674
+ }
675
+ return result;
676
+ }
677
+ function isObject(val) {
678
+ return Object.prototype.toString.call(val) === "[object Object]";
679
+ }
680
+ function compactObject(data) {
681
+ if (!isObject(data)) {
682
+ return data;
683
+ }
684
+ return Object.keys(data).reduce(function(accumulator, key) {
685
+ const isObj = isObject(data[key]);
686
+ const value = isObj ? compactObject(data[key]) : data[key];
687
+ const isEmptyObject = isObj && !Object.keys(value).length;
688
+ if (value === void 0 || isEmptyObject) {
689
+ return accumulator;
690
+ }
691
+ return Object.assign(accumulator, { [key]: value });
692
+ }, {});
693
+ }
694
+ function walkStats(stats, base, resultSet) {
695
+ if (!base || resultSet.has(base.id)) {
696
+ return;
697
+ }
698
+ resultSet.set(base.id, base);
699
+ Object.keys(base).forEach((name) => {
700
+ if (name.endsWith("Id")) {
701
+ walkStats(stats, stats.get(base[name]), resultSet);
702
+ } else if (name.endsWith("Ids")) {
703
+ base[name].forEach((id) => {
704
+ walkStats(stats, stats.get(id), resultSet);
705
+ });
706
+ }
707
+ });
708
+ }
709
+ function filterStats(result, track, outbound) {
710
+ const streamStatsType = outbound ? "outbound-rtp" : "inbound-rtp";
711
+ const filteredResult = /* @__PURE__ */ new Map();
712
+ if (track === null) {
713
+ return filteredResult;
714
+ }
715
+ const trackStats = [];
716
+ result.forEach((value) => {
717
+ if (value.type === "track" && value.trackIdentifier === track.id) {
718
+ trackStats.push(value);
719
+ }
720
+ });
721
+ trackStats.forEach((trackStat) => {
722
+ result.forEach((stats) => {
723
+ if (stats.type === streamStatsType && stats.trackId === trackStat.id) {
724
+ walkStats(result, stats, filteredResult);
725
+ }
726
+ });
727
+ });
728
+ return filteredResult;
729
+ }
730
+ const logging = log;
731
+ function shimGetUserMedia$2(window2, browserDetails) {
732
+ const navigator2 = window2 && window2.navigator;
733
+ if (!navigator2.mediaDevices) {
734
+ return;
735
+ }
736
+ const constraintsToChrome_ = function(c) {
737
+ if (typeof c !== "object" || c.mandatory || c.optional) {
738
+ return c;
739
+ }
740
+ const cc = {};
741
+ Object.keys(c).forEach((key) => {
742
+ if (key === "require" || key === "advanced" || key === "mediaSource") {
743
+ return;
744
+ }
745
+ const r = typeof c[key] === "object" ? c[key] : { ideal: c[key] };
746
+ if (r.exact !== void 0 && typeof r.exact === "number") {
747
+ r.min = r.max = r.exact;
748
+ }
749
+ const oldname_ = function(prefix, name) {
750
+ if (prefix) {
751
+ return prefix + name.charAt(0).toUpperCase() + name.slice(1);
752
+ }
753
+ return name === "deviceId" ? "sourceId" : name;
754
+ };
755
+ if (r.ideal !== void 0) {
756
+ cc.optional = cc.optional || [];
757
+ let oc = {};
758
+ if (typeof r.ideal === "number") {
759
+ oc[oldname_("min", key)] = r.ideal;
760
+ cc.optional.push(oc);
761
+ oc = {};
762
+ oc[oldname_("max", key)] = r.ideal;
763
+ cc.optional.push(oc);
764
+ } else {
765
+ oc[oldname_("", key)] = r.ideal;
766
+ cc.optional.push(oc);
767
+ }
768
+ }
769
+ if (r.exact !== void 0 && typeof r.exact !== "number") {
770
+ cc.mandatory = cc.mandatory || {};
771
+ cc.mandatory[oldname_("", key)] = r.exact;
772
+ } else {
773
+ ["min", "max"].forEach((mix) => {
774
+ if (r[mix] !== void 0) {
775
+ cc.mandatory = cc.mandatory || {};
776
+ cc.mandatory[oldname_(mix, key)] = r[mix];
777
+ }
778
+ });
779
+ }
780
+ });
781
+ if (c.advanced) {
782
+ cc.optional = (cc.optional || []).concat(c.advanced);
783
+ }
784
+ return cc;
785
+ };
786
+ const shimConstraints_ = function(constraints, func) {
787
+ if (browserDetails.version >= 61) {
788
+ return func(constraints);
789
+ }
790
+ constraints = JSON.parse(JSON.stringify(constraints));
791
+ if (constraints && typeof constraints.audio === "object") {
792
+ const remap = function(obj, a, b) {
793
+ if (a in obj && !(b in obj)) {
794
+ obj[b] = obj[a];
795
+ delete obj[a];
796
+ }
797
+ };
798
+ constraints = JSON.parse(JSON.stringify(constraints));
799
+ remap(constraints.audio, "autoGainControl", "googAutoGainControl");
800
+ remap(constraints.audio, "noiseSuppression", "googNoiseSuppression");
801
+ constraints.audio = constraintsToChrome_(constraints.audio);
802
+ }
803
+ if (constraints && typeof constraints.video === "object") {
804
+ let face = constraints.video.facingMode;
805
+ face = face && (typeof face === "object" ? face : { ideal: face });
806
+ const getSupportedFacingModeLies = browserDetails.version < 66;
807
+ if (face && (face.exact === "user" || face.exact === "environment" || face.ideal === "user" || face.ideal === "environment") && !(navigator2.mediaDevices.getSupportedConstraints && navigator2.mediaDevices.getSupportedConstraints().facingMode && !getSupportedFacingModeLies)) {
808
+ delete constraints.video.facingMode;
809
+ let matches;
810
+ if (face.exact === "environment" || face.ideal === "environment") {
811
+ matches = ["back", "rear"];
812
+ } else if (face.exact === "user" || face.ideal === "user") {
813
+ matches = ["front"];
814
+ }
815
+ if (matches) {
816
+ return navigator2.mediaDevices.enumerateDevices().then((devices) => {
817
+ devices = devices.filter((d) => d.kind === "videoinput");
818
+ let dev = devices.find((d) => matches.some((match) => d.label.toLowerCase().includes(match)));
819
+ if (!dev && devices.length && matches.includes("back")) {
820
+ dev = devices[devices.length - 1];
821
+ }
822
+ if (dev) {
823
+ constraints.video.deviceId = face.exact ? { exact: dev.deviceId } : { ideal: dev.deviceId };
824
+ }
825
+ constraints.video = constraintsToChrome_(constraints.video);
826
+ logging("chrome: " + JSON.stringify(constraints));
827
+ return func(constraints);
828
+ });
829
+ }
830
+ }
831
+ constraints.video = constraintsToChrome_(constraints.video);
832
+ }
833
+ logging("chrome: " + JSON.stringify(constraints));
834
+ return func(constraints);
835
+ };
836
+ const shimError_ = function(e) {
837
+ if (browserDetails.version >= 64) {
838
+ return e;
839
+ }
840
+ return {
841
+ name: {
842
+ PermissionDeniedError: "NotAllowedError",
843
+ PermissionDismissedError: "NotAllowedError",
844
+ InvalidStateError: "NotAllowedError",
845
+ DevicesNotFoundError: "NotFoundError",
846
+ ConstraintNotSatisfiedError: "OverconstrainedError",
847
+ TrackStartError: "NotReadableError",
848
+ MediaDeviceFailedDueToShutdown: "NotAllowedError",
849
+ MediaDeviceKillSwitchOn: "NotAllowedError",
850
+ TabCaptureError: "AbortError",
851
+ ScreenCaptureError: "AbortError",
852
+ DeviceCaptureError: "AbortError"
853
+ }[e.name] || e.name,
854
+ message: e.message,
855
+ constraint: e.constraint || e.constraintName,
856
+ toString() {
857
+ return this.name + (this.message && ": ") + this.message;
858
+ }
859
+ };
860
+ };
861
+ const getUserMedia_ = function(constraints, onSuccess, onError) {
862
+ shimConstraints_(constraints, (c) => {
863
+ navigator2.webkitGetUserMedia(c, onSuccess, (e) => {
864
+ if (onError) {
865
+ onError(shimError_(e));
866
+ }
867
+ });
868
+ });
869
+ };
870
+ navigator2.getUserMedia = getUserMedia_.bind(navigator2);
871
+ if (navigator2.mediaDevices.getUserMedia) {
872
+ const origGetUserMedia = navigator2.mediaDevices.getUserMedia.bind(navigator2.mediaDevices);
873
+ navigator2.mediaDevices.getUserMedia = function(cs) {
874
+ return shimConstraints_(cs, (c) => origGetUserMedia(c).then((stream) => {
875
+ if (c.audio && !stream.getAudioTracks().length || c.video && !stream.getVideoTracks().length) {
876
+ stream.getTracks().forEach((track) => {
877
+ track.stop();
878
+ });
879
+ throw new DOMException("", "NotFoundError");
880
+ }
881
+ return stream;
882
+ }, (e) => Promise.reject(shimError_(e))));
883
+ };
884
+ }
885
+ }
886
+ function shimMediaStream(window2) {
887
+ window2.MediaStream = window2.MediaStream || window2.webkitMediaStream;
888
+ }
889
+ function shimOnTrack$1(window2) {
890
+ if (typeof window2 === "object" && window2.RTCPeerConnection && !("ontrack" in window2.RTCPeerConnection.prototype)) {
891
+ Object.defineProperty(window2.RTCPeerConnection.prototype, "ontrack", {
892
+ get() {
893
+ return this._ontrack;
894
+ },
895
+ set(f) {
896
+ if (this._ontrack) {
897
+ this.removeEventListener("track", this._ontrack);
898
+ }
899
+ this.addEventListener("track", this._ontrack = f);
900
+ },
901
+ enumerable: true,
902
+ configurable: true
903
+ });
904
+ const origSetRemoteDescription = window2.RTCPeerConnection.prototype.setRemoteDescription;
905
+ window2.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription() {
906
+ if (!this._ontrackpoly) {
907
+ this._ontrackpoly = (e) => {
908
+ e.stream.addEventListener("addtrack", (te) => {
909
+ let receiver;
910
+ if (window2.RTCPeerConnection.prototype.getReceivers) {
911
+ receiver = this.getReceivers().find((r) => r.track && r.track.id === te.track.id);
912
+ } else {
913
+ receiver = { track: te.track };
914
+ }
915
+ const event = new Event("track");
916
+ event.track = te.track;
917
+ event.receiver = receiver;
918
+ event.transceiver = { receiver };
919
+ event.streams = [e.stream];
920
+ this.dispatchEvent(event);
921
+ });
922
+ e.stream.getTracks().forEach((track) => {
923
+ let receiver;
924
+ if (window2.RTCPeerConnection.prototype.getReceivers) {
925
+ receiver = this.getReceivers().find((r) => r.track && r.track.id === track.id);
926
+ } else {
927
+ receiver = { track };
928
+ }
929
+ const event = new Event("track");
930
+ event.track = track;
931
+ event.receiver = receiver;
932
+ event.transceiver = { receiver };
933
+ event.streams = [e.stream];
934
+ this.dispatchEvent(event);
935
+ });
936
+ };
937
+ this.addEventListener("addstream", this._ontrackpoly);
938
+ }
939
+ return origSetRemoteDescription.apply(this, arguments);
940
+ };
941
+ } else {
942
+ wrapPeerConnectionEvent(window2, "track", (e) => {
943
+ if (!e.transceiver) {
944
+ Object.defineProperty(
945
+ e,
946
+ "transceiver",
947
+ { value: { receiver: e.receiver } }
948
+ );
949
+ }
950
+ return e;
951
+ });
952
+ }
953
+ }
954
+ function shimGetSendersWithDtmf(window2) {
955
+ if (typeof window2 === "object" && window2.RTCPeerConnection && !("getSenders" in window2.RTCPeerConnection.prototype) && "createDTMFSender" in window2.RTCPeerConnection.prototype) {
956
+ const shimSenderWithDtmf = function(pc, track) {
957
+ return {
958
+ track,
959
+ get dtmf() {
960
+ if (this._dtmf === void 0) {
961
+ if (track.kind === "audio") {
962
+ this._dtmf = pc.createDTMFSender(track);
963
+ } else {
964
+ this._dtmf = null;
965
+ }
966
+ }
967
+ return this._dtmf;
968
+ },
969
+ _pc: pc
970
+ };
971
+ };
972
+ if (!window2.RTCPeerConnection.prototype.getSenders) {
973
+ window2.RTCPeerConnection.prototype.getSenders = function getSenders() {
974
+ this._senders = this._senders || [];
975
+ return this._senders.slice();
976
+ };
977
+ const origAddTrack = window2.RTCPeerConnection.prototype.addTrack;
978
+ window2.RTCPeerConnection.prototype.addTrack = function addTrack(track, stream) {
979
+ let sender = origAddTrack.apply(this, arguments);
980
+ if (!sender) {
981
+ sender = shimSenderWithDtmf(this, track);
982
+ this._senders.push(sender);
983
+ }
984
+ return sender;
985
+ };
986
+ const origRemoveTrack = window2.RTCPeerConnection.prototype.removeTrack;
987
+ window2.RTCPeerConnection.prototype.removeTrack = function removeTrack(sender) {
988
+ origRemoveTrack.apply(this, arguments);
989
+ const idx = this._senders.indexOf(sender);
990
+ if (idx !== -1) {
991
+ this._senders.splice(idx, 1);
992
+ }
993
+ };
994
+ }
995
+ const origAddStream = window2.RTCPeerConnection.prototype.addStream;
996
+ window2.RTCPeerConnection.prototype.addStream = function addStream(stream) {
997
+ this._senders = this._senders || [];
998
+ origAddStream.apply(this, [stream]);
999
+ stream.getTracks().forEach((track) => {
1000
+ this._senders.push(shimSenderWithDtmf(this, track));
1001
+ });
1002
+ };
1003
+ const origRemoveStream = window2.RTCPeerConnection.prototype.removeStream;
1004
+ window2.RTCPeerConnection.prototype.removeStream = function removeStream(stream) {
1005
+ this._senders = this._senders || [];
1006
+ origRemoveStream.apply(this, [stream]);
1007
+ stream.getTracks().forEach((track) => {
1008
+ const sender = this._senders.find((s) => s.track === track);
1009
+ if (sender) {
1010
+ this._senders.splice(this._senders.indexOf(sender), 1);
1011
+ }
1012
+ });
1013
+ };
1014
+ } else if (typeof window2 === "object" && window2.RTCPeerConnection && "getSenders" in window2.RTCPeerConnection.prototype && "createDTMFSender" in window2.RTCPeerConnection.prototype && window2.RTCRtpSender && !("dtmf" in window2.RTCRtpSender.prototype)) {
1015
+ const origGetSenders = window2.RTCPeerConnection.prototype.getSenders;
1016
+ window2.RTCPeerConnection.prototype.getSenders = function getSenders() {
1017
+ const senders = origGetSenders.apply(this, []);
1018
+ senders.forEach((sender) => sender._pc = this);
1019
+ return senders;
1020
+ };
1021
+ Object.defineProperty(window2.RTCRtpSender.prototype, "dtmf", {
1022
+ get() {
1023
+ if (this._dtmf === void 0) {
1024
+ if (this.track.kind === "audio") {
1025
+ this._dtmf = this._pc.createDTMFSender(this.track);
1026
+ } else {
1027
+ this._dtmf = null;
1028
+ }
1029
+ }
1030
+ return this._dtmf;
1031
+ }
1032
+ });
1033
+ }
1034
+ }
1035
+ function shimSenderReceiverGetStats(window2) {
1036
+ if (!(typeof window2 === "object" && window2.RTCPeerConnection && window2.RTCRtpSender && window2.RTCRtpReceiver)) {
1037
+ return;
1038
+ }
1039
+ if (!("getStats" in window2.RTCRtpSender.prototype)) {
1040
+ const origGetSenders = window2.RTCPeerConnection.prototype.getSenders;
1041
+ if (origGetSenders) {
1042
+ window2.RTCPeerConnection.prototype.getSenders = function getSenders() {
1043
+ const senders = origGetSenders.apply(this, []);
1044
+ senders.forEach((sender) => sender._pc = this);
1045
+ return senders;
1046
+ };
1047
+ }
1048
+ const origAddTrack = window2.RTCPeerConnection.prototype.addTrack;
1049
+ if (origAddTrack) {
1050
+ window2.RTCPeerConnection.prototype.addTrack = function addTrack() {
1051
+ const sender = origAddTrack.apply(this, arguments);
1052
+ sender._pc = this;
1053
+ return sender;
1054
+ };
1055
+ }
1056
+ window2.RTCRtpSender.prototype.getStats = function getStats() {
1057
+ const sender = this;
1058
+ return this._pc.getStats().then((result) => (
1059
+ /* Note: this will include stats of all senders that
1060
+ * send a track with the same id as sender.track as
1061
+ * it is not possible to identify the RTCRtpSender.
1062
+ */
1063
+ filterStats(result, sender.track, true)
1064
+ ));
1065
+ };
1066
+ }
1067
+ if (!("getStats" in window2.RTCRtpReceiver.prototype)) {
1068
+ const origGetReceivers = window2.RTCPeerConnection.prototype.getReceivers;
1069
+ if (origGetReceivers) {
1070
+ window2.RTCPeerConnection.prototype.getReceivers = function getReceivers() {
1071
+ const receivers = origGetReceivers.apply(this, []);
1072
+ receivers.forEach((receiver) => receiver._pc = this);
1073
+ return receivers;
1074
+ };
1075
+ }
1076
+ wrapPeerConnectionEvent(window2, "track", (e) => {
1077
+ e.receiver._pc = e.srcElement;
1078
+ return e;
1079
+ });
1080
+ window2.RTCRtpReceiver.prototype.getStats = function getStats() {
1081
+ const receiver = this;
1082
+ return this._pc.getStats().then((result) => filterStats(result, receiver.track, false));
1083
+ };
1084
+ }
1085
+ if (!("getStats" in window2.RTCRtpSender.prototype && "getStats" in window2.RTCRtpReceiver.prototype)) {
1086
+ return;
1087
+ }
1088
+ const origGetStats = window2.RTCPeerConnection.prototype.getStats;
1089
+ window2.RTCPeerConnection.prototype.getStats = function getStats() {
1090
+ if (arguments.length > 0 && arguments[0] instanceof window2.MediaStreamTrack) {
1091
+ const track = arguments[0];
1092
+ let sender;
1093
+ let receiver;
1094
+ let err;
1095
+ this.getSenders().forEach((s) => {
1096
+ if (s.track === track) {
1097
+ if (sender) {
1098
+ err = true;
1099
+ } else {
1100
+ sender = s;
1101
+ }
1102
+ }
1103
+ });
1104
+ this.getReceivers().forEach((r) => {
1105
+ if (r.track === track) {
1106
+ if (receiver) {
1107
+ err = true;
1108
+ } else {
1109
+ receiver = r;
1110
+ }
1111
+ }
1112
+ return r.track === track;
1113
+ });
1114
+ if (err || sender && receiver) {
1115
+ return Promise.reject(new DOMException(
1116
+ "There are more than one sender or receiver for the track.",
1117
+ "InvalidAccessError"
1118
+ ));
1119
+ } else if (sender) {
1120
+ return sender.getStats();
1121
+ } else if (receiver) {
1122
+ return receiver.getStats();
1123
+ }
1124
+ return Promise.reject(new DOMException(
1125
+ "There is no sender or receiver for the track.",
1126
+ "InvalidAccessError"
1127
+ ));
1128
+ }
1129
+ return origGetStats.apply(this, arguments);
1130
+ };
1131
+ }
1132
+ function shimAddTrackRemoveTrackWithNative(window2) {
1133
+ window2.RTCPeerConnection.prototype.getLocalStreams = function getLocalStreams() {
1134
+ this._shimmedLocalStreams = this._shimmedLocalStreams || {};
1135
+ return Object.keys(this._shimmedLocalStreams).map((streamId) => this._shimmedLocalStreams[streamId][0]);
1136
+ };
1137
+ const origAddTrack = window2.RTCPeerConnection.prototype.addTrack;
1138
+ window2.RTCPeerConnection.prototype.addTrack = function addTrack(track, stream) {
1139
+ if (!stream) {
1140
+ return origAddTrack.apply(this, arguments);
1141
+ }
1142
+ this._shimmedLocalStreams = this._shimmedLocalStreams || {};
1143
+ const sender = origAddTrack.apply(this, arguments);
1144
+ if (!this._shimmedLocalStreams[stream.id]) {
1145
+ this._shimmedLocalStreams[stream.id] = [stream, sender];
1146
+ } else if (this._shimmedLocalStreams[stream.id].indexOf(sender) === -1) {
1147
+ this._shimmedLocalStreams[stream.id].push(sender);
1148
+ }
1149
+ return sender;
1150
+ };
1151
+ const origAddStream = window2.RTCPeerConnection.prototype.addStream;
1152
+ window2.RTCPeerConnection.prototype.addStream = function addStream(stream) {
1153
+ this._shimmedLocalStreams = this._shimmedLocalStreams || {};
1154
+ stream.getTracks().forEach((track) => {
1155
+ const alreadyExists = this.getSenders().find((s) => s.track === track);
1156
+ if (alreadyExists) {
1157
+ throw new DOMException(
1158
+ "Track already exists.",
1159
+ "InvalidAccessError"
1160
+ );
1161
+ }
1162
+ });
1163
+ const existingSenders = this.getSenders();
1164
+ origAddStream.apply(this, arguments);
1165
+ const newSenders = this.getSenders().filter((newSender) => existingSenders.indexOf(newSender) === -1);
1166
+ this._shimmedLocalStreams[stream.id] = [stream].concat(newSenders);
1167
+ };
1168
+ const origRemoveStream = window2.RTCPeerConnection.prototype.removeStream;
1169
+ window2.RTCPeerConnection.prototype.removeStream = function removeStream(stream) {
1170
+ this._shimmedLocalStreams = this._shimmedLocalStreams || {};
1171
+ delete this._shimmedLocalStreams[stream.id];
1172
+ return origRemoveStream.apply(this, arguments);
1173
+ };
1174
+ const origRemoveTrack = window2.RTCPeerConnection.prototype.removeTrack;
1175
+ window2.RTCPeerConnection.prototype.removeTrack = function removeTrack(sender) {
1176
+ this._shimmedLocalStreams = this._shimmedLocalStreams || {};
1177
+ if (sender) {
1178
+ Object.keys(this._shimmedLocalStreams).forEach((streamId) => {
1179
+ const idx = this._shimmedLocalStreams[streamId].indexOf(sender);
1180
+ if (idx !== -1) {
1181
+ this._shimmedLocalStreams[streamId].splice(idx, 1);
1182
+ }
1183
+ if (this._shimmedLocalStreams[streamId].length === 1) {
1184
+ delete this._shimmedLocalStreams[streamId];
1185
+ }
1186
+ });
1187
+ }
1188
+ return origRemoveTrack.apply(this, arguments);
1189
+ };
1190
+ }
1191
+ function shimAddTrackRemoveTrack(window2, browserDetails) {
1192
+ if (!window2.RTCPeerConnection) {
1193
+ return;
1194
+ }
1195
+ if (window2.RTCPeerConnection.prototype.addTrack && browserDetails.version >= 65) {
1196
+ return shimAddTrackRemoveTrackWithNative(window2);
1197
+ }
1198
+ const origGetLocalStreams = window2.RTCPeerConnection.prototype.getLocalStreams;
1199
+ window2.RTCPeerConnection.prototype.getLocalStreams = function getLocalStreams() {
1200
+ const nativeStreams = origGetLocalStreams.apply(this);
1201
+ this._reverseStreams = this._reverseStreams || {};
1202
+ return nativeStreams.map((stream) => this._reverseStreams[stream.id]);
1203
+ };
1204
+ const origAddStream = window2.RTCPeerConnection.prototype.addStream;
1205
+ window2.RTCPeerConnection.prototype.addStream = function addStream(stream) {
1206
+ this._streams = this._streams || {};
1207
+ this._reverseStreams = this._reverseStreams || {};
1208
+ stream.getTracks().forEach((track) => {
1209
+ const alreadyExists = this.getSenders().find((s) => s.track === track);
1210
+ if (alreadyExists) {
1211
+ throw new DOMException(
1212
+ "Track already exists.",
1213
+ "InvalidAccessError"
1214
+ );
1215
+ }
1216
+ });
1217
+ if (!this._reverseStreams[stream.id]) {
1218
+ const newStream = new window2.MediaStream(stream.getTracks());
1219
+ this._streams[stream.id] = newStream;
1220
+ this._reverseStreams[newStream.id] = stream;
1221
+ stream = newStream;
1222
+ }
1223
+ origAddStream.apply(this, [stream]);
1224
+ };
1225
+ const origRemoveStream = window2.RTCPeerConnection.prototype.removeStream;
1226
+ window2.RTCPeerConnection.prototype.removeStream = function removeStream(stream) {
1227
+ this._streams = this._streams || {};
1228
+ this._reverseStreams = this._reverseStreams || {};
1229
+ origRemoveStream.apply(this, [this._streams[stream.id] || stream]);
1230
+ delete this._reverseStreams[this._streams[stream.id] ? this._streams[stream.id].id : stream.id];
1231
+ delete this._streams[stream.id];
1232
+ };
1233
+ window2.RTCPeerConnection.prototype.addTrack = function addTrack(track, stream) {
1234
+ if (this.signalingState === "closed") {
1235
+ throw new DOMException(
1236
+ "The RTCPeerConnection's signalingState is 'closed'.",
1237
+ "InvalidStateError"
1238
+ );
1239
+ }
1240
+ const streams = [].slice.call(arguments, 1);
1241
+ if (streams.length !== 1 || !streams[0].getTracks().find((t) => t === track)) {
1242
+ throw new DOMException(
1243
+ "The adapter.js addTrack polyfill only supports a single stream which is associated with the specified track.",
1244
+ "NotSupportedError"
1245
+ );
1246
+ }
1247
+ const alreadyExists = this.getSenders().find((s) => s.track === track);
1248
+ if (alreadyExists) {
1249
+ throw new DOMException(
1250
+ "Track already exists.",
1251
+ "InvalidAccessError"
1252
+ );
1253
+ }
1254
+ this._streams = this._streams || {};
1255
+ this._reverseStreams = this._reverseStreams || {};
1256
+ const oldStream = this._streams[stream.id];
1257
+ if (oldStream) {
1258
+ oldStream.addTrack(track);
1259
+ Promise.resolve().then(() => {
1260
+ this.dispatchEvent(new Event("negotiationneeded"));
1261
+ });
1262
+ } else {
1263
+ const newStream = new window2.MediaStream([track]);
1264
+ this._streams[stream.id] = newStream;
1265
+ this._reverseStreams[newStream.id] = stream;
1266
+ this.addStream(newStream);
1267
+ }
1268
+ return this.getSenders().find((s) => s.track === track);
1269
+ };
1270
+ function replaceInternalStreamId(pc, description) {
1271
+ let sdp2 = description.sdp;
1272
+ Object.keys(pc._reverseStreams || []).forEach((internalId) => {
1273
+ const externalStream = pc._reverseStreams[internalId];
1274
+ const internalStream = pc._streams[externalStream.id];
1275
+ sdp2 = sdp2.replace(
1276
+ new RegExp(internalStream.id, "g"),
1277
+ externalStream.id
1278
+ );
1279
+ });
1280
+ return new RTCSessionDescription({
1281
+ type: description.type,
1282
+ sdp: sdp2
1283
+ });
1284
+ }
1285
+ function replaceExternalStreamId(pc, description) {
1286
+ let sdp2 = description.sdp;
1287
+ Object.keys(pc._reverseStreams || []).forEach((internalId) => {
1288
+ const externalStream = pc._reverseStreams[internalId];
1289
+ const internalStream = pc._streams[externalStream.id];
1290
+ sdp2 = sdp2.replace(
1291
+ new RegExp(externalStream.id, "g"),
1292
+ internalStream.id
1293
+ );
1294
+ });
1295
+ return new RTCSessionDescription({
1296
+ type: description.type,
1297
+ sdp: sdp2
1298
+ });
1299
+ }
1300
+ ["createOffer", "createAnswer"].forEach(function(method) {
1301
+ const nativeMethod = window2.RTCPeerConnection.prototype[method];
1302
+ const methodObj = { [method]() {
1303
+ const args = arguments;
1304
+ const isLegacyCall = arguments.length && typeof arguments[0] === "function";
1305
+ if (isLegacyCall) {
1306
+ return nativeMethod.apply(this, [
1307
+ (description) => {
1308
+ const desc = replaceInternalStreamId(this, description);
1309
+ args[0].apply(null, [desc]);
1310
+ },
1311
+ (err) => {
1312
+ if (args[1]) {
1313
+ args[1].apply(null, err);
1314
+ }
1315
+ },
1316
+ arguments[2]
1317
+ ]);
1318
+ }
1319
+ return nativeMethod.apply(this, arguments).then((description) => replaceInternalStreamId(this, description));
1320
+ } };
1321
+ window2.RTCPeerConnection.prototype[method] = methodObj[method];
1322
+ });
1323
+ const origSetLocalDescription = window2.RTCPeerConnection.prototype.setLocalDescription;
1324
+ window2.RTCPeerConnection.prototype.setLocalDescription = function setLocalDescription() {
1325
+ if (!arguments.length || !arguments[0].type) {
1326
+ return origSetLocalDescription.apply(this, arguments);
1327
+ }
1328
+ arguments[0] = replaceExternalStreamId(this, arguments[0]);
1329
+ return origSetLocalDescription.apply(this, arguments);
1330
+ };
1331
+ const origLocalDescription = Object.getOwnPropertyDescriptor(
1332
+ window2.RTCPeerConnection.prototype,
1333
+ "localDescription"
1334
+ );
1335
+ Object.defineProperty(
1336
+ window2.RTCPeerConnection.prototype,
1337
+ "localDescription",
1338
+ {
1339
+ get() {
1340
+ const description = origLocalDescription.get.apply(this);
1341
+ if (description.type === "") {
1342
+ return description;
1343
+ }
1344
+ return replaceInternalStreamId(this, description);
1345
+ }
1346
+ }
1347
+ );
1348
+ window2.RTCPeerConnection.prototype.removeTrack = function removeTrack(sender) {
1349
+ if (this.signalingState === "closed") {
1350
+ throw new DOMException(
1351
+ "The RTCPeerConnection's signalingState is 'closed'.",
1352
+ "InvalidStateError"
1353
+ );
1354
+ }
1355
+ if (!sender._pc) {
1356
+ throw new DOMException("Argument 1 of RTCPeerConnection.removeTrack does not implement interface RTCRtpSender.", "TypeError");
1357
+ }
1358
+ const isLocal = sender._pc === this;
1359
+ if (!isLocal) {
1360
+ throw new DOMException(
1361
+ "Sender was not created by this connection.",
1362
+ "InvalidAccessError"
1363
+ );
1364
+ }
1365
+ this._streams = this._streams || {};
1366
+ let stream;
1367
+ Object.keys(this._streams).forEach((streamid) => {
1368
+ const hasTrack = this._streams[streamid].getTracks().find((track) => sender.track === track);
1369
+ if (hasTrack) {
1370
+ stream = this._streams[streamid];
1371
+ }
1372
+ });
1373
+ if (stream) {
1374
+ if (stream.getTracks().length === 1) {
1375
+ this.removeStream(this._reverseStreams[stream.id]);
1376
+ } else {
1377
+ stream.removeTrack(sender.track);
1378
+ }
1379
+ this.dispatchEvent(new Event("negotiationneeded"));
1380
+ }
1381
+ };
1382
+ }
1383
+ function shimPeerConnection$1(window2, browserDetails) {
1384
+ if (!window2.RTCPeerConnection && window2.webkitRTCPeerConnection) {
1385
+ window2.RTCPeerConnection = window2.webkitRTCPeerConnection;
1386
+ }
1387
+ if (!window2.RTCPeerConnection) {
1388
+ return;
1389
+ }
1390
+ if (browserDetails.version < 53) {
1391
+ ["setLocalDescription", "setRemoteDescription", "addIceCandidate"].forEach(function(method) {
1392
+ const nativeMethod = window2.RTCPeerConnection.prototype[method];
1393
+ const methodObj = { [method]() {
1394
+ arguments[0] = new (method === "addIceCandidate" ? window2.RTCIceCandidate : window2.RTCSessionDescription)(arguments[0]);
1395
+ return nativeMethod.apply(this, arguments);
1396
+ } };
1397
+ window2.RTCPeerConnection.prototype[method] = methodObj[method];
1398
+ });
1399
+ }
1400
+ }
1401
+ function fixNegotiationNeeded(window2, browserDetails) {
1402
+ wrapPeerConnectionEvent(window2, "negotiationneeded", (e) => {
1403
+ const pc = e.target;
1404
+ if (browserDetails.version < 72 || pc.getConfiguration && pc.getConfiguration().sdpSemantics === "plan-b") {
1405
+ if (pc.signalingState !== "stable") {
1406
+ return;
1407
+ }
1408
+ }
1409
+ return e;
1410
+ });
1411
+ }
1412
+ const chromeShim = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1413
+ __proto__: null,
1414
+ fixNegotiationNeeded,
1415
+ shimAddTrackRemoveTrack,
1416
+ shimAddTrackRemoveTrackWithNative,
1417
+ shimGetSendersWithDtmf,
1418
+ shimGetUserMedia: shimGetUserMedia$2,
1419
+ shimMediaStream,
1420
+ shimOnTrack: shimOnTrack$1,
1421
+ shimPeerConnection: shimPeerConnection$1,
1422
+ shimSenderReceiverGetStats
1423
+ }, Symbol.toStringTag, { value: "Module" }));
1424
+ function shimGetUserMedia$1(window2, browserDetails) {
1425
+ const navigator2 = window2 && window2.navigator;
1426
+ const MediaStreamTrack = window2 && window2.MediaStreamTrack;
1427
+ navigator2.getUserMedia = function(constraints, onSuccess, onError) {
1428
+ deprecated(
1429
+ "navigator.getUserMedia",
1430
+ "navigator.mediaDevices.getUserMedia"
1431
+ );
1432
+ navigator2.mediaDevices.getUserMedia(constraints).then(onSuccess, onError);
1433
+ };
1434
+ if (!(browserDetails.version > 55 && "autoGainControl" in navigator2.mediaDevices.getSupportedConstraints())) {
1435
+ const remap = function(obj, a, b) {
1436
+ if (a in obj && !(b in obj)) {
1437
+ obj[b] = obj[a];
1438
+ delete obj[a];
1439
+ }
1440
+ };
1441
+ const nativeGetUserMedia = navigator2.mediaDevices.getUserMedia.bind(navigator2.mediaDevices);
1442
+ navigator2.mediaDevices.getUserMedia = function(c) {
1443
+ if (typeof c === "object" && typeof c.audio === "object") {
1444
+ c = JSON.parse(JSON.stringify(c));
1445
+ remap(c.audio, "autoGainControl", "mozAutoGainControl");
1446
+ remap(c.audio, "noiseSuppression", "mozNoiseSuppression");
1447
+ }
1448
+ return nativeGetUserMedia(c);
1449
+ };
1450
+ if (MediaStreamTrack && MediaStreamTrack.prototype.getSettings) {
1451
+ const nativeGetSettings = MediaStreamTrack.prototype.getSettings;
1452
+ MediaStreamTrack.prototype.getSettings = function() {
1453
+ const obj = nativeGetSettings.apply(this, arguments);
1454
+ remap(obj, "mozAutoGainControl", "autoGainControl");
1455
+ remap(obj, "mozNoiseSuppression", "noiseSuppression");
1456
+ return obj;
1457
+ };
1458
+ }
1459
+ if (MediaStreamTrack && MediaStreamTrack.prototype.applyConstraints) {
1460
+ const nativeApplyConstraints = MediaStreamTrack.prototype.applyConstraints;
1461
+ MediaStreamTrack.prototype.applyConstraints = function(c) {
1462
+ if (this.kind === "audio" && typeof c === "object") {
1463
+ c = JSON.parse(JSON.stringify(c));
1464
+ remap(c, "autoGainControl", "mozAutoGainControl");
1465
+ remap(c, "noiseSuppression", "mozNoiseSuppression");
1466
+ }
1467
+ return nativeApplyConstraints.apply(this, [c]);
1468
+ };
1469
+ }
1470
+ }
1471
+ }
1472
+ function shimGetDisplayMedia(window2, preferredMediaSource) {
1473
+ if (window2.navigator.mediaDevices && "getDisplayMedia" in window2.navigator.mediaDevices) {
1474
+ return;
1475
+ }
1476
+ if (!window2.navigator.mediaDevices) {
1477
+ return;
1478
+ }
1479
+ window2.navigator.mediaDevices.getDisplayMedia = function getDisplayMedia(constraints) {
1480
+ if (!(constraints && constraints.video)) {
1481
+ const err = new DOMException("getDisplayMedia without video constraints is undefined");
1482
+ err.name = "NotFoundError";
1483
+ err.code = 8;
1484
+ return Promise.reject(err);
1485
+ }
1486
+ if (constraints.video === true) {
1487
+ constraints.video = { mediaSource: preferredMediaSource };
1488
+ } else {
1489
+ constraints.video.mediaSource = preferredMediaSource;
1490
+ }
1491
+ return window2.navigator.mediaDevices.getUserMedia(constraints);
1492
+ };
1493
+ }
1494
+ function shimOnTrack(window2) {
1495
+ if (typeof window2 === "object" && window2.RTCTrackEvent && "receiver" in window2.RTCTrackEvent.prototype && !("transceiver" in window2.RTCTrackEvent.prototype)) {
1496
+ Object.defineProperty(window2.RTCTrackEvent.prototype, "transceiver", {
1497
+ get() {
1498
+ return { receiver: this.receiver };
1499
+ }
1500
+ });
1501
+ }
1502
+ }
1503
+ function shimPeerConnection(window2, browserDetails) {
1504
+ if (typeof window2 !== "object" || !(window2.RTCPeerConnection || window2.mozRTCPeerConnection)) {
1505
+ return;
1506
+ }
1507
+ if (!window2.RTCPeerConnection && window2.mozRTCPeerConnection) {
1508
+ window2.RTCPeerConnection = window2.mozRTCPeerConnection;
1509
+ }
1510
+ if (browserDetails.version < 53) {
1511
+ ["setLocalDescription", "setRemoteDescription", "addIceCandidate"].forEach(function(method) {
1512
+ const nativeMethod = window2.RTCPeerConnection.prototype[method];
1513
+ const methodObj = { [method]() {
1514
+ arguments[0] = new (method === "addIceCandidate" ? window2.RTCIceCandidate : window2.RTCSessionDescription)(arguments[0]);
1515
+ return nativeMethod.apply(this, arguments);
1516
+ } };
1517
+ window2.RTCPeerConnection.prototype[method] = methodObj[method];
1518
+ });
1519
+ }
1520
+ const modernStatsTypes = {
1521
+ inboundrtp: "inbound-rtp",
1522
+ outboundrtp: "outbound-rtp",
1523
+ candidatepair: "candidate-pair",
1524
+ localcandidate: "local-candidate",
1525
+ remotecandidate: "remote-candidate"
1526
+ };
1527
+ const nativeGetStats = window2.RTCPeerConnection.prototype.getStats;
1528
+ window2.RTCPeerConnection.prototype.getStats = function getStats() {
1529
+ const [selector, onSucc, onErr] = arguments;
1530
+ return nativeGetStats.apply(this, [selector || null]).then((stats) => {
1531
+ if (browserDetails.version < 53 && !onSucc) {
1532
+ try {
1533
+ stats.forEach((stat) => {
1534
+ stat.type = modernStatsTypes[stat.type] || stat.type;
1535
+ });
1536
+ } catch (e) {
1537
+ if (e.name !== "TypeError") {
1538
+ throw e;
1539
+ }
1540
+ stats.forEach((stat, i) => {
1541
+ stats.set(i, Object.assign({}, stat, {
1542
+ type: modernStatsTypes[stat.type] || stat.type
1543
+ }));
1544
+ });
1545
+ }
1546
+ }
1547
+ return stats;
1548
+ }).then(onSucc, onErr);
1549
+ };
1550
+ }
1551
+ function shimSenderGetStats(window2) {
1552
+ if (!(typeof window2 === "object" && window2.RTCPeerConnection && window2.RTCRtpSender)) {
1553
+ return;
1554
+ }
1555
+ if (window2.RTCRtpSender && "getStats" in window2.RTCRtpSender.prototype) {
1556
+ return;
1557
+ }
1558
+ const origGetSenders = window2.RTCPeerConnection.prototype.getSenders;
1559
+ if (origGetSenders) {
1560
+ window2.RTCPeerConnection.prototype.getSenders = function getSenders() {
1561
+ const senders = origGetSenders.apply(this, []);
1562
+ senders.forEach((sender) => sender._pc = this);
1563
+ return senders;
1564
+ };
1565
+ }
1566
+ const origAddTrack = window2.RTCPeerConnection.prototype.addTrack;
1567
+ if (origAddTrack) {
1568
+ window2.RTCPeerConnection.prototype.addTrack = function addTrack() {
1569
+ const sender = origAddTrack.apply(this, arguments);
1570
+ sender._pc = this;
1571
+ return sender;
1572
+ };
1573
+ }
1574
+ window2.RTCRtpSender.prototype.getStats = function getStats() {
1575
+ return this.track ? this._pc.getStats(this.track) : Promise.resolve(/* @__PURE__ */ new Map());
1576
+ };
1577
+ }
1578
+ function shimReceiverGetStats(window2) {
1579
+ if (!(typeof window2 === "object" && window2.RTCPeerConnection && window2.RTCRtpSender)) {
1580
+ return;
1581
+ }
1582
+ if (window2.RTCRtpSender && "getStats" in window2.RTCRtpReceiver.prototype) {
1583
+ return;
1584
+ }
1585
+ const origGetReceivers = window2.RTCPeerConnection.prototype.getReceivers;
1586
+ if (origGetReceivers) {
1587
+ window2.RTCPeerConnection.prototype.getReceivers = function getReceivers() {
1588
+ const receivers = origGetReceivers.apply(this, []);
1589
+ receivers.forEach((receiver) => receiver._pc = this);
1590
+ return receivers;
1591
+ };
1592
+ }
1593
+ wrapPeerConnectionEvent(window2, "track", (e) => {
1594
+ e.receiver._pc = e.srcElement;
1595
+ return e;
1596
+ });
1597
+ window2.RTCRtpReceiver.prototype.getStats = function getStats() {
1598
+ return this._pc.getStats(this.track);
1599
+ };
1600
+ }
1601
+ function shimRemoveStream(window2) {
1602
+ if (!window2.RTCPeerConnection || "removeStream" in window2.RTCPeerConnection.prototype) {
1603
+ return;
1604
+ }
1605
+ window2.RTCPeerConnection.prototype.removeStream = function removeStream(stream) {
1606
+ deprecated("removeStream", "removeTrack");
1607
+ this.getSenders().forEach((sender) => {
1608
+ if (sender.track && stream.getTracks().includes(sender.track)) {
1609
+ this.removeTrack(sender);
1610
+ }
1611
+ });
1612
+ };
1613
+ }
1614
+ function shimRTCDataChannel(window2) {
1615
+ if (window2.DataChannel && !window2.RTCDataChannel) {
1616
+ window2.RTCDataChannel = window2.DataChannel;
1617
+ }
1618
+ }
1619
+ function shimAddTransceiver(window2) {
1620
+ if (!(typeof window2 === "object" && window2.RTCPeerConnection)) {
1621
+ return;
1622
+ }
1623
+ const origAddTransceiver = window2.RTCPeerConnection.prototype.addTransceiver;
1624
+ if (origAddTransceiver) {
1625
+ window2.RTCPeerConnection.prototype.addTransceiver = function addTransceiver() {
1626
+ this.setParametersPromises = [];
1627
+ let sendEncodings = arguments[1] && arguments[1].sendEncodings;
1628
+ if (sendEncodings === void 0) {
1629
+ sendEncodings = [];
1630
+ }
1631
+ sendEncodings = [...sendEncodings];
1632
+ const shouldPerformCheck = sendEncodings.length > 0;
1633
+ if (shouldPerformCheck) {
1634
+ sendEncodings.forEach((encodingParam) => {
1635
+ if ("rid" in encodingParam) {
1636
+ const ridRegex = /^[a-z0-9]{0,16}$/i;
1637
+ if (!ridRegex.test(encodingParam.rid)) {
1638
+ throw new TypeError("Invalid RID value provided.");
1639
+ }
1640
+ }
1641
+ if ("scaleResolutionDownBy" in encodingParam) {
1642
+ if (!(parseFloat(encodingParam.scaleResolutionDownBy) >= 1)) {
1643
+ throw new RangeError("scale_resolution_down_by must be >= 1.0");
1644
+ }
1645
+ }
1646
+ if ("maxFramerate" in encodingParam) {
1647
+ if (!(parseFloat(encodingParam.maxFramerate) >= 0)) {
1648
+ throw new RangeError("max_framerate must be >= 0.0");
1649
+ }
1650
+ }
1651
+ });
1652
+ }
1653
+ const transceiver = origAddTransceiver.apply(this, arguments);
1654
+ if (shouldPerformCheck) {
1655
+ const { sender } = transceiver;
1656
+ const params = sender.getParameters();
1657
+ if (!("encodings" in params) || // Avoid being fooled by patched getParameters() below.
1658
+ params.encodings.length === 1 && Object.keys(params.encodings[0]).length === 0) {
1659
+ params.encodings = sendEncodings;
1660
+ sender.sendEncodings = sendEncodings;
1661
+ this.setParametersPromises.push(
1662
+ sender.setParameters(params).then(() => {
1663
+ delete sender.sendEncodings;
1664
+ }).catch(() => {
1665
+ delete sender.sendEncodings;
1666
+ })
1667
+ );
1668
+ }
1669
+ }
1670
+ return transceiver;
1671
+ };
1672
+ }
1673
+ }
1674
+ function shimGetParameters(window2) {
1675
+ if (!(typeof window2 === "object" && window2.RTCRtpSender)) {
1676
+ return;
1677
+ }
1678
+ const origGetParameters = window2.RTCRtpSender.prototype.getParameters;
1679
+ if (origGetParameters) {
1680
+ window2.RTCRtpSender.prototype.getParameters = function getParameters() {
1681
+ const params = origGetParameters.apply(this, arguments);
1682
+ if (!("encodings" in params)) {
1683
+ params.encodings = [].concat(this.sendEncodings || [{}]);
1684
+ }
1685
+ return params;
1686
+ };
1687
+ }
1688
+ }
1689
+ function shimCreateOffer(window2) {
1690
+ if (!(typeof window2 === "object" && window2.RTCPeerConnection)) {
1691
+ return;
1692
+ }
1693
+ const origCreateOffer = window2.RTCPeerConnection.prototype.createOffer;
1694
+ window2.RTCPeerConnection.prototype.createOffer = function createOffer2() {
1695
+ if (this.setParametersPromises && this.setParametersPromises.length) {
1696
+ return Promise.all(this.setParametersPromises).then(() => {
1697
+ return origCreateOffer.apply(this, arguments);
1698
+ }).finally(() => {
1699
+ this.setParametersPromises = [];
1700
+ });
1701
+ }
1702
+ return origCreateOffer.apply(this, arguments);
1703
+ };
1704
+ }
1705
+ function shimCreateAnswer(window2) {
1706
+ if (!(typeof window2 === "object" && window2.RTCPeerConnection)) {
1707
+ return;
1708
+ }
1709
+ const origCreateAnswer = window2.RTCPeerConnection.prototype.createAnswer;
1710
+ window2.RTCPeerConnection.prototype.createAnswer = function createAnswer2() {
1711
+ if (this.setParametersPromises && this.setParametersPromises.length) {
1712
+ return Promise.all(this.setParametersPromises).then(() => {
1713
+ return origCreateAnswer.apply(this, arguments);
1714
+ }).finally(() => {
1715
+ this.setParametersPromises = [];
1716
+ });
1717
+ }
1718
+ return origCreateAnswer.apply(this, arguments);
1719
+ };
1720
+ }
1721
+ const firefoxShim = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
1722
+ __proto__: null,
1723
+ shimAddTransceiver,
1724
+ shimCreateAnswer,
1725
+ shimCreateOffer,
1726
+ shimGetDisplayMedia,
1727
+ shimGetParameters,
1728
+ shimGetUserMedia: shimGetUserMedia$1,
1729
+ shimOnTrack,
1730
+ shimPeerConnection,
1731
+ shimRTCDataChannel,
1732
+ shimReceiverGetStats,
1733
+ shimRemoveStream,
1734
+ shimSenderGetStats
1735
+ }, Symbol.toStringTag, { value: "Module" }));
1736
+ function shimLocalStreamsAPI(window2) {
1737
+ if (typeof window2 !== "object" || !window2.RTCPeerConnection) {
1738
+ return;
1739
+ }
1740
+ if (!("getLocalStreams" in window2.RTCPeerConnection.prototype)) {
1741
+ window2.RTCPeerConnection.prototype.getLocalStreams = function getLocalStreams() {
1742
+ if (!this._localStreams) {
1743
+ this._localStreams = [];
1744
+ }
1745
+ return this._localStreams;
1746
+ };
1747
+ }
1748
+ if (!("addStream" in window2.RTCPeerConnection.prototype)) {
1749
+ const _addTrack = window2.RTCPeerConnection.prototype.addTrack;
1750
+ window2.RTCPeerConnection.prototype.addStream = function addStream(stream) {
1751
+ if (!this._localStreams) {
1752
+ this._localStreams = [];
1753
+ }
1754
+ if (!this._localStreams.includes(stream)) {
1755
+ this._localStreams.push(stream);
1756
+ }
1757
+ stream.getAudioTracks().forEach((track) => _addTrack.call(
1758
+ this,
1759
+ track,
1760
+ stream
1761
+ ));
1762
+ stream.getVideoTracks().forEach((track) => _addTrack.call(
1763
+ this,
1764
+ track,
1765
+ stream
1766
+ ));
1767
+ };
1768
+ window2.RTCPeerConnection.prototype.addTrack = function addTrack(track, ...streams) {
1769
+ if (streams) {
1770
+ streams.forEach((stream) => {
1771
+ if (!this._localStreams) {
1772
+ this._localStreams = [stream];
1773
+ } else if (!this._localStreams.includes(stream)) {
1774
+ this._localStreams.push(stream);
1775
+ }
1776
+ });
1777
+ }
1778
+ return _addTrack.apply(this, arguments);
1779
+ };
1780
+ }
1781
+ if (!("removeStream" in window2.RTCPeerConnection.prototype)) {
1782
+ window2.RTCPeerConnection.prototype.removeStream = function removeStream(stream) {
1783
+ if (!this._localStreams) {
1784
+ this._localStreams = [];
1785
+ }
1786
+ const index = this._localStreams.indexOf(stream);
1787
+ if (index === -1) {
1788
+ return;
1789
+ }
1790
+ this._localStreams.splice(index, 1);
1791
+ const tracks = stream.getTracks();
1792
+ this.getSenders().forEach((sender) => {
1793
+ if (tracks.includes(sender.track)) {
1794
+ this.removeTrack(sender);
1795
+ }
1796
+ });
1797
+ };
1798
+ }
1799
+ }
1800
+ function shimRemoteStreamsAPI(window2) {
1801
+ if (typeof window2 !== "object" || !window2.RTCPeerConnection) {
1802
+ return;
1803
+ }
1804
+ if (!("getRemoteStreams" in window2.RTCPeerConnection.prototype)) {
1805
+ window2.RTCPeerConnection.prototype.getRemoteStreams = function getRemoteStreams() {
1806
+ return this._remoteStreams ? this._remoteStreams : [];
1807
+ };
1808
+ }
1809
+ if (!("onaddstream" in window2.RTCPeerConnection.prototype)) {
1810
+ Object.defineProperty(window2.RTCPeerConnection.prototype, "onaddstream", {
1811
+ get() {
1812
+ return this._onaddstream;
1813
+ },
1814
+ set(f) {
1815
+ if (this._onaddstream) {
1816
+ this.removeEventListener("addstream", this._onaddstream);
1817
+ this.removeEventListener("track", this._onaddstreampoly);
1818
+ }
1819
+ this.addEventListener("addstream", this._onaddstream = f);
1820
+ this.addEventListener("track", this._onaddstreampoly = (e) => {
1821
+ e.streams.forEach((stream) => {
1822
+ if (!this._remoteStreams) {
1823
+ this._remoteStreams = [];
1824
+ }
1825
+ if (this._remoteStreams.includes(stream)) {
1826
+ return;
1827
+ }
1828
+ this._remoteStreams.push(stream);
1829
+ const event = new Event("addstream");
1830
+ event.stream = stream;
1831
+ this.dispatchEvent(event);
1832
+ });
1833
+ });
1834
+ }
1835
+ });
1836
+ const origSetRemoteDescription = window2.RTCPeerConnection.prototype.setRemoteDescription;
1837
+ window2.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription() {
1838
+ const pc = this;
1839
+ if (!this._onaddstreampoly) {
1840
+ this.addEventListener("track", this._onaddstreampoly = function(e) {
1841
+ e.streams.forEach((stream) => {
1842
+ if (!pc._remoteStreams) {
1843
+ pc._remoteStreams = [];
1844
+ }
1845
+ if (pc._remoteStreams.indexOf(stream) >= 0) {
1846
+ return;
1847
+ }
1848
+ pc._remoteStreams.push(stream);
1849
+ const event = new Event("addstream");
1850
+ event.stream = stream;
1851
+ pc.dispatchEvent(event);
1852
+ });
1853
+ });
1854
+ }
1855
+ return origSetRemoteDescription.apply(pc, arguments);
1856
+ };
1857
+ }
1858
+ }
1859
+ function shimCallbacksAPI(window2) {
1860
+ if (typeof window2 !== "object" || !window2.RTCPeerConnection) {
1861
+ return;
1862
+ }
1863
+ const prototype = window2.RTCPeerConnection.prototype;
1864
+ const origCreateOffer = prototype.createOffer;
1865
+ const origCreateAnswer = prototype.createAnswer;
1866
+ const setLocalDescription = prototype.setLocalDescription;
1867
+ const setRemoteDescription = prototype.setRemoteDescription;
1868
+ const addIceCandidate2 = prototype.addIceCandidate;
1869
+ prototype.createOffer = function createOffer2(successCallback, failureCallback) {
1870
+ const options = arguments.length >= 2 ? arguments[2] : arguments[0];
1871
+ const promise = origCreateOffer.apply(this, [options]);
1872
+ if (!failureCallback) {
1873
+ return promise;
1874
+ }
1875
+ promise.then(successCallback, failureCallback);
1876
+ return Promise.resolve();
1877
+ };
1878
+ prototype.createAnswer = function createAnswer2(successCallback, failureCallback) {
1879
+ const options = arguments.length >= 2 ? arguments[2] : arguments[0];
1880
+ const promise = origCreateAnswer.apply(this, [options]);
1881
+ if (!failureCallback) {
1882
+ return promise;
1883
+ }
1884
+ promise.then(successCallback, failureCallback);
1885
+ return Promise.resolve();
1886
+ };
1887
+ let withCallback = function(description, successCallback, failureCallback) {
1888
+ const promise = setLocalDescription.apply(this, [description]);
1889
+ if (!failureCallback) {
1890
+ return promise;
1891
+ }
1892
+ promise.then(successCallback, failureCallback);
1893
+ return Promise.resolve();
1894
+ };
1895
+ prototype.setLocalDescription = withCallback;
1896
+ withCallback = function(description, successCallback, failureCallback) {
1897
+ const promise = setRemoteDescription.apply(this, [description]);
1898
+ if (!failureCallback) {
1899
+ return promise;
1900
+ }
1901
+ promise.then(successCallback, failureCallback);
1902
+ return Promise.resolve();
1903
+ };
1904
+ prototype.setRemoteDescription = withCallback;
1905
+ withCallback = function(candidate, successCallback, failureCallback) {
1906
+ const promise = addIceCandidate2.apply(this, [candidate]);
1907
+ if (!failureCallback) {
1908
+ return promise;
1909
+ }
1910
+ promise.then(successCallback, failureCallback);
1911
+ return Promise.resolve();
1912
+ };
1913
+ prototype.addIceCandidate = withCallback;
1914
+ }
1915
+ function shimGetUserMedia(window2) {
1916
+ const navigator2 = window2 && window2.navigator;
1917
+ if (navigator2.mediaDevices && navigator2.mediaDevices.getUserMedia) {
1918
+ const mediaDevices = navigator2.mediaDevices;
1919
+ const _getUserMedia = mediaDevices.getUserMedia.bind(mediaDevices);
1920
+ navigator2.mediaDevices.getUserMedia = (constraints) => {
1921
+ return _getUserMedia(shimConstraints(constraints));
1922
+ };
1923
+ }
1924
+ if (!navigator2.getUserMedia && navigator2.mediaDevices && navigator2.mediaDevices.getUserMedia) {
1925
+ navigator2.getUserMedia = (function getUserMedia(constraints, cb, errcb) {
1926
+ navigator2.mediaDevices.getUserMedia(constraints).then(cb, errcb);
1927
+ }).bind(navigator2);
1928
+ }
1929
+ }
1930
+ function shimConstraints(constraints) {
1931
+ if (constraints && constraints.video !== void 0) {
1932
+ return Object.assign(
1933
+ {},
1934
+ constraints,
1935
+ { video: compactObject(constraints.video) }
1936
+ );
1937
+ }
1938
+ return constraints;
1939
+ }
1940
+ function shimRTCIceServerUrls(window2) {
1941
+ if (!window2.RTCPeerConnection) {
1942
+ return;
1943
+ }
1944
+ const OrigPeerConnection = window2.RTCPeerConnection;
1945
+ window2.RTCPeerConnection = function RTCPeerConnection(pcConfig, pcConstraints) {
1946
+ if (pcConfig && pcConfig.iceServers) {
1947
+ const newIceServers = [];
1948
+ for (let i = 0; i < pcConfig.iceServers.length; i++) {
1949
+ let server = pcConfig.iceServers[i];
1950
+ if (server.urls === void 0 && server.url) {
1951
+ deprecated("RTCIceServer.url", "RTCIceServer.urls");
1952
+ server = JSON.parse(JSON.stringify(server));
1953
+ server.urls = server.url;
1954
+ delete server.url;
1955
+ newIceServers.push(server);
1956
+ } else {
1957
+ newIceServers.push(pcConfig.iceServers[i]);
1958
+ }
1959
+ }
1960
+ pcConfig.iceServers = newIceServers;
1961
+ }
1962
+ return new OrigPeerConnection(pcConfig, pcConstraints);
1963
+ };
1964
+ window2.RTCPeerConnection.prototype = OrigPeerConnection.prototype;
1965
+ if ("generateCertificate" in OrigPeerConnection) {
1966
+ Object.defineProperty(window2.RTCPeerConnection, "generateCertificate", {
1967
+ get() {
1968
+ return OrigPeerConnection.generateCertificate;
1969
+ }
1970
+ });
1971
+ }
1972
+ }
1973
+ function shimTrackEventTransceiver(window2) {
1974
+ if (typeof window2 === "object" && window2.RTCTrackEvent && "receiver" in window2.RTCTrackEvent.prototype && !("transceiver" in window2.RTCTrackEvent.prototype)) {
1975
+ Object.defineProperty(window2.RTCTrackEvent.prototype, "transceiver", {
1976
+ get() {
1977
+ return { receiver: this.receiver };
1978
+ }
1979
+ });
1980
+ }
1981
+ }
1982
+ function shimCreateOfferLegacy(window2) {
1983
+ const origCreateOffer = window2.RTCPeerConnection.prototype.createOffer;
1984
+ window2.RTCPeerConnection.prototype.createOffer = function createOffer2(offerOptions) {
1985
+ if (offerOptions) {
1986
+ if (typeof offerOptions.offerToReceiveAudio !== "undefined") {
1987
+ offerOptions.offerToReceiveAudio = !!offerOptions.offerToReceiveAudio;
1988
+ }
1989
+ const audioTransceiver = this.getTransceivers().find((transceiver) => transceiver.receiver.track.kind === "audio");
1990
+ if (offerOptions.offerToReceiveAudio === false && audioTransceiver) {
1991
+ if (audioTransceiver.direction === "sendrecv") {
1992
+ if (audioTransceiver.setDirection) {
1993
+ audioTransceiver.setDirection("sendonly");
1994
+ } else {
1995
+ audioTransceiver.direction = "sendonly";
1996
+ }
1997
+ } else if (audioTransceiver.direction === "recvonly") {
1998
+ if (audioTransceiver.setDirection) {
1999
+ audioTransceiver.setDirection("inactive");
2000
+ } else {
2001
+ audioTransceiver.direction = "inactive";
2002
+ }
2003
+ }
2004
+ } else if (offerOptions.offerToReceiveAudio === true && !audioTransceiver) {
2005
+ this.addTransceiver("audio", { direction: "recvonly" });
2006
+ }
2007
+ if (typeof offerOptions.offerToReceiveVideo !== "undefined") {
2008
+ offerOptions.offerToReceiveVideo = !!offerOptions.offerToReceiveVideo;
2009
+ }
2010
+ const videoTransceiver = this.getTransceivers().find((transceiver) => transceiver.receiver.track.kind === "video");
2011
+ if (offerOptions.offerToReceiveVideo === false && videoTransceiver) {
2012
+ if (videoTransceiver.direction === "sendrecv") {
2013
+ if (videoTransceiver.setDirection) {
2014
+ videoTransceiver.setDirection("sendonly");
2015
+ } else {
2016
+ videoTransceiver.direction = "sendonly";
2017
+ }
2018
+ } else if (videoTransceiver.direction === "recvonly") {
2019
+ if (videoTransceiver.setDirection) {
2020
+ videoTransceiver.setDirection("inactive");
2021
+ } else {
2022
+ videoTransceiver.direction = "inactive";
2023
+ }
2024
+ }
2025
+ } else if (offerOptions.offerToReceiveVideo === true && !videoTransceiver) {
2026
+ this.addTransceiver("video", { direction: "recvonly" });
2027
+ }
2028
+ }
2029
+ return origCreateOffer.apply(this, arguments);
2030
+ };
2031
+ }
2032
+ function shimAudioContext(window2) {
2033
+ if (typeof window2 !== "object" || window2.AudioContext) {
2034
+ return;
2035
+ }
2036
+ window2.AudioContext = window2.webkitAudioContext;
2037
+ }
2038
+ const safariShim = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2039
+ __proto__: null,
2040
+ shimAudioContext,
2041
+ shimCallbacksAPI,
2042
+ shimConstraints,
2043
+ shimCreateOfferLegacy,
2044
+ shimGetUserMedia,
2045
+ shimLocalStreamsAPI,
2046
+ shimRTCIceServerUrls,
2047
+ shimRemoteStreamsAPI,
2048
+ shimTrackEventTransceiver
2049
+ }, Symbol.toStringTag, { value: "Module" }));
2050
+ var sdp$1 = { exports: {} };
2051
+ var hasRequiredSdp;
2052
+ function requireSdp() {
2053
+ if (hasRequiredSdp) return sdp$1.exports;
2054
+ hasRequiredSdp = 1;
2055
+ (function(module) {
2056
+ const SDPUtils2 = {};
2057
+ SDPUtils2.generateIdentifier = function() {
2058
+ return Math.random().toString(36).substring(2, 12);
2059
+ };
2060
+ SDPUtils2.localCName = SDPUtils2.generateIdentifier();
2061
+ SDPUtils2.splitLines = function(blob) {
2062
+ return blob.trim().split("\n").map((line) => line.trim());
2063
+ };
2064
+ SDPUtils2.splitSections = function(blob) {
2065
+ const parts = blob.split("\nm=");
2066
+ return parts.map((part, index) => (index > 0 ? "m=" + part : part).trim() + "\r\n");
2067
+ };
2068
+ SDPUtils2.getDescription = function(blob) {
2069
+ const sections = SDPUtils2.splitSections(blob);
2070
+ return sections && sections[0];
2071
+ };
2072
+ SDPUtils2.getMediaSections = function(blob) {
2073
+ const sections = SDPUtils2.splitSections(blob);
2074
+ sections.shift();
2075
+ return sections;
2076
+ };
2077
+ SDPUtils2.matchPrefix = function(blob, prefix) {
2078
+ return SDPUtils2.splitLines(blob).filter((line) => line.indexOf(prefix) === 0);
2079
+ };
2080
+ SDPUtils2.parseCandidate = function(line) {
2081
+ let parts;
2082
+ if (line.indexOf("a=candidate:") === 0) {
2083
+ parts = line.substring(12).split(" ");
2084
+ } else {
2085
+ parts = line.substring(10).split(" ");
2086
+ }
2087
+ const candidate = {
2088
+ foundation: parts[0],
2089
+ component: { 1: "rtp", 2: "rtcp" }[parts[1]] || parts[1],
2090
+ protocol: parts[2].toLowerCase(),
2091
+ priority: parseInt(parts[3], 10),
2092
+ ip: parts[4],
2093
+ address: parts[4],
2094
+ // address is an alias for ip.
2095
+ port: parseInt(parts[5], 10),
2096
+ // skip parts[6] == 'typ'
2097
+ type: parts[7]
2098
+ };
2099
+ for (let i = 8; i < parts.length; i += 2) {
2100
+ switch (parts[i]) {
2101
+ case "raddr":
2102
+ candidate.relatedAddress = parts[i + 1];
2103
+ break;
2104
+ case "rport":
2105
+ candidate.relatedPort = parseInt(parts[i + 1], 10);
2106
+ break;
2107
+ case "tcptype":
2108
+ candidate.tcpType = parts[i + 1];
2109
+ break;
2110
+ case "ufrag":
2111
+ candidate.ufrag = parts[i + 1];
2112
+ candidate.usernameFragment = parts[i + 1];
2113
+ break;
2114
+ default:
2115
+ if (candidate[parts[i]] === void 0) {
2116
+ candidate[parts[i]] = parts[i + 1];
2117
+ }
2118
+ break;
2119
+ }
2120
+ }
2121
+ return candidate;
2122
+ };
2123
+ SDPUtils2.writeCandidate = function(candidate) {
2124
+ const sdp2 = [];
2125
+ sdp2.push(candidate.foundation);
2126
+ const component = candidate.component;
2127
+ if (component === "rtp") {
2128
+ sdp2.push(1);
2129
+ } else if (component === "rtcp") {
2130
+ sdp2.push(2);
2131
+ } else {
2132
+ sdp2.push(component);
2133
+ }
2134
+ sdp2.push(candidate.protocol.toUpperCase());
2135
+ sdp2.push(candidate.priority);
2136
+ sdp2.push(candidate.address || candidate.ip);
2137
+ sdp2.push(candidate.port);
2138
+ const type = candidate.type;
2139
+ sdp2.push("typ");
2140
+ sdp2.push(type);
2141
+ if (type !== "host" && candidate.relatedAddress && candidate.relatedPort) {
2142
+ sdp2.push("raddr");
2143
+ sdp2.push(candidate.relatedAddress);
2144
+ sdp2.push("rport");
2145
+ sdp2.push(candidate.relatedPort);
2146
+ }
2147
+ if (candidate.tcpType && candidate.protocol.toLowerCase() === "tcp") {
2148
+ sdp2.push("tcptype");
2149
+ sdp2.push(candidate.tcpType);
2150
+ }
2151
+ if (candidate.usernameFragment || candidate.ufrag) {
2152
+ sdp2.push("ufrag");
2153
+ sdp2.push(candidate.usernameFragment || candidate.ufrag);
2154
+ }
2155
+ return "candidate:" + sdp2.join(" ");
2156
+ };
2157
+ SDPUtils2.parseIceOptions = function(line) {
2158
+ return line.substring(14).split(" ");
2159
+ };
2160
+ SDPUtils2.parseRtpMap = function(line) {
2161
+ let parts = line.substring(9).split(" ");
2162
+ const parsed = {
2163
+ payloadType: parseInt(parts.shift(), 10)
2164
+ // was: id
2165
+ };
2166
+ parts = parts[0].split("/");
2167
+ parsed.name = parts[0];
2168
+ parsed.clockRate = parseInt(parts[1], 10);
2169
+ parsed.channels = parts.length === 3 ? parseInt(parts[2], 10) : 1;
2170
+ parsed.numChannels = parsed.channels;
2171
+ return parsed;
2172
+ };
2173
+ SDPUtils2.writeRtpMap = function(codec) {
2174
+ let pt = codec.payloadType;
2175
+ if (codec.preferredPayloadType !== void 0) {
2176
+ pt = codec.preferredPayloadType;
2177
+ }
2178
+ const channels = codec.channels || codec.numChannels || 1;
2179
+ return "a=rtpmap:" + pt + " " + codec.name + "/" + codec.clockRate + (channels !== 1 ? "/" + channels : "") + "\r\n";
2180
+ };
2181
+ SDPUtils2.parseExtmap = function(line) {
2182
+ const parts = line.substring(9).split(" ");
2183
+ return {
2184
+ id: parseInt(parts[0], 10),
2185
+ direction: parts[0].indexOf("/") > 0 ? parts[0].split("/")[1] : "sendrecv",
2186
+ uri: parts[1],
2187
+ attributes: parts.slice(2).join(" ")
2188
+ };
2189
+ };
2190
+ SDPUtils2.writeExtmap = function(headerExtension) {
2191
+ return "a=extmap:" + (headerExtension.id || headerExtension.preferredId) + (headerExtension.direction && headerExtension.direction !== "sendrecv" ? "/" + headerExtension.direction : "") + " " + headerExtension.uri + (headerExtension.attributes ? " " + headerExtension.attributes : "") + "\r\n";
2192
+ };
2193
+ SDPUtils2.parseFmtp = function(line) {
2194
+ const parsed = {};
2195
+ let kv;
2196
+ const parts = line.substring(line.indexOf(" ") + 1).split(";");
2197
+ for (let j = 0; j < parts.length; j++) {
2198
+ kv = parts[j].trim().split("=");
2199
+ parsed[kv[0].trim()] = kv[1];
2200
+ }
2201
+ return parsed;
2202
+ };
2203
+ SDPUtils2.writeFmtp = function(codec) {
2204
+ let line = "";
2205
+ let pt = codec.payloadType;
2206
+ if (codec.preferredPayloadType !== void 0) {
2207
+ pt = codec.preferredPayloadType;
2208
+ }
2209
+ if (codec.parameters && Object.keys(codec.parameters).length) {
2210
+ const params = [];
2211
+ Object.keys(codec.parameters).forEach((param) => {
2212
+ if (codec.parameters[param] !== void 0) {
2213
+ params.push(param + "=" + codec.parameters[param]);
2214
+ } else {
2215
+ params.push(param);
2216
+ }
2217
+ });
2218
+ line += "a=fmtp:" + pt + " " + params.join(";") + "\r\n";
2219
+ }
2220
+ return line;
2221
+ };
2222
+ SDPUtils2.parseRtcpFb = function(line) {
2223
+ const parts = line.substring(line.indexOf(" ") + 1).split(" ");
2224
+ return {
2225
+ type: parts.shift(),
2226
+ parameter: parts.join(" ")
2227
+ };
2228
+ };
2229
+ SDPUtils2.writeRtcpFb = function(codec) {
2230
+ let lines = "";
2231
+ let pt = codec.payloadType;
2232
+ if (codec.preferredPayloadType !== void 0) {
2233
+ pt = codec.preferredPayloadType;
2234
+ }
2235
+ if (codec.rtcpFeedback && codec.rtcpFeedback.length) {
2236
+ codec.rtcpFeedback.forEach((fb) => {
2237
+ lines += "a=rtcp-fb:" + pt + " " + fb.type + (fb.parameter && fb.parameter.length ? " " + fb.parameter : "") + "\r\n";
2238
+ });
2239
+ }
2240
+ return lines;
2241
+ };
2242
+ SDPUtils2.parseSsrcMedia = function(line) {
2243
+ const sp = line.indexOf(" ");
2244
+ const parts = {
2245
+ ssrc: parseInt(line.substring(7, sp), 10)
2246
+ };
2247
+ const colon = line.indexOf(":", sp);
2248
+ if (colon > -1) {
2249
+ parts.attribute = line.substring(sp + 1, colon);
2250
+ parts.value = line.substring(colon + 1);
2251
+ } else {
2252
+ parts.attribute = line.substring(sp + 1);
2253
+ }
2254
+ return parts;
2255
+ };
2256
+ SDPUtils2.parseSsrcGroup = function(line) {
2257
+ const parts = line.substring(13).split(" ");
2258
+ return {
2259
+ semantics: parts.shift(),
2260
+ ssrcs: parts.map((ssrc) => parseInt(ssrc, 10))
2261
+ };
2262
+ };
2263
+ SDPUtils2.getMid = function(mediaSection) {
2264
+ const mid = SDPUtils2.matchPrefix(mediaSection, "a=mid:")[0];
2265
+ if (mid) {
2266
+ return mid.substring(6);
2267
+ }
2268
+ };
2269
+ SDPUtils2.parseFingerprint = function(line) {
2270
+ const parts = line.substring(14).split(" ");
2271
+ return {
2272
+ algorithm: parts[0].toLowerCase(),
2273
+ // algorithm is case-sensitive in Edge.
2274
+ value: parts[1].toUpperCase()
2275
+ // the definition is upper-case in RFC 4572.
2276
+ };
2277
+ };
2278
+ SDPUtils2.getDtlsParameters = function(mediaSection, sessionpart) {
2279
+ const lines = SDPUtils2.matchPrefix(
2280
+ mediaSection + sessionpart,
2281
+ "a=fingerprint:"
2282
+ );
2283
+ return {
2284
+ role: "auto",
2285
+ fingerprints: lines.map(SDPUtils2.parseFingerprint)
2286
+ };
2287
+ };
2288
+ SDPUtils2.writeDtlsParameters = function(params, setupType) {
2289
+ let sdp2 = "a=setup:" + setupType + "\r\n";
2290
+ params.fingerprints.forEach((fp) => {
2291
+ sdp2 += "a=fingerprint:" + fp.algorithm + " " + fp.value + "\r\n";
2292
+ });
2293
+ return sdp2;
2294
+ };
2295
+ SDPUtils2.parseCryptoLine = function(line) {
2296
+ const parts = line.substring(9).split(" ");
2297
+ return {
2298
+ tag: parseInt(parts[0], 10),
2299
+ cryptoSuite: parts[1],
2300
+ keyParams: parts[2],
2301
+ sessionParams: parts.slice(3)
2302
+ };
2303
+ };
2304
+ SDPUtils2.writeCryptoLine = function(parameters) {
2305
+ return "a=crypto:" + parameters.tag + " " + parameters.cryptoSuite + " " + (typeof parameters.keyParams === "object" ? SDPUtils2.writeCryptoKeyParams(parameters.keyParams) : parameters.keyParams) + (parameters.sessionParams ? " " + parameters.sessionParams.join(" ") : "") + "\r\n";
2306
+ };
2307
+ SDPUtils2.parseCryptoKeyParams = function(keyParams) {
2308
+ if (keyParams.indexOf("inline:") !== 0) {
2309
+ return null;
2310
+ }
2311
+ const parts = keyParams.substring(7).split("|");
2312
+ return {
2313
+ keyMethod: "inline",
2314
+ keySalt: parts[0],
2315
+ lifeTime: parts[1],
2316
+ mkiValue: parts[2] ? parts[2].split(":")[0] : void 0,
2317
+ mkiLength: parts[2] ? parts[2].split(":")[1] : void 0
2318
+ };
2319
+ };
2320
+ SDPUtils2.writeCryptoKeyParams = function(keyParams) {
2321
+ return keyParams.keyMethod + ":" + keyParams.keySalt + (keyParams.lifeTime ? "|" + keyParams.lifeTime : "") + (keyParams.mkiValue && keyParams.mkiLength ? "|" + keyParams.mkiValue + ":" + keyParams.mkiLength : "");
2322
+ };
2323
+ SDPUtils2.getCryptoParameters = function(mediaSection, sessionpart) {
2324
+ const lines = SDPUtils2.matchPrefix(
2325
+ mediaSection + sessionpart,
2326
+ "a=crypto:"
2327
+ );
2328
+ return lines.map(SDPUtils2.parseCryptoLine);
2329
+ };
2330
+ SDPUtils2.getIceParameters = function(mediaSection, sessionpart) {
2331
+ const ufrag = SDPUtils2.matchPrefix(
2332
+ mediaSection + sessionpart,
2333
+ "a=ice-ufrag:"
2334
+ )[0];
2335
+ const pwd = SDPUtils2.matchPrefix(
2336
+ mediaSection + sessionpart,
2337
+ "a=ice-pwd:"
2338
+ )[0];
2339
+ if (!(ufrag && pwd)) {
2340
+ return null;
2341
+ }
2342
+ return {
2343
+ usernameFragment: ufrag.substring(12),
2344
+ password: pwd.substring(10)
2345
+ };
2346
+ };
2347
+ SDPUtils2.writeIceParameters = function(params) {
2348
+ let sdp2 = "a=ice-ufrag:" + params.usernameFragment + "\r\na=ice-pwd:" + params.password + "\r\n";
2349
+ if (params.iceLite) {
2350
+ sdp2 += "a=ice-lite\r\n";
2351
+ }
2352
+ return sdp2;
2353
+ };
2354
+ SDPUtils2.parseRtpParameters = function(mediaSection) {
2355
+ const description = {
2356
+ codecs: [],
2357
+ headerExtensions: [],
2358
+ fecMechanisms: [],
2359
+ rtcp: []
2360
+ };
2361
+ const lines = SDPUtils2.splitLines(mediaSection);
2362
+ const mline = lines[0].split(" ");
2363
+ description.profile = mline[2];
2364
+ for (let i = 3; i < mline.length; i++) {
2365
+ const pt = mline[i];
2366
+ const rtpmapline = SDPUtils2.matchPrefix(
2367
+ mediaSection,
2368
+ "a=rtpmap:" + pt + " "
2369
+ )[0];
2370
+ if (rtpmapline) {
2371
+ const codec = SDPUtils2.parseRtpMap(rtpmapline);
2372
+ const fmtps = SDPUtils2.matchPrefix(
2373
+ mediaSection,
2374
+ "a=fmtp:" + pt + " "
2375
+ );
2376
+ codec.parameters = fmtps.length ? SDPUtils2.parseFmtp(fmtps[0]) : {};
2377
+ codec.rtcpFeedback = SDPUtils2.matchPrefix(
2378
+ mediaSection,
2379
+ "a=rtcp-fb:" + pt + " "
2380
+ ).map(SDPUtils2.parseRtcpFb);
2381
+ description.codecs.push(codec);
2382
+ switch (codec.name.toUpperCase()) {
2383
+ case "RED":
2384
+ case "ULPFEC":
2385
+ description.fecMechanisms.push(codec.name.toUpperCase());
2386
+ break;
2387
+ }
2388
+ }
2389
+ }
2390
+ SDPUtils2.matchPrefix(mediaSection, "a=extmap:").forEach((line) => {
2391
+ description.headerExtensions.push(SDPUtils2.parseExtmap(line));
2392
+ });
2393
+ const wildcardRtcpFb = SDPUtils2.matchPrefix(mediaSection, "a=rtcp-fb:* ").map(SDPUtils2.parseRtcpFb);
2394
+ description.codecs.forEach((codec) => {
2395
+ wildcardRtcpFb.forEach((fb) => {
2396
+ const duplicate = codec.rtcpFeedback.find((existingFeedback) => {
2397
+ return existingFeedback.type === fb.type && existingFeedback.parameter === fb.parameter;
2398
+ });
2399
+ if (!duplicate) {
2400
+ codec.rtcpFeedback.push(fb);
2401
+ }
2402
+ });
2403
+ });
2404
+ return description;
2405
+ };
2406
+ SDPUtils2.writeRtpDescription = function(kind, caps) {
2407
+ let sdp2 = "";
2408
+ sdp2 += "m=" + kind + " ";
2409
+ sdp2 += caps.codecs.length > 0 ? "9" : "0";
2410
+ sdp2 += " " + (caps.profile || "UDP/TLS/RTP/SAVPF") + " ";
2411
+ sdp2 += caps.codecs.map((codec) => {
2412
+ if (codec.preferredPayloadType !== void 0) {
2413
+ return codec.preferredPayloadType;
2414
+ }
2415
+ return codec.payloadType;
2416
+ }).join(" ") + "\r\n";
2417
+ sdp2 += "c=IN IP4 0.0.0.0\r\n";
2418
+ sdp2 += "a=rtcp:9 IN IP4 0.0.0.0\r\n";
2419
+ caps.codecs.forEach((codec) => {
2420
+ sdp2 += SDPUtils2.writeRtpMap(codec);
2421
+ sdp2 += SDPUtils2.writeFmtp(codec);
2422
+ sdp2 += SDPUtils2.writeRtcpFb(codec);
2423
+ });
2424
+ let maxptime = 0;
2425
+ caps.codecs.forEach((codec) => {
2426
+ if (codec.maxptime > maxptime) {
2427
+ maxptime = codec.maxptime;
2428
+ }
2429
+ });
2430
+ if (maxptime > 0) {
2431
+ sdp2 += "a=maxptime:" + maxptime + "\r\n";
2432
+ }
2433
+ if (caps.headerExtensions) {
2434
+ caps.headerExtensions.forEach((extension) => {
2435
+ sdp2 += SDPUtils2.writeExtmap(extension);
2436
+ });
2437
+ }
2438
+ return sdp2;
2439
+ };
2440
+ SDPUtils2.parseRtpEncodingParameters = function(mediaSection) {
2441
+ const encodingParameters = [];
2442
+ const description = SDPUtils2.parseRtpParameters(mediaSection);
2443
+ const hasRed = description.fecMechanisms.indexOf("RED") !== -1;
2444
+ const hasUlpfec = description.fecMechanisms.indexOf("ULPFEC") !== -1;
2445
+ const ssrcs = SDPUtils2.matchPrefix(mediaSection, "a=ssrc:").map((line) => SDPUtils2.parseSsrcMedia(line)).filter((parts) => parts.attribute === "cname");
2446
+ const primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc;
2447
+ let secondarySsrc;
2448
+ const flows = SDPUtils2.matchPrefix(mediaSection, "a=ssrc-group:FID").map((line) => {
2449
+ const parts = line.substring(17).split(" ");
2450
+ return parts.map((part) => parseInt(part, 10));
2451
+ });
2452
+ if (flows.length > 0 && flows[0].length > 1 && flows[0][0] === primarySsrc) {
2453
+ secondarySsrc = flows[0][1];
2454
+ }
2455
+ description.codecs.forEach((codec) => {
2456
+ if (codec.name.toUpperCase() === "RTX" && codec.parameters.apt) {
2457
+ let encParam = {
2458
+ ssrc: primarySsrc,
2459
+ codecPayloadType: parseInt(codec.parameters.apt, 10)
2460
+ };
2461
+ if (primarySsrc && secondarySsrc) {
2462
+ encParam.rtx = { ssrc: secondarySsrc };
2463
+ }
2464
+ encodingParameters.push(encParam);
2465
+ if (hasRed) {
2466
+ encParam = JSON.parse(JSON.stringify(encParam));
2467
+ encParam.fec = {
2468
+ ssrc: primarySsrc,
2469
+ mechanism: hasUlpfec ? "red+ulpfec" : "red"
2470
+ };
2471
+ encodingParameters.push(encParam);
2472
+ }
2473
+ }
2474
+ });
2475
+ if (encodingParameters.length === 0 && primarySsrc) {
2476
+ encodingParameters.push({
2477
+ ssrc: primarySsrc
2478
+ });
2479
+ }
2480
+ let bandwidth = SDPUtils2.matchPrefix(mediaSection, "b=");
2481
+ if (bandwidth.length) {
2482
+ if (bandwidth[0].indexOf("b=TIAS:") === 0) {
2483
+ bandwidth = parseInt(bandwidth[0].substring(7), 10);
2484
+ } else if (bandwidth[0].indexOf("b=AS:") === 0) {
2485
+ bandwidth = parseInt(bandwidth[0].substring(5), 10) * 1e3 * 0.95 - 50 * 40 * 8;
2486
+ } else {
2487
+ bandwidth = void 0;
2488
+ }
2489
+ encodingParameters.forEach((params) => {
2490
+ params.maxBitrate = bandwidth;
2491
+ });
2492
+ }
2493
+ return encodingParameters;
2494
+ };
2495
+ SDPUtils2.parseRtcpParameters = function(mediaSection) {
2496
+ const rtcpParameters = {};
2497
+ const remoteSsrc = SDPUtils2.matchPrefix(mediaSection, "a=ssrc:").map((line) => SDPUtils2.parseSsrcMedia(line)).filter((obj) => obj.attribute === "cname")[0];
2498
+ if (remoteSsrc) {
2499
+ rtcpParameters.cname = remoteSsrc.value;
2500
+ rtcpParameters.ssrc = remoteSsrc.ssrc;
2501
+ }
2502
+ const rsize = SDPUtils2.matchPrefix(mediaSection, "a=rtcp-rsize");
2503
+ rtcpParameters.reducedSize = rsize.length > 0;
2504
+ rtcpParameters.compound = rsize.length === 0;
2505
+ const mux = SDPUtils2.matchPrefix(mediaSection, "a=rtcp-mux");
2506
+ rtcpParameters.mux = mux.length > 0;
2507
+ return rtcpParameters;
2508
+ };
2509
+ SDPUtils2.writeRtcpParameters = function(rtcpParameters) {
2510
+ let sdp2 = "";
2511
+ if (rtcpParameters.reducedSize) {
2512
+ sdp2 += "a=rtcp-rsize\r\n";
2513
+ }
2514
+ if (rtcpParameters.mux) {
2515
+ sdp2 += "a=rtcp-mux\r\n";
2516
+ }
2517
+ if (rtcpParameters.ssrc !== void 0 && rtcpParameters.cname) {
2518
+ sdp2 += "a=ssrc:" + rtcpParameters.ssrc + " cname:" + rtcpParameters.cname + "\r\n";
2519
+ }
2520
+ return sdp2;
2521
+ };
2522
+ SDPUtils2.parseMsid = function(mediaSection) {
2523
+ let parts;
2524
+ const spec = SDPUtils2.matchPrefix(mediaSection, "a=msid:");
2525
+ if (spec.length === 1) {
2526
+ parts = spec[0].substring(7).split(" ");
2527
+ return { stream: parts[0], track: parts[1] };
2528
+ }
2529
+ const planB = SDPUtils2.matchPrefix(mediaSection, "a=ssrc:").map((line) => SDPUtils2.parseSsrcMedia(line)).filter((msidParts) => msidParts.attribute === "msid");
2530
+ if (planB.length > 0) {
2531
+ parts = planB[0].value.split(" ");
2532
+ return { stream: parts[0], track: parts[1] };
2533
+ }
2534
+ };
2535
+ SDPUtils2.parseSctpDescription = function(mediaSection) {
2536
+ const mline = SDPUtils2.parseMLine(mediaSection);
2537
+ const maxSizeLine = SDPUtils2.matchPrefix(mediaSection, "a=max-message-size:");
2538
+ let maxMessageSize;
2539
+ if (maxSizeLine.length > 0) {
2540
+ maxMessageSize = parseInt(maxSizeLine[0].substring(19), 10);
2541
+ }
2542
+ if (isNaN(maxMessageSize)) {
2543
+ maxMessageSize = 65536;
2544
+ }
2545
+ const sctpPort = SDPUtils2.matchPrefix(mediaSection, "a=sctp-port:");
2546
+ if (sctpPort.length > 0) {
2547
+ return {
2548
+ port: parseInt(sctpPort[0].substring(12), 10),
2549
+ protocol: mline.fmt,
2550
+ maxMessageSize
2551
+ };
2552
+ }
2553
+ const sctpMapLines = SDPUtils2.matchPrefix(mediaSection, "a=sctpmap:");
2554
+ if (sctpMapLines.length > 0) {
2555
+ const parts = sctpMapLines[0].substring(10).split(" ");
2556
+ return {
2557
+ port: parseInt(parts[0], 10),
2558
+ protocol: parts[1],
2559
+ maxMessageSize
2560
+ };
2561
+ }
2562
+ };
2563
+ SDPUtils2.writeSctpDescription = function(media, sctp) {
2564
+ let output = [];
2565
+ if (media.protocol !== "DTLS/SCTP") {
2566
+ output = [
2567
+ "m=" + media.kind + " 9 " + media.protocol + " " + sctp.protocol + "\r\n",
2568
+ "c=IN IP4 0.0.0.0\r\n",
2569
+ "a=sctp-port:" + sctp.port + "\r\n"
2570
+ ];
2571
+ } else {
2572
+ output = [
2573
+ "m=" + media.kind + " 9 " + media.protocol + " " + sctp.port + "\r\n",
2574
+ "c=IN IP4 0.0.0.0\r\n",
2575
+ "a=sctpmap:" + sctp.port + " " + sctp.protocol + " 65535\r\n"
2576
+ ];
2577
+ }
2578
+ if (sctp.maxMessageSize !== void 0) {
2579
+ output.push("a=max-message-size:" + sctp.maxMessageSize + "\r\n");
2580
+ }
2581
+ return output.join("");
2582
+ };
2583
+ SDPUtils2.generateSessionId = function() {
2584
+ return Math.random().toString().substr(2, 22);
2585
+ };
2586
+ SDPUtils2.writeSessionBoilerplate = function(sessId, sessVer, sessUser) {
2587
+ let sessionId;
2588
+ const version = sessVer !== void 0 ? sessVer : 2;
2589
+ if (sessId) {
2590
+ sessionId = sessId;
2591
+ } else {
2592
+ sessionId = SDPUtils2.generateSessionId();
2593
+ }
2594
+ const user = sessUser || "thisisadapterortc";
2595
+ return "v=0\r\no=" + user + " " + sessionId + " " + version + " IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n";
2596
+ };
2597
+ SDPUtils2.getDirection = function(mediaSection, sessionpart) {
2598
+ const lines = SDPUtils2.splitLines(mediaSection);
2599
+ for (let i = 0; i < lines.length; i++) {
2600
+ switch (lines[i]) {
2601
+ case "a=sendrecv":
2602
+ case "a=sendonly":
2603
+ case "a=recvonly":
2604
+ case "a=inactive":
2605
+ return lines[i].substring(2);
2606
+ }
2607
+ }
2608
+ if (sessionpart) {
2609
+ return SDPUtils2.getDirection(sessionpart);
2610
+ }
2611
+ return "sendrecv";
2612
+ };
2613
+ SDPUtils2.getKind = function(mediaSection) {
2614
+ const lines = SDPUtils2.splitLines(mediaSection);
2615
+ const mline = lines[0].split(" ");
2616
+ return mline[0].substring(2);
2617
+ };
2618
+ SDPUtils2.isRejected = function(mediaSection) {
2619
+ return mediaSection.split(" ", 2)[1] === "0";
2620
+ };
2621
+ SDPUtils2.parseMLine = function(mediaSection) {
2622
+ const lines = SDPUtils2.splitLines(mediaSection);
2623
+ const parts = lines[0].substring(2).split(" ");
2624
+ return {
2625
+ kind: parts[0],
2626
+ port: parseInt(parts[1], 10),
2627
+ protocol: parts[2],
2628
+ fmt: parts.slice(3).join(" ")
2629
+ };
2630
+ };
2631
+ SDPUtils2.parseOLine = function(mediaSection) {
2632
+ const line = SDPUtils2.matchPrefix(mediaSection, "o=")[0];
2633
+ const parts = line.substring(2).split(" ");
2634
+ return {
2635
+ username: parts[0],
2636
+ sessionId: parts[1],
2637
+ sessionVersion: parseInt(parts[2], 10),
2638
+ netType: parts[3],
2639
+ addressType: parts[4],
2640
+ address: parts[5]
2641
+ };
2642
+ };
2643
+ SDPUtils2.isValidSDP = function(blob) {
2644
+ if (typeof blob !== "string" || blob.length === 0) {
2645
+ return false;
2646
+ }
2647
+ const lines = SDPUtils2.splitLines(blob);
2648
+ for (let i = 0; i < lines.length; i++) {
2649
+ if (lines[i].length < 2 || lines[i].charAt(1) !== "=") {
2650
+ return false;
2651
+ }
2652
+ }
2653
+ return true;
2654
+ };
2655
+ {
2656
+ module.exports = SDPUtils2;
2657
+ }
2658
+ })(sdp$1);
2659
+ return sdp$1.exports;
2660
+ }
2661
+ var sdpExports = requireSdp();
2662
+ const SDPUtils = /* @__PURE__ */ getDefaultExportFromCjs(sdpExports);
2663
+ const sdp = /* @__PURE__ */ _mergeNamespaces({
2664
+ __proto__: null,
2665
+ default: SDPUtils
2666
+ }, [sdpExports]);
2667
+ function shimRTCIceCandidate(window2) {
2668
+ if (!window2.RTCIceCandidate || window2.RTCIceCandidate && "foundation" in window2.RTCIceCandidate.prototype) {
2669
+ return;
2670
+ }
2671
+ const NativeRTCIceCandidate = window2.RTCIceCandidate;
2672
+ window2.RTCIceCandidate = function RTCIceCandidate2(args) {
2673
+ if (typeof args === "object" && args.candidate && args.candidate.indexOf("a=") === 0) {
2674
+ args = JSON.parse(JSON.stringify(args));
2675
+ args.candidate = args.candidate.substring(2);
2676
+ }
2677
+ if (args.candidate && args.candidate.length) {
2678
+ const nativeCandidate = new NativeRTCIceCandidate(args);
2679
+ const parsedCandidate = SDPUtils.parseCandidate(args.candidate);
2680
+ for (const key in parsedCandidate) {
2681
+ if (!(key in nativeCandidate)) {
2682
+ Object.defineProperty(
2683
+ nativeCandidate,
2684
+ key,
2685
+ { value: parsedCandidate[key] }
2686
+ );
2687
+ }
2688
+ }
2689
+ nativeCandidate.toJSON = function toJSON() {
2690
+ return {
2691
+ candidate: nativeCandidate.candidate,
2692
+ sdpMid: nativeCandidate.sdpMid,
2693
+ sdpMLineIndex: nativeCandidate.sdpMLineIndex,
2694
+ usernameFragment: nativeCandidate.usernameFragment
2695
+ };
2696
+ };
2697
+ return nativeCandidate;
2698
+ }
2699
+ return new NativeRTCIceCandidate(args);
2700
+ };
2701
+ window2.RTCIceCandidate.prototype = NativeRTCIceCandidate.prototype;
2702
+ wrapPeerConnectionEvent(window2, "icecandidate", (e) => {
2703
+ if (e.candidate) {
2704
+ Object.defineProperty(e, "candidate", {
2705
+ value: new window2.RTCIceCandidate(e.candidate),
2706
+ writable: "false"
2707
+ });
2708
+ }
2709
+ return e;
2710
+ });
2711
+ }
2712
+ function shimRTCIceCandidateRelayProtocol(window2) {
2713
+ if (!window2.RTCIceCandidate || window2.RTCIceCandidate && "relayProtocol" in window2.RTCIceCandidate.prototype) {
2714
+ return;
2715
+ }
2716
+ wrapPeerConnectionEvent(window2, "icecandidate", (e) => {
2717
+ if (e.candidate) {
2718
+ const parsedCandidate = SDPUtils.parseCandidate(e.candidate.candidate);
2719
+ if (parsedCandidate.type === "relay") {
2720
+ e.candidate.relayProtocol = {
2721
+ 0: "tls",
2722
+ 1: "tcp",
2723
+ 2: "udp"
2724
+ }[parsedCandidate.priority >> 24];
2725
+ }
2726
+ }
2727
+ return e;
2728
+ });
2729
+ }
2730
+ function shimMaxMessageSize(window2, browserDetails) {
2731
+ if (!window2.RTCPeerConnection) {
2732
+ return;
2733
+ }
2734
+ if (!("sctp" in window2.RTCPeerConnection.prototype)) {
2735
+ Object.defineProperty(window2.RTCPeerConnection.prototype, "sctp", {
2736
+ get() {
2737
+ return typeof this._sctp === "undefined" ? null : this._sctp;
2738
+ }
2739
+ });
2740
+ }
2741
+ const sctpInDescription = function(description) {
2742
+ if (!description || !description.sdp) {
2743
+ return false;
2744
+ }
2745
+ const sections = SDPUtils.splitSections(description.sdp);
2746
+ sections.shift();
2747
+ return sections.some((mediaSection) => {
2748
+ const mLine = SDPUtils.parseMLine(mediaSection);
2749
+ return mLine && mLine.kind === "application" && mLine.protocol.indexOf("SCTP") !== -1;
2750
+ });
2751
+ };
2752
+ const getRemoteFirefoxVersion = function(description) {
2753
+ const match = description.sdp.match(/mozilla...THIS_IS_SDPARTA-(\d+)/);
2754
+ if (match === null || match.length < 2) {
2755
+ return -1;
2756
+ }
2757
+ const version = parseInt(match[1], 10);
2758
+ return version !== version ? -1 : version;
2759
+ };
2760
+ const getCanSendMaxMessageSize = function(remoteIsFirefox) {
2761
+ let canSendMaxMessageSize = 65536;
2762
+ if (browserDetails.browser === "firefox") {
2763
+ if (browserDetails.version < 57) {
2764
+ if (remoteIsFirefox === -1) {
2765
+ canSendMaxMessageSize = 16384;
2766
+ } else {
2767
+ canSendMaxMessageSize = 2147483637;
2768
+ }
2769
+ } else if (browserDetails.version < 60) {
2770
+ canSendMaxMessageSize = browserDetails.version === 57 ? 65535 : 65536;
2771
+ } else {
2772
+ canSendMaxMessageSize = 2147483637;
2773
+ }
2774
+ }
2775
+ return canSendMaxMessageSize;
2776
+ };
2777
+ const getMaxMessageSize = function(description, remoteIsFirefox) {
2778
+ let maxMessageSize = 65536;
2779
+ if (browserDetails.browser === "firefox" && browserDetails.version === 57) {
2780
+ maxMessageSize = 65535;
2781
+ }
2782
+ const match = SDPUtils.matchPrefix(
2783
+ description.sdp,
2784
+ "a=max-message-size:"
2785
+ );
2786
+ if (match.length > 0) {
2787
+ maxMessageSize = parseInt(match[0].substring(19), 10);
2788
+ } else if (browserDetails.browser === "firefox" && remoteIsFirefox !== -1) {
2789
+ maxMessageSize = 2147483637;
2790
+ }
2791
+ return maxMessageSize;
2792
+ };
2793
+ const origSetRemoteDescription = window2.RTCPeerConnection.prototype.setRemoteDescription;
2794
+ window2.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription() {
2795
+ this._sctp = null;
2796
+ if (browserDetails.browser === "chrome" && browserDetails.version >= 76) {
2797
+ const { sdpSemantics } = this.getConfiguration();
2798
+ if (sdpSemantics === "plan-b") {
2799
+ Object.defineProperty(this, "sctp", {
2800
+ get() {
2801
+ return typeof this._sctp === "undefined" ? null : this._sctp;
2802
+ },
2803
+ enumerable: true,
2804
+ configurable: true
2805
+ });
2806
+ }
2807
+ }
2808
+ if (sctpInDescription(arguments[0])) {
2809
+ const isFirefox = getRemoteFirefoxVersion(arguments[0]);
2810
+ const canSendMMS = getCanSendMaxMessageSize(isFirefox);
2811
+ const remoteMMS = getMaxMessageSize(arguments[0], isFirefox);
2812
+ let maxMessageSize;
2813
+ if (canSendMMS === 0 && remoteMMS === 0) {
2814
+ maxMessageSize = Number.POSITIVE_INFINITY;
2815
+ } else if (canSendMMS === 0 || remoteMMS === 0) {
2816
+ maxMessageSize = Math.max(canSendMMS, remoteMMS);
2817
+ } else {
2818
+ maxMessageSize = Math.min(canSendMMS, remoteMMS);
2819
+ }
2820
+ const sctp = {};
2821
+ Object.defineProperty(sctp, "maxMessageSize", {
2822
+ get() {
2823
+ return maxMessageSize;
2824
+ }
2825
+ });
2826
+ this._sctp = sctp;
2827
+ }
2828
+ return origSetRemoteDescription.apply(this, arguments);
2829
+ };
2830
+ }
2831
+ function shimSendThrowTypeError(window2) {
2832
+ if (!(window2.RTCPeerConnection && "createDataChannel" in window2.RTCPeerConnection.prototype)) {
2833
+ return;
2834
+ }
2835
+ function wrapDcSend(dc, pc) {
2836
+ const origDataChannelSend = dc.send;
2837
+ dc.send = function send() {
2838
+ const data = arguments[0];
2839
+ const length = data.length || data.size || data.byteLength;
2840
+ if (dc.readyState === "open" && pc.sctp && length > pc.sctp.maxMessageSize) {
2841
+ throw new TypeError("Message too large (can send a maximum of " + pc.sctp.maxMessageSize + " bytes)");
2842
+ }
2843
+ return origDataChannelSend.apply(dc, arguments);
2844
+ };
2845
+ }
2846
+ const origCreateDataChannel = window2.RTCPeerConnection.prototype.createDataChannel;
2847
+ window2.RTCPeerConnection.prototype.createDataChannel = function createDataChannel() {
2848
+ const dataChannel = origCreateDataChannel.apply(this, arguments);
2849
+ wrapDcSend(dataChannel, this);
2850
+ return dataChannel;
2851
+ };
2852
+ wrapPeerConnectionEvent(window2, "datachannel", (e) => {
2853
+ wrapDcSend(e.channel, e.target);
2854
+ return e;
2855
+ });
2856
+ }
2857
+ function shimConnectionState(window2) {
2858
+ if (!window2.RTCPeerConnection || "connectionState" in window2.RTCPeerConnection.prototype) {
2859
+ return;
2860
+ }
2861
+ const proto = window2.RTCPeerConnection.prototype;
2862
+ Object.defineProperty(proto, "connectionState", {
2863
+ get() {
2864
+ return {
2865
+ completed: "connected",
2866
+ checking: "connecting"
2867
+ }[this.iceConnectionState] || this.iceConnectionState;
2868
+ },
2869
+ enumerable: true,
2870
+ configurable: true
2871
+ });
2872
+ Object.defineProperty(proto, "onconnectionstatechange", {
2873
+ get() {
2874
+ return this._onconnectionstatechange || null;
2875
+ },
2876
+ set(cb) {
2877
+ if (this._onconnectionstatechange) {
2878
+ this.removeEventListener(
2879
+ "connectionstatechange",
2880
+ this._onconnectionstatechange
2881
+ );
2882
+ delete this._onconnectionstatechange;
2883
+ }
2884
+ if (cb) {
2885
+ this.addEventListener(
2886
+ "connectionstatechange",
2887
+ this._onconnectionstatechange = cb
2888
+ );
2889
+ }
2890
+ },
2891
+ enumerable: true,
2892
+ configurable: true
2893
+ });
2894
+ ["setLocalDescription", "setRemoteDescription"].forEach((method) => {
2895
+ const origMethod = proto[method];
2896
+ proto[method] = function() {
2897
+ if (!this._connectionstatechangepoly) {
2898
+ this._connectionstatechangepoly = (e) => {
2899
+ const pc = e.target;
2900
+ if (pc._lastConnectionState !== pc.connectionState) {
2901
+ pc._lastConnectionState = pc.connectionState;
2902
+ const newEvent = new Event("connectionstatechange", e);
2903
+ pc.dispatchEvent(newEvent);
2904
+ }
2905
+ return e;
2906
+ };
2907
+ this.addEventListener(
2908
+ "iceconnectionstatechange",
2909
+ this._connectionstatechangepoly
2910
+ );
2911
+ }
2912
+ return origMethod.apply(this, arguments);
2913
+ };
2914
+ });
2915
+ }
2916
+ function removeExtmapAllowMixed(window2, browserDetails) {
2917
+ if (!window2.RTCPeerConnection) {
2918
+ return;
2919
+ }
2920
+ if (browserDetails.browser === "chrome" && browserDetails.version >= 71) {
2921
+ return;
2922
+ }
2923
+ if (browserDetails.browser === "safari" && browserDetails.version >= 605) {
2924
+ return;
2925
+ }
2926
+ const nativeSRD = window2.RTCPeerConnection.prototype.setRemoteDescription;
2927
+ window2.RTCPeerConnection.prototype.setRemoteDescription = function setRemoteDescription(desc) {
2928
+ if (desc && desc.sdp && desc.sdp.indexOf("\na=extmap-allow-mixed") !== -1) {
2929
+ const sdp2 = desc.sdp.split("\n").filter((line) => {
2930
+ return line.trim() !== "a=extmap-allow-mixed";
2931
+ }).join("\n");
2932
+ if (window2.RTCSessionDescription && desc instanceof window2.RTCSessionDescription) {
2933
+ arguments[0] = new window2.RTCSessionDescription({
2934
+ type: desc.type,
2935
+ sdp: sdp2
2936
+ });
2937
+ } else {
2938
+ desc.sdp = sdp2;
2939
+ }
2940
+ }
2941
+ return nativeSRD.apply(this, arguments);
2942
+ };
2943
+ }
2944
+ function shimAddIceCandidateNullOrEmpty(window2, browserDetails) {
2945
+ if (!(window2.RTCPeerConnection && window2.RTCPeerConnection.prototype)) {
2946
+ return;
2947
+ }
2948
+ const nativeAddIceCandidate = window2.RTCPeerConnection.prototype.addIceCandidate;
2949
+ if (!nativeAddIceCandidate || nativeAddIceCandidate.length === 0) {
2950
+ return;
2951
+ }
2952
+ window2.RTCPeerConnection.prototype.addIceCandidate = function addIceCandidate2() {
2953
+ if (!arguments[0]) {
2954
+ if (arguments[1]) {
2955
+ arguments[1].apply(null);
2956
+ }
2957
+ return Promise.resolve();
2958
+ }
2959
+ if ((browserDetails.browser === "chrome" && browserDetails.version < 78 || browserDetails.browser === "firefox" && browserDetails.version < 68 || browserDetails.browser === "safari") && arguments[0] && arguments[0].candidate === "") {
2960
+ return Promise.resolve();
2961
+ }
2962
+ return nativeAddIceCandidate.apply(this, arguments);
2963
+ };
2964
+ }
2965
+ function shimParameterlessSetLocalDescription(window2, browserDetails) {
2966
+ if (!(window2.RTCPeerConnection && window2.RTCPeerConnection.prototype)) {
2967
+ return;
2968
+ }
2969
+ const nativeSetLocalDescription = window2.RTCPeerConnection.prototype.setLocalDescription;
2970
+ if (!nativeSetLocalDescription || nativeSetLocalDescription.length === 0) {
2971
+ return;
2972
+ }
2973
+ window2.RTCPeerConnection.prototype.setLocalDescription = function setLocalDescription() {
2974
+ let desc = arguments[0] || {};
2975
+ if (typeof desc !== "object" || desc.type && desc.sdp) {
2976
+ return nativeSetLocalDescription.apply(this, arguments);
2977
+ }
2978
+ desc = { type: desc.type, sdp: desc.sdp };
2979
+ if (!desc.type) {
2980
+ switch (this.signalingState) {
2981
+ case "stable":
2982
+ case "have-local-offer":
2983
+ case "have-remote-pranswer":
2984
+ desc.type = "offer";
2985
+ break;
2986
+ default:
2987
+ desc.type = "answer";
2988
+ break;
2989
+ }
2990
+ }
2991
+ if (desc.sdp || desc.type !== "offer" && desc.type !== "answer") {
2992
+ return nativeSetLocalDescription.apply(this, [desc]);
2993
+ }
2994
+ const func = desc.type === "offer" ? this.createOffer : this.createAnswer;
2995
+ return func.apply(this).then((d) => nativeSetLocalDescription.apply(this, [d]));
2996
+ };
2997
+ }
2998
+ const commonShim = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2999
+ __proto__: null,
3000
+ removeExtmapAllowMixed,
3001
+ shimAddIceCandidateNullOrEmpty,
3002
+ shimConnectionState,
3003
+ shimMaxMessageSize,
3004
+ shimParameterlessSetLocalDescription,
3005
+ shimRTCIceCandidate,
3006
+ shimRTCIceCandidateRelayProtocol,
3007
+ shimSendThrowTypeError
3008
+ }, Symbol.toStringTag, { value: "Module" }));
3009
+ function adapterFactory({ window: window2 } = {}, options = {
3010
+ shimChrome: true,
3011
+ shimFirefox: true,
3012
+ shimSafari: true
3013
+ }) {
3014
+ const logging2 = log;
3015
+ const browserDetails = detectBrowser(window2);
3016
+ const adapter2 = {
3017
+ browserDetails,
3018
+ commonShim,
3019
+ extractVersion,
3020
+ disableLog,
3021
+ disableWarnings,
3022
+ // Expose sdp as a convenience. For production apps include directly.
3023
+ sdp
3024
+ };
3025
+ switch (browserDetails.browser) {
3026
+ case "chrome":
3027
+ if (!chromeShim || !shimPeerConnection$1 || !options.shimChrome) {
3028
+ logging2("Chrome shim is not included in this adapter release.");
3029
+ return adapter2;
3030
+ }
3031
+ if (browserDetails.version === null) {
3032
+ logging2("Chrome shim can not determine version, not shimming.");
3033
+ return adapter2;
3034
+ }
3035
+ logging2("adapter.js shimming chrome.");
3036
+ adapter2.browserShim = chromeShim;
3037
+ shimAddIceCandidateNullOrEmpty(window2, browserDetails);
3038
+ shimParameterlessSetLocalDescription(window2);
3039
+ shimGetUserMedia$2(window2, browserDetails);
3040
+ shimMediaStream(window2);
3041
+ shimPeerConnection$1(window2, browserDetails);
3042
+ shimOnTrack$1(window2);
3043
+ shimAddTrackRemoveTrack(window2, browserDetails);
3044
+ shimGetSendersWithDtmf(window2);
3045
+ shimSenderReceiverGetStats(window2);
3046
+ fixNegotiationNeeded(window2, browserDetails);
3047
+ shimRTCIceCandidate(window2);
3048
+ shimRTCIceCandidateRelayProtocol(window2);
3049
+ shimConnectionState(window2);
3050
+ shimMaxMessageSize(window2, browserDetails);
3051
+ shimSendThrowTypeError(window2);
3052
+ removeExtmapAllowMixed(window2, browserDetails);
3053
+ break;
3054
+ case "firefox":
3055
+ if (!firefoxShim || !shimPeerConnection || !options.shimFirefox) {
3056
+ logging2("Firefox shim is not included in this adapter release.");
3057
+ return adapter2;
3058
+ }
3059
+ logging2("adapter.js shimming firefox.");
3060
+ adapter2.browserShim = firefoxShim;
3061
+ shimAddIceCandidateNullOrEmpty(window2, browserDetails);
3062
+ shimParameterlessSetLocalDescription(window2);
3063
+ shimGetUserMedia$1(window2, browserDetails);
3064
+ shimPeerConnection(window2, browserDetails);
3065
+ shimOnTrack(window2);
3066
+ shimRemoveStream(window2);
3067
+ shimSenderGetStats(window2);
3068
+ shimReceiverGetStats(window2);
3069
+ shimRTCDataChannel(window2);
3070
+ shimAddTransceiver(window2);
3071
+ shimGetParameters(window2);
3072
+ shimCreateOffer(window2);
3073
+ shimCreateAnswer(window2);
3074
+ shimRTCIceCandidate(window2);
3075
+ shimConnectionState(window2);
3076
+ shimMaxMessageSize(window2, browserDetails);
3077
+ shimSendThrowTypeError(window2);
3078
+ break;
3079
+ case "safari":
3080
+ if (!safariShim || !options.shimSafari) {
3081
+ logging2("Safari shim is not included in this adapter release.");
3082
+ return adapter2;
3083
+ }
3084
+ logging2("adapter.js shimming safari.");
3085
+ adapter2.browserShim = safariShim;
3086
+ shimAddIceCandidateNullOrEmpty(window2, browserDetails);
3087
+ shimParameterlessSetLocalDescription(window2);
3088
+ shimRTCIceServerUrls(window2);
3089
+ shimCreateOfferLegacy(window2);
3090
+ shimCallbacksAPI(window2);
3091
+ shimLocalStreamsAPI(window2);
3092
+ shimRemoteStreamsAPI(window2);
3093
+ shimTrackEventTransceiver(window2);
3094
+ shimGetUserMedia(window2);
3095
+ shimAudioContext(window2);
3096
+ shimRTCIceCandidate(window2);
3097
+ shimRTCIceCandidateRelayProtocol(window2);
3098
+ shimMaxMessageSize(window2, browserDetails);
3099
+ shimSendThrowTypeError(window2);
3100
+ removeExtmapAllowMixed(window2, browserDetails);
3101
+ break;
3102
+ default:
3103
+ logging2("Unsupported browser!");
3104
+ break;
3105
+ }
3106
+ return adapter2;
3107
+ }
3108
+ const adapter = adapterFactory({ window: typeof window === "undefined" ? void 0 : window });
3109
+ const setRemoteDescriptionWithHandleOffer = (peerConnection, sdp2, sendAnswer, onError) => {
3110
+ const description = new RTCSessionDescription({ type: "offer", sdp: sdp2 });
3111
+ peerConnection.setRemoteDescription(description).then(() => createAnswer(peerConnection, sendAnswer, onError)).catch((error) => onError == null ? void 0 : onError(createWebRtcError(FailCode.HANDLE_OFFER, error)));
3112
+ };
3113
+ const createAnswer = (peerConnection, sendAnswer, onError) => {
3114
+ peerConnection.createAnswer().then((answer) => setLocalDescriptionWithCreateAnswer(peerConnection, answer, sendAnswer, onError)).catch((error) => onError == null ? void 0 : onError(createWebRtcError(FailCode.CREATE_ANSWER, error)));
3115
+ };
3116
+ const setLocalDescriptionWithCreateAnswer = (peerConnection, answer, sendAnswer, onError) => {
3117
+ peerConnection.setLocalDescription(answer).then(() => {
3118
+ sendAnswer == null ? void 0 : sendAnswer(answer.sdp ?? "");
3119
+ }).catch((error) => onError == null ? void 0 : onError(createWebRtcError(FailCode.LOCAL_DES, error)));
3120
+ };
3121
+ const createPeerConnection = (config) => {
3122
+ const iceServers = [
3123
+ { urls: config.stunServerUri },
3124
+ { urls: config.stunServerUriAli },
3125
+ {
3126
+ urls: config.turnServerUri,
3127
+ username: config.turnServerUserName,
3128
+ credential: config.turnServerPassword
3129
+ }
3130
+ ];
3131
+ const peerConnectionConfig = {
3132
+ iceServers,
3133
+ iceTransportPolicy: "all",
3134
+ sdpSemantics: "unified-plan",
3135
+ rtcpMuxPolicy: "require",
3136
+ bundlePolicy: "max-bundle"
3137
+ };
3138
+ if (adapter.browserDetails.browser === "chrome") {
3139
+ peerConnectionConfig.sdpSemantics = adapter.browserDetails.version && adapter.browserDetails.version < 72 ? "plan-b" : "unified-plan";
3140
+ }
3141
+ const constraints = {
3142
+ optional: [{ DtlsSrtpKeyAgreement: true }, { googIPv6: true }]
3143
+ };
3144
+ const RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;
3145
+ return new RTCPeerConnection(peerConnectionConfig, constraints);
3146
+ };
3147
+ const configPeerConnection = (peerConnection, onICEMessage, onTrack, onConnectState, onError) => {
3148
+ peerConnection.onicecandidate = (event) => {
3149
+ if (!event.candidate) {
3150
+ console.log("ICE candidate collection completed");
3151
+ return;
3152
+ }
3153
+ const candidateObj = {
3154
+ sdp: event.candidate.candidate,
3155
+ sdpMid: event.candidate.sdpMid,
3156
+ sdpMLineIndex: event.candidate.sdpMLineIndex
3157
+ };
3158
+ onICEMessage(JSON.stringify(candidateObj));
3159
+ };
3160
+ peerConnection.oniceconnectionstatechange = () => {
3161
+ const state = peerConnection.iceConnectionState;
3162
+ if (!state) {
3163
+ return;
3164
+ }
3165
+ if (state === "failed") {
3166
+ onError == null ? void 0 : onError(createWebRtcError(FailCode.ICE_STATE, "failed"));
3167
+ }
3168
+ onConnectState == null ? void 0 : onConnectState(state);
3169
+ };
3170
+ peerConnection.ontrack = (event) => {
3171
+ const track = event.track;
3172
+ track.contentHint = "detail";
3173
+ onTrack == null ? void 0 : onTrack(track);
3174
+ };
3175
+ };
3176
+ const setRemoteDescriptionWithHandleAnswer = (peerConnection, sdp2, onError) => {
3177
+ const description = new RTCSessionDescription({ type: "answer", sdp: sdp2 });
3178
+ peerConnection.setRemoteDescription(description).catch((err) => onError == null ? void 0 : onError(createWebRtcError(FailCode.REMOTE_DES, err)));
3179
+ };
3180
+ const createOffer = (peerConnection, sendOfferMessage, onError) => {
3181
+ peerConnection.createOffer().then((offer) => setLocalDescriptionWithCreateOffer(peerConnection, offer, sendOfferMessage, onError)).catch((err) => onError == null ? void 0 : onError(createWebRtcError(FailCode.CREATE_OFFER, err)));
3182
+ };
3183
+ const setLocalDescriptionWithCreateOffer = (peerConnection, offer, sendOfferMessage, onError) => {
3184
+ peerConnection.setLocalDescription(offer).then(() => sendOfferMessage(offer.sdp ?? "")).catch((err) => onError == null ? void 0 : onError(createWebRtcError(FailCode.LOCAL_DES, err)));
3185
+ };
3186
+ const addIceCandidate = (peerConnection, candidate, onError) => {
3187
+ peerConnection.addIceCandidate(candidate).catch((err) => onError == null ? void 0 : onError(createWebRtcError(FailCode.HANDLE_ICE, err)));
3188
+ };
3189
+ class WebRTCClient extends EventEmitter {
3190
+ constructor(config) {
3191
+ super();
3192
+ __publicField(this, "config");
3193
+ __publicField(this, "peerConnection", null);
3194
+ __publicField(this, "localStream", null);
3195
+ __publicField(this, "isPushingStream", false);
3196
+ __publicField(this, "dataChannel", null);
3197
+ __publicField(this, "statsTimer", null);
3198
+ __publicField(this, "lastReportTime", 0);
3199
+ __publicField(this, "lastBytesReceived", 0);
3200
+ __publicField(this, "lastPacketsLost", 0);
3201
+ __publicField(this, "lastPacketsReceived", 0);
3202
+ __publicField(this, "lostPacketCount", 0);
3203
+ __publicField(this, "maxLostRate", 0);
3204
+ __publicField(this, "decodedCount", 0);
3205
+ __publicField(this, "lastSecondDecodedCount", 0);
3206
+ this.config = config;
3207
+ }
3208
+ async startPush() {
3209
+ if (this.isPushingStream) return;
3210
+ this.isPushingStream = true;
3211
+ try {
3212
+ await this.readyCapture();
3213
+ } catch (err) {
3214
+ this.emit(EmitType.webrtcError, createWebRtcError(FailCode.CAMERA, err));
3215
+ }
3216
+ }
3217
+ handleOffer(offerSdp) {
3218
+ this.resetPeerConnection();
3219
+ setRemoteDescriptionWithHandleOffer(this.peerConnection, offerSdp, (sdp2) => {
3220
+ this.emit(EmitType.sendAnswer, sdp2);
3221
+ }, (err) => this.emit(EmitType.webrtcError, err));
3222
+ }
3223
+ handleAnswer(answerSdp) {
3224
+ setRemoteDescriptionWithHandleAnswer(this.peerConnection, answerSdp, (err) => this.emit(EmitType.webrtcError, err));
3225
+ }
3226
+ handleIceCandidate(candidate) {
3227
+ addIceCandidate(this.peerConnection, candidate, (err) => this.emit(EmitType.webrtcError, err));
3228
+ }
3229
+ sendChannelData(type, data) {
3230
+ try {
3231
+ let channelData = "";
3232
+ switch (type) {
3233
+ case ChannelDataType.ClickData:
3234
+ channelData = ChannelData.click(data);
3235
+ break;
3236
+ case ChannelDataType.ClipboardData:
3237
+ channelData = ChannelData.clipboard(data);
3238
+ break;
3239
+ case ChannelDataType.ActionInput:
3240
+ channelData = ChannelData.input(data);
3241
+ break;
3242
+ case ChannelDataType.ActionChinese:
3243
+ channelData = ChannelData.chinese(data);
3244
+ break;
3245
+ case ChannelDataType.ActionRequestCloudDeviceInfo:
3246
+ channelData = ChannelData.requestCloudDeviceInfo();
3247
+ break;
3248
+ case ChannelDataType.ActionClarity:
3249
+ channelData = ChannelData.clarity(data);
3250
+ break;
3251
+ }
3252
+ const buffer = new TextEncoder().encode(channelData).buffer;
3253
+ this.dataChannel.send(buffer);
3254
+ } catch (err) {
3255
+ this.emit(EmitType.webrtcError, createWebRtcError(FailCode.DATACHANNEL_ERR, err));
3256
+ }
3257
+ }
3258
+ closeConnection() {
3259
+ if (this.statsTimer) {
3260
+ clearInterval(this.statsTimer);
3261
+ this.statsTimer = null;
3262
+ }
3263
+ if (!this.peerConnection) {
3264
+ if (this.peerConnection.getSenders) {
3265
+ this.peerConnection.getSenders().forEach((sender) => {
3266
+ if (sender.track) {
3267
+ sender.track.stop();
3268
+ }
3269
+ });
3270
+ }
3271
+ if (this.peerConnection.getReceivers) {
3272
+ this.peerConnection.getReceivers().forEach((receiver) => {
3273
+ if (receiver.track) {
3274
+ receiver.track.stop();
3275
+ }
3276
+ });
3277
+ }
3278
+ if (this.peerConnection.getTransceivers) {
3279
+ this.peerConnection.getTransceivers().forEach((transceiver) => {
3280
+ var _a;
3281
+ (_a = transceiver.stop) == null ? void 0 : _a.call(transceiver);
3282
+ });
3283
+ }
3284
+ this.peerConnection.close();
3285
+ this.removeAllListeners();
3286
+ this.dataChannel = null;
3287
+ this.peerConnection.onicecandidate = null;
3288
+ this.peerConnection.ontrack = null;
3289
+ this.peerConnection.ondatachannel = null;
3290
+ this.peerConnection.onconnectionstatechange = null;
3291
+ this.peerConnection.oniceconnectionstatechange = null;
3292
+ this.peerConnection.onsignalingstatechange = null;
3293
+ this.peerConnection.onnegotiationneeded = null;
3294
+ this.peerConnection.onicegatheringstatechange = null;
3295
+ this.peerConnection = null;
3296
+ }
3297
+ }
3298
+ async readyCapture() {
3299
+ this.resetPeerConnection();
3300
+ try {
3301
+ this.localStream = await navigator.mediaDevices.getUserMedia({ video: { width: 640, height: 480 }, audio: true });
3302
+ const rotatedStream = await this.getRotatedStream(this.localStream);
3303
+ rotatedStream.getTracks().forEach((track) => {
3304
+ track.contentHint = "detail";
3305
+ this.peerConnection.addTrack(track, rotatedStream);
3306
+ });
3307
+ this.peerConnection.getSenders().forEach((sender) => this.setVideoParams(sender));
3308
+ createOffer(this.peerConnection, (sdp2) => {
3309
+ this.emit(EmitType.sendOffer, sdp2);
3310
+ }, (err) => this.emit(EmitType.webrtcError, err));
3311
+ } catch (e) {
3312
+ throw new Error(`mediaDevices error: ${e}`);
3313
+ }
3314
+ }
3315
+ async getRotatedStream(localStream) {
3316
+ const canvas = document.createElement("canvas");
3317
+ const ctx = canvas.getContext("2d");
3318
+ const videoTrack = localStream.getVideoTracks()[0];
3319
+ const { width, height } = await new Promise((resolve) => {
3320
+ const video2 = document.createElement("video");
3321
+ video2.srcObject = new MediaStream([videoTrack]);
3322
+ video2.onloadedmetadata = () => resolve({ width: video2.videoWidth, height: video2.videoHeight });
3323
+ });
3324
+ canvas.width = 640;
3325
+ canvas.height = 480;
3326
+ const video = document.createElement("video");
3327
+ video.srcObject = localStream;
3328
+ await video.play();
3329
+ const drawFrame = () => {
3330
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
3331
+ ctx.save();
3332
+ ctx.translate(canvas.width / 2, canvas.height / 2);
3333
+ ctx.rotate(Math.PI / 2);
3334
+ ctx.drawImage(video, -width / 2, -height / 2, width, height);
3335
+ ctx.restore();
3336
+ requestAnimationFrame(drawFrame);
3337
+ };
3338
+ drawFrame();
3339
+ return canvas.captureStream();
3340
+ }
3341
+ async setVideoParams(sender) {
3342
+ const params = sender.getParameters();
3343
+ params.degradationPreference = "maintain-resolution";
3344
+ params.encodings.forEach((encoding) => {
3345
+ encoding.maxBitrate = 1e6;
3346
+ encoding.priority = "high";
3347
+ encoding.scaleResolutionDownBy = 1;
3348
+ });
3349
+ await sender.setParameters(params);
3350
+ }
3351
+ stopPush() {
3352
+ var _a;
3353
+ if (!this.isPushingStream) return;
3354
+ this.isPushingStream = false;
3355
+ (_a = this.localStream) == null ? void 0 : _a.getTracks().forEach((track) => {
3356
+ var _a2;
3357
+ (_a2 = this.peerConnection) == null ? void 0 : _a2.getSenders().forEach((sender) => {
3358
+ var _a3;
3359
+ (_a3 = this.peerConnection) == null ? void 0 : _a3.removeTrack(sender);
3360
+ });
3361
+ track.stop();
3362
+ });
3363
+ this.localStream = null;
3364
+ createOffer(this.peerConnection, (sdp2) => {
3365
+ this.emit(EmitType.sendOffer, sdp2);
3366
+ }, (err) => this.emit(EmitType.webrtcError, err));
3367
+ }
3368
+ resetPeerConnection() {
3369
+ if (!this.peerConnection) {
3370
+ this.peerConnection = createPeerConnection(this.config);
3371
+ configPeerConnection(this.peerConnection, (candidate) => {
3372
+ this.emit(EmitType.sendICEMessage, candidate);
3373
+ }, (track) => {
3374
+ console.error("send track====>", track, Date.now());
3375
+ this.emit(EmitType.streamTrack, track);
3376
+ }, (state) => {
3377
+ this.emit(EmitType.iceConnectionState, state);
3378
+ }, (err) => this.emit(EmitType.webrtcError, err));
3379
+ this.checkStats();
3380
+ this.configDataChannel();
3381
+ }
3382
+ }
3383
+ configDataChannel() {
3384
+ this.peerConnection.ondatachannel = (event) => {
3385
+ this.dataChannel = event.channel;
3386
+ this.dataChannel.onmessage = (event2) => this.handleDataChannelMessage(event2);
3387
+ this.dataChannel.onerror = (error) => this.emit(EmitType.webrtcError, createWebRtcError(FailCode.DATACHANNEL_ERR, error));
3388
+ this.sendChannelData(ChannelDataType.ActionRequestCloudDeviceInfo, "");
3389
+ };
3390
+ }
3391
+ handleDataChannelMessage(event) {
3392
+ const data = JSON.parse(event.data);
3393
+ if (data.type === "ActionCommandEvent") {
3394
+ const { action, value } = JSON.parse(data.data);
3395
+ if (action === "ACTION_CONTROL_VIDEO") {
3396
+ value === "ENABLE" ? this.startPush() : this.stopPush();
3397
+ }
3398
+ } else if (data.type === "ActionUpdateCloudStatus") {
3399
+ const { rotation, screenWidth, screenHeight } = JSON.parse(data.data);
3400
+ const direction = [StreamRotation.ROTATION_0, StreamRotation.ROTATION_180].includes(rotation) ? ContainerDirection.Vertical : ContainerDirection.Horizontal;
3401
+ const cloudStatus = {
3402
+ direction,
3403
+ screenWidth,
3404
+ screenHeight
3405
+ };
3406
+ this.emit(EmitType.cloudStatusChanged, cloudStatus);
3407
+ }
3408
+ }
3409
+ checkStats() {
3410
+ this.statsTimer = setInterval(() => this.processStats(), 1e3);
3411
+ }
3412
+ processStats() {
3413
+ if (!this.peerConnection) {
3414
+ return;
3415
+ }
3416
+ this.peerConnection.getStats(null).then((statsReport) => {
3417
+ let videoFps = 0;
3418
+ let totalDecodeTime = 0;
3419
+ let roundTripTime = 0;
3420
+ let packetsLost = 0;
3421
+ let packetsReceived = 0;
3422
+ let bytesReceived = 0;
3423
+ let framesDecoded = 0;
3424
+ let pliCount = 0;
3425
+ let connectionType = "";
3426
+ const currentTime = Date.now();
3427
+ statsReport.forEach((report) => {
3428
+ if (report.type === "inbound-rtp") {
3429
+ bytesReceived += report.bytesReceived || 0;
3430
+ packetsLost += report.packetsLost || 0;
3431
+ packetsReceived += report.packetsReceived || 0;
3432
+ if (report.kind === "video") {
3433
+ videoFps = report.framesPerSecond || 0;
3434
+ totalDecodeTime = report.totalDecodeTime || 0;
3435
+ framesDecoded = report.framesDecoded || 0;
3436
+ report.framesReceived || 0;
3437
+ pliCount = (report.pliCount || 0) + (report.firCount || 0);
3438
+ }
3439
+ }
3440
+ if (report.type === "candidate-pair" && report.state === "succeeded") {
3441
+ roundTripTime = typeof report.currentRoundTripTime !== "undefined" ? report.currentRoundTripTime : report.responsesReceived > 0 ? report.totalRoundTripTime / report.responsesReceived : 0;
3442
+ const local = statsReport.get(report.localCandidateId);
3443
+ const remote = statsReport.get(report.remoteCandidateId);
3444
+ if (local && remote) {
3445
+ connectionType = this.getConnectionType(local, remote);
3446
+ }
3447
+ }
3448
+ });
3449
+ roundTripTime = Math.floor((roundTripTime || 0) * 1e3);
3450
+ const deltaTime = currentTime - this.lastReportTime;
3451
+ const bytesDiff = bytesReceived - this.lastBytesReceived;
3452
+ const bytesPerSecond = deltaTime > 0 ? bytesDiff * 1e3 / deltaTime : 0;
3453
+ const kilobytesPerSecond = bytesPerSecond / 1024;
3454
+ const megabytesPerSecond = kilobytesPerSecond / 1024;
3455
+ this.lastBytesReceived = bytesReceived;
3456
+ this.lastReportTime = currentTime;
3457
+ let lossRate = 0;
3458
+ const lostPackets = packetsLost - this.lastPacketsLost;
3459
+ const receivedPackets = packetsReceived - this.lastPacketsReceived;
3460
+ if (lostPackets > 0 && receivedPackets > 0) {
3461
+ lossRate = lostPackets / (lostPackets + receivedPackets);
3462
+ this.maxLostRate = Math.max(this.maxLostRate || 0, lossRate);
3463
+ this.lostPacketCount++;
3464
+ }
3465
+ this.lastPacketsLost = packetsLost;
3466
+ this.lastPacketsReceived = packetsReceived;
3467
+ const fps = typeof videoFps !== "undefined" ? videoFps : framesDecoded - this.lastSecondDecodedCount;
3468
+ this.lastSecondDecodedCount = framesDecoded;
3469
+ const bitrate = kilobytesPerSecond < 1024 ? `${Math.floor(kilobytesPerSecond)} KB/s` : `${Math.floor(megabytesPerSecond)} MB/s`;
3470
+ const averageDecodeTime = framesDecoded > 0 ? Math.floor(1e4 * totalDecodeTime / framesDecoded) : 0;
3471
+ const screenInfo = {
3472
+ connectionType,
3473
+ framesPerSecond: fps,
3474
+ currentRoundTripTime: roundTripTime,
3475
+ lostRate: Math.floor(lossRate * 100),
3476
+ // percent
3477
+ bitrate,
3478
+ pliCount,
3479
+ averageDecodeTime
3480
+ };
3481
+ this.emit(EmitType.statisticInfo, screenInfo);
3482
+ }).catch((error) => {
3483
+ this.emit(EmitType.webrtcError, createWebRtcError(FailCode.STREAM_STATE, error));
3484
+ });
3485
+ }
3486
+ getConnectionType(local, remote) {
3487
+ if (local.candidateType === "host" && remote.candidateType === "host") return "直连";
3488
+ if (local.candidateType === "relay" || remote.candidateType === "relay") return "中继";
3489
+ return "NAT";
3490
+ }
3491
+ }
3492
+ class WebRTCSdk extends EventEmitter {
3493
+ constructor(options) {
3494
+ super();
3495
+ __publicField(this, "config");
3496
+ __publicField(this, "signalingClient");
3497
+ __publicField(this, "webRTCClient");
3498
+ /**
3499
+ * 处理 signal 消息,根据不同消息类型分发到 webRTCClient 或直接触发 SDK 事件
3500
+ * @param message 信令消息
3501
+ */
3502
+ __publicField(this, "handleSignaling", (message) => {
3503
+ switch (message.type) {
3504
+ case MessageType.Peers:
3505
+ this.config.myId = message.myId;
3506
+ break;
3507
+ case MessageType.Offer:
3508
+ if (message.senderId && message.sdp) {
3509
+ this.config.targetId = message.senderId;
3510
+ this.webRTCClient.handleOffer(message.sdp);
3511
+ }
3512
+ break;
3513
+ case MessageType.Answer:
3514
+ if (message.sdp) {
3515
+ this.webRTCClient.handleAnswer(message.sdp);
3516
+ }
3517
+ break;
3518
+ case MessageType.IceCandidates:
3519
+ if (message.ice) {
3520
+ try {
3521
+ const candidateObj = JSON.parse(message.ice);
3522
+ candidateObj.candidate = candidateObj.sdp;
3523
+ this.webRTCClient.handleIceCandidate(new RTCIceCandidate(candidateObj));
3524
+ } catch (error) {
3525
+ this.emit("error", { type: "iceCandidate", error });
3526
+ }
3527
+ }
3528
+ break;
3529
+ case MessageType.SignOut:
3530
+ if (message.myId === this.config.myId) {
3531
+ this.webRTCClient.closeConnection();
3532
+ this.signalingClient.close();
3533
+ this.removeAllListeners();
3534
+ }
3535
+ break;
3536
+ case MessageType.NotAvailable:
3537
+ this.emit(EmitType.webrtcError, createWebRtcError(FailCode.NOT_AVAILABLE, ""));
3538
+ break;
3539
+ case MessageType.Ping:
3540
+ this.sendPong();
3541
+ break;
3542
+ }
3543
+ });
3544
+ /** 发送 Offer 信令 */
3545
+ __publicField(this, "sendOffer", (offerSdp) => {
3546
+ if (offerSdp && offerSdp.length > 0) {
3547
+ const message = {
3548
+ type: SendType.Offer,
3549
+ identity: SendType.Identity,
3550
+ roomId: this.config.roomId,
3551
+ senderId: this.config.myId,
3552
+ targetId: this.config.targetId,
3553
+ sdp: offerSdp
3554
+ };
3555
+ this.signalingClient.sendMessage(JSON.stringify(message));
3556
+ }
3557
+ });
3558
+ /** 发送 Answer 信令 */
3559
+ __publicField(this, "sendAnswer", (answerSdp) => {
3560
+ if (answerSdp && answerSdp.length > 0) {
3561
+ const message = {
3562
+ type: SendType.Answer,
3563
+ identity: SendType.Identity,
3564
+ roomId: this.config.roomId,
3565
+ senderId: this.config.myId,
3566
+ targetId: this.config.targetId,
3567
+ sdp: answerSdp
3568
+ };
3569
+ this.signalingClient.sendMessage(JSON.stringify(message));
3570
+ }
3571
+ });
3572
+ /** 发送 ICE 候选信息 */
3573
+ __publicField(this, "sendICEMessage", (ice) => {
3574
+ if (ice && ice.length > 0) {
3575
+ const message = {
3576
+ type: SendType.IceCandidates,
3577
+ identity: SendType.Identity,
3578
+ roomId: this.config.roomId,
3579
+ senderId: this.config.myId,
3580
+ targetId: this.config.targetId,
3581
+ ice
3582
+ };
3583
+ this.signalingClient.sendMessage(JSON.stringify(message));
3584
+ }
3585
+ });
3586
+ this.config = new WebRTCConfig(options);
3587
+ this.signalingClient = new SignalingClient(this.config);
3588
+ this.webRTCClient = new WebRTCClient(this.config);
3589
+ this.signalingClient.on(EmitType.signalMessage, (message) => this.handleSignaling(message));
3590
+ this.signalingClient.on(EmitType.webrtcError, (err) => {
3591
+ this.emit(EmitType.webrtcError, err);
3592
+ });
3593
+ this.webRTCClient.on(EmitType.sendOffer, (sdp2) => this.sendOffer(sdp2));
3594
+ this.webRTCClient.on(EmitType.sendAnswer, (sdp2) => this.sendAnswer(sdp2));
3595
+ this.webRTCClient.on(EmitType.sendICEMessage, (candidate) => this.sendICEMessage(candidate));
3596
+ this.webRTCClient.on(EmitType.streamTrack, (track) => this.emit(EmitType.streamTrack, track));
3597
+ this.webRTCClient.on(
3598
+ EmitType.iceConnectionState,
3599
+ (state) => this.emit(EmitType.iceConnectionState, state)
3600
+ );
3601
+ this.webRTCClient.on(
3602
+ EmitType.cloudStatusChanged,
3603
+ (info) => this.emit(EmitType.cloudStatusChanged, info)
3604
+ );
3605
+ this.webRTCClient.on(EmitType.webrtcError, (err) => {
3606
+ this.emit(EmitType.webrtcError, err);
3607
+ });
3608
+ this.webRTCClient.on(EmitType.statisticInfo, (info) => {
3609
+ this.emit(EmitType.statisticInfo, info);
3610
+ });
3611
+ }
3612
+ /** 开始连接 signal 服务 */
3613
+ startConnection() {
3614
+ this.signalingClient.start();
3615
+ }
3616
+ /** 停止连接,并发送退出信令 */
3617
+ stop() {
3618
+ this.webRTCClient.closeConnection();
3619
+ this.sendSignOut();
3620
+ this.removeAllListeners();
3621
+ }
3622
+ /** 开始推流:触发媒体采集与轨道添加 */
3623
+ async startPush() {
3624
+ try {
3625
+ await this.webRTCClient.readyCapture();
3626
+ } catch (error) {
3627
+ this.emit("error", { type: "camera", error });
3628
+ }
3629
+ }
3630
+ /** 发送信道数据 */
3631
+ sendChannelData(type, data) {
3632
+ this.webRTCClient.sendChannelData(type, data);
3633
+ }
3634
+ sendPong() {
3635
+ const message = {
3636
+ type: SendType.Pong
3637
+ };
3638
+ const jsonMessage = JSON.stringify(message);
3639
+ this.signalingClient.sendMessage(jsonMessage);
3640
+ }
3641
+ sendSignOut() {
3642
+ const message = {
3643
+ type: SendType.SignOut,
3644
+ identity: SendType.Identity,
3645
+ roomId: this.config.roomId,
3646
+ myId: this.config.myId
3647
+ };
3648
+ this.signalingClient.sendMessage(JSON.stringify(message));
3649
+ }
3650
+ }
3651
+ const META_SHIFT_ON = 1;
3652
+ const META_ALT_ON = 2;
3653
+ const META_CTRL_ON = 4096;
3654
+ const META_META_ON = 65536;
3655
+ const computeAndroidMetaState = (event) => {
3656
+ let state = 0;
3657
+ if (event.shiftKey) state |= META_SHIFT_ON;
3658
+ if (event.altKey) state |= META_ALT_ON;
3659
+ if (event.ctrlKey) state |= META_CTRL_ON;
3660
+ if (event.metaKey) state |= META_META_ON;
3661
+ return state;
3662
+ };
3663
+ const KeyCodeMap = {
3664
+ // 数字键
3665
+ "Digit1": 8,
3666
+ "Digit2": 9,
3667
+ "Digit3": 10,
3668
+ "Digit4": 11,
3669
+ "Digit5": 12,
3670
+ "Digit6": 13,
3671
+ "Digit7": 14,
3672
+ "Digit8": 15,
3673
+ "Digit9": 16,
3674
+ "Digit0": 7,
3675
+ // 符号键(主键盘区)
3676
+ "Minus": 69,
3677
+ "Equal": 70,
3678
+ "Backquote": 68,
3679
+ "BracketLeft": 71,
3680
+ "BracketRight": 72,
3681
+ "Backslash": 73,
3682
+ "Semicolon": 74,
3683
+ "Quote": 75,
3684
+ "Comma": 55,
3685
+ "Period": 56,
3686
+ "Slash": 76,
3687
+ // 功能键
3688
+ "Escape": 111,
3689
+ "Backspace": 67,
3690
+ "Tab": 61,
3691
+ "Enter": 66,
3692
+ "Space": 62,
3693
+ "CapsLock": 115,
3694
+ // 修饰键
3695
+ "ShiftLeft": 59,
3696
+ "ShiftRight": 60,
3697
+ "ControlLeft": 113,
3698
+ "ControlRight": 114,
3699
+ "AltLeft": 57,
3700
+ "AltRight": 58,
3701
+ "MetaLeft": 117,
3702
+ "MetaRight": 118,
3703
+ // 方向键
3704
+ "ArrowUp": 19,
3705
+ "ArrowDown": 20,
3706
+ "ArrowLeft": 21,
3707
+ "ArrowRight": 22,
3708
+ // 字母键(物理位置映射)
3709
+ "KeyA": 29,
3710
+ "KeyB": 30,
3711
+ "KeyC": 31,
3712
+ "KeyD": 32,
3713
+ "KeyE": 33,
3714
+ "KeyF": 34,
3715
+ "KeyG": 35,
3716
+ "KeyH": 36,
3717
+ "KeyI": 37,
3718
+ "KeyJ": 38,
3719
+ "KeyK": 39,
3720
+ "KeyL": 40,
3721
+ "KeyM": 41,
3722
+ "KeyN": 42,
3723
+ "KeyO": 43,
3724
+ "KeyP": 44,
3725
+ "KeyQ": 45,
3726
+ "KeyR": 46,
3727
+ "KeyS": 47,
3728
+ "KeyT": 48,
3729
+ "KeyU": 49,
3730
+ "KeyV": 50,
3731
+ "KeyW": 51,
3732
+ "KeyX": 52,
3733
+ "KeyY": 53,
3734
+ "KeyZ": 54,
3735
+ // 功能键扩展
3736
+ "F1": 131,
3737
+ "F2": 132,
3738
+ "F3": 133,
3739
+ "F4": 134,
3740
+ "F5": 135,
3741
+ "F6": 136,
3742
+ "F7": 137,
3743
+ "F8": 138,
3744
+ "F9": 139,
3745
+ "F10": 140,
3746
+ "F11": 141,
3747
+ "F12": 142,
3748
+ // 数字小键盘
3749
+ "Numpad0": 7,
3750
+ "Numpad1": 8,
3751
+ "Numpad2": 9,
3752
+ "Numpad3": 10,
3753
+ "Numpad4": 11,
3754
+ "Numpad5": 12,
3755
+ "Numpad6": 13,
3756
+ "Numpad7": 14,
3757
+ "Numpad8": 15,
3758
+ "Numpad9": 16,
3759
+ "NumpadAdd": 157,
3760
+ "NumpadSubtract": 156,
3761
+ "NumpadMultiply": 155,
3762
+ "NumpadDivide": 154,
3763
+ "NumpadDecimal": 158,
3764
+ "NumpadEnter": 66,
3765
+ // 其他特殊键
3766
+ "Insert": 124,
3767
+ "Delete": 112,
3768
+ "Home": 122,
3769
+ "End": 123,
3770
+ "PageUp": 92,
3771
+ "PageDown": 93,
3772
+ "ScrollLock": 116,
3773
+ "Pause": 121,
3774
+ "ContextMenu": 117
3775
+ };
3776
+ const getKeyEventData = (event) => {
3777
+ const keyCode = KeyCodeMap[event.code] ?? -1;
3778
+ const metaState = computeAndroidMetaState(event);
3779
+ return {
3780
+ androidKeyCode: keyCode,
3781
+ metaState
3782
+ };
3783
+ };
3784
+ function transformCoordinate(viewWidth, viewHeight, cloudWidth, cloudHeight, viewAngle, streamAngle, inputX, inputY) {
3785
+ let realShortWidth;
3786
+ let short;
3787
+ if (viewAngle === -90) {
3788
+ short = viewHeight;
3789
+ realShortWidth = cloudWidth * viewWidth / cloudHeight;
3790
+ } else {
3791
+ short = viewWidth;
3792
+ realShortWidth = cloudWidth * viewHeight / cloudHeight;
3793
+ }
3794
+ const invalidValue = (short - realShortWidth) / 2;
3795
+ const mid = short / 2;
3796
+ const start = invalidValue;
3797
+ const end = short - invalidValue;
3798
+ const len = mid - invalidValue;
3799
+ if (viewAngle === -90) {
3800
+ if (inputY < invalidValue || inputY > viewHeight - invalidValue) {
3801
+ return null;
3802
+ }
3803
+ const resultY = linearTransform(invalidValue, mid, start, end, len, inputY);
3804
+ if (streamAngle === -90) {
3805
+ return [inputX, resultY];
3806
+ } else {
3807
+ return [viewHeight - resultY, inputX];
3808
+ }
3809
+ } else {
3810
+ if (inputX < invalidValue || inputX > viewWidth - invalidValue) {
3811
+ return null;
3812
+ }
3813
+ const resultX = linearTransform(invalidValue, mid, start, end, len, inputX);
3814
+ if (streamAngle === -90) {
3815
+ const [rotX, rotY] = rotatePoint90(viewWidth, viewHeight, cloudWidth, cloudHeight, resultX, inputY);
3816
+ return [rotX, rotY];
3817
+ } else {
3818
+ return [resultX, inputY];
3819
+ }
3820
+ }
3821
+ }
3822
+ function valueToPercentage(viewWidth, viewHeight, cloudWidth, cloudHeight, viewAngle, streamAngle, inputX, inputY) {
3823
+ let xRatio;
3824
+ let yRatio;
3825
+ if (viewAngle === 0 && streamAngle === 0) {
3826
+ xRatio = inputX / viewWidth;
3827
+ yRatio = inputY / viewHeight;
3828
+ } else if (viewAngle === -90 && streamAngle === 0) {
3829
+ xRatio = inputX / viewHeight;
3830
+ yRatio = inputY / viewWidth;
3831
+ } else if (viewAngle === -90 && streamAngle === -90) {
3832
+ xRatio = inputX / viewWidth * (cloudHeight / cloudWidth);
3833
+ yRatio = inputY / viewHeight * (cloudWidth / cloudHeight);
3834
+ } else {
3835
+ xRatio = inputX / viewHeight * (cloudHeight / cloudWidth);
3836
+ yRatio = inputY / viewWidth * (cloudWidth / cloudHeight);
3837
+ }
3838
+ return [xRatio, yRatio];
3839
+ }
3840
+ function linearTransform(invalidValue, mid, start, end, len, input) {
3841
+ if (input >= start && input <= mid - 0.1) {
3842
+ return (input - invalidValue) * mid / len;
3843
+ } else if (input === mid) {
3844
+ return mid;
3845
+ } else if (input >= mid + 0.1 && input <= end) {
3846
+ return mid + (input - mid) * mid / len;
3847
+ } else {
3848
+ return input;
3849
+ }
3850
+ }
3851
+ function rotatePoint90(width, height, cloudWidth, cloudHeight, inputX, inputY) {
3852
+ const offsetLongSide = height / 2;
3853
+ const offsetShortSide = width / 2;
3854
+ const x0 = inputX - offsetShortSide;
3855
+ const y0 = inputY - offsetLongSide;
3856
+ const xRotated = y0 + offsetLongSide;
3857
+ const yRotated = -x0 + offsetShortSide;
3858
+ return [xRotated, yRotated];
3859
+ }
3860
+ export {
3861
+ ActionType,
3862
+ ChannelDataType,
3863
+ ContainerDirection,
3864
+ EmitType,
3865
+ InputData,
3866
+ KeyEventData,
3867
+ TouchData,
3868
+ WebRTCSdk,
3869
+ getKeyEventData,
3870
+ transformCoordinate,
3871
+ valueToPercentage
3872
+ };