yjz-web-sdk 1.0.8-beta.12 → 1.0.8-beta.14

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.
@@ -15,7 +15,6 @@ export declare class WebRTCSdk extends EventEmitter {
15
15
  private connectCount;
16
16
  private MAX_COUNT;
17
17
  private timeout;
18
- private cache;
19
18
  constructor(options: WebRTCConfigOptions);
20
19
  initConfig(): Promise<void>;
21
20
  /** 开始连接 signal 服务 */
@@ -25,13 +25,17 @@ export declare class WebRTCClient extends EventEmitter {
25
25
  private fileImage?;
26
26
  private ua;
27
27
  constructor(config: WebRTCConfig);
28
- startPush(): Promise<void>;
28
+ startPush(useBackCamera?: boolean): Promise<void>;
29
29
  handleOffer(offerSdp: string): void;
30
30
  handleAnswer(answerSdp: string): void;
31
31
  handleIceCandidate(candidate: RTCIceCandidateInit): void;
32
32
  sendChannelData(type: ChannelDataType, data: any): void;
33
33
  closeConnection(): void;
34
- readyCapture(): Promise<void>;
34
+ readyCapture(useBackCamera: boolean): Promise<void>;
35
+ /**
36
+ * ✅ 切换前后摄像头(无缝)
37
+ */
38
+ switchCamera(useBackCamera: boolean): Promise<void>;
35
39
  private getRotatedStream;
36
40
  private setVideoParams;
37
41
  stopPush(): void;
@@ -551,7 +551,9 @@ class SignalingClient extends EventEmitter {
551
551
  type: SendType.SwitchControlToMain,
552
552
  identity: SendType.Identity,
553
553
  groupId: this.config.groupId,
554
- roomId
554
+ turnKey: this.config.turnKey,
555
+ roomId,
556
+ traceId: generateRandomString(16)
555
557
  };
556
558
  const jsonMessage = JSON.stringify(message);
557
559
  Logger.debug("调试日志:", `切换主控信令消息====>${jsonMessage}`);
@@ -3257,9 +3259,14 @@ const createAnswer = (peerConnection, sendAnswer, onError) => {
3257
3259
  peerConnection.createAnswer().then((answer) => setLocalDescriptionWithCreateAnswer(peerConnection, answer, sendAnswer, onError)).catch((error) => onError == null ? void 0 : onError(createWebRtcError(FailCode.CREATE_ANSWER, error)));
3258
3260
  };
3259
3261
  const setLocalDescriptionWithCreateAnswer = (peerConnection, answer, sendAnswer, onError) => {
3262
+ var _a;
3260
3263
  Logger.info("信息日志:", "设置本地answer Description=======>");
3261
- peerConnection.setLocalDescription(answer).then(() => {
3262
- sendAnswer == null ? void 0 : sendAnswer(answer.sdp ?? "");
3264
+ let sdp2 = (_a = answer.sdp) == null ? void 0 : _a.replace(
3265
+ /a=rtpmap:\d+ opus\/48000\/2\r\n/g,
3266
+ "$&a=ptime:0\r\na=maxptime:10\r\n"
3267
+ );
3268
+ peerConnection.setLocalDescription({ type: answer.type, sdp: sdp2 }).then(() => {
3269
+ sendAnswer == null ? void 0 : sendAnswer(sdp2 ?? "");
3263
3270
  }).catch((error) => {
3264
3271
  onError == null ? void 0 : onError(createWebRtcError(FailCode.LOCAL_DES, error));
3265
3272
  });
@@ -3276,7 +3283,7 @@ const createPeerConnection = (config) => {
3276
3283
  ];
3277
3284
  const peerConnectionConfig = {
3278
3285
  iceServers,
3279
- iceTransportPolicy: "relay",
3286
+ iceTransportPolicy: "all",
3280
3287
  bundlePolicy: "max-bundle"
3281
3288
  };
3282
3289
  return new RTCPeerConnection(peerConnectionConfig);
@@ -3306,7 +3313,7 @@ const configPeerConnection = (peerConnection, onICEMessage, onTrack, onConnectSt
3306
3313
  onConnectState == null ? void 0 : onConnectState(state);
3307
3314
  };
3308
3315
  peerConnection.ontrack = (event) => {
3309
- Logger.debug("信息日志:", `webrtc p2p连接后获取的音视频track`);
3316
+ Logger.debug("信息日志:", "webrtc p2p连接后获取的音视频track");
3310
3317
  const track = event.track;
3311
3318
  track.contentHint = "motion";
3312
3319
  onTrack == null ? void 0 : onTrack(track);
@@ -3325,10 +3332,15 @@ const createOffer = async (peerConnection, sendOfferMessage) => {
3325
3332
  }
3326
3333
  };
3327
3334
  const setLocalDescriptionWithCreateOffer = async (peerConnection, offer, sendOfferMessage) => {
3335
+ var _a;
3328
3336
  Logger.info("信息日志:", "设置本地offer Description=======>");
3329
3337
  try {
3330
- await peerConnection.setLocalDescription(offer);
3331
- sendOfferMessage(offer.sdp ?? "");
3338
+ const sdp2 = (_a = offer.sdp) == null ? void 0 : _a.replace(
3339
+ /a=rtpmap:\d+ opus\/48000\/2\r\n/g,
3340
+ "$&a=ptime:0\r\na=maxptime:10\r\n"
3341
+ );
3342
+ await peerConnection.setLocalDescription({ type: offer.type, sdp: sdp2 });
3343
+ sendOfferMessage(sdp2 ?? "");
3332
3344
  } catch (err) {
3333
3345
  throw new Error("摄像头视频流添加失败");
3334
3346
  }
@@ -3614,14 +3626,13 @@ class WebRTCClient extends EventEmitter {
3614
3626
  this.config = config;
3615
3627
  this.ua = navigator.userAgent;
3616
3628
  }
3617
- async startPush() {
3618
- if (this.isPushingStream) return;
3629
+ async startPush(useBackCamera = true) {
3619
3630
  if (this.isPushingLocalStream) {
3620
3631
  this.stopLocal();
3621
3632
  }
3622
3633
  try {
3623
3634
  this.isPushingStream = true;
3624
- await this.readyCapture();
3635
+ await this.readyCapture(useBackCamera);
3625
3636
  } catch (err) {
3626
3637
  this.isPushingStream = false;
3627
3638
  let errorMessage;
@@ -3742,27 +3753,78 @@ class WebRTCClient extends EventEmitter {
3742
3753
  this.peerConnection = null;
3743
3754
  }
3744
3755
  }
3745
- async readyCapture() {
3756
+ async readyCapture(useBackCamera) {
3746
3757
  this.resetPeerConnection();
3747
- Logger.info("信息日志:", "启用摄像头推流到云机=======>");
3758
+ this.stopPush();
3759
+ Logger.info("信息日志:", "启用摄像头推流到云机=======>", useBackCamera);
3748
3760
  try {
3749
3761
  this.localStream = await navigator.mediaDevices.getUserMedia({
3750
- video: { width: { ideal: 640 }, height: { ideal: 480 } },
3762
+ video: {
3763
+ width: { ideal: 640 },
3764
+ height: { ideal: 480 },
3765
+ facingMode: useBackCamera ? { ideal: "environment" } : { ideal: "user" },
3766
+ frameRate: { ideal: 20, max: 30 }
3767
+ },
3751
3768
  audio: true
3752
3769
  });
3753
3770
  const senders = [];
3754
- const rotatedStream = await this.getRotatedStream(this.localStream);
3771
+ const rotatedStream = await this.getRotatedStream(this.localStream, useBackCamera);
3755
3772
  this.rotatedStream = rotatedStream;
3756
3773
  rotatedStream.getTracks().forEach((track) => {
3757
3774
  track.contentHint = "detail";
3758
3775
  const sender = this.peerConnection.addTrack(track, rotatedStream);
3759
3776
  senders.push(sender);
3760
3777
  });
3761
- senders.forEach((sender) => this.setVideoParams(sender));
3762
3778
  await createOffer(this.peerConnection, (sdp2) => {
3763
3779
  this.emit(EmitType.sendOffer, sdp2);
3764
3780
  });
3781
+ senders.forEach((sender) => this.setVideoParams(sender));
3782
+ } catch (err) {
3783
+ console.log("err===>", err);
3784
+ if (err instanceof DOMException) {
3785
+ switch (err.name) {
3786
+ case "NotAllowedError":
3787
+ throw new Error("用户拒绝了摄像头或麦克风权限");
3788
+ case "NotFoundError":
3789
+ throw new Error("未找到摄像头或麦克风设备");
3790
+ case "OverconstrainedError":
3791
+ throw new Error("设备无法满足指定约束");
3792
+ case "NotReadableError":
3793
+ throw new Error("设备忙或无法访问");
3794
+ default:
3795
+ throw new Error(`其他错误: ${err.message}`);
3796
+ }
3797
+ }
3798
+ throw new Error(`mediaDevices 异常: ${err}`);
3799
+ }
3800
+ }
3801
+ /**
3802
+ * ✅ 切换前后摄像头(无缝)
3803
+ */
3804
+ async switchCamera(useBackCamera) {
3805
+ var _a;
3806
+ try {
3807
+ Logger.info("信息日志:", `切换摄像头 => ${useBackCamera ? "后置" : "前置"}`);
3808
+ this.isPushingStream = true;
3809
+ this.localStream = await navigator.mediaDevices.getUserMedia({
3810
+ video: {
3811
+ width: { ideal: 640 },
3812
+ height: { ideal: 480 },
3813
+ facingMode: useBackCamera ? { ideal: "environment" } : { ideal: "user" },
3814
+ frameRate: { ideal: 20, max: 30 }
3815
+ },
3816
+ audio: false
3817
+ // 音频不需要重新采集
3818
+ });
3819
+ const rotatedStream = await this.getRotatedStream(this.localStream, useBackCamera);
3820
+ this.rotatedStream = rotatedStream;
3821
+ const newTrack = this.rotatedStream.getVideoTracks()[0];
3822
+ const sender = (_a = this.peerConnection) == null ? void 0 : _a.getSenders().find((s) => s.track && s.track.kind === "video");
3823
+ if (sender) {
3824
+ await sender.replaceTrack(newTrack);
3825
+ }
3765
3826
  } catch (err) {
3827
+ this.isPushingStream = false;
3766
3828
  if (err instanceof DOMException) {
3767
3829
  switch (err.name) {
3768
3830
  case "NotAllowedError":
@@ -3780,7 +3842,7 @@ class WebRTCClient extends EventEmitter {
3780
3842
  throw new Error(`mediaDevices 异常: ${err}`);
3781
3843
  }
3782
3844
  }
3783
- async getRotatedStream(localStream) {
3845
+ async getRotatedStream(localStream, useBackCamera) {
3784
3846
  const canvas = document.createElement("canvas");
3785
3847
  const ctx = canvas.getContext("2d");
3786
3848
  const video = document.createElement("video");
@@ -3795,11 +3857,12 @@ class WebRTCClient extends EventEmitter {
3795
3857
  ctx.clearRect(0, 0, canvas.width, canvas.height);
3796
3858
  ctx.save();
3797
3859
  ctx.translate(canvas.width / 2, canvas.height / 2);
3798
- ctx.rotate(Math.PI / 2);
3860
+ const angle = useBackCamera ? -Math.PI / 2 : Math.PI / 2;
3861
+ ctx.rotate(angle);
3799
3862
  ctx.drawImage(video, -width / 2, -height / 2, width, height);
3800
3863
  ctx.restore();
3801
3864
  };
3802
- const fps = 30;
3865
+ const fps = 25;
3803
3866
  const frameInterval = 1e3 / fps;
3804
3867
  let lastTime = 0;
3805
3868
  let rafId;
@@ -3819,16 +3882,40 @@ class WebRTCClient extends EventEmitter {
3819
3882
  });
3820
3883
  return stream;
3821
3884
  }
3885
+ // private async setVideoParams(sender: RTCRtpSender) {
3886
+ // Logger.info('信息日志:', '设置推流视频参数=======>')
3887
+ // const params = sender.getParameters();
3888
+ // params.degradationPreference = 'balanced';
3889
+ // const isMobile = /Android|iPhone|iPad/i.test(navigator.userAgent);
3890
+ // params.encodings.forEach(encoding => {
3891
+ // encoding.maxBitrate = isMobile ? 800000 : 1000000;
3892
+ // encoding.priority = 'high';
3893
+ // encoding.scaleResolutionDownBy = 1.0;
3894
+ // });
3895
+ // await sender.setParameters(params);
3896
+ // }
3822
3897
  async setVideoParams(sender) {
3823
- Logger.info("信息日志:", "设置推流视频参数=======>");
3824
3898
  const params = sender.getParameters();
3899
+ const isMobile = /Android|iPhone|iPad/i.test(navigator.userAgent);
3900
+ const targetBitrate = isMobile ? 6e5 : 18e5;
3901
+ const targetFramerate = 30;
3825
3902
  params.degradationPreference = "maintain-resolution";
3903
+ if (!params.encodings || params.encodings.length === 0) {
3904
+ params.encodings = [{}];
3905
+ }
3906
+ console.log("params.codecs===>", params.codecs);
3826
3907
  params.encodings.forEach((encoding) => {
3827
- encoding.maxBitrate = 1e6;
3828
- encoding.priority = "high";
3908
+ encoding.maxBitrate = targetBitrate;
3909
+ encoding.maxFramerate = targetFramerate;
3829
3910
  encoding.scaleResolutionDownBy = 1;
3911
+ encoding.priority = "high";
3830
3912
  });
3831
- await sender.setParameters(params);
3913
+ try {
3914
+ await sender.setParameters(params);
3915
+ Logger.info("信息日志:", `设置推流视频参数成功:${targetBitrate / 1e3}kbps / ${targetFramerate}fps`);
3916
+ } catch (e) {
3917
+ Logger.error("设置推流参数失败:", e);
3918
+ }
3832
3919
  }
3833
3920
  stopPush() {
3834
3921
  var _a, _b, _c;
@@ -3875,10 +3962,15 @@ class WebRTCClient extends EventEmitter {
3875
3962
  handleDataChannelMessage(event) {
3876
3963
  const data = JSON.parse(event.data);
3877
3964
  if (data.type === ChannelDataType.ActionCommandEvent) {
3878
- const { action, value } = JSON.parse(data.data);
3965
+ const { action, value, cameraId } = JSON.parse(data.data);
3879
3966
  if (action === "ACTION_CONTROL_VIDEO") {
3967
+ console.log("cameraId===>", cameraId, Number(cameraId) !== 0);
3880
3968
  if (value === "ENABLE") {
3881
- this.startPush();
3969
+ if (this.isPushingStream) {
3970
+ this.switchCamera(Number(cameraId) === 0);
3971
+ } else {
3972
+ this.startPush(Number(cameraId) === 0);
3973
+ }
3882
3974
  } else {
3883
3975
  this.stopPush();
3884
3976
  this.stopLocal();
@@ -4202,121 +4294,8 @@ const selectBestTurnServer = async (turnList) => {
4202
4294
  return { error: e.message || "未知错误" };
4203
4295
  }
4204
4296
  };
4205
- class MapCache {
4206
- // 默认过期时间(毫秒)
4207
- constructor(key, maxSize = 100, expireMs = 5 * 60 * 1e3) {
4208
- __publicField(this, "key");
4209
- __publicField(this, "maxSize");
4210
- __publicField(this, "defaultExpire");
4211
- this.key = key;
4212
- this.maxSize = maxSize;
4213
- this.defaultExpire = expireMs;
4214
- }
4215
- /** 从 localStorage 读取 Map(自动清理过期的 item) */
4216
- getMap() {
4217
- const raw = localStorage.getItem(this.key);
4218
- if (!raw) return /* @__PURE__ */ new Map();
4219
- try {
4220
- const data = JSON.parse(raw);
4221
- const now = Date.now();
4222
- const result = /* @__PURE__ */ new Map();
4223
- let changed = false;
4224
- for (const [k, obj] of Object.entries(data)) {
4225
- if (now - obj.timestamp <= obj.expire) {
4226
- result.set(k, obj.value);
4227
- } else {
4228
- changed = true;
4229
- }
4230
- }
4231
- if (changed) this.saveMap(result);
4232
- return result;
4233
- } catch {
4234
- return /* @__PURE__ */ new Map();
4235
- }
4236
- }
4237
- /** 保存 Map(每个值都有独立的 timestamp/expire) */
4238
- saveMap(map, meta) {
4239
- const obj = {};
4240
- const now = Date.now();
4241
- for (const [k, v] of map.entries()) {
4242
- if (meta && meta[k]) {
4243
- obj[k] = { value: v, timestamp: meta[k].timestamp, expire: meta[k].expire };
4244
- } else {
4245
- obj[k] = { value: v, timestamp: now, expire: this.defaultExpire };
4246
- }
4247
- }
4248
- localStorage.setItem(this.key, JSON.stringify(obj));
4249
- }
4250
- /** 设置值(支持单项自定义过期时间) */
4251
- set(key, value, expireMs) {
4252
- const map = this.getMap();
4253
- const raw = localStorage.getItem(this.key);
4254
- let meta = {};
4255
- if (raw) {
4256
- try {
4257
- meta = JSON.parse(raw);
4258
- } catch {
4259
- meta = {};
4260
- }
4261
- }
4262
- if (map.size >= this.maxSize && !map.has(key)) {
4263
- const firstKey = map.keys().next().value;
4264
- if (typeof firstKey === "string") {
4265
- map.delete(firstKey);
4266
- delete meta[firstKey];
4267
- }
4268
- }
4269
- map.set(key, value);
4270
- meta[key] = { timestamp: Date.now(), expire: expireMs ?? this.defaultExpire };
4271
- this.saveMap(map, meta);
4272
- }
4273
- /** 获取值(单项过期会自动清除) */
4274
- get(key) {
4275
- const map = this.getMap();
4276
- return map.get(key);
4277
- }
4278
- /** 检查是否存在且未过期 */
4279
- has(key) {
4280
- const raw = localStorage.getItem(this.key);
4281
- if (!raw) return false;
4282
- try {
4283
- const data = JSON.parse(raw);
4284
- const obj = data[key];
4285
- if (!obj) return false;
4286
- const now = Date.now();
4287
- if (now - obj.timestamp <= obj.expire) {
4288
- return true;
4289
- } else {
4290
- this.delete(key);
4291
- return false;
4292
- }
4293
- } catch {
4294
- return false;
4295
- }
4296
- }
4297
- /** 删除 */
4298
- delete(key) {
4299
- const map = this.getMap();
4300
- map.delete(key);
4301
- const raw = localStorage.getItem(this.key);
4302
- if (raw) {
4303
- try {
4304
- const meta = JSON.parse(raw);
4305
- delete meta[key];
4306
- this.saveMap(map, meta);
4307
- } catch {
4308
- this.saveMap(map);
4309
- }
4310
- } else {
4311
- this.saveMap(map);
4312
- }
4313
- }
4314
- /** 清空 */
4315
- clear() {
4316
- localStorage.removeItem(this.key);
4317
- }
4318
- }
4319
4297
  class WebRTCSdk extends EventEmitter {
4298
+ // private cache: MapCache;
4320
4299
  constructor(options) {
4321
4300
  super();
4322
4301
  __publicField(this, "config", null);
@@ -4328,7 +4307,6 @@ class WebRTCSdk extends EventEmitter {
4328
4307
  __publicField(this, "connectCount", 0);
4329
4308
  __publicField(this, "MAX_COUNT", 1);
4330
4309
  __publicField(this, "timeout", null);
4331
- __publicField(this, "cache");
4332
4310
  /**
4333
4311
  * 处理 signal 消息,根据不同消息类型分发到 webRTCClient 或直接触发 SDK 事件
4334
4312
  * @param message 信令消息
@@ -4486,11 +4464,6 @@ class WebRTCSdk extends EventEmitter {
4486
4464
  }
4487
4465
  });
4488
4466
  this.options = options;
4489
- if (this.options.cacheTimeout !== void 0 && this.options.cacheTimeout > 0) {
4490
- this.cache = new MapCache("screenCache", 100, this.options.cacheTimeout);
4491
- } else {
4492
- this.cache = new MapCache("screenCache", 100);
4493
- }
4494
4467
  if (this.options.connectorType !== ConnectorType.LanForwarding) {
4495
4468
  enableLog(!!this.options.enableLogger);
4496
4469
  if (this.options.enableLogger !== void 0 && this.options.enableLogger) {
@@ -4520,7 +4493,6 @@ class WebRTCSdk extends EventEmitter {
4520
4493
  return false;
4521
4494
  }
4522
4495
  this.options.turnServerUri = result.url;
4523
- this.cache.set(this.options.roomId, this.options.turnServerUri);
4524
4496
  this.options.turnKey = [result.url];
4525
4497
  return true;
4526
4498
  } else {
@@ -4571,14 +4543,7 @@ class WebRTCSdk extends EventEmitter {
4571
4543
  return;
4572
4544
  }
4573
4545
  } else {
4574
- const isActive = this.cache.has(this.options.roomId);
4575
- if (isActive) {
4576
- const turnUri = this.cache.get(this.options.roomId);
4577
- this.options.turnServerUri = turnUri;
4578
- this.options.turnKey = [turnUri];
4579
- } else {
4580
- await this.initConfig();
4581
- }
4546
+ await this.initConfig();
4582
4547
  }
4583
4548
  this.initConnectConfig();
4584
4549
  this.initSignalingClient();
@@ -5069,8 +5034,8 @@ function useRemoteVideo(videoContainer, remoteVideoElement, videoAngle, emit) {
5069
5034
  const widthRadio = ref(0);
5070
5035
  const heightRadio = ref(0);
5071
5036
  const resizeObserver = ref(null);
5072
- const frameCallbackId = ref(0);
5073
5037
  const isRotated = computed(() => videoAngle.value % 180 !== 0);
5038
+ const frameCallbackId = ref(0);
5074
5039
  const videoSize = computed(() => {
5075
5040
  let width = 0;
5076
5041
  let height = 0;
@@ -5109,10 +5074,15 @@ function useRemoteVideo(videoContainer, remoteVideoElement, videoAngle, emit) {
5109
5074
  };
5110
5075
  screenStatus.value = true;
5111
5076
  emit("loadedSuccess");
5077
+ const isMobile = /Android|iPhone|iPad/i.test(navigator.userAgent);
5078
+ if (isMobile) {
5079
+ startVideoFrameCallback(video);
5080
+ }
5112
5081
  };
5113
5082
  video.addEventListener("loadedmetadata", handleMetadata);
5114
5083
  onBeforeUnmount(() => {
5115
5084
  video.removeEventListener("loadedmetadata", handleMetadata);
5085
+ if (frameCallbackId.value) video.cancelVideoFrameCallback(frameCallbackId.value);
5116
5086
  });
5117
5087
  };
5118
5088
  const initVideoContainer = () => {
@@ -5130,8 +5100,15 @@ function useRemoteVideo(videoContainer, remoteVideoElement, videoAngle, emit) {
5130
5100
  }
5131
5101
  const mediaStream = videoEl.srcObject;
5132
5102
  updateTrack(mediaStream, newTrack);
5103
+ videoEl.playbackRate = 1;
5133
5104
  videoEl.playsInline = true;
5105
+ videoEl.disablePictureInPicture = true;
5106
+ videoEl.setAttribute("playsinline", "true");
5134
5107
  videoEl.setAttribute("webkit-playsinline", "true");
5108
+ videoEl.setAttribute("x5-video-player-type", "h5");
5109
+ videoEl.setAttribute("x5-video-player-fullscreen", "false");
5110
+ videoEl.setAttribute("x5-video-orientation", "portraint");
5111
+ videoEl.preload = "auto";
5135
5112
  };
5136
5113
  const updateTrack = (stream, newTrack) => {
5137
5114
  if (newTrack.kind === "video") {
@@ -5144,8 +5121,6 @@ function useRemoteVideo(videoContainer, remoteVideoElement, videoAngle, emit) {
5144
5121
  if (!stream.getAudioTracks().some((t) => t.id === newTrack.id)) {
5145
5122
  stream.addTrack(newTrack);
5146
5123
  }
5147
- } else {
5148
- console.warn("不支持的 track 类型:", newTrack.kind);
5149
5124
  }
5150
5125
  };
5151
5126
  const stopPlay = () => {
@@ -5154,29 +5129,17 @@ function useRemoteVideo(videoContainer, remoteVideoElement, videoAngle, emit) {
5154
5129
  if (video && video.srcObject) {
5155
5130
  video.srcObject.getTracks().forEach((track) => track.stop());
5156
5131
  video.srcObject = null;
5157
- video.cancelVideoFrameCallback(frameCallbackId.value);
5132
+ if (frameCallbackId.value) video.cancelVideoFrameCallback(frameCallbackId.value);
5158
5133
  }
5159
5134
  };
5160
5135
  const handleVisibilityChange = () => {
5161
- if (document.visibilityState === "visible") {
5162
- const video = remoteVideoElement.value;
5163
- if (video && video.srcObject) {
5164
- video.srcObject.getTracks().forEach((track) => {
5165
- if (track.kind === "audio" && !track.enabled) {
5166
- track.enabled = true;
5167
- }
5168
- });
5169
- }
5170
- } else {
5171
- const video = remoteVideoElement.value;
5172
- if (video && video.srcObject) {
5173
- video.srcObject.getTracks().forEach((track) => {
5174
- if (track.kind === "audio" && track.enabled) {
5175
- track.enabled = false;
5176
- }
5177
- });
5136
+ const video = remoteVideoElement.value;
5137
+ if (!video || !video.srcObject) return;
5138
+ video.srcObject.getTracks().forEach((track) => {
5139
+ if (track.kind === "audio") {
5140
+ track.enabled = document.visibilityState === "visible";
5178
5141
  }
5179
- }
5142
+ });
5180
5143
  };
5181
5144
  onMounted(() => {
5182
5145
  document.addEventListener("visibilitychange", handleVisibilityChange);
@@ -5188,6 +5151,16 @@ function useRemoteVideo(videoContainer, remoteVideoElement, videoAngle, emit) {
5188
5151
  }
5189
5152
  stopPlay();
5190
5153
  });
5154
+ const startVideoFrameCallback = (video) => {
5155
+ const handleFrame = (_now, _metadata) => {
5156
+ video.playbackRate = 1.1;
5157
+ setTimeout(() => {
5158
+ video.playbackRate = 1;
5159
+ }, 600);
5160
+ frameCallbackId.value = video.requestVideoFrameCallback(handleFrame);
5161
+ };
5162
+ frameCallbackId.value = video.requestVideoFrameCallback(handleFrame);
5163
+ };
5191
5164
  return {
5192
5165
  videoSize,
5193
5166
  remoteVideo,
@@ -14,11 +14,11 @@ i(this,"webSocket",null),i(this,"timeout",null),this.config=e}
14
14
  /**
15
15
  * 发送消息到服务端
16
16
  * @param message - 消息字符串
17
- */sendMessage(e){this.webSocket&&this.webSocket.readyState===WebSocket.OPEN&&this.webSocket.send(e)}sendSignInMessage(){const e={traceId:this.config.traceId,type:h.SignIn,targetId:this.config.myId,identity:h.Identity,turnServerUri:this.config.turnServerUri,roomId:this.config.roomId,token:this.config.token,isGroup:this.config.isGroup,turnKey:this.config.turnKey,connectorType:this.config.connectorType},t=JSON.stringify(e);w.debug("调试日志:",`屏控登录信息====>${t}`),this.sendMessage(t)}sendSwitchControlMessage(e,t){const n={type:h.SwitchControl,identity:h.Identity,roomId:e,connectorType:t,targetId:this.config.myId},i=JSON.stringify(n);w.debug("调试日志:",`切换主控信令消息====>${i}`),this.sendMessage(i)}sendSwitchControlToMainMessage(e){const t={type:h.SwitchControlToMain,identity:h.Identity,groupId:this.config.groupId,roomId:e},n=JSON.stringify(t);w.debug("调试日志:",`切换主控信令消息====>${n}`),this.sendMessage(n)}sendGroupAcceptControl(e,t){const n={type:h.GroupAcceptControl,targetId:this.config.myId,identity:h.Identity,roomIds:e,isAccept:t},i=JSON.stringify(n);w.debug("调试日志:",`修改控制状态====>${i}`),this.sendMessage(i)}sendGroupAction(e){const t=P(16),n={type:h.GroupSendAction,identity:h.Identity,targetId:this.config.myId,groupId:this.config.groupId,action:e,epSendAt:Date.now(),traceId:t},i=JSON.stringify(n);w.debug("调试日志:",`发送群控事件====>${i}`),this.sendMessage(i)}sendGroupSignInMessage(){const e={traceId:this.config.traceId,type:h.GroupSignIn,identity:h.Identity,turnServerUri:this.config.turnServerUri,mainRoomIdOfGroup:this.config.mainRoomIdOfGroup,subRoomIdsOfGroup:this.config.subRoomIdsOfGroup,turnKey:this.config.turnKey,groupId:"group_0001",token:this.config.token},t=JSON.stringify(e);w.debug("调试日志:",`群控登录信息====>${t}`),this.sendMessage(t)}}function P(e){const t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";let n="";for(let i=0;i<e;i++){n+=t[Math.floor(62*Math.random())]}return n}let k=!0,I=!0;function A(e,t,n){const i=e.match(t);return i&&i.length>=n&&parseFloat(i[n],10)}function _(e,t,n){if(!e.RTCPeerConnection)return;const i=e.RTCPeerConnection.prototype,r=i.addEventListener;i.addEventListener=function(e,i){if(e!==t)return r.apply(this,arguments);const o=e=>{const t=n(e);t&&(i.handleEvent?i.handleEvent(t):i(t))};return this._eventMap=this._eventMap||{},this._eventMap[t]||(this._eventMap[t]=new Map),this._eventMap[t].set(i,o),r.apply(this,[e,o])};const o=i.removeEventListener;i.removeEventListener=function(e,n){if(e!==t||!this._eventMap||!this._eventMap[t])return o.apply(this,arguments);if(!this._eventMap[t].has(n))return o.apply(this,arguments);const i=this._eventMap[t].get(n);return this._eventMap[t].delete(n),0===this._eventMap[t].size&&delete this._eventMap[t],0===Object.keys(this._eventMap).length&&delete this._eventMap,o.apply(this,[e,i])},Object.defineProperty(i,"on"+t,{get(){return this["_on"+t]},set(e){this["_on"+t]&&(this.removeEventListener(t,this["_on"+t]),delete this["_on"+t]),e&&this.addEventListener(t,this["_on"+t]=e)},enumerable:!0,configurable:!0})}function O(e){return"boolean"!=typeof e?new Error("Argument type: "+typeof e+". Please use a boolean."):(k=e,e?"adapter.js logging disabled":"adapter.js logging enabled")}function D(e){return"boolean"!=typeof e?new Error("Argument type: "+typeof e+". Please use a boolean."):(I=!e,"adapter.js deprecation warnings "+(e?"disabled":"enabled"))}function M(){if("object"==typeof window){if(k)return;"undefined"!=typeof console&&console.log}}function L(e,t){}function x(e){return"[object Object]"===Object.prototype.toString.call(e)}function N(e){return x(e)?Object.keys(e).reduce(function(t,n){const i=x(e[n]),r=i?N(e[n]):e[n],o=i&&!Object.keys(r).length;return void 0===r||o?t:Object.assign(t,{[n]:r})},{}):e}function j(e,t,n){t&&!n.has(t.id)&&(n.set(t.id,t),Object.keys(t).forEach(i=>{i.endsWith("Id")?j(e,e.get(t[i]),n):i.endsWith("Ids")&&t[i].forEach(t=>{j(e,e.get(t),n)})}))}function U(e,t,n){const i=n?"outbound-rtp":"inbound-rtp",r=new Map;if(null===t)return r;const o=[];return e.forEach(e=>{"track"===e.type&&e.trackIdentifier===t.id&&o.push(e)}),o.forEach(t=>{e.forEach(n=>{n.type===i&&n.trackId===t.id&&j(e,n,r)})}),r}const F=M;function G(e,t){const n=e&&e.navigator;if(!n.mediaDevices)return;const i=function(e){if("object"!=typeof e||e.mandatory||e.optional)return e;const t={};return Object.keys(e).forEach(n=>{if("require"===n||"advanced"===n||"mediaSource"===n)return;const i="object"==typeof e[n]?e[n]:{ideal:e[n]};void 0!==i.exact&&"number"==typeof i.exact&&(i.min=i.max=i.exact);const r=function(e,t){return e?e+t.charAt(0).toUpperCase()+t.slice(1):"deviceId"===t?"sourceId":t};if(void 0!==i.ideal){t.optional=t.optional||[];let e={};"number"==typeof i.ideal?(e[r("min",n)]=i.ideal,t.optional.push(e),e={},e[r("max",n)]=i.ideal,t.optional.push(e)):(e[r("",n)]=i.ideal,t.optional.push(e))}void 0!==i.exact&&"number"!=typeof i.exact?(t.mandatory=t.mandatory||{},t.mandatory[r("",n)]=i.exact):["min","max"].forEach(e=>{void 0!==i[e]&&(t.mandatory=t.mandatory||{},t.mandatory[r(e,n)]=i[e])})}),e.advanced&&(t.optional=(t.optional||[]).concat(e.advanced)),t},r=function(e,r){if(t.version>=61)return r(e);if((e=JSON.parse(JSON.stringify(e)))&&"object"==typeof e.audio){const t=function(e,t,n){t in e&&!(n in e)&&(e[n]=e[t],delete e[t])};t((e=JSON.parse(JSON.stringify(e))).audio,"autoGainControl","googAutoGainControl"),t(e.audio,"noiseSuppression","googNoiseSuppression"),e.audio=i(e.audio)}if(e&&"object"==typeof e.video){let o=e.video.facingMode;o=o&&("object"==typeof o?o:{ideal:o});const s=t.version<66;if(o&&("user"===o.exact||"environment"===o.exact||"user"===o.ideal||"environment"===o.ideal)&&(!n.mediaDevices.getSupportedConstraints||!n.mediaDevices.getSupportedConstraints().facingMode||s)){let t;if(delete e.video.facingMode,"environment"===o.exact||"environment"===o.ideal?t=["back","rear"]:"user"!==o.exact&&"user"!==o.ideal||(t=["front"]),t)return n.mediaDevices.enumerateDevices().then(n=>{let s=(n=n.filter(e=>"videoinput"===e.kind)).find(e=>t.some(t=>e.label.toLowerCase().includes(t)));return!s&&n.length&&t.includes("back")&&(s=n[n.length-1]),s&&(e.video.deviceId=o.exact?{exact:s.deviceId}:{ideal:s.deviceId}),e.video=i(e.video),F("chrome: "+JSON.stringify(e)),r(e)})}e.video=i(e.video)}return F("chrome: "+JSON.stringify(e)),r(e)},o=function(e){return t.version>=64?e:{name:{PermissionDeniedError:"NotAllowedError",PermissionDismissedError:"NotAllowedError",InvalidStateError:"NotAllowedError",DevicesNotFoundError:"NotFoundError",ConstraintNotSatisfiedError:"OverconstrainedError",TrackStartError:"NotReadableError",MediaDeviceFailedDueToShutdown:"NotAllowedError",MediaDeviceKillSwitchOn:"NotAllowedError",TabCaptureError:"AbortError",ScreenCaptureError:"AbortError",DeviceCaptureError:"AbortError"}[e.name]||e.name,message:e.message,constraint:e.constraint||e.constraintName,toString(){return this.name+(this.message&&": ")+this.message}}};if(n.getUserMedia=function(e,t,i){r(e,e=>{n.webkitGetUserMedia(e,t,e=>{i&&i(o(e))})})}.bind(n),n.mediaDevices.getUserMedia){const e=n.mediaDevices.getUserMedia.bind(n.mediaDevices);n.mediaDevices.getUserMedia=function(t){return r(t,t=>e(t).then(e=>{if(t.audio&&!e.getAudioTracks().length||t.video&&!e.getVideoTracks().length)throw e.getTracks().forEach(e=>{e.stop()}),new DOMException("","NotFoundError");return e},e=>Promise.reject(o(e))))}}}function K(e){e.MediaStream=e.MediaStream||e.webkitMediaStream}function V(e){if("object"==typeof e&&e.RTCPeerConnection&&!("ontrack"in e.RTCPeerConnection.prototype)){Object.defineProperty(e.RTCPeerConnection.prototype,"ontrack",{get(){return this._ontrack},set(e){this._ontrack&&this.removeEventListener("track",this._ontrack),this.addEventListener("track",this._ontrack=e)},enumerable:!0,configurable:!0});const t=e.RTCPeerConnection.prototype.setRemoteDescription;e.RTCPeerConnection.prototype.setRemoteDescription=function(){return this._ontrackpoly||(this._ontrackpoly=t=>{t.stream.addEventListener("addtrack",n=>{let i;i=e.RTCPeerConnection.prototype.getReceivers?this.getReceivers().find(e=>e.track&&e.track.id===n.track.id):{track:n.track};const r=new Event("track");r.track=n.track,r.receiver=i,r.transceiver={receiver:i},r.streams=[t.stream],this.dispatchEvent(r)}),t.stream.getTracks().forEach(n=>{let i;i=e.RTCPeerConnection.prototype.getReceivers?this.getReceivers().find(e=>e.track&&e.track.id===n.id):{track:n};const r=new Event("track");r.track=n,r.receiver=i,r.transceiver={receiver:i},r.streams=[t.stream],this.dispatchEvent(r)})},this.addEventListener("addstream",this._ontrackpoly)),t.apply(this,arguments)}}else _(e,"track",e=>(e.transceiver||Object.defineProperty(e,"transceiver",{value:{receiver:e.receiver}}),e))}function z(e){if("object"==typeof e&&e.RTCPeerConnection&&!("getSenders"in e.RTCPeerConnection.prototype)&&"createDTMFSender"in e.RTCPeerConnection.prototype){const t=function(e,t){return{track:t,get dtmf(){return void 0===this._dtmf&&("audio"===t.kind?this._dtmf=e.createDTMFSender(t):this._dtmf=null),this._dtmf},_pc:e}};if(!e.RTCPeerConnection.prototype.getSenders){e.RTCPeerConnection.prototype.getSenders=function(){return this._senders=this._senders||[],this._senders.slice()};const n=e.RTCPeerConnection.prototype.addTrack;e.RTCPeerConnection.prototype.addTrack=function(e,i){let r=n.apply(this,arguments);return r||(r=t(this,e),this._senders.push(r)),r};const i=e.RTCPeerConnection.prototype.removeTrack;e.RTCPeerConnection.prototype.removeTrack=function(e){i.apply(this,arguments);const t=this._senders.indexOf(e);-1!==t&&this._senders.splice(t,1)}}const n=e.RTCPeerConnection.prototype.addStream;e.RTCPeerConnection.prototype.addStream=function(e){this._senders=this._senders||[],n.apply(this,[e]),e.getTracks().forEach(e=>{this._senders.push(t(this,e))})};const i=e.RTCPeerConnection.prototype.removeStream;e.RTCPeerConnection.prototype.removeStream=function(e){this._senders=this._senders||[],i.apply(this,[e]),e.getTracks().forEach(e=>{const t=this._senders.find(t=>t.track===e);t&&this._senders.splice(this._senders.indexOf(t),1)})}}else if("object"==typeof e&&e.RTCPeerConnection&&"getSenders"in e.RTCPeerConnection.prototype&&"createDTMFSender"in e.RTCPeerConnection.prototype&&e.RTCRtpSender&&!("dtmf"in e.RTCRtpSender.prototype)){const t=e.RTCPeerConnection.prototype.getSenders;e.RTCPeerConnection.prototype.getSenders=function(){const e=t.apply(this,[]);return e.forEach(e=>e._pc=this),e},Object.defineProperty(e.RTCRtpSender.prototype,"dtmf",{get(){return void 0===this._dtmf&&("audio"===this.track.kind?this._dtmf=this._pc.createDTMFSender(this.track):this._dtmf=null),this._dtmf}})}}function W(e){if(!("object"==typeof e&&e.RTCPeerConnection&&e.RTCRtpSender&&e.RTCRtpReceiver))return;if(!("getStats"in e.RTCRtpSender.prototype)){const t=e.RTCPeerConnection.prototype.getSenders;t&&(e.RTCPeerConnection.prototype.getSenders=function(){const e=t.apply(this,[]);return e.forEach(e=>e._pc=this),e});const n=e.RTCPeerConnection.prototype.addTrack;n&&(e.RTCPeerConnection.prototype.addTrack=function(){const e=n.apply(this,arguments);return e._pc=this,e}),e.RTCRtpSender.prototype.getStats=function(){const e=this;return this._pc.getStats().then(t=>
17
+ */sendMessage(e){this.webSocket&&this.webSocket.readyState===WebSocket.OPEN&&this.webSocket.send(e)}sendSignInMessage(){const e={traceId:this.config.traceId,type:h.SignIn,targetId:this.config.myId,identity:h.Identity,turnServerUri:this.config.turnServerUri,roomId:this.config.roomId,token:this.config.token,isGroup:this.config.isGroup,turnKey:this.config.turnKey,connectorType:this.config.connectorType},t=JSON.stringify(e);w.debug("调试日志:",`屏控登录信息====>${t}`),this.sendMessage(t)}sendSwitchControlMessage(e,t){const n={type:h.SwitchControl,identity:h.Identity,roomId:e,connectorType:t,targetId:this.config.myId},i=JSON.stringify(n);w.debug("调试日志:",`切换主控信令消息====>${i}`),this.sendMessage(i)}sendSwitchControlToMainMessage(e){const t={type:h.SwitchControlToMain,identity:h.Identity,groupId:this.config.groupId,turnKey:this.config.turnKey,roomId:e,traceId:P(16)},n=JSON.stringify(t);w.debug("调试日志:",`切换主控信令消息====>${n}`),this.sendMessage(n)}sendGroupAcceptControl(e,t){const n={type:h.GroupAcceptControl,targetId:this.config.myId,identity:h.Identity,roomIds:e,isAccept:t},i=JSON.stringify(n);w.debug("调试日志:",`修改控制状态====>${i}`),this.sendMessage(i)}sendGroupAction(e){const t=P(16),n={type:h.GroupSendAction,identity:h.Identity,targetId:this.config.myId,groupId:this.config.groupId,action:e,epSendAt:Date.now(),traceId:t},i=JSON.stringify(n);w.debug("调试日志:",`发送群控事件====>${i}`),this.sendMessage(i)}sendGroupSignInMessage(){const e={traceId:this.config.traceId,type:h.GroupSignIn,identity:h.Identity,turnServerUri:this.config.turnServerUri,mainRoomIdOfGroup:this.config.mainRoomIdOfGroup,subRoomIdsOfGroup:this.config.subRoomIdsOfGroup,turnKey:this.config.turnKey,groupId:"group_0001",token:this.config.token},t=JSON.stringify(e);w.debug("调试日志:",`群控登录信息====>${t}`),this.sendMessage(t)}}function P(e){const t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";let n="";for(let i=0;i<e;i++){n+=t[Math.floor(62*Math.random())]}return n}let k=!0,I=!0;function A(e,t,n){const i=e.match(t);return i&&i.length>=n&&parseFloat(i[n],10)}function _(e,t,n){if(!e.RTCPeerConnection)return;const i=e.RTCPeerConnection.prototype,r=i.addEventListener;i.addEventListener=function(e,i){if(e!==t)return r.apply(this,arguments);const o=e=>{const t=n(e);t&&(i.handleEvent?i.handleEvent(t):i(t))};return this._eventMap=this._eventMap||{},this._eventMap[t]||(this._eventMap[t]=new Map),this._eventMap[t].set(i,o),r.apply(this,[e,o])};const o=i.removeEventListener;i.removeEventListener=function(e,n){if(e!==t||!this._eventMap||!this._eventMap[t])return o.apply(this,arguments);if(!this._eventMap[t].has(n))return o.apply(this,arguments);const i=this._eventMap[t].get(n);return this._eventMap[t].delete(n),0===this._eventMap[t].size&&delete this._eventMap[t],0===Object.keys(this._eventMap).length&&delete this._eventMap,o.apply(this,[e,i])},Object.defineProperty(i,"on"+t,{get(){return this["_on"+t]},set(e){this["_on"+t]&&(this.removeEventListener(t,this["_on"+t]),delete this["_on"+t]),e&&this.addEventListener(t,this["_on"+t]=e)},enumerable:!0,configurable:!0})}function O(e){return"boolean"!=typeof e?new Error("Argument type: "+typeof e+". Please use a boolean."):(k=e,e?"adapter.js logging disabled":"adapter.js logging enabled")}function D(e){return"boolean"!=typeof e?new Error("Argument type: "+typeof e+". Please use a boolean."):(I=!e,"adapter.js deprecation warnings "+(e?"disabled":"enabled"))}function M(){if("object"==typeof window){if(k)return;"undefined"!=typeof console&&console.log}}function L(e,t){}function x(e){return"[object Object]"===Object.prototype.toString.call(e)}function N(e){return x(e)?Object.keys(e).reduce(function(t,n){const i=x(e[n]),r=i?N(e[n]):e[n],o=i&&!Object.keys(r).length;return void 0===r||o?t:Object.assign(t,{[n]:r})},{}):e}function j(e,t,n){t&&!n.has(t.id)&&(n.set(t.id,t),Object.keys(t).forEach(i=>{i.endsWith("Id")?j(e,e.get(t[i]),n):i.endsWith("Ids")&&t[i].forEach(t=>{j(e,e.get(t),n)})}))}function F(e,t,n){const i=n?"outbound-rtp":"inbound-rtp",r=new Map;if(null===t)return r;const o=[];return e.forEach(e=>{"track"===e.type&&e.trackIdentifier===t.id&&o.push(e)}),o.forEach(t=>{e.forEach(n=>{n.type===i&&n.trackId===t.id&&j(e,n,r)})}),r}const U=M;function G(e,t){const n=e&&e.navigator;if(!n.mediaDevices)return;const i=function(e){if("object"!=typeof e||e.mandatory||e.optional)return e;const t={};return Object.keys(e).forEach(n=>{if("require"===n||"advanced"===n||"mediaSource"===n)return;const i="object"==typeof e[n]?e[n]:{ideal:e[n]};void 0!==i.exact&&"number"==typeof i.exact&&(i.min=i.max=i.exact);const r=function(e,t){return e?e+t.charAt(0).toUpperCase()+t.slice(1):"deviceId"===t?"sourceId":t};if(void 0!==i.ideal){t.optional=t.optional||[];let e={};"number"==typeof i.ideal?(e[r("min",n)]=i.ideal,t.optional.push(e),e={},e[r("max",n)]=i.ideal,t.optional.push(e)):(e[r("",n)]=i.ideal,t.optional.push(e))}void 0!==i.exact&&"number"!=typeof i.exact?(t.mandatory=t.mandatory||{},t.mandatory[r("",n)]=i.exact):["min","max"].forEach(e=>{void 0!==i[e]&&(t.mandatory=t.mandatory||{},t.mandatory[r(e,n)]=i[e])})}),e.advanced&&(t.optional=(t.optional||[]).concat(e.advanced)),t},r=function(e,r){if(t.version>=61)return r(e);if((e=JSON.parse(JSON.stringify(e)))&&"object"==typeof e.audio){const t=function(e,t,n){t in e&&!(n in e)&&(e[n]=e[t],delete e[t])};t((e=JSON.parse(JSON.stringify(e))).audio,"autoGainControl","googAutoGainControl"),t(e.audio,"noiseSuppression","googNoiseSuppression"),e.audio=i(e.audio)}if(e&&"object"==typeof e.video){let o=e.video.facingMode;o=o&&("object"==typeof o?o:{ideal:o});const s=t.version<66;if(o&&("user"===o.exact||"environment"===o.exact||"user"===o.ideal||"environment"===o.ideal)&&(!n.mediaDevices.getSupportedConstraints||!n.mediaDevices.getSupportedConstraints().facingMode||s)){let t;if(delete e.video.facingMode,"environment"===o.exact||"environment"===o.ideal?t=["back","rear"]:"user"!==o.exact&&"user"!==o.ideal||(t=["front"]),t)return n.mediaDevices.enumerateDevices().then(n=>{let s=(n=n.filter(e=>"videoinput"===e.kind)).find(e=>t.some(t=>e.label.toLowerCase().includes(t)));return!s&&n.length&&t.includes("back")&&(s=n[n.length-1]),s&&(e.video.deviceId=o.exact?{exact:s.deviceId}:{ideal:s.deviceId}),e.video=i(e.video),U("chrome: "+JSON.stringify(e)),r(e)})}e.video=i(e.video)}return U("chrome: "+JSON.stringify(e)),r(e)},o=function(e){return t.version>=64?e:{name:{PermissionDeniedError:"NotAllowedError",PermissionDismissedError:"NotAllowedError",InvalidStateError:"NotAllowedError",DevicesNotFoundError:"NotFoundError",ConstraintNotSatisfiedError:"OverconstrainedError",TrackStartError:"NotReadableError",MediaDeviceFailedDueToShutdown:"NotAllowedError",MediaDeviceKillSwitchOn:"NotAllowedError",TabCaptureError:"AbortError",ScreenCaptureError:"AbortError",DeviceCaptureError:"AbortError"}[e.name]||e.name,message:e.message,constraint:e.constraint||e.constraintName,toString(){return this.name+(this.message&&": ")+this.message}}};if(n.getUserMedia=function(e,t,i){r(e,e=>{n.webkitGetUserMedia(e,t,e=>{i&&i(o(e))})})}.bind(n),n.mediaDevices.getUserMedia){const e=n.mediaDevices.getUserMedia.bind(n.mediaDevices);n.mediaDevices.getUserMedia=function(t){return r(t,t=>e(t).then(e=>{if(t.audio&&!e.getAudioTracks().length||t.video&&!e.getVideoTracks().length)throw e.getTracks().forEach(e=>{e.stop()}),new DOMException("","NotFoundError");return e},e=>Promise.reject(o(e))))}}}function K(e){e.MediaStream=e.MediaStream||e.webkitMediaStream}function V(e){if("object"==typeof e&&e.RTCPeerConnection&&!("ontrack"in e.RTCPeerConnection.prototype)){Object.defineProperty(e.RTCPeerConnection.prototype,"ontrack",{get(){return this._ontrack},set(e){this._ontrack&&this.removeEventListener("track",this._ontrack),this.addEventListener("track",this._ontrack=e)},enumerable:!0,configurable:!0});const t=e.RTCPeerConnection.prototype.setRemoteDescription;e.RTCPeerConnection.prototype.setRemoteDescription=function(){return this._ontrackpoly||(this._ontrackpoly=t=>{t.stream.addEventListener("addtrack",n=>{let i;i=e.RTCPeerConnection.prototype.getReceivers?this.getReceivers().find(e=>e.track&&e.track.id===n.track.id):{track:n.track};const r=new Event("track");r.track=n.track,r.receiver=i,r.transceiver={receiver:i},r.streams=[t.stream],this.dispatchEvent(r)}),t.stream.getTracks().forEach(n=>{let i;i=e.RTCPeerConnection.prototype.getReceivers?this.getReceivers().find(e=>e.track&&e.track.id===n.id):{track:n};const r=new Event("track");r.track=n,r.receiver=i,r.transceiver={receiver:i},r.streams=[t.stream],this.dispatchEvent(r)})},this.addEventListener("addstream",this._ontrackpoly)),t.apply(this,arguments)}}else _(e,"track",e=>(e.transceiver||Object.defineProperty(e,"transceiver",{value:{receiver:e.receiver}}),e))}function z(e){if("object"==typeof e&&e.RTCPeerConnection&&!("getSenders"in e.RTCPeerConnection.prototype)&&"createDTMFSender"in e.RTCPeerConnection.prototype){const t=function(e,t){return{track:t,get dtmf(){return void 0===this._dtmf&&("audio"===t.kind?this._dtmf=e.createDTMFSender(t):this._dtmf=null),this._dtmf},_pc:e}};if(!e.RTCPeerConnection.prototype.getSenders){e.RTCPeerConnection.prototype.getSenders=function(){return this._senders=this._senders||[],this._senders.slice()};const n=e.RTCPeerConnection.prototype.addTrack;e.RTCPeerConnection.prototype.addTrack=function(e,i){let r=n.apply(this,arguments);return r||(r=t(this,e),this._senders.push(r)),r};const i=e.RTCPeerConnection.prototype.removeTrack;e.RTCPeerConnection.prototype.removeTrack=function(e){i.apply(this,arguments);const t=this._senders.indexOf(e);-1!==t&&this._senders.splice(t,1)}}const n=e.RTCPeerConnection.prototype.addStream;e.RTCPeerConnection.prototype.addStream=function(e){this._senders=this._senders||[],n.apply(this,[e]),e.getTracks().forEach(e=>{this._senders.push(t(this,e))})};const i=e.RTCPeerConnection.prototype.removeStream;e.RTCPeerConnection.prototype.removeStream=function(e){this._senders=this._senders||[],i.apply(this,[e]),e.getTracks().forEach(e=>{const t=this._senders.find(t=>t.track===e);t&&this._senders.splice(this._senders.indexOf(t),1)})}}else if("object"==typeof e&&e.RTCPeerConnection&&"getSenders"in e.RTCPeerConnection.prototype&&"createDTMFSender"in e.RTCPeerConnection.prototype&&e.RTCRtpSender&&!("dtmf"in e.RTCRtpSender.prototype)){const t=e.RTCPeerConnection.prototype.getSenders;e.RTCPeerConnection.prototype.getSenders=function(){const e=t.apply(this,[]);return e.forEach(e=>e._pc=this),e},Object.defineProperty(e.RTCRtpSender.prototype,"dtmf",{get(){return void 0===this._dtmf&&("audio"===this.track.kind?this._dtmf=this._pc.createDTMFSender(this.track):this._dtmf=null),this._dtmf}})}}function W(e){if(!("object"==typeof e&&e.RTCPeerConnection&&e.RTCRtpSender&&e.RTCRtpReceiver))return;if(!("getStats"in e.RTCRtpSender.prototype)){const t=e.RTCPeerConnection.prototype.getSenders;t&&(e.RTCPeerConnection.prototype.getSenders=function(){const e=t.apply(this,[]);return e.forEach(e=>e._pc=this),e});const n=e.RTCPeerConnection.prototype.addTrack;n&&(e.RTCPeerConnection.prototype.addTrack=function(){const e=n.apply(this,arguments);return e._pc=this,e}),e.RTCRtpSender.prototype.getStats=function(){const e=this;return this._pc.getStats().then(t=>
18
18
  /* Note: this will include stats of all senders that
19
19
  * send a track with the same id as sender.track as
20
20
  * it is not possible to identify the RTCRtpSender.
21
- */U(t,e.track,!0))}}if(!("getStats"in e.RTCRtpReceiver.prototype)){const t=e.RTCPeerConnection.prototype.getReceivers;t&&(e.RTCPeerConnection.prototype.getReceivers=function(){const e=t.apply(this,[]);return e.forEach(e=>e._pc=this),e}),_(e,"track",e=>(e.receiver._pc=e.srcElement,e)),e.RTCRtpReceiver.prototype.getStats=function(){const e=this;return this._pc.getStats().then(t=>U(t,e.track,!1))}}if(!("getStats"in e.RTCRtpSender.prototype)||!("getStats"in e.RTCRtpReceiver.prototype))return;const t=e.RTCPeerConnection.prototype.getStats;e.RTCPeerConnection.prototype.getStats=function(){if(arguments.length>0&&arguments[0]instanceof e.MediaStreamTrack){const e=arguments[0];let t,n,i;return this.getSenders().forEach(n=>{n.track===e&&(t?i=!0:t=n)}),this.getReceivers().forEach(t=>(t.track===e&&(n?i=!0:n=t),t.track===e)),i||t&&n?Promise.reject(new DOMException("There are more than one sender or receiver for the track.","InvalidAccessError")):t?t.getStats():n?n.getStats():Promise.reject(new DOMException("There is no sender or receiver for the track.","InvalidAccessError"))}return t.apply(this,arguments)}}function J(e){e.RTCPeerConnection.prototype.getLocalStreams=function(){return this._shimmedLocalStreams=this._shimmedLocalStreams||{},Object.keys(this._shimmedLocalStreams).map(e=>this._shimmedLocalStreams[e][0])};const t=e.RTCPeerConnection.prototype.addTrack;e.RTCPeerConnection.prototype.addTrack=function(e,n){if(!n)return t.apply(this,arguments);this._shimmedLocalStreams=this._shimmedLocalStreams||{};const i=t.apply(this,arguments);return this._shimmedLocalStreams[n.id]?-1===this._shimmedLocalStreams[n.id].indexOf(i)&&this._shimmedLocalStreams[n.id].push(i):this._shimmedLocalStreams[n.id]=[n,i],i};const n=e.RTCPeerConnection.prototype.addStream;e.RTCPeerConnection.prototype.addStream=function(e){this._shimmedLocalStreams=this._shimmedLocalStreams||{},e.getTracks().forEach(e=>{if(this.getSenders().find(t=>t.track===e))throw new DOMException("Track already exists.","InvalidAccessError")});const t=this.getSenders();n.apply(this,arguments);const i=this.getSenders().filter(e=>-1===t.indexOf(e));this._shimmedLocalStreams[e.id]=[e].concat(i)};const i=e.RTCPeerConnection.prototype.removeStream;e.RTCPeerConnection.prototype.removeStream=function(e){return this._shimmedLocalStreams=this._shimmedLocalStreams||{},delete this._shimmedLocalStreams[e.id],i.apply(this,arguments)};const r=e.RTCPeerConnection.prototype.removeTrack;e.RTCPeerConnection.prototype.removeTrack=function(e){return this._shimmedLocalStreams=this._shimmedLocalStreams||{},e&&Object.keys(this._shimmedLocalStreams).forEach(t=>{const n=this._shimmedLocalStreams[t].indexOf(e);-1!==n&&this._shimmedLocalStreams[t].splice(n,1),1===this._shimmedLocalStreams[t].length&&delete this._shimmedLocalStreams[t]}),r.apply(this,arguments)}}function B(e,t){if(!e.RTCPeerConnection)return;if(e.RTCPeerConnection.prototype.addTrack&&t.version>=65)return J(e);const n=e.RTCPeerConnection.prototype.getLocalStreams;e.RTCPeerConnection.prototype.getLocalStreams=function(){const e=n.apply(this);return this._reverseStreams=this._reverseStreams||{},e.map(e=>this._reverseStreams[e.id])};const i=e.RTCPeerConnection.prototype.addStream;e.RTCPeerConnection.prototype.addStream=function(t){if(this._streams=this._streams||{},this._reverseStreams=this._reverseStreams||{},t.getTracks().forEach(e=>{if(this.getSenders().find(t=>t.track===e))throw new DOMException("Track already exists.","InvalidAccessError")}),!this._reverseStreams[t.id]){const n=new e.MediaStream(t.getTracks());this._streams[t.id]=n,this._reverseStreams[n.id]=t,t=n}i.apply(this,[t])};const r=e.RTCPeerConnection.prototype.removeStream;function o(e,t){let n=t.sdp;return Object.keys(e._reverseStreams||[]).forEach(t=>{const i=e._reverseStreams[t],r=e._streams[i.id];n=n.replace(new RegExp(r.id,"g"),i.id)}),new RTCSessionDescription({type:t.type,sdp:n})}e.RTCPeerConnection.prototype.removeStream=function(e){this._streams=this._streams||{},this._reverseStreams=this._reverseStreams||{},r.apply(this,[this._streams[e.id]||e]),delete this._reverseStreams[this._streams[e.id]?this._streams[e.id].id:e.id],delete this._streams[e.id]},e.RTCPeerConnection.prototype.addTrack=function(t,n){if("closed"===this.signalingState)throw new DOMException("The RTCPeerConnection's signalingState is 'closed'.","InvalidStateError");const i=[].slice.call(arguments,1);if(1!==i.length||!i[0].getTracks().find(e=>e===t))throw new DOMException("The adapter.js addTrack polyfill only supports a single stream which is associated with the specified track.","NotSupportedError");if(this.getSenders().find(e=>e.track===t))throw new DOMException("Track already exists.","InvalidAccessError");this._streams=this._streams||{},this._reverseStreams=this._reverseStreams||{};const r=this._streams[n.id];if(r)r.addTrack(t),Promise.resolve().then(()=>{this.dispatchEvent(new Event("negotiationneeded"))});else{const i=new e.MediaStream([t]);this._streams[n.id]=i,this._reverseStreams[i.id]=n,this.addStream(i)}return this.getSenders().find(e=>e.track===t)},["createOffer","createAnswer"].forEach(function(t){const n=e.RTCPeerConnection.prototype[t],i={[t](){const e=arguments;return arguments.length&&"function"==typeof arguments[0]?n.apply(this,[t=>{const n=o(this,t);e[0].apply(null,[n])},t=>{e[1]&&e[1].apply(null,t)},arguments[2]]):n.apply(this,arguments).then(e=>o(this,e))}};e.RTCPeerConnection.prototype[t]=i[t]});const s=e.RTCPeerConnection.prototype.setLocalDescription;e.RTCPeerConnection.prototype.setLocalDescription=function(){return arguments.length&&arguments[0].type?(arguments[0]=function(e,t){let n=t.sdp;return Object.keys(e._reverseStreams||[]).forEach(t=>{const i=e._reverseStreams[t],r=e._streams[i.id];n=n.replace(new RegExp(i.id,"g"),r.id)}),new RTCSessionDescription({type:t.type,sdp:n})}(this,arguments[0]),s.apply(this,arguments)):s.apply(this,arguments)};const a=Object.getOwnPropertyDescriptor(e.RTCPeerConnection.prototype,"localDescription");Object.defineProperty(e.RTCPeerConnection.prototype,"localDescription",{get(){const e=a.get.apply(this);return""===e.type?e:o(this,e)}}),e.RTCPeerConnection.prototype.removeTrack=function(e){if("closed"===this.signalingState)throw new DOMException("The RTCPeerConnection's signalingState is 'closed'.","InvalidStateError");if(!e._pc)throw new DOMException("Argument 1 of RTCPeerConnection.removeTrack does not implement interface RTCRtpSender.","TypeError");if(!(e._pc===this))throw new DOMException("Sender was not created by this connection.","InvalidAccessError");let t;this._streams=this._streams||{},Object.keys(this._streams).forEach(n=>{this._streams[n].getTracks().find(t=>e.track===t)&&(t=this._streams[n])}),t&&(1===t.getTracks().length?this.removeStream(this._reverseStreams[t.id]):t.removeTrack(e.track),this.dispatchEvent(new Event("negotiationneeded")))}}function H(e,t){!e.RTCPeerConnection&&e.webkitRTCPeerConnection&&(e.RTCPeerConnection=e.webkitRTCPeerConnection),e.RTCPeerConnection&&t.version<53&&["setLocalDescription","setRemoteDescription","addIceCandidate"].forEach(function(t){const n=e.RTCPeerConnection.prototype[t],i={[t](){return arguments[0]=new("addIceCandidate"===t?e.RTCIceCandidate:e.RTCSessionDescription)(arguments[0]),n.apply(this,arguments)}};e.RTCPeerConnection.prototype[t]=i[t]})}function q(e,t){_(e,"negotiationneeded",e=>{const n=e.target;if(!(t.version<72||n.getConfiguration&&"plan-b"===n.getConfiguration().sdpSemantics)||"stable"===n.signalingState)return e})}const $=Object.freeze(Object.defineProperty({__proto__:null,fixNegotiationNeeded:q,shimAddTrackRemoveTrack:B,shimAddTrackRemoveTrackWithNative:J,shimGetSendersWithDtmf:z,shimGetUserMedia:G,shimMediaStream:K,shimOnTrack:V,shimPeerConnection:H,shimSenderReceiverGetStats:W},Symbol.toStringTag,{value:"Module"}));function X(e,t){const n=e&&e.navigator,i=e&&e.MediaStreamTrack;if(n.getUserMedia=function(e,t,i){n.mediaDevices.getUserMedia(e).then(t,i)},!(t.version>55&&"autoGainControl"in n.mediaDevices.getSupportedConstraints())){const e=function(e,t,n){t in e&&!(n in e)&&(e[n]=e[t],delete e[t])},t=n.mediaDevices.getUserMedia.bind(n.mediaDevices);if(n.mediaDevices.getUserMedia=function(n){return"object"==typeof n&&"object"==typeof n.audio&&(n=JSON.parse(JSON.stringify(n)),e(n.audio,"autoGainControl","mozAutoGainControl"),e(n.audio,"noiseSuppression","mozNoiseSuppression")),t(n)},i&&i.prototype.getSettings){const t=i.prototype.getSettings;i.prototype.getSettings=function(){const n=t.apply(this,arguments);return e(n,"mozAutoGainControl","autoGainControl"),e(n,"mozNoiseSuppression","noiseSuppression"),n}}if(i&&i.prototype.applyConstraints){const t=i.prototype.applyConstraints;i.prototype.applyConstraints=function(n){return"audio"===this.kind&&"object"==typeof n&&(n=JSON.parse(JSON.stringify(n)),e(n,"autoGainControl","mozAutoGainControl"),e(n,"noiseSuppression","mozNoiseSuppression")),t.apply(this,[n])}}}}function Y(e){"object"==typeof e&&e.RTCTrackEvent&&"receiver"in e.RTCTrackEvent.prototype&&!("transceiver"in e.RTCTrackEvent.prototype)&&Object.defineProperty(e.RTCTrackEvent.prototype,"transceiver",{get(){return{receiver:this.receiver}}})}function Q(e,t){if("object"!=typeof e||!e.RTCPeerConnection&&!e.mozRTCPeerConnection)return;!e.RTCPeerConnection&&e.mozRTCPeerConnection&&(e.RTCPeerConnection=e.mozRTCPeerConnection),t.version<53&&["setLocalDescription","setRemoteDescription","addIceCandidate"].forEach(function(t){const n=e.RTCPeerConnection.prototype[t],i={[t](){return arguments[0]=new("addIceCandidate"===t?e.RTCIceCandidate:e.RTCSessionDescription)(arguments[0]),n.apply(this,arguments)}};e.RTCPeerConnection.prototype[t]=i[t]});const n={inboundrtp:"inbound-rtp",outboundrtp:"outbound-rtp",candidatepair:"candidate-pair",localcandidate:"local-candidate",remotecandidate:"remote-candidate"},i=e.RTCPeerConnection.prototype.getStats;e.RTCPeerConnection.prototype.getStats=function(){const[e,r,o]=arguments;return i.apply(this,[e||null]).then(e=>{if(t.version<53&&!r)try{e.forEach(e=>{e.type=n[e.type]||e.type})}catch(i){if("TypeError"!==i.name)throw i;e.forEach((t,i)=>{e.set(i,Object.assign({},t,{type:n[t.type]||t.type}))})}return e}).then(r,o)}}function Z(e){if("object"!=typeof e||!e.RTCPeerConnection||!e.RTCRtpSender)return;if(e.RTCRtpSender&&"getStats"in e.RTCRtpSender.prototype)return;const t=e.RTCPeerConnection.prototype.getSenders;t&&(e.RTCPeerConnection.prototype.getSenders=function(){const e=t.apply(this,[]);return e.forEach(e=>e._pc=this),e});const n=e.RTCPeerConnection.prototype.addTrack;n&&(e.RTCPeerConnection.prototype.addTrack=function(){const e=n.apply(this,arguments);return e._pc=this,e}),e.RTCRtpSender.prototype.getStats=function(){return this.track?this._pc.getStats(this.track):Promise.resolve(new Map)}}function ee(e){if("object"!=typeof e||!e.RTCPeerConnection||!e.RTCRtpSender)return;if(e.RTCRtpSender&&"getStats"in e.RTCRtpReceiver.prototype)return;const t=e.RTCPeerConnection.prototype.getReceivers;t&&(e.RTCPeerConnection.prototype.getReceivers=function(){const e=t.apply(this,[]);return e.forEach(e=>e._pc=this),e}),_(e,"track",e=>(e.receiver._pc=e.srcElement,e)),e.RTCRtpReceiver.prototype.getStats=function(){return this._pc.getStats(this.track)}}function te(e){e.RTCPeerConnection&&!("removeStream"in e.RTCPeerConnection.prototype)&&(e.RTCPeerConnection.prototype.removeStream=function(e){this.getSenders().forEach(t=>{t.track&&e.getTracks().includes(t.track)&&this.removeTrack(t)})})}function ne(e){e.DataChannel&&!e.RTCDataChannel&&(e.RTCDataChannel=e.DataChannel)}function ie(e){if("object"!=typeof e||!e.RTCPeerConnection)return;const t=e.RTCPeerConnection.prototype.addTransceiver;t&&(e.RTCPeerConnection.prototype.addTransceiver=function(){this.setParametersPromises=[];let e=arguments[1]&&arguments[1].sendEncodings;void 0===e&&(e=[]),e=[...e];const n=e.length>0;n&&e.forEach(e=>{if("rid"in e){if(!/^[a-z0-9]{0,16}$/i.test(e.rid))throw new TypeError("Invalid RID value provided.")}if("scaleResolutionDownBy"in e&&!(parseFloat(e.scaleResolutionDownBy)>=1))throw new RangeError("scale_resolution_down_by must be >= 1.0");if("maxFramerate"in e&&!(parseFloat(e.maxFramerate)>=0))throw new RangeError("max_framerate must be >= 0.0")});const i=t.apply(this,arguments);if(n){const{sender:t}=i,n=t.getParameters();(!("encodings"in n)||// Avoid being fooled by patched getParameters() below.
21
+ */F(t,e.track,!0))}}if(!("getStats"in e.RTCRtpReceiver.prototype)){const t=e.RTCPeerConnection.prototype.getReceivers;t&&(e.RTCPeerConnection.prototype.getReceivers=function(){const e=t.apply(this,[]);return e.forEach(e=>e._pc=this),e}),_(e,"track",e=>(e.receiver._pc=e.srcElement,e)),e.RTCRtpReceiver.prototype.getStats=function(){const e=this;return this._pc.getStats().then(t=>F(t,e.track,!1))}}if(!("getStats"in e.RTCRtpSender.prototype)||!("getStats"in e.RTCRtpReceiver.prototype))return;const t=e.RTCPeerConnection.prototype.getStats;e.RTCPeerConnection.prototype.getStats=function(){if(arguments.length>0&&arguments[0]instanceof e.MediaStreamTrack){const e=arguments[0];let t,n,i;return this.getSenders().forEach(n=>{n.track===e&&(t?i=!0:t=n)}),this.getReceivers().forEach(t=>(t.track===e&&(n?i=!0:n=t),t.track===e)),i||t&&n?Promise.reject(new DOMException("There are more than one sender or receiver for the track.","InvalidAccessError")):t?t.getStats():n?n.getStats():Promise.reject(new DOMException("There is no sender or receiver for the track.","InvalidAccessError"))}return t.apply(this,arguments)}}function B(e){e.RTCPeerConnection.prototype.getLocalStreams=function(){return this._shimmedLocalStreams=this._shimmedLocalStreams||{},Object.keys(this._shimmedLocalStreams).map(e=>this._shimmedLocalStreams[e][0])};const t=e.RTCPeerConnection.prototype.addTrack;e.RTCPeerConnection.prototype.addTrack=function(e,n){if(!n)return t.apply(this,arguments);this._shimmedLocalStreams=this._shimmedLocalStreams||{};const i=t.apply(this,arguments);return this._shimmedLocalStreams[n.id]?-1===this._shimmedLocalStreams[n.id].indexOf(i)&&this._shimmedLocalStreams[n.id].push(i):this._shimmedLocalStreams[n.id]=[n,i],i};const n=e.RTCPeerConnection.prototype.addStream;e.RTCPeerConnection.prototype.addStream=function(e){this._shimmedLocalStreams=this._shimmedLocalStreams||{},e.getTracks().forEach(e=>{if(this.getSenders().find(t=>t.track===e))throw new DOMException("Track already exists.","InvalidAccessError")});const t=this.getSenders();n.apply(this,arguments);const i=this.getSenders().filter(e=>-1===t.indexOf(e));this._shimmedLocalStreams[e.id]=[e].concat(i)};const i=e.RTCPeerConnection.prototype.removeStream;e.RTCPeerConnection.prototype.removeStream=function(e){return this._shimmedLocalStreams=this._shimmedLocalStreams||{},delete this._shimmedLocalStreams[e.id],i.apply(this,arguments)};const r=e.RTCPeerConnection.prototype.removeTrack;e.RTCPeerConnection.prototype.removeTrack=function(e){return this._shimmedLocalStreams=this._shimmedLocalStreams||{},e&&Object.keys(this._shimmedLocalStreams).forEach(t=>{const n=this._shimmedLocalStreams[t].indexOf(e);-1!==n&&this._shimmedLocalStreams[t].splice(n,1),1===this._shimmedLocalStreams[t].length&&delete this._shimmedLocalStreams[t]}),r.apply(this,arguments)}}function J(e,t){if(!e.RTCPeerConnection)return;if(e.RTCPeerConnection.prototype.addTrack&&t.version>=65)return B(e);const n=e.RTCPeerConnection.prototype.getLocalStreams;e.RTCPeerConnection.prototype.getLocalStreams=function(){const e=n.apply(this);return this._reverseStreams=this._reverseStreams||{},e.map(e=>this._reverseStreams[e.id])};const i=e.RTCPeerConnection.prototype.addStream;e.RTCPeerConnection.prototype.addStream=function(t){if(this._streams=this._streams||{},this._reverseStreams=this._reverseStreams||{},t.getTracks().forEach(e=>{if(this.getSenders().find(t=>t.track===e))throw new DOMException("Track already exists.","InvalidAccessError")}),!this._reverseStreams[t.id]){const n=new e.MediaStream(t.getTracks());this._streams[t.id]=n,this._reverseStreams[n.id]=t,t=n}i.apply(this,[t])};const r=e.RTCPeerConnection.prototype.removeStream;function o(e,t){let n=t.sdp;return Object.keys(e._reverseStreams||[]).forEach(t=>{const i=e._reverseStreams[t],r=e._streams[i.id];n=n.replace(new RegExp(r.id,"g"),i.id)}),new RTCSessionDescription({type:t.type,sdp:n})}e.RTCPeerConnection.prototype.removeStream=function(e){this._streams=this._streams||{},this._reverseStreams=this._reverseStreams||{},r.apply(this,[this._streams[e.id]||e]),delete this._reverseStreams[this._streams[e.id]?this._streams[e.id].id:e.id],delete this._streams[e.id]},e.RTCPeerConnection.prototype.addTrack=function(t,n){if("closed"===this.signalingState)throw new DOMException("The RTCPeerConnection's signalingState is 'closed'.","InvalidStateError");const i=[].slice.call(arguments,1);if(1!==i.length||!i[0].getTracks().find(e=>e===t))throw new DOMException("The adapter.js addTrack polyfill only supports a single stream which is associated with the specified track.","NotSupportedError");if(this.getSenders().find(e=>e.track===t))throw new DOMException("Track already exists.","InvalidAccessError");this._streams=this._streams||{},this._reverseStreams=this._reverseStreams||{};const r=this._streams[n.id];if(r)r.addTrack(t),Promise.resolve().then(()=>{this.dispatchEvent(new Event("negotiationneeded"))});else{const i=new e.MediaStream([t]);this._streams[n.id]=i,this._reverseStreams[i.id]=n,this.addStream(i)}return this.getSenders().find(e=>e.track===t)},["createOffer","createAnswer"].forEach(function(t){const n=e.RTCPeerConnection.prototype[t],i={[t](){const e=arguments;return arguments.length&&"function"==typeof arguments[0]?n.apply(this,[t=>{const n=o(this,t);e[0].apply(null,[n])},t=>{e[1]&&e[1].apply(null,t)},arguments[2]]):n.apply(this,arguments).then(e=>o(this,e))}};e.RTCPeerConnection.prototype[t]=i[t]});const s=e.RTCPeerConnection.prototype.setLocalDescription;e.RTCPeerConnection.prototype.setLocalDescription=function(){return arguments.length&&arguments[0].type?(arguments[0]=function(e,t){let n=t.sdp;return Object.keys(e._reverseStreams||[]).forEach(t=>{const i=e._reverseStreams[t],r=e._streams[i.id];n=n.replace(new RegExp(i.id,"g"),r.id)}),new RTCSessionDescription({type:t.type,sdp:n})}(this,arguments[0]),s.apply(this,arguments)):s.apply(this,arguments)};const a=Object.getOwnPropertyDescriptor(e.RTCPeerConnection.prototype,"localDescription");Object.defineProperty(e.RTCPeerConnection.prototype,"localDescription",{get(){const e=a.get.apply(this);return""===e.type?e:o(this,e)}}),e.RTCPeerConnection.prototype.removeTrack=function(e){if("closed"===this.signalingState)throw new DOMException("The RTCPeerConnection's signalingState is 'closed'.","InvalidStateError");if(!e._pc)throw new DOMException("Argument 1 of RTCPeerConnection.removeTrack does not implement interface RTCRtpSender.","TypeError");if(!(e._pc===this))throw new DOMException("Sender was not created by this connection.","InvalidAccessError");let t;this._streams=this._streams||{},Object.keys(this._streams).forEach(n=>{this._streams[n].getTracks().find(t=>e.track===t)&&(t=this._streams[n])}),t&&(1===t.getTracks().length?this.removeStream(this._reverseStreams[t.id]):t.removeTrack(e.track),this.dispatchEvent(new Event("negotiationneeded")))}}function H(e,t){!e.RTCPeerConnection&&e.webkitRTCPeerConnection&&(e.RTCPeerConnection=e.webkitRTCPeerConnection),e.RTCPeerConnection&&t.version<53&&["setLocalDescription","setRemoteDescription","addIceCandidate"].forEach(function(t){const n=e.RTCPeerConnection.prototype[t],i={[t](){return arguments[0]=new("addIceCandidate"===t?e.RTCIceCandidate:e.RTCSessionDescription)(arguments[0]),n.apply(this,arguments)}};e.RTCPeerConnection.prototype[t]=i[t]})}function $(e,t){_(e,"negotiationneeded",e=>{const n=e.target;if(!(t.version<72||n.getConfiguration&&"plan-b"===n.getConfiguration().sdpSemantics)||"stable"===n.signalingState)return e})}const q=Object.freeze(Object.defineProperty({__proto__:null,fixNegotiationNeeded:$,shimAddTrackRemoveTrack:J,shimAddTrackRemoveTrackWithNative:B,shimGetSendersWithDtmf:z,shimGetUserMedia:G,shimMediaStream:K,shimOnTrack:V,shimPeerConnection:H,shimSenderReceiverGetStats:W},Symbol.toStringTag,{value:"Module"}));function X(e,t){const n=e&&e.navigator,i=e&&e.MediaStreamTrack;if(n.getUserMedia=function(e,t,i){n.mediaDevices.getUserMedia(e).then(t,i)},!(t.version>55&&"autoGainControl"in n.mediaDevices.getSupportedConstraints())){const e=function(e,t,n){t in e&&!(n in e)&&(e[n]=e[t],delete e[t])},t=n.mediaDevices.getUserMedia.bind(n.mediaDevices);if(n.mediaDevices.getUserMedia=function(n){return"object"==typeof n&&"object"==typeof n.audio&&(n=JSON.parse(JSON.stringify(n)),e(n.audio,"autoGainControl","mozAutoGainControl"),e(n.audio,"noiseSuppression","mozNoiseSuppression")),t(n)},i&&i.prototype.getSettings){const t=i.prototype.getSettings;i.prototype.getSettings=function(){const n=t.apply(this,arguments);return e(n,"mozAutoGainControl","autoGainControl"),e(n,"mozNoiseSuppression","noiseSuppression"),n}}if(i&&i.prototype.applyConstraints){const t=i.prototype.applyConstraints;i.prototype.applyConstraints=function(n){return"audio"===this.kind&&"object"==typeof n&&(n=JSON.parse(JSON.stringify(n)),e(n,"autoGainControl","mozAutoGainControl"),e(n,"noiseSuppression","mozNoiseSuppression")),t.apply(this,[n])}}}}function Y(e){"object"==typeof e&&e.RTCTrackEvent&&"receiver"in e.RTCTrackEvent.prototype&&!("transceiver"in e.RTCTrackEvent.prototype)&&Object.defineProperty(e.RTCTrackEvent.prototype,"transceiver",{get(){return{receiver:this.receiver}}})}function Q(e,t){if("object"!=typeof e||!e.RTCPeerConnection&&!e.mozRTCPeerConnection)return;!e.RTCPeerConnection&&e.mozRTCPeerConnection&&(e.RTCPeerConnection=e.mozRTCPeerConnection),t.version<53&&["setLocalDescription","setRemoteDescription","addIceCandidate"].forEach(function(t){const n=e.RTCPeerConnection.prototype[t],i={[t](){return arguments[0]=new("addIceCandidate"===t?e.RTCIceCandidate:e.RTCSessionDescription)(arguments[0]),n.apply(this,arguments)}};e.RTCPeerConnection.prototype[t]=i[t]});const n={inboundrtp:"inbound-rtp",outboundrtp:"outbound-rtp",candidatepair:"candidate-pair",localcandidate:"local-candidate",remotecandidate:"remote-candidate"},i=e.RTCPeerConnection.prototype.getStats;e.RTCPeerConnection.prototype.getStats=function(){const[e,r,o]=arguments;return i.apply(this,[e||null]).then(e=>{if(t.version<53&&!r)try{e.forEach(e=>{e.type=n[e.type]||e.type})}catch(i){if("TypeError"!==i.name)throw i;e.forEach((t,i)=>{e.set(i,Object.assign({},t,{type:n[t.type]||t.type}))})}return e}).then(r,o)}}function Z(e){if("object"!=typeof e||!e.RTCPeerConnection||!e.RTCRtpSender)return;if(e.RTCRtpSender&&"getStats"in e.RTCRtpSender.prototype)return;const t=e.RTCPeerConnection.prototype.getSenders;t&&(e.RTCPeerConnection.prototype.getSenders=function(){const e=t.apply(this,[]);return e.forEach(e=>e._pc=this),e});const n=e.RTCPeerConnection.prototype.addTrack;n&&(e.RTCPeerConnection.prototype.addTrack=function(){const e=n.apply(this,arguments);return e._pc=this,e}),e.RTCRtpSender.prototype.getStats=function(){return this.track?this._pc.getStats(this.track):Promise.resolve(new Map)}}function ee(e){if("object"!=typeof e||!e.RTCPeerConnection||!e.RTCRtpSender)return;if(e.RTCRtpSender&&"getStats"in e.RTCRtpReceiver.prototype)return;const t=e.RTCPeerConnection.prototype.getReceivers;t&&(e.RTCPeerConnection.prototype.getReceivers=function(){const e=t.apply(this,[]);return e.forEach(e=>e._pc=this),e}),_(e,"track",e=>(e.receiver._pc=e.srcElement,e)),e.RTCRtpReceiver.prototype.getStats=function(){return this._pc.getStats(this.track)}}function te(e){e.RTCPeerConnection&&!("removeStream"in e.RTCPeerConnection.prototype)&&(e.RTCPeerConnection.prototype.removeStream=function(e){this.getSenders().forEach(t=>{t.track&&e.getTracks().includes(t.track)&&this.removeTrack(t)})})}function ne(e){e.DataChannel&&!e.RTCDataChannel&&(e.RTCDataChannel=e.DataChannel)}function ie(e){if("object"!=typeof e||!e.RTCPeerConnection)return;const t=e.RTCPeerConnection.prototype.addTransceiver;t&&(e.RTCPeerConnection.prototype.addTransceiver=function(){this.setParametersPromises=[];let e=arguments[1]&&arguments[1].sendEncodings;void 0===e&&(e=[]),e=[...e];const n=e.length>0;n&&e.forEach(e=>{if("rid"in e){if(!/^[a-z0-9]{0,16}$/i.test(e.rid))throw new TypeError("Invalid RID value provided.")}if("scaleResolutionDownBy"in e&&!(parseFloat(e.scaleResolutionDownBy)>=1))throw new RangeError("scale_resolution_down_by must be >= 1.0");if("maxFramerate"in e&&!(parseFloat(e.maxFramerate)>=0))throw new RangeError("max_framerate must be >= 0.0")});const i=t.apply(this,arguments);if(n){const{sender:t}=i,n=t.getParameters();(!("encodings"in n)||// Avoid being fooled by patched getParameters() below.
22
22
  1===n.encodings.length&&0===Object.keys(n.encodings[0]).length)&&(n.encodings=e,t.sendEncodings=e,this.setParametersPromises.push(t.setParameters(n).then(()=>{delete t.sendEncodings}).catch(()=>{delete t.sendEncodings})))}return i})}function re(e){if("object"!=typeof e||!e.RTCRtpSender)return;const t=e.RTCRtpSender.prototype.getParameters;t&&(e.RTCRtpSender.prototype.getParameters=function(){const e=t.apply(this,arguments);return"encodings"in e||(e.encodings=[].concat(this.sendEncodings||[{}])),e})}function oe(e){if("object"!=typeof e||!e.RTCPeerConnection)return;const t=e.RTCPeerConnection.prototype.createOffer;e.RTCPeerConnection.prototype.createOffer=function(){return this.setParametersPromises&&this.setParametersPromises.length?Promise.all(this.setParametersPromises).then(()=>t.apply(this,arguments)).finally(()=>{this.setParametersPromises=[]}):t.apply(this,arguments)}}function se(e){if("object"!=typeof e||!e.RTCPeerConnection)return;const t=e.RTCPeerConnection.prototype.createAnswer;e.RTCPeerConnection.prototype.createAnswer=function(){return this.setParametersPromises&&this.setParametersPromises.length?Promise.all(this.setParametersPromises).then(()=>t.apply(this,arguments)).finally(()=>{this.setParametersPromises=[]}):t.apply(this,arguments)}}const ae=Object.freeze(Object.defineProperty({__proto__:null,shimAddTransceiver:ie,shimCreateAnswer:se,shimCreateOffer:oe,shimGetDisplayMedia:function(e,t){e.navigator.mediaDevices&&"getDisplayMedia"in e.navigator.mediaDevices||e.navigator.mediaDevices&&(e.navigator.mediaDevices.getDisplayMedia=function(n){if(!n||!n.video){const e=new DOMException("getDisplayMedia without video constraints is undefined");return e.name="NotFoundError",e.code=8,Promise.reject(e)}return!0===n.video?n.video={mediaSource:t}:n.video.mediaSource=t,e.navigator.mediaDevices.getUserMedia(n)})},shimGetParameters:re,shimGetUserMedia:X,shimOnTrack:Y,shimPeerConnection:Q,shimRTCDataChannel:ne,shimReceiverGetStats:ee,shimRemoveStream:te,shimSenderGetStats:Z},Symbol.toStringTag,{value:"Module"}));function ce(e){if("object"==typeof e&&e.RTCPeerConnection){if("getLocalStreams"in e.RTCPeerConnection.prototype||(e.RTCPeerConnection.prototype.getLocalStreams=function(){return this._localStreams||(this._localStreams=[]),this._localStreams}),!("addStream"in e.RTCPeerConnection.prototype)){const t=e.RTCPeerConnection.prototype.addTrack;e.RTCPeerConnection.prototype.addStream=function(e){this._localStreams||(this._localStreams=[]),this._localStreams.includes(e)||this._localStreams.push(e),e.getAudioTracks().forEach(n=>t.call(this,n,e)),e.getVideoTracks().forEach(n=>t.call(this,n,e))},e.RTCPeerConnection.prototype.addTrack=function(e,...n){return n&&n.forEach(e=>{this._localStreams?this._localStreams.includes(e)||this._localStreams.push(e):this._localStreams=[e]}),t.apply(this,arguments)}}"removeStream"in e.RTCPeerConnection.prototype||(e.RTCPeerConnection.prototype.removeStream=function(e){this._localStreams||(this._localStreams=[]);const t=this._localStreams.indexOf(e);if(-1===t)return;this._localStreams.splice(t,1);const n=e.getTracks();this.getSenders().forEach(e=>{n.includes(e.track)&&this.removeTrack(e)})})}}function de(e){if("object"==typeof e&&e.RTCPeerConnection&&("getRemoteStreams"in e.RTCPeerConnection.prototype||(e.RTCPeerConnection.prototype.getRemoteStreams=function(){return this._remoteStreams?this._remoteStreams:[]}),!("onaddstream"in e.RTCPeerConnection.prototype))){Object.defineProperty(e.RTCPeerConnection.prototype,"onaddstream",{get(){return this._onaddstream},set(e){this._onaddstream&&(this.removeEventListener("addstream",this._onaddstream),this.removeEventListener("track",this._onaddstreampoly)),this.addEventListener("addstream",this._onaddstream=e),this.addEventListener("track",this._onaddstreampoly=e=>{e.streams.forEach(e=>{if(this._remoteStreams||(this._remoteStreams=[]),this._remoteStreams.includes(e))return;this._remoteStreams.push(e);const t=new Event("addstream");t.stream=e,this.dispatchEvent(t)})})}});const t=e.RTCPeerConnection.prototype.setRemoteDescription;e.RTCPeerConnection.prototype.setRemoteDescription=function(){const e=this;return this._onaddstreampoly||this.addEventListener("track",this._onaddstreampoly=function(t){t.streams.forEach(t=>{if(e._remoteStreams||(e._remoteStreams=[]),e._remoteStreams.indexOf(t)>=0)return;e._remoteStreams.push(t);const n=new Event("addstream");n.stream=t,e.dispatchEvent(n)})}),t.apply(e,arguments)}}}function le(e){if("object"!=typeof e||!e.RTCPeerConnection)return;const t=e.RTCPeerConnection.prototype,n=t.createOffer,i=t.createAnswer,r=t.setLocalDescription,o=t.setRemoteDescription,s=t.addIceCandidate;t.createOffer=function(e,t){const i=arguments.length>=2?arguments[2]:arguments[0],r=n.apply(this,[i]);return t?(r.then(e,t),Promise.resolve()):r},t.createAnswer=function(e,t){const n=arguments.length>=2?arguments[2]:arguments[0],r=i.apply(this,[n]);return t?(r.then(e,t),Promise.resolve()):r};let a=function(e,t,n){const i=r.apply(this,[e]);return n?(i.then(t,n),Promise.resolve()):i};t.setLocalDescription=a,a=function(e,t,n){const i=o.apply(this,[e]);return n?(i.then(t,n),Promise.resolve()):i},t.setRemoteDescription=a,a=function(e,t,n){const i=s.apply(this,[e]);return n?(i.then(t,n),Promise.resolve()):i},t.addIceCandidate=a}function he(e){const t=e&&e.navigator;if(t.mediaDevices&&t.mediaDevices.getUserMedia){const e=t.mediaDevices,n=e.getUserMedia.bind(e);t.mediaDevices.getUserMedia=e=>n(pe(e))}!t.getUserMedia&&t.mediaDevices&&t.mediaDevices.getUserMedia&&(t.getUserMedia=function(e,n,i){t.mediaDevices.getUserMedia(e).then(n,i)}.bind(t))}function pe(e){return e&&void 0!==e.video?Object.assign({},e,{video:N(e.video)}):e}function ue(e){if(!e.RTCPeerConnection)return;const t=e.RTCPeerConnection;e.RTCPeerConnection=function(e,n){if(e&&e.iceServers){const t=[];for(let n=0;n<e.iceServers.length;n++){let i=e.iceServers[n];void 0===i.urls&&i.url?(L(),i=JSON.parse(JSON.stringify(i)),i.urls=i.url,delete i.url,t.push(i)):t.push(e.iceServers[n])}e.iceServers=t}return new t(e,n)},e.RTCPeerConnection.prototype=t.prototype,"generateCertificate"in t&&Object.defineProperty(e.RTCPeerConnection,"generateCertificate",{get:()=>t.generateCertificate})}function fe(e){"object"==typeof e&&e.RTCTrackEvent&&"receiver"in e.RTCTrackEvent.prototype&&!("transceiver"in e.RTCTrackEvent.prototype)&&Object.defineProperty(e.RTCTrackEvent.prototype,"transceiver",{get(){return{receiver:this.receiver}}})}function me(e){const t=e.RTCPeerConnection.prototype.createOffer;e.RTCPeerConnection.prototype.createOffer=function(e){if(e){void 0!==e.offerToReceiveAudio&&(e.offerToReceiveAudio=!!e.offerToReceiveAudio);const t=this.getTransceivers().find(e=>"audio"===e.receiver.track.kind);!1===e.offerToReceiveAudio&&t?"sendrecv"===t.direction?t.setDirection?t.setDirection("sendonly"):t.direction="sendonly":"recvonly"===t.direction&&(t.setDirection?t.setDirection("inactive"):t.direction="inactive"):!0!==e.offerToReceiveAudio||t||this.addTransceiver("audio",{direction:"recvonly"}),void 0!==e.offerToReceiveVideo&&(e.offerToReceiveVideo=!!e.offerToReceiveVideo);const n=this.getTransceivers().find(e=>"video"===e.receiver.track.kind);!1===e.offerToReceiveVideo&&n?"sendrecv"===n.direction?n.setDirection?n.setDirection("sendonly"):n.direction="sendonly":"recvonly"===n.direction&&(n.setDirection?n.setDirection("inactive"):n.direction="inactive"):!0!==e.offerToReceiveVideo||n||this.addTransceiver("video",{direction:"recvonly"})}return t.apply(this,arguments)}}function ge(e){"object"!=typeof e||e.AudioContext||(e.AudioContext=e.webkitAudioContext)}const Ce=Object.freeze(Object.defineProperty({__proto__:null,shimAudioContext:ge,shimCallbacksAPI:le,shimConstraints:pe,shimCreateOfferLegacy:me,shimGetUserMedia:he,shimLocalStreamsAPI:ce,shimRTCIceServerUrls:ue,shimRemoteStreamsAPI:de,shimTrackEventTransceiver:fe},Symbol.toStringTag,{value:"Module"}));var ye,ve={exports:{}};var Se=(ye||(ye=1,function(e){const t={generateIdentifier:function(){return Math.random().toString(36).substring(2,12)}};t.localCName=t.generateIdentifier(),t.splitLines=function(e){return e.trim().split("\n").map(e=>e.trim())},t.splitSections=function(e){return e.split("\nm=").map((e,t)=>(t>0?"m="+e:e).trim()+"\r\n")},t.getDescription=function(e){const n=t.splitSections(e);return n&&n[0]},t.getMediaSections=function(e){const n=t.splitSections(e);return n.shift(),n},t.matchPrefix=function(e,n){return t.splitLines(e).filter(e=>0===e.indexOf(n))},t.parseCandidate=function(e){let t;t=0===e.indexOf("a=candidate:")?e.substring(12).split(" "):e.substring(10).split(" ");const n={foundation:t[0],component:{1:"rtp",2:"rtcp"}[t[1]]||t[1],protocol:t[2].toLowerCase(),priority:parseInt(t[3],10),ip:t[4],address:t[4],
23
23
  // address is an alias for ip.
24
24
  port:parseInt(t[5],10),
@@ -27,7 +27,7 @@ type:t[7]};for(let i=8;i<t.length;i+=2)switch(t[i]){case"raddr":n.relatedAddress
27
27
  // algorithm is case-sensitive in Edge.
28
28
  value:t[1].toUpperCase()}},t.getDtlsParameters=function(e,n){return{role:"auto",fingerprints:t.matchPrefix(e+n,"a=fingerprint:").map(t.parseFingerprint)}},t.writeDtlsParameters=function(e,t){let n="a=setup:"+t+"\r\n";return e.fingerprints.forEach(e=>{n+="a=fingerprint:"+e.algorithm+" "+e.value+"\r\n"}),n},t.parseCryptoLine=function(e){const t=e.substring(9).split(" ");return{tag:parseInt(t[0],10),cryptoSuite:t[1],keyParams:t[2],sessionParams:t.slice(3)}},t.writeCryptoLine=function(e){return"a=crypto:"+e.tag+" "+e.cryptoSuite+" "+("object"==typeof e.keyParams?t.writeCryptoKeyParams(e.keyParams):e.keyParams)+(e.sessionParams?" "+e.sessionParams.join(" "):"")+"\r\n"},t.parseCryptoKeyParams=function(e){if(0!==e.indexOf("inline:"))return null;const t=e.substring(7).split("|");return{keyMethod:"inline",keySalt:t[0],lifeTime:t[1],mkiValue:t[2]?t[2].split(":")[0]:void 0,mkiLength:t[2]?t[2].split(":")[1]:void 0}},t.writeCryptoKeyParams=function(e){return e.keyMethod+":"+e.keySalt+(e.lifeTime?"|"+e.lifeTime:"")+(e.mkiValue&&e.mkiLength?"|"+e.mkiValue+":"+e.mkiLength:"")},t.getCryptoParameters=function(e,n){return t.matchPrefix(e+n,"a=crypto:").map(t.parseCryptoLine)},t.getIceParameters=function(e,n){const i=t.matchPrefix(e+n,"a=ice-ufrag:")[0],r=t.matchPrefix(e+n,"a=ice-pwd:")[0];return i&&r?{usernameFragment:i.substring(12),password:r.substring(10)}:null},t.writeIceParameters=function(e){let t="a=ice-ufrag:"+e.usernameFragment+"\r\na=ice-pwd:"+e.password+"\r\n";return e.iceLite&&(t+="a=ice-lite\r\n"),t},t.parseRtpParameters=function(e){const n={codecs:[],headerExtensions:[],fecMechanisms:[],rtcp:[]},i=t.splitLines(e)[0].split(" ");n.profile=i[2];for(let o=3;o<i.length;o++){const r=i[o],s=t.matchPrefix(e,"a=rtpmap:"+r+" ")[0];if(s){const i=t.parseRtpMap(s),o=t.matchPrefix(e,"a=fmtp:"+r+" ");switch(i.parameters=o.length?t.parseFmtp(o[0]):{},i.rtcpFeedback=t.matchPrefix(e,"a=rtcp-fb:"+r+" ").map(t.parseRtcpFb),n.codecs.push(i),i.name.toUpperCase()){case"RED":case"ULPFEC":n.fecMechanisms.push(i.name.toUpperCase())}}}t.matchPrefix(e,"a=extmap:").forEach(e=>{n.headerExtensions.push(t.parseExtmap(e))});const r=t.matchPrefix(e,"a=rtcp-fb:* ").map(t.parseRtcpFb);return n.codecs.forEach(e=>{r.forEach(t=>{e.rtcpFeedback.find(e=>e.type===t.type&&e.parameter===t.parameter)||e.rtcpFeedback.push(t)})}),n},t.writeRtpDescription=function(e,n){let i="";i+="m="+e+" ",i+=n.codecs.length>0?"9":"0",i+=" "+(n.profile||"UDP/TLS/RTP/SAVPF")+" ",i+=n.codecs.map(e=>void 0!==e.preferredPayloadType?e.preferredPayloadType:e.payloadType).join(" ")+"\r\n",i+="c=IN IP4 0.0.0.0\r\n",i+="a=rtcp:9 IN IP4 0.0.0.0\r\n",n.codecs.forEach(e=>{i+=t.writeRtpMap(e),i+=t.writeFmtp(e),i+=t.writeRtcpFb(e)});let r=0;return n.codecs.forEach(e=>{e.maxptime>r&&(r=e.maxptime)}),r>0&&(i+="a=maxptime:"+r+"\r\n"),n.headerExtensions&&n.headerExtensions.forEach(e=>{i+=t.writeExtmap(e)}),i},t.parseRtpEncodingParameters=function(e){const n=[],i=t.parseRtpParameters(e),r=-1!==i.fecMechanisms.indexOf("RED"),o=-1!==i.fecMechanisms.indexOf("ULPFEC"),s=t.matchPrefix(e,"a=ssrc:").map(e=>t.parseSsrcMedia(e)).filter(e=>"cname"===e.attribute),a=s.length>0&&s[0].ssrc;let c;const d=t.matchPrefix(e,"a=ssrc-group:FID").map(e=>e.substring(17).split(" ").map(e=>parseInt(e,10)));d.length>0&&d[0].length>1&&d[0][0]===a&&(c=d[0][1]),i.codecs.forEach(e=>{if("RTX"===e.name.toUpperCase()&&e.parameters.apt){let t={ssrc:a,codecPayloadType:parseInt(e.parameters.apt,10)};a&&c&&(t.rtx={ssrc:c}),n.push(t),r&&(t=JSON.parse(JSON.stringify(t)),t.fec={ssrc:a,mechanism:o?"red+ulpfec":"red"},n.push(t))}}),0===n.length&&a&&n.push({ssrc:a});let l=t.matchPrefix(e,"b=");return l.length&&(l=0===l[0].indexOf("b=TIAS:")?parseInt(l[0].substring(7),10):0===l[0].indexOf("b=AS:")?1e3*parseInt(l[0].substring(5),10)*.95-16e3:void 0,n.forEach(e=>{e.maxBitrate=l})),n},t.parseRtcpParameters=function(e){const n={},i=t.matchPrefix(e,"a=ssrc:").map(e=>t.parseSsrcMedia(e)).filter(e=>"cname"===e.attribute)[0];i&&(n.cname=i.value,n.ssrc=i.ssrc);const r=t.matchPrefix(e,"a=rtcp-rsize");n.reducedSize=r.length>0,n.compound=0===r.length;const o=t.matchPrefix(e,"a=rtcp-mux");return n.mux=o.length>0,n},t.writeRtcpParameters=function(e){let t="";return e.reducedSize&&(t+="a=rtcp-rsize\r\n"),e.mux&&(t+="a=rtcp-mux\r\n"),void 0!==e.ssrc&&e.cname&&(t+="a=ssrc:"+e.ssrc+" cname:"+e.cname+"\r\n"),t},t.parseMsid=function(e){let n;const i=t.matchPrefix(e,"a=msid:");if(1===i.length)return n=i[0].substring(7).split(" "),{stream:n[0],track:n[1]};const r=t.matchPrefix(e,"a=ssrc:").map(e=>t.parseSsrcMedia(e)).filter(e=>"msid"===e.attribute);return r.length>0?(n=r[0].value.split(" "),{stream:n[0],track:n[1]}):void 0},t.parseSctpDescription=function(e){const n=t.parseMLine(e),i=t.matchPrefix(e,"a=max-message-size:");let r;i.length>0&&(r=parseInt(i[0].substring(19),10)),isNaN(r)&&(r=65536);const o=t.matchPrefix(e,"a=sctp-port:");if(o.length>0)return{port:parseInt(o[0].substring(12),10),protocol:n.fmt,maxMessageSize:r};const s=t.matchPrefix(e,"a=sctpmap:");if(s.length>0){const e=s[0].substring(10).split(" ");return{port:parseInt(e[0],10),protocol:e[1],maxMessageSize:r}}},t.writeSctpDescription=function(e,t){let n=[];return n="DTLS/SCTP"!==e.protocol?["m="+e.kind+" 9 "+e.protocol+" "+t.protocol+"\r\n","c=IN IP4 0.0.0.0\r\n","a=sctp-port:"+t.port+"\r\n"]:["m="+e.kind+" 9 "+e.protocol+" "+t.port+"\r\n","c=IN IP4 0.0.0.0\r\n","a=sctpmap:"+t.port+" "+t.protocol+" 65535\r\n"],void 0!==t.maxMessageSize&&n.push("a=max-message-size:"+t.maxMessageSize+"\r\n"),n.join("")},t.generateSessionId=function(){return Math.random().toString().substr(2,22)},t.writeSessionBoilerplate=function(e,n,i){let r;const o=void 0!==n?n:2;return r=e||t.generateSessionId(),"v=0\r\no="+(i||"thisisadapterortc")+" "+r+" "+o+" IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\n"},t.getDirection=function(e,n){const i=t.splitLines(e);for(let t=0;t<i.length;t++)switch(i[t]){case"a=sendrecv":case"a=sendonly":case"a=recvonly":case"a=inactive":return i[t].substring(2)}return n?t.getDirection(n):"sendrecv"},t.getKind=function(e){return t.splitLines(e)[0].split(" ")[0].substring(2)},t.isRejected=function(e){return"0"===e.split(" ",2)[1]},t.parseMLine=function(e){const n=t.splitLines(e)[0].substring(2).split(" ");return{kind:n[0],port:parseInt(n[1],10),protocol:n[2],fmt:n.slice(3).join(" ")}},t.parseOLine=function(e){const n=t.matchPrefix(e,"o=")[0].substring(2).split(" ");return{username:n[0],sessionId:n[1],sessionVersion:parseInt(n[2],10),netType:n[3],addressType:n[4],address:n[5]}},t.isValidSDP=function(e){if("string"!=typeof e||0===e.length)return!1;const n=t.splitLines(e);for(let t=0;t<n.length;t++)if(n[t].length<2||"="!==n[t].charAt(1))return!1;return!0},e.exports=t}(ve)),ve.exports);const Te=o(Se),Re=r({__proto__:null,default:Te},[Se]);function be(e){if(!e.RTCIceCandidate||e.RTCIceCandidate&&"foundation"in e.RTCIceCandidate.prototype)return;const t=e.RTCIceCandidate;e.RTCIceCandidate=function(e){if("object"==typeof e&&e.candidate&&0===e.candidate.indexOf("a=")&&((e=JSON.parse(JSON.stringify(e))).candidate=e.candidate.substring(2)),e.candidate&&e.candidate.length){const n=new t(e),i=Te.parseCandidate(e.candidate);for(const e in i)e in n||Object.defineProperty(n,e,{value:i[e]});return n.toJSON=function(){return{candidate:n.candidate,sdpMid:n.sdpMid,sdpMLineIndex:n.sdpMLineIndex,usernameFragment:n.usernameFragment}},n}return new t(e)},e.RTCIceCandidate.prototype=t.prototype,_(e,"icecandidate",t=>(t.candidate&&Object.defineProperty(t,"candidate",{value:new e.RTCIceCandidate(t.candidate),writable:"false"}),t))}function we(e){!e.RTCIceCandidate||e.RTCIceCandidate&&"relayProtocol"in e.RTCIceCandidate.prototype||_(e,"icecandidate",e=>{if(e.candidate){const t=Te.parseCandidate(e.candidate.candidate);"relay"===t.type&&(e.candidate.relayProtocol={0:"tls",1:"tcp",2:"udp"}[t.priority>>24])}return e})}function Ee(e,t){if(!e.RTCPeerConnection)return;"sctp"in e.RTCPeerConnection.prototype||Object.defineProperty(e.RTCPeerConnection.prototype,"sctp",{get(){return void 0===this._sctp?null:this._sctp}});const n=e.RTCPeerConnection.prototype.setRemoteDescription;e.RTCPeerConnection.prototype.setRemoteDescription=function(){if(this._sctp=null,"chrome"===t.browser&&t.version>=76){const{sdpSemantics:e}=this.getConfiguration();"plan-b"===e&&Object.defineProperty(this,"sctp",{get(){return void 0===this._sctp?null:this._sctp},enumerable:!0,configurable:!0})}if(function(e){if(!e||!e.sdp)return!1;const t=Te.splitSections(e.sdp);return t.shift(),t.some(e=>{const t=Te.parseMLine(e);return t&&"application"===t.kind&&-1!==t.protocol.indexOf("SCTP")})}(arguments[0])){const e=function(e){const t=e.sdp.match(/mozilla...THIS_IS_SDPARTA-(\d+)/);if(null===t||t.length<2)return-1;const n=parseInt(t[1],10);return n!=n?-1:n}(arguments[0]),n=function(e){let n=65536;return"firefox"===t.browser&&(n=t.version<57?-1===e?16384:2147483637:t.version<60?57===t.version?65535:65536:2147483637),n}(e),i=function(e,n){let i=65536;"firefox"===t.browser&&57===t.version&&(i=65535);const r=Te.matchPrefix(e.sdp,"a=max-message-size:");return r.length>0?i=parseInt(r[0].substring(19),10):"firefox"===t.browser&&-1!==n&&(i=2147483637),i}(arguments[0],e);let r;r=0===n&&0===i?Number.POSITIVE_INFINITY:0===n||0===i?Math.max(n,i):Math.min(n,i);const o={};Object.defineProperty(o,"maxMessageSize",{get:()=>r}),this._sctp=o}return n.apply(this,arguments)}}function Pe(e){if(!e.RTCPeerConnection||!("createDataChannel"in e.RTCPeerConnection.prototype))return;function t(e,t){const n=e.send;e.send=function(){const i=arguments[0],r=i.length||i.size||i.byteLength;if("open"===e.readyState&&t.sctp&&r>t.sctp.maxMessageSize)throw new TypeError("Message too large (can send a maximum of "+t.sctp.maxMessageSize+" bytes)");return n.apply(e,arguments)}}const n=e.RTCPeerConnection.prototype.createDataChannel;e.RTCPeerConnection.prototype.createDataChannel=function(){const e=n.apply(this,arguments);return t(e,this),e},_(e,"datachannel",e=>(t(e.channel,e.target),e))}function ke(e){if(!e.RTCPeerConnection||"connectionState"in e.RTCPeerConnection.prototype)return;const t=e.RTCPeerConnection.prototype;Object.defineProperty(t,"connectionState",{get(){return{completed:"connected",checking:"connecting"}[this.iceConnectionState]||this.iceConnectionState},enumerable:!0,configurable:!0}),Object.defineProperty(t,"onconnectionstatechange",{get(){return this._onconnectionstatechange||null},set(e){this._onconnectionstatechange&&(this.removeEventListener("connectionstatechange",this._onconnectionstatechange),delete this._onconnectionstatechange),e&&this.addEventListener("connectionstatechange",this._onconnectionstatechange=e)},enumerable:!0,configurable:!0}),["setLocalDescription","setRemoteDescription"].forEach(e=>{const n=t[e];t[e]=function(){return this._connectionstatechangepoly||(this._connectionstatechangepoly=e=>{const t=e.target;if(t._lastConnectionState!==t.connectionState){t._lastConnectionState=t.connectionState;const n=new Event("connectionstatechange",e);t.dispatchEvent(n)}return e},this.addEventListener("iceconnectionstatechange",this._connectionstatechangepoly)),n.apply(this,arguments)}})}function Ie(e,t){if(!e.RTCPeerConnection)return;if("chrome"===t.browser&&t.version>=71)return;if("safari"===t.browser&&t._safariVersion>=13.1)return;const n=e.RTCPeerConnection.prototype.setRemoteDescription;e.RTCPeerConnection.prototype.setRemoteDescription=function(t){if(t&&t.sdp&&-1!==t.sdp.indexOf("\na=extmap-allow-mixed")){const n=t.sdp.split("\n").filter(e=>"a=extmap-allow-mixed"!==e.trim()).join("\n");e.RTCSessionDescription&&t instanceof e.RTCSessionDescription?arguments[0]=new e.RTCSessionDescription({type:t.type,sdp:n}):t.sdp=n}return n.apply(this,arguments)}}function Ae(e,t){if(!e.RTCPeerConnection||!e.RTCPeerConnection.prototype)return;const n=e.RTCPeerConnection.prototype.addIceCandidate;n&&0!==n.length&&(e.RTCPeerConnection.prototype.addIceCandidate=function(){return arguments[0]?("chrome"===t.browser&&t.version<78||"firefox"===t.browser&&t.version<68||"safari"===t.browser)&&arguments[0]&&""===arguments[0].candidate?Promise.resolve():n.apply(this,arguments):(arguments[1]&&arguments[1].apply(null),Promise.resolve())})}function _e(e,t){if(!e.RTCPeerConnection||!e.RTCPeerConnection.prototype)return;const n=e.RTCPeerConnection.prototype.setLocalDescription;n&&0!==n.length&&(e.RTCPeerConnection.prototype.setLocalDescription=function(){let e=arguments[0]||{};if("object"!=typeof e||e.type&&e.sdp)return n.apply(this,arguments);if(e={type:e.type,sdp:e.sdp},!e.type)switch(this.signalingState){case"stable":case"have-local-offer":case"have-remote-pranswer":e.type="offer";break;default:e.type="answer"}if(e.sdp||"offer"!==e.type&&"answer"!==e.type)return n.apply(this,[e]);return("offer"===e.type?this.createOffer:this.createAnswer).apply(this).then(e=>n.apply(this,[e]))})}const Oe=Object.freeze(Object.defineProperty({__proto__:null,removeExtmapAllowMixed:Ie,shimAddIceCandidateNullOrEmpty:Ae,shimConnectionState:ke,shimMaxMessageSize:Ee,shimParameterlessSetLocalDescription:_e,shimRTCIceCandidate:be,shimRTCIceCandidateRelayProtocol:we,shimSendThrowTypeError:Pe},Symbol.toStringTag,{value:"Module"}));!function({window:e}={},t={shimChrome:!0,shimFirefox:!0,shimSafari:!0}){const n=M,i=function(e){const t={browser:null,version:null};if(void 0===e||!e.navigator||!e.navigator.userAgent)return t.browser="Not a browser.",t;const{navigator:n}=e;if(n.userAgentData&&n.userAgentData.brands){const e=n.userAgentData.brands.find(e=>"Chromium"===e.brand);if(e)return{browser:"chrome",version:parseInt(e.version,10)}}if(n.mozGetUserMedia)t.browser="firefox",t.version=parseInt(A(n.userAgent,/Firefox\/(\d+)\./,1));else if(n.webkitGetUserMedia||!1===e.isSecureContext&&e.webkitRTCPeerConnection)t.browser="chrome",t.version=parseInt(A(n.userAgent,/Chrom(e|ium)\/(\d+)\./,2));else{if(!e.RTCPeerConnection||!n.userAgent.match(/AppleWebKit\/(\d+)\./))return t.browser="Not a supported browser.",t;t.browser="safari",t.version=parseInt(A(n.userAgent,/AppleWebKit\/(\d+)\./,1)),t.supportsUnifiedPlan=e.RTCRtpTransceiver&&"currentDirection"in e.RTCRtpTransceiver.prototype,t._safariVersion=A(n.userAgent,/Version\/(\d+(\.?\d+))/,1)}return t}(e),r={browserDetails:i,commonShim:Oe,extractVersion:A,disableLog:O,disableWarnings:D,
29
29
  // Expose sdp as a convenience. For production apps include directly.
30
- sdp:Re};switch(i.browser){case"chrome":if(!$||!H||!t.shimChrome)return n("Chrome shim is not included in this adapter release."),r;if(null===i.version)return n("Chrome shim can not determine version, not shimming."),r;n("adapter.js shimming chrome."),r.browserShim=$,Ae(e,i),_e(e),G(e,i),K(e),H(e,i),V(e),B(e,i),z(e),W(e),q(e,i),be(e),we(e),ke(e),Ee(e,i),Pe(e),Ie(e,i);break;case"firefox":if(!ae||!Q||!t.shimFirefox)return n("Firefox shim is not included in this adapter release."),r;n("adapter.js shimming firefox."),r.browserShim=ae,Ae(e,i),_e(e),X(e,i),Q(e,i),Y(e),te(e),Z(e),ee(e),ne(e),ie(e),re(e),oe(e),se(e),be(e),ke(e),Ee(e,i),Pe(e);break;case"safari":if(!Ce||!t.shimSafari)return n("Safari shim is not included in this adapter release."),r;n("adapter.js shimming safari."),r.browserShim=Ce,Ae(e,i),_e(e),ue(e),me(e),le(e),ce(e),de(e),fe(e),he(e),ge(e),be(e),we(e),Ee(e,i),Pe(e),Ie(e,i);break;default:n("Unsupported browser!")}}({window:"undefined"==typeof window?void 0:window});class De{constructor(e){i(this,"signalServerUrl"),i(this,"myId"),i(this,"roomId"),i(this,"targetId"),i(this,"stunServerUri"),i(this,"stunServerUriAli"),i(this,"stunServerUriTel"),i(this,"turnServerUri"),i(this,"turnServerUserName"),i(this,"turnServerPassword"),i(this,"token"),i(this,"connectorType"),i(this,"mainRoomIdOfGroup"),i(this,"subRoomIdsOfGroup"),i(this,"mainCloudMyId"),i(this,"connectorAndRoomId"),i(this,"groupId"),i(this,"isGroup"),i(this,"turnKey"),i(this,"traceId",""),i(this,"signAgain"),this.signalServerUrl=e.signalServerUrl||"",this.myId=e.myId||"",this.roomId=e.roomId||"",this.targetId=e.targetId||"",this.turnKey=e.turnKey||[],this.stunServerUri=e.stunServerUri||"stun:stun.l.google.com:19302",this.stunServerUriAli=e.stunServerUriAli||"stun:stun.middle.aliyun.com:3478",this.stunServerUriTel=e.stunServerUriTel||"stun:stun.qq.com:3478",this.turnServerUri=e.turnServerUri||"turn:121.37.25.106:3478",this.turnServerUserName=e.turnServerUserName||"yangyj",this.turnServerPassword=e.turnServerPassword||"hb@2025@168",this.token=e.token,this.connectorType=e.connectorType||p.WebRTC,this.mainRoomIdOfGroup=e.mainRoomIdOfGroup,this.subRoomIdsOfGroup=e.subRoomIdsOfGroup,this.connectorAndRoomId=e.connectorAndRoomId,this.mainCloudMyId=e.mainCloudMyId,this.groupId=e.groupId,this.isGroup=e.isGroup,this.traceId=e.traceId||"",this.signAgain=e.signAgain||!0}}const Me=(e,t,n)=>{w.info("信息日志:","创建webrtcAnswer=======>"),e.createAnswer().then(i=>Le(e,i,t,n)).catch(e=>null==n?void 0:n(g(u.CREATE_ANSWER,e)))},Le=(e,t,n,i)=>{w.info("信息日志:","设置本地answer Description=======>"),e.setLocalDescription(t).then(()=>{null==n||n(t.sdp??"")}).catch(e=>{null==i||i(g(u.LOCAL_DES,e))})},xe=async(e,t)=>{try{const n=await e.createOffer();await Ne(e,n,t)}catch(n){throw new Error("摄像头视频流添加失败")}},Ne=async(e,t,n)=>{w.info("信息日志:","设置本地offer Description=======>");try{await e.setLocalDescription(t),n(t.sdp??"")}catch(i){throw new Error("摄像头视频流添加失败")}};var je=(e=>(e.ClickData="ClickData",e.ClipboardData="ClipboardData",e.ActionCommand="ActionCommand",e.ActionInput="ActionInput",e.ActionChinese="ActionChinese",e.ActionRequestCloudDeviceInfo="ActionRequestCloudDeviceInfo",e.ActionClarity="ActionClarity",e.ActionWheel="ActionWheel",e.CloudClipData="CloudClipData",e.ActionCommandEvent="ActionCommandEvent",e.ActionUpdateCloudStatus="ActionUpdateCloudStatus",e.ActionGesture="ActionGesture",e.ActionTrack="ActionTrack",e))(je||{}),Ue=(e=>(e.ENABLE="ENABLE",e.DISABLE="DISABLE",e))(Ue||{}),Fe=(e=>(e.ActionBack="ActionBack",e.ActionHome="ActionHome",e.ActionRecent="ActionRecent",e.ActionSwitchNavButtons="ActionSwitchNavButtons",e.ActionSwitchNavGestural="ActionSwitchNavGestural",e))(Fe||{}),Ge=(e=>(e.ACTION_CONTROL_VIDEO_AND_AUDIO="ACTION_CONTROL_VIDEO_AND_AUDIO",e.ACTION_CONTROL_VIDEO="ACTION_CONTROL_VIDEO",e.ACTION_CONTROL_AUDIO="ACTION_CONTROL_AUDIO",e))(Ge||{});const Ke={ACTION_DOWN:0,ACTION_MOVE:2,ACTION_UP:1},Ve={ROTATION_0:0,ROTATION_180:2},ze={Vertical:0,Horizontal:1};class We{constructor(e,t,n,r,o,s="adb"){i(this,"action"),i(this,"p"),i(this,"x"),i(this,"y"),i(this,"offsetTime"),i(this,"type"),this.action=e,this.p=t,this.x=n,this.y=r,this.offsetTime=o,this.type=s}}class Je{constructor(e){i(this,"axis"),this.axis=e}}class Be{constructor(e,t){i(this,"keyCode"),i(this,"meta"),this.keyCode=e,this.meta=t}}class He{constructor(e,t=null,n=null){i(this,"type"),i(this,"data"),i(this,"myId"),this.type=e,this.data=t,this.myId=n}toString(){return JSON.stringify({type:this.type,data:this.data,myId:this.myId})}
30
+ sdp:Re};switch(i.browser){case"chrome":if(!q||!H||!t.shimChrome)return n("Chrome shim is not included in this adapter release."),r;if(null===i.version)return n("Chrome shim can not determine version, not shimming."),r;n("adapter.js shimming chrome."),r.browserShim=q,Ae(e,i),_e(e),G(e,i),K(e),H(e,i),V(e),J(e,i),z(e),W(e),$(e,i),be(e),we(e),ke(e),Ee(e,i),Pe(e),Ie(e,i);break;case"firefox":if(!ae||!Q||!t.shimFirefox)return n("Firefox shim is not included in this adapter release."),r;n("adapter.js shimming firefox."),r.browserShim=ae,Ae(e,i),_e(e),X(e,i),Q(e,i),Y(e),te(e),Z(e),ee(e),ne(e),ie(e),re(e),oe(e),se(e),be(e),ke(e),Ee(e,i),Pe(e);break;case"safari":if(!Ce||!t.shimSafari)return n("Safari shim is not included in this adapter release."),r;n("adapter.js shimming safari."),r.browserShim=Ce,Ae(e,i),_e(e),ue(e),me(e),le(e),ce(e),de(e),fe(e),he(e),ge(e),be(e),we(e),Ee(e,i),Pe(e),Ie(e,i);break;default:n("Unsupported browser!")}}({window:"undefined"==typeof window?void 0:window});class De{constructor(e){i(this,"signalServerUrl"),i(this,"myId"),i(this,"roomId"),i(this,"targetId"),i(this,"stunServerUri"),i(this,"stunServerUriAli"),i(this,"stunServerUriTel"),i(this,"turnServerUri"),i(this,"turnServerUserName"),i(this,"turnServerPassword"),i(this,"token"),i(this,"connectorType"),i(this,"mainRoomIdOfGroup"),i(this,"subRoomIdsOfGroup"),i(this,"mainCloudMyId"),i(this,"connectorAndRoomId"),i(this,"groupId"),i(this,"isGroup"),i(this,"turnKey"),i(this,"traceId",""),i(this,"signAgain"),this.signalServerUrl=e.signalServerUrl||"",this.myId=e.myId||"",this.roomId=e.roomId||"",this.targetId=e.targetId||"",this.turnKey=e.turnKey||[],this.stunServerUri=e.stunServerUri||"stun:stun.l.google.com:19302",this.stunServerUriAli=e.stunServerUriAli||"stun:stun.middle.aliyun.com:3478",this.stunServerUriTel=e.stunServerUriTel||"stun:stun.qq.com:3478",this.turnServerUri=e.turnServerUri||"turn:121.37.25.106:3478",this.turnServerUserName=e.turnServerUserName||"yangyj",this.turnServerPassword=e.turnServerPassword||"hb@2025@168",this.token=e.token,this.connectorType=e.connectorType||p.WebRTC,this.mainRoomIdOfGroup=e.mainRoomIdOfGroup,this.subRoomIdsOfGroup=e.subRoomIdsOfGroup,this.connectorAndRoomId=e.connectorAndRoomId,this.mainCloudMyId=e.mainCloudMyId,this.groupId=e.groupId,this.isGroup=e.isGroup,this.traceId=e.traceId||"",this.signAgain=e.signAgain||!0}}const Me=(e,t,n)=>{w.info("信息日志:","创建webrtcAnswer=======>"),e.createAnswer().then(i=>Le(e,i,t,n)).catch(e=>null==n?void 0:n(g(u.CREATE_ANSWER,e)))},Le=(e,t,n,i)=>{var r;w.info("信息日志:","设置本地answer Description=======>");let o=null==(r=t.sdp)?void 0:r.replace(/a=rtpmap:\d+ opus\/48000\/2\r\n/g,"$&a=ptime:0\r\na=maxptime:10\r\n");e.setLocalDescription({type:t.type,sdp:o}).then(()=>{null==n||n(o??"")}).catch(e=>{null==i||i(g(u.LOCAL_DES,e))})},xe=async(e,t)=>{try{const n=await e.createOffer();await Ne(e,n,t)}catch(n){throw new Error("摄像头视频流添加失败")}},Ne=async(e,t,n)=>{var i;w.info("信息日志:","设置本地offer Description=======>");try{const r=null==(i=t.sdp)?void 0:i.replace(/a=rtpmap:\d+ opus\/48000\/2\r\n/g,"$&a=ptime:0\r\na=maxptime:10\r\n");await e.setLocalDescription({type:t.type,sdp:r}),n(r??"")}catch(r){throw new Error("摄像头视频流添加失败")}};var je=(e=>(e.ClickData="ClickData",e.ClipboardData="ClipboardData",e.ActionCommand="ActionCommand",e.ActionInput="ActionInput",e.ActionChinese="ActionChinese",e.ActionRequestCloudDeviceInfo="ActionRequestCloudDeviceInfo",e.ActionClarity="ActionClarity",e.ActionWheel="ActionWheel",e.CloudClipData="CloudClipData",e.ActionCommandEvent="ActionCommandEvent",e.ActionUpdateCloudStatus="ActionUpdateCloudStatus",e.ActionGesture="ActionGesture",e.ActionTrack="ActionTrack",e))(je||{}),Fe=(e=>(e.ENABLE="ENABLE",e.DISABLE="DISABLE",e))(Fe||{}),Ue=(e=>(e.ActionBack="ActionBack",e.ActionHome="ActionHome",e.ActionRecent="ActionRecent",e.ActionSwitchNavButtons="ActionSwitchNavButtons",e.ActionSwitchNavGestural="ActionSwitchNavGestural",e))(Ue||{}),Ge=(e=>(e.ACTION_CONTROL_VIDEO_AND_AUDIO="ACTION_CONTROL_VIDEO_AND_AUDIO",e.ACTION_CONTROL_VIDEO="ACTION_CONTROL_VIDEO",e.ACTION_CONTROL_AUDIO="ACTION_CONTROL_AUDIO",e))(Ge||{});const Ke={ACTION_DOWN:0,ACTION_MOVE:2,ACTION_UP:1},Ve={ROTATION_0:0,ROTATION_180:2},ze={Vertical:0,Horizontal:1};class We{constructor(e,t,n,r,o,s="adb"){i(this,"action"),i(this,"p"),i(this,"x"),i(this,"y"),i(this,"offsetTime"),i(this,"type"),this.action=e,this.p=t,this.x=n,this.y=r,this.offsetTime=o,this.type=s}}class Be{constructor(e){i(this,"axis"),this.axis=e}}class Je{constructor(e,t){i(this,"keyCode"),i(this,"meta"),this.keyCode=e,this.meta=t}}class He{constructor(e,t=null,n=null){i(this,"type"),i(this,"data"),i(this,"myId"),this.type=e,this.data=t,this.myId=n}toString(){return JSON.stringify({type:this.type,data:this.data,myId:this.myId})}
31
31
  /**
32
32
  * 格式化数据
33
33
  * 如果数据已经是字符串,则直接返回;否则使用 JSON.stringify() 转换为字符串
@@ -64,24 +64,32 @@ sdp:Re};switch(i.browser){case"chrome":if(!$||!H||!t.shimChrome)return n("Chrome
64
64
  /**
65
65
  * 生成清晰度数据(clarity)
66
66
  * @param data 清晰度数据
67
- */static clarity(e){return new He("ActionClarity",this.formatData(e))}static switchAudio(e){return new He("ActionCommandEvent",this.formatData(e))}static changeSender(e){return new He("ActionTrack",this.formatData(e))}}class qe{
67
+ */static clarity(e){return new He("ActionClarity",this.formatData(e))}static switchAudio(e){return new He("ActionCommandEvent",this.formatData(e))}static changeSender(e){return new He("ActionTrack",this.formatData(e))}}class $e{
68
68
  /** 读取文件头并判断类型 */
69
- static async detectFileType(e){const t=await e.slice(0,16).arrayBuffer(),n=new Uint8Array(t);return 255===n[0]&&216===n[1]&&255===n[2]||137===n[0]&&80===n[1]&&78===n[2]&&71===n[3]||71===n[0]&&73===n[1]&&70===n[2]&&56===n[3]||82===n[0]&&73===n[1]&&70===n[2]&&70===n[3]&&87===n[8]&&69===n[9]&&66===n[10]&&80===n[11]?"image":"ftyp"===String.fromCharCode(...n.slice(4,8))||26===n[0]&&69===n[1]&&223===n[2]&&163===n[3]||79===n[0]&&103===n[1]&&103===n[2]&&83===n[3]?"video":"unknown"}}class $e extends d{constructor(e){super(),i(this,"config"),i(this,"peerConnection",null),i(this,"localStream",null),i(this,"rotatedStream",null),i(this,"isPushingStream",!1),i(this,"isPushingLocalStream",!1),i(this,"dataChannel",null),i(this,"statsTimer"),i(this,"lastReportTime",0),i(this,"lastBytesReceived",0),i(this,"lastPacketsLost",0),i(this,"lastPacketsReceived",0),i(this,"lostPacketCount",0),i(this,"maxLostRate",0),i(this,"lastSecondDecodedCount",0),i(this,"fileVideo"),i(this,"canvas"),i(this,"canvasStream",null),i(this,"rafId",0),i(this,"currentMedia",null),i(this,"fileImage"),i(this,"ua",""),i(this,"startPushLocal",async e=>{var t;if(!this.isPushingLocalStream&&e)try{await this.loadMedia(e),this.startCanvasStream();const n=[];null==(t=this.canvasStream)||t.getTracks().forEach(e=>{e.contentHint="detail";const t=this.peerConnection.addTrack(e,this.canvasStream);n.push(t)}),n.forEach(e=>this.setVideoParams(e)),await xe(this.peerConnection,e=>{this.emit(y.sendOffer,e)}),this.isPushingLocalStream=!0}catch(n){let e;this.isPushingLocalStream=!1,e=n instanceof Error?n.message:String(n),this.emit(y.cameraError,C(m.LOCAL_STREAM_FAIL,e))}}),this.config=e,this.ua=navigator.userAgent}async startPush(){if(!this.isPushingStream){this.isPushingLocalStream&&this.stopLocal();try{this.isPushingStream=!0,await this.readyCapture()}catch(e){let t;this.isPushingStream=!1,t=e instanceof Error?e.message:String(e),this.emit(y.cameraError,C(m.CAMERA_STREAM_FAIL,t))}}}handleOffer(e){this.resetPeerConnection(),((e,t,n,i)=>{w.info("信息日志:","设置远程offer Description=======>");const r=new RTCSessionDescription({type:"offer",sdp:t});e.setRemoteDescription(r).then(()=>Me(e,n,i)).catch(e=>null==i?void 0:i(g(u.HANDLE_OFFER,e)))})(this.peerConnection,e,e=>{this.emit(y.sendAnswer,e)},e=>this.emit(y.webrtcError,e))}handleAnswer(e){((e,t,n)=>{const i=new RTCSessionDescription({type:"answer",sdp:t});e.setRemoteDescription(i).catch(e=>null==n?void 0:n(g(u.REMOTE_DES,e)))})(this.peerConnection,e??"",e=>this.emit(y.webrtcError,e))}handleIceCandidate(e){((e,t,n)=>{w.info("信息日志:","接收远程ice 并设置=======>"),e.addIceCandidate(t).catch(e=>null==n?void 0:n(g(u.HANDLE_ICE,e)))})(this.peerConnection,e,e=>this.emit(y.webrtcError,e))}sendChannelData(e,t){var n;try{let i=null;switch(e){case je.ClickData:i=He.click(t);break;case je.ClipboardData:i=He.clipboard(t);break;case je.ActionInput:i=He.input(t,this.config.myId);break;case je.ActionChinese:i=He.chinese(t);break;case je.ActionRequestCloudDeviceInfo:i=He.requestCloudDeviceInfo();break;case je.ActionClarity:i=He.clarity(t);break;case je.ActionWheel:i=He.wheel(t);break;case je.ActionGesture:i=He.gesture(t);break;case je.ActionCommand:i=He.action(t);break;case je.ActionCommandEvent:i=He.switchAudio(t);break;case je.ActionTrack:i=He.changeSender(t)}if(i){const e=JSON.stringify(i),t=(new TextEncoder).encode(e).buffer;null==(n=this.dataChannel)||n.send(t),i=null}}catch(i){this.emit(y.webrtcError,g(u.DATACHANNEL_ERR,i))}}closeConnection(){w.info("信息日志:","关闭webrtc连接=======>"),this.statsTimer&&(clearInterval(this.statsTimer),this.statsTimer=void 0),this.stopPush(),this.stopLocal(),this.peerConnection&&("function"==typeof this.peerConnection.getSenders&&this.peerConnection.getSenders&&this.peerConnection.getSenders().forEach(e=>{var t,n;e.track&&(null==(n=(t=e.track).stop)||n.call(t))}),"function"==typeof this.peerConnection.getReceivers&&this.peerConnection.getReceivers&&this.peerConnection.getReceivers().forEach(e=>{var t,n;e.track&&(null==(n=(t=e.track).stop)||n.call(t))}),this.peerConnection.getTransceivers&&this.peerConnection.getTransceivers().forEach(e=>{var t;null==(t=e.stop)||t.call(e)}),this.removeAllListeners(),this.dataChannel=null,this.peerConnection.onicecandidate=null,this.peerConnection.ontrack=null,this.peerConnection.ondatachannel=null,this.peerConnection.onconnectionstatechange=null,this.peerConnection.oniceconnectionstatechange=null,this.peerConnection.onsignalingstatechange=null,this.peerConnection.onnegotiationneeded=null,this.peerConnection.onicegatheringstatechange=null,this.peerConnection.close(),this.peerConnection=null)}async readyCapture(){this.resetPeerConnection(),w.info("信息日志:","启用摄像头推流到云机=======>");try{this.localStream=await navigator.mediaDevices.getUserMedia({video:{width:{ideal:640},height:{ideal:480}},audio:!0});const e=[],t=await this.getRotatedStream(this.localStream);this.rotatedStream=t,t.getTracks().forEach(n=>{n.contentHint="detail";const i=this.peerConnection.addTrack(n,t);e.push(i)}),e.forEach(e=>this.setVideoParams(e)),await xe(this.peerConnection,e=>{this.emit(y.sendOffer,e)})}catch(e){if(e instanceof DOMException)switch(e.name){case"NotAllowedError":throw new Error("用户拒绝了摄像头或麦克风权限");case"NotFoundError":throw new Error("未找到摄像头或麦克风设备");case"OverconstrainedError":throw new Error("设备无法满足指定约束");case"NotReadableError":throw new Error("设备忙或无法访问");default:throw new Error(`其他错误: ${e.message}`)}throw new Error(`mediaDevices 异常: ${e}`)}}async getRotatedStream(e){const t=document.createElement("canvas"),n=t.getContext("2d"),i=document.createElement("video");i.srcObject=e,i.muted=!0,await i.play();const r=i.videoWidth,o=i.videoHeight;t.width=640,t.height=480;const s=1e3/30;let a,c=0;const d=e=>{e-c>=s&&(n.clearRect(0,0,t.width,t.height),n.save(),n.translate(t.width/2,t.height/2),n.rotate(Math.PI/2),n.drawImage(i,-r/2,-o/2,r,o),n.restore(),c=e),a=requestAnimationFrame(d)};a=requestAnimationFrame(d);const l=t.captureStream(30);return l.getTracks().forEach(e=>{const t=()=>cancelAnimationFrame(a);e.addEventListener("ended",t),e.addEventListener("stop",t)}),l}async setVideoParams(e){w.info("信息日志:","设置推流视频参数=======>");const t=e.getParameters();t.degradationPreference="maintain-resolution",t.encodings.forEach(e=>{e.maxBitrate=1e6,e.priority="high",e.scaleResolutionDownBy=1}),await e.setParameters(t)}stopPush(){var e,t,n;this.isPushingStream&&(this.isPushingStream=!1,w.info("信息日志:","停止推流到云机=======>"),null==(e=this.localStream)||e.getTracks().forEach(e=>e.stop()),this.localStream=null,null==(t=this.rotatedStream)||t.getTracks().forEach(e=>e.stop()),this.rotatedStream=null,null==(n=this.peerConnection)||n.getSenders().forEach(e=>{var t;try{null==(t=this.peerConnection)||t.removeTrack(e)}catch(n){}}))}resetPeerConnection(){var e,t,n,i,r;this.peerConnection||(this.peerConnection=(e=>{w.info("信息日志:","初始化 Webrtc PeerConnection=======>");const t=[{urls:e.stunServerUri},{urls:e.turnServerUri,username:e.turnServerUserName,credential:e.turnServerPassword}];return new RTCPeerConnection({iceServers:t,iceTransportPolicy:"relay",bundlePolicy:"max-bundle"})})(this.config),e=this.peerConnection,t=e=>{this.emit(y.sendICEMessage,e)},n=e=>{this.emit(y.streamTrack,e)},i=e=>{this.emit(y.iceConnectionState,e),"connected"===e&&this.checkStats()},r=e=>this.emit(y.webrtcError,e),e.onicecandidate=e=>{if(!e.candidate)return;const n={sdp:e.candidate.candidate,sdpMid:e.candidate.sdpMid,sdpMLineIndex:e.candidate.sdpMLineIndex};w.debug("信息日志:",`webrtc 生成的icecandidate===>${JSON.stringify(n)}`),t(JSON.stringify(n))},e.onconnectionstatechange=()=>{const t=e.iceConnectionState;t&&(w.debug("信息日志:","webrtc p2p连接状态===>",t),"failed"!==t&&"disconnected"!==t&&"closed"!==t||null==r||r(g(u.ICE_STATE,"failed")),null==i||i(t))},e.ontrack=e=>{w.debug("信息日志:","webrtc p2p连接后获取的音视频track");const t=e.track;t.contentHint="motion",null==n||n(t)},this.configDataChannel())}configDataChannel(){this.peerConnection.ondatachannel=e=>{this.dataChannel=e.channel,this.dataChannel.onmessage=e=>this.handleDataChannelMessage(e),this.dataChannel.onerror=e=>this.emit(y.webrtcError,g(u.DATACHANNEL_ERR,e)),this.sendChannelData(je.ActionRequestCloudDeviceInfo,"")}}handleDataChannelMessage(e){const t=JSON.parse(e.data);if(t.type===je.ActionCommandEvent){const{action:e,value:n}=JSON.parse(t.data);"ACTION_CONTROL_VIDEO"===e&&("ENABLE"===n?this.startPush():(this.stopPush(),this.stopLocal()))}else if(t.type===je.ActionUpdateCloudStatus){const{rotation:e,screenWidth:n,screenHeight:i,gestureMode:r,level:o,isClarity:s}=JSON.parse(t.data),a={direction:[Ve.ROTATION_0,Ve.ROTATION_180].includes(e)?ze.Vertical:ze.Horizontal,screenWidth:n,screenHeight:i,gestureMode:r,clarityLevel:o,isClarity:s};this.emit(y.cloudStatusChanged,a)}else t.type===je.CloudClipData&&this.emit(y.cloudClipData,t.data)}checkStats(){this.statsTimer=setInterval(()=>this.processStats(),1e3)}processStats(){this.peerConnection&&this.peerConnection.getStats(null).then(e=>{let t=0,n=0,i=0,r=0,o=0,s=0,a=0,c=0,d=0,l="";const h=Date.now();e.forEach(h=>{if("inbound-rtp"===h.type&&(s+=h.bytesReceived||0,r+=h.packetsLost||0,o+=h.packetsReceived||0,"video"===h.kind&&(t=h.framesPerSecond||0,n=h.totalDecodeTime||0,a=h.framesDecoded||0,d=h.framesReceived||0,c=(h.pliCount||0)+(h.firCount||0))),"candidate-pair"===h.type&&"succeeded"===h.state){i=void 0!==h.currentRoundTripTime?h.currentRoundTripTime:h.responsesReceived>0?h.totalRoundTripTime/h.responsesReceived:0;const t=e.get(h.localCandidateId),n=e.get(h.remoteCandidateId);t&&n&&(l=this.getConnectionType(t,n))}}),this.ua.includes("Firefox")||(i=Math.floor(1e3*(i||0)));const p=h-this.lastReportTime,u=s-this.lastBytesReceived,f=(p>0?1e3*u/p:0)/1024,m=f/1024;this.lastBytesReceived=s,this.lastReportTime=h;let g=0;const C=r-this.lastPacketsLost,v=o-this.lastPacketsReceived;C>0&&v>0&&(g=C/(C+v),this.maxLostRate=Math.max(this.maxLostRate||0,g),this.lostPacketCount++),this.lastPacketsLost=r,this.lastPacketsReceived=o;const S=void 0!==t?t:a-this.lastSecondDecodedCount;this.lastSecondDecodedCount=a;const T=f<1024?`${Math.floor(f)} KB/s`:`${Math.floor(m)} MB/s`,R=a>0?Math.floor(1e4*n/a):0,b={connectionType:l,framesPerSecond:S,currentRoundTripTime:i,lostRate:Math.floor(100*g),
69
+ static async detectFileType(e){const t=await e.slice(0,16).arrayBuffer(),n=new Uint8Array(t);return 255===n[0]&&216===n[1]&&255===n[2]||137===n[0]&&80===n[1]&&78===n[2]&&71===n[3]||71===n[0]&&73===n[1]&&70===n[2]&&56===n[3]||82===n[0]&&73===n[1]&&70===n[2]&&70===n[3]&&87===n[8]&&69===n[9]&&66===n[10]&&80===n[11]?"image":"ftyp"===String.fromCharCode(...n.slice(4,8))||26===n[0]&&69===n[1]&&223===n[2]&&163===n[3]||79===n[0]&&103===n[1]&&103===n[2]&&83===n[3]?"video":"unknown"}}class qe extends d{constructor(e){super(),i(this,"config"),i(this,"peerConnection",null),i(this,"localStream",null),i(this,"rotatedStream",null),i(this,"isPushingStream",!1),i(this,"isPushingLocalStream",!1),i(this,"dataChannel",null),i(this,"statsTimer"),i(this,"lastReportTime",0),i(this,"lastBytesReceived",0),i(this,"lastPacketsLost",0),i(this,"lastPacketsReceived",0),i(this,"lostPacketCount",0),i(this,"maxLostRate",0),i(this,"lastSecondDecodedCount",0),i(this,"fileVideo"),i(this,"canvas"),i(this,"canvasStream",null),i(this,"rafId",0),i(this,"currentMedia",null),i(this,"fileImage"),i(this,"ua",""),i(this,"startPushLocal",async e=>{var t;if(!this.isPushingLocalStream&&e)try{await this.loadMedia(e),this.startCanvasStream();const n=[];null==(t=this.canvasStream)||t.getTracks().forEach(e=>{e.contentHint="detail";const t=this.peerConnection.addTrack(e,this.canvasStream);n.push(t)}),n.forEach(e=>this.setVideoParams(e)),await xe(this.peerConnection,e=>{this.emit(y.sendOffer,e)}),this.isPushingLocalStream=!0}catch(n){let e;this.isPushingLocalStream=!1,e=n instanceof Error?n.message:String(n),this.emit(y.cameraError,C(m.LOCAL_STREAM_FAIL,e))}}),this.config=e,this.ua=navigator.userAgent}async startPush(e=!0){this.isPushingLocalStream&&this.stopLocal();try{this.isPushingStream=!0,await this.readyCapture(e)}catch(t){let e;this.isPushingStream=!1,e=t instanceof Error?t.message:String(t),this.emit(y.cameraError,C(m.CAMERA_STREAM_FAIL,e))}}handleOffer(e){this.resetPeerConnection(),((e,t,n,i)=>{w.info("信息日志:","设置远程offer Description=======>");const r=new RTCSessionDescription({type:"offer",sdp:t});e.setRemoteDescription(r).then(()=>Me(e,n,i)).catch(e=>null==i?void 0:i(g(u.HANDLE_OFFER,e)))})(this.peerConnection,e,e=>{this.emit(y.sendAnswer,e)},e=>this.emit(y.webrtcError,e))}handleAnswer(e){((e,t,n)=>{const i=new RTCSessionDescription({type:"answer",sdp:t});e.setRemoteDescription(i).catch(e=>null==n?void 0:n(g(u.REMOTE_DES,e)))})(this.peerConnection,e??"",e=>this.emit(y.webrtcError,e))}handleIceCandidate(e){((e,t,n)=>{w.info("信息日志:","接收远程ice 并设置=======>"),e.addIceCandidate(t).catch(e=>null==n?void 0:n(g(u.HANDLE_ICE,e)))})(this.peerConnection,e,e=>this.emit(y.webrtcError,e))}sendChannelData(e,t){var n;try{let i=null;switch(e){case je.ClickData:i=He.click(t);break;case je.ClipboardData:i=He.clipboard(t);break;case je.ActionInput:i=He.input(t,this.config.myId);break;case je.ActionChinese:i=He.chinese(t);break;case je.ActionRequestCloudDeviceInfo:i=He.requestCloudDeviceInfo();break;case je.ActionClarity:i=He.clarity(t);break;case je.ActionWheel:i=He.wheel(t);break;case je.ActionGesture:i=He.gesture(t);break;case je.ActionCommand:i=He.action(t);break;case je.ActionCommandEvent:i=He.switchAudio(t);break;case je.ActionTrack:i=He.changeSender(t)}if(i){const e=JSON.stringify(i),t=(new TextEncoder).encode(e).buffer;null==(n=this.dataChannel)||n.send(t),i=null}}catch(i){this.emit(y.webrtcError,g(u.DATACHANNEL_ERR,i))}}closeConnection(){w.info("信息日志:","关闭webrtc连接=======>"),this.statsTimer&&(clearInterval(this.statsTimer),this.statsTimer=void 0),this.stopPush(),this.stopLocal(),this.peerConnection&&("function"==typeof this.peerConnection.getSenders&&this.peerConnection.getSenders&&this.peerConnection.getSenders().forEach(e=>{var t,n;e.track&&(null==(n=(t=e.track).stop)||n.call(t))}),"function"==typeof this.peerConnection.getReceivers&&this.peerConnection.getReceivers&&this.peerConnection.getReceivers().forEach(e=>{var t,n;e.track&&(null==(n=(t=e.track).stop)||n.call(t))}),this.peerConnection.getTransceivers&&this.peerConnection.getTransceivers().forEach(e=>{var t;null==(t=e.stop)||t.call(e)}),this.removeAllListeners(),this.dataChannel=null,this.peerConnection.onicecandidate=null,this.peerConnection.ontrack=null,this.peerConnection.ondatachannel=null,this.peerConnection.onconnectionstatechange=null,this.peerConnection.oniceconnectionstatechange=null,this.peerConnection.onsignalingstatechange=null,this.peerConnection.onnegotiationneeded=null,this.peerConnection.onicegatheringstatechange=null,this.peerConnection.close(),this.peerConnection=null)}async readyCapture(e){this.resetPeerConnection(),this.stopPush(),w.info("信息日志:","启用摄像头推流到云机=======>",e);try{this.localStream=await navigator.mediaDevices.getUserMedia({video:{width:{ideal:640},height:{ideal:480},facingMode:e?{ideal:"environment"}:{ideal:"user"},frameRate:{ideal:20,max:30}},audio:!0});const t=[],n=await this.getRotatedStream(this.localStream,e);this.rotatedStream=n,n.getTracks().forEach(e=>{e.contentHint="detail";const i=this.peerConnection.addTrack(e,n);t.push(i)}),await xe(this.peerConnection,e=>{this.emit(y.sendOffer,e)}),t.forEach(e=>this.setVideoParams(e))}catch(t){if(t instanceof DOMException)switch(t.name){case"NotAllowedError":throw new Error("用户拒绝了摄像头或麦克风权限");case"NotFoundError":throw new Error("未找到摄像头或麦克风设备");case"OverconstrainedError":throw new Error("设备无法满足指定约束");case"NotReadableError":throw new Error("设备忙或无法访问");default:throw new Error(`其他错误: ${t.message}`)}throw new Error(`mediaDevices 异常: ${t}`)}}
70
+ /**
71
+ * ✅ 切换前后摄像头(无缝)
72
+ */async switchCamera(e){var t;try{w.info("信息日志:","切换摄像头 => "+(e?"后置":"前置")),this.isPushingStream=!0,this.localStream=await navigator.mediaDevices.getUserMedia({video:{width:{ideal:640},height:{ideal:480},facingMode:e?{ideal:"environment"}:{ideal:"user"},frameRate:{ideal:20,max:30}},audio:!1});const n=await this.getRotatedStream(this.localStream,e);this.rotatedStream=n;const i=this.rotatedStream.getVideoTracks()[0],r=null==(t=this.peerConnection)?void 0:t.getSenders().find(e=>e.track&&"video"===e.track.kind);r&&await r.replaceTrack(i)}catch(n){if(this.isPushingStream=!1,n instanceof DOMException)switch(n.name){case"NotAllowedError":throw new Error("用户拒绝了摄像头或麦克风权限");case"NotFoundError":throw new Error("未找到摄像头或麦克风设备");case"OverconstrainedError":throw new Error("设备无法满足指定约束");case"NotReadableError":throw new Error("设备忙或无法访问");default:throw new Error(`其他错误: ${n.message}`)}throw new Error(`mediaDevices 异常: ${n}`)}}async getRotatedStream(e,t){const n=document.createElement("canvas"),i=n.getContext("2d"),r=document.createElement("video");r.srcObject=e,r.muted=!0,await r.play();const o=r.videoWidth,s=r.videoHeight;n.width=640,n.height=480;let a,c=0;const d=e=>{e-c>=40&&((()=>{i.clearRect(0,0,n.width,n.height),i.save(),i.translate(n.width/2,n.height/2);const e=t?-Math.PI/2:Math.PI/2;i.rotate(e),i.drawImage(r,-o/2,-s/2,o,s),i.restore()})(),c=e),a=requestAnimationFrame(d)};a=requestAnimationFrame(d);const l=n.captureStream(25);return l.getTracks().forEach(e=>{const t=()=>cancelAnimationFrame(a);e.addEventListener("ended",t),e.addEventListener("stop",t)}),l}
73
+ // private async setVideoParams(sender: RTCRtpSender) {
74
+ // Logger.info('信息日志:', '设置推流视频参数=======>')
75
+ // const params = sender.getParameters();
76
+ // params.degradationPreference = 'balanced';
77
+ // const isMobile = /Android|iPhone|iPad/i.test(navigator.userAgent);
78
+ // params.encodings.forEach(encoding => {
79
+ // encoding.maxBitrate = isMobile ? 800000 : 1000000;
80
+ // encoding.priority = 'high';
81
+ // encoding.scaleResolutionDownBy = 1.0;
82
+ // });
83
+ // await sender.setParameters(params);
84
+ // }
85
+ async setVideoParams(e){const t=e.getParameters(),n=/Android|iPhone|iPad/i.test(navigator.userAgent)?6e5:18e5;t.degradationPreference="maintain-resolution",t.encodings&&0!==t.encodings.length||(t.encodings=[{}]),t.encodings.forEach(e=>{e.maxBitrate=n,e.maxFramerate=30,e.scaleResolutionDownBy=1,e.priority="high"});try{await e.setParameters(t),w.info("信息日志:",`设置推流视频参数成功:${n/1e3}kbps / 30fps`)}catch(i){w.error("设置推流参数失败:",i)}}stopPush(){var e,t,n;this.isPushingStream&&(this.isPushingStream=!1,w.info("信息日志:","停止推流到云机=======>"),null==(e=this.localStream)||e.getTracks().forEach(e=>e.stop()),this.localStream=null,null==(t=this.rotatedStream)||t.getTracks().forEach(e=>e.stop()),this.rotatedStream=null,null==(n=this.peerConnection)||n.getSenders().forEach(e=>{var t;try{null==(t=this.peerConnection)||t.removeTrack(e)}catch(n){}}))}resetPeerConnection(){var e,t,n,i,r;this.peerConnection||(this.peerConnection=(e=>{w.info("信息日志:","初始化 Webrtc PeerConnection=======>");const t=[{urls:e.stunServerUri},{urls:e.turnServerUri,username:e.turnServerUserName,credential:e.turnServerPassword}];return new RTCPeerConnection({iceServers:t,iceTransportPolicy:"all",bundlePolicy:"max-bundle"})})(this.config),e=this.peerConnection,t=e=>{this.emit(y.sendICEMessage,e)},n=e=>{this.emit(y.streamTrack,e)},i=e=>{this.emit(y.iceConnectionState,e),"connected"===e&&this.checkStats()},r=e=>this.emit(y.webrtcError,e),e.onicecandidate=e=>{if(!e.candidate)return;const n={sdp:e.candidate.candidate,sdpMid:e.candidate.sdpMid,sdpMLineIndex:e.candidate.sdpMLineIndex};w.debug("信息日志:",`webrtc 生成的icecandidate===>${JSON.stringify(n)}`),t(JSON.stringify(n))},e.onconnectionstatechange=()=>{const t=e.iceConnectionState;t&&(w.debug("信息日志:","webrtc p2p连接状态===>",t),"failed"!==t&&"disconnected"!==t&&"closed"!==t||null==r||r(g(u.ICE_STATE,"failed")),null==i||i(t))},e.ontrack=e=>{w.debug("信息日志:","webrtc p2p连接后获取的音视频track");const t=e.track;t.contentHint="motion",null==n||n(t)},this.configDataChannel())}configDataChannel(){this.peerConnection.ondatachannel=e=>{this.dataChannel=e.channel,this.dataChannel.onmessage=e=>this.handleDataChannelMessage(e),this.dataChannel.onerror=e=>this.emit(y.webrtcError,g(u.DATACHANNEL_ERR,e)),this.sendChannelData(je.ActionRequestCloudDeviceInfo,"")}}handleDataChannelMessage(e){const t=JSON.parse(e.data);if(t.type===je.ActionCommandEvent){const{action:e,value:n,cameraId:i}=JSON.parse(t.data);"ACTION_CONTROL_VIDEO"===e&&("ENABLE"===n?this.isPushingStream?this.switchCamera(0===Number(i)):this.startPush(0===Number(i)):(this.stopPush(),this.stopLocal()))}else if(t.type===je.ActionUpdateCloudStatus){const{rotation:e,screenWidth:n,screenHeight:i,gestureMode:r,level:o,isClarity:s}=JSON.parse(t.data),a={direction:[Ve.ROTATION_0,Ve.ROTATION_180].includes(e)?ze.Vertical:ze.Horizontal,screenWidth:n,screenHeight:i,gestureMode:r,clarityLevel:o,isClarity:s};this.emit(y.cloudStatusChanged,a)}else t.type===je.CloudClipData&&this.emit(y.cloudClipData,t.data)}checkStats(){this.statsTimer=setInterval(()=>this.processStats(),1e3)}processStats(){this.peerConnection&&this.peerConnection.getStats(null).then(e=>{let t=0,n=0,i=0,r=0,o=0,s=0,a=0,c=0,d=0,l="";const h=Date.now();e.forEach(h=>{if("inbound-rtp"===h.type&&(s+=h.bytesReceived||0,r+=h.packetsLost||0,o+=h.packetsReceived||0,"video"===h.kind&&(t=h.framesPerSecond||0,n=h.totalDecodeTime||0,a=h.framesDecoded||0,d=h.framesReceived||0,c=(h.pliCount||0)+(h.firCount||0))),"candidate-pair"===h.type&&"succeeded"===h.state){i=void 0!==h.currentRoundTripTime?h.currentRoundTripTime:h.responsesReceived>0?h.totalRoundTripTime/h.responsesReceived:0;const t=e.get(h.localCandidateId),n=e.get(h.remoteCandidateId);t&&n&&(l=this.getConnectionType(t,n))}}),this.ua.includes("Firefox")||(i=Math.floor(1e3*(i||0)));const p=h-this.lastReportTime,u=s-this.lastBytesReceived,f=(p>0?1e3*u/p:0)/1024,m=f/1024;this.lastBytesReceived=s,this.lastReportTime=h;let g=0;const C=r-this.lastPacketsLost,v=o-this.lastPacketsReceived;C>0&&v>0&&(g=C/(C+v),this.maxLostRate=Math.max(this.maxLostRate||0,g),this.lostPacketCount++),this.lastPacketsLost=r,this.lastPacketsReceived=o;const S=void 0!==t?t:a-this.lastSecondDecodedCount;this.lastSecondDecodedCount=a;const T=f<1024?`${Math.floor(f)} KB/s`:`${Math.floor(m)} MB/s`,R=a>0?Math.floor(1e4*n/a):0,b={connectionType:l,framesPerSecond:S,currentRoundTripTime:i,lostRate:Math.floor(100*g),
70
86
  // percent
71
87
  bitrate:T,pliCount:c,averageDecodeTime:R,framesDecoded:a,framesReceived:d};this.emit(y.statisticInfo,b)}).catch(e=>{this.emit(y.webrtcError,g(u.STREAM_STATE,e))})}getConnectionType(e,t){return"host"===e.candidateType&&"host"===t.candidateType?"直连":"relay"===e.candidateType||"relay"===t.candidateType?"中继":"NAT"}
72
88
  /** 获取或创建 video 元素(懒初始化) */getFileVideo(){return this.fileVideo||(this.fileVideo=document.createElement("video"),this.fileVideo.muted=!0,this.fileVideo.playsInline=!0),this.fileVideo}
73
- /** 获取或创建 canvas 元素(懒初始化) */getCanvas(){return this.canvas||(this.canvas=document.createElement("canvas"),this.canvas.width=640,this.canvas.height=480),this.canvas}async loadMedia(e){var t;const n=this.getFileVideo(),i=this.getFileImage(),r=e.type.toLowerCase(),o=null==(t=e.name.split(".").pop())?void 0:t.toLowerCase();let s="unknown";if(r.startsWith("video/")||o&&["mp4","webm","ogg","mov","mkv"].includes(o)?s="video":(r.startsWith("image/")||o&&["jpg","jpeg","png","gif","bmp","webp"].includes(o))&&(s="image"),"unknown"===s&&(s=await qe.detectFileType(e)),"video"===s)return new Promise((t,i)=>{const r=URL.createObjectURL(e);n.src=r,n.onloadedmetadata=()=>t(),n.onerror=()=>i(new Error(`视频文件加载失败: ${e.name}`)),n.play().catch(e=>i(new Error(`视频播放失败: ${e}`))),this.currentMedia=n});if("image"===s)return new Promise((t,n)=>{const r=URL.createObjectURL(e);i.src=r,i.onload=()=>t(),i.onerror=()=>n(new Error(`图片文件加载失败: ${e.name}`)),this.currentMedia=i});throw new Error(`不支持的文件类型: ${r||o}`)}startCanvasStream(e=30){w.info("信息日志:","初始化,使用本地文件推流到云机=======>");const t=this.getCanvas(),n=t.getContext("2d"),i=this.currentMedia;if(!i)throw new Error("请先加载媒体文件");let r=0;const o=1e3/e;let s=1;const a=e=>{if(e-r>=o){let o,s;if(n.clearRect(0,0,t.width,t.height),n.save(),n.translate(t.width/2,t.height/2),n.rotate(Math.PI/2),n.scale(-1,1),i instanceof HTMLVideoElement)o=i.videoWidth,s=i.videoHeight;else{if(!(i instanceof HTMLImageElement))throw new Error("不支持的媒体类型");o=i.width,s=i.height}const a=Math.min(t.height/o,t.width/s),c=o*a,d=s*a;n.drawImage(i,-c/2,-d/2,c,d),n.restore(),r=e}s=requestAnimationFrame(a)};return a(0),this.rafId=requestAnimationFrame(a),this.canvasStream=t.captureStream(e),this.canvasStream.getTracks().forEach(e=>{const t=()=>cancelAnimationFrame(s);e.addEventListener("ended",t),e.addEventListener("stop",t)}),this.canvasStream}getFileImage(){if(!this.fileImage){const e=document.createElement("img");e.style.display="none",document.body.appendChild(e),this.fileImage=e}return this.fileImage}
74
- /** 停止推流并释放资源 */stopLocal(){var e,t;this.isPushingLocalStream&&(this.isPushingLocalStream=!1,cancelAnimationFrame(this.rafId),null==(e=this.canvasStream)||e.getTracks().forEach(e=>e.stop()),this.canvasStream=null,null==(t=this.peerConnection)||t.getSenders().forEach(e=>{var t;try{null==(t=this.peerConnection)||t.removeTrack(e)}catch(n){w.error("错误日志:","移除音视频轨道失败=====>",n)}}),this.fileVideo&&(this.fileVideo.pause(),this.fileVideo.src=""))}}const Xe=async(e,t=600)=>{const n=e.map(e=>({urls:e,username:"yangyj",credential:"hb@2025@168"})).map(e=>((e,t=600)=>new Promise(n=>{const i=performance.now();let r=!1;const o=new RTCPeerConnection({iceServers:[e],iceTransportPolicy:"relay"});o.createDataChannel("test"),o.createOffer().then(e=>o.setLocalDescription(e)).catch(()=>{r||(r=!0,o.close(),n({...e,rtt:1/0}))}),o.onicecandidate=t=>{if(!r){if(t.candidate&&t.candidate.candidate.includes("relay")){const t=Math.trunc(performance.now()-i);r=!0,o.close(),n({...e,rtt:t})}null===t.candidate&&(r=!0,o.close(),n({...e,rtt:1/0}))}},setTimeout(()=>{r||(r=!0,o.close(),n({...e,rtt:1/0}))},t)}))(e,t).then(e=>e).catch(t=>(w.warn("警告日志:","中继计算超时=====>",t),{...e,rtt:1/0}))),i=await Promise.all(n);w.debug("调试日志:","信令计算结果======>",i);const r=i.filter(e=>e.rtt!==1/0);if(0===r.length)throw new Error("All TURN servers are unreachable or slow (RTT = Infinity).");const o=r.sort((e,t)=>e.rtt-t.rtt)[0];return{best:o?Ye(o):void 0,all:i.map(Ye)}},Ye=e=>({urls:e.urls,rtt:e.rtt}),Qe=e=>!(e.hostTurn&&0!==e.hostTurn.length||e.spareTurn&&0!==e.spareTurn.length);class Ze{
75
- // 默认过期时间(毫秒)
76
- constructor(e,t=100,n=3e5){i(this,"key"),i(this,"maxSize"),i(this,"defaultExpire"),this.key=e,this.maxSize=t,this.defaultExpire=n}
77
- /** 从 localStorage 读取 Map(自动清理过期的 item) */getMap(){const e=localStorage.getItem(this.key);if(!e)return new Map;try{const t=JSON.parse(e),n=Date.now(),i=new Map;let r=!1;for(const[e,o]of Object.entries(t))n-o.timestamp<=o.expire?i.set(e,o.value):r=!0;return r&&this.saveMap(i),i}catch{
78
- return new Map}}
79
- /** 保存 Map(每个值都有独立的 timestamp/expire) */saveMap(e,t){const n={},i=Date.now();for(const[r,o]of e.entries())t&&t[r]?n[r]={value:o,timestamp:t[r].timestamp,expire:t[r].expire}:n[r]={value:o,timestamp:i,expire:this.defaultExpire};localStorage.setItem(this.key,JSON.stringify(n))}
80
- /** 设置值(支持单项自定义过期时间) */set(e,t,n){const i=this.getMap(),r=localStorage.getItem(this.key);let o={};if(r)try{o=JSON.parse(r)}catch{o={}}if(i.size>=this.maxSize&&!i.has(e)){const e=i.keys().next().value;"string"==typeof e&&(i.delete(e),delete o[e])}i.set(e,t),o[e]={timestamp:Date.now(),expire:n??this.defaultExpire},this.saveMap(i,o)}
81
- /** 获取值(单项过期会自动清除) */get(e){return this.getMap().get(e)}
82
- /** 检查是否存在且未过期 */has(e){const t=localStorage.getItem(this.key);if(!t)return!1;try{const n=JSON.parse(t)[e];if(!n)return!1;return Date.now()-n.timestamp<=n.expire||(this.delete(e),!1)}catch{return!1}}
83
- /** 删除 */delete(e){const t=this.getMap();t.delete(e);const n=localStorage.getItem(this.key);if(n)try{const i=JSON.parse(n);delete i[e],this.saveMap(t,i)}catch{this.saveMap(t)}else this.saveMap(t)}
84
- /** 清空 */clear(){localStorage.removeItem(this.key)}}class et extends d{constructor(e){super(),i(this,"config",null),i(this,"signalingClient",null),i(this,"webRTCClient",null),i(this,"options"),i(this,"isConnected",!1),i(this,"isConnecting",!1),i(this,"connectCount",0),i(this,"MAX_COUNT",1),i(this,"timeout",null),i(this,"cache"),
89
+ /** 获取或创建 canvas 元素(懒初始化) */getCanvas(){return this.canvas||(this.canvas=document.createElement("canvas"),this.canvas.width=640,this.canvas.height=480),this.canvas}async loadMedia(e){var t;const n=this.getFileVideo(),i=this.getFileImage(),r=e.type.toLowerCase(),o=null==(t=e.name.split(".").pop())?void 0:t.toLowerCase();let s="unknown";if(r.startsWith("video/")||o&&["mp4","webm","ogg","mov","mkv"].includes(o)?s="video":(r.startsWith("image/")||o&&["jpg","jpeg","png","gif","bmp","webp"].includes(o))&&(s="image"),"unknown"===s&&(s=await $e.detectFileType(e)),"video"===s)return new Promise((t,i)=>{const r=URL.createObjectURL(e);n.src=r,n.onloadedmetadata=()=>t(),n.onerror=()=>i(new Error(`视频文件加载失败: ${e.name}`)),n.play().catch(e=>i(new Error(`视频播放失败: ${e}`))),this.currentMedia=n});if("image"===s)return new Promise((t,n)=>{const r=URL.createObjectURL(e);i.src=r,i.onload=()=>t(),i.onerror=()=>n(new Error(`图片文件加载失败: ${e.name}`)),this.currentMedia=i});throw new Error(`不支持的文件类型: ${r||o}`)}startCanvasStream(e=30){w.info("信息日志:","初始化,使用本地文件推流到云机=======>");const t=this.getCanvas(),n=t.getContext("2d"),i=this.currentMedia;if(!i)throw new Error("请先加载媒体文件");let r=0;const o=1e3/e;let s=1;const a=e=>{if(e-r>=o){let o,s;if(n.clearRect(0,0,t.width,t.height),n.save(),n.translate(t.width/2,t.height/2),n.rotate(Math.PI/2),n.scale(-1,1),i instanceof HTMLVideoElement)o=i.videoWidth,s=i.videoHeight;else{if(!(i instanceof HTMLImageElement))throw new Error("不支持的媒体类型");o=i.width,s=i.height}const a=Math.min(t.height/o,t.width/s),c=o*a,d=s*a;n.drawImage(i,-c/2,-d/2,c,d),n.restore(),r=e}s=requestAnimationFrame(a)};return a(0),this.rafId=requestAnimationFrame(a),this.canvasStream=t.captureStream(e),this.canvasStream.getTracks().forEach(e=>{const t=()=>cancelAnimationFrame(s);e.addEventListener("ended",t),e.addEventListener("stop",t)}),this.canvasStream}getFileImage(){if(!this.fileImage){const e=document.createElement("img");e.style.display="none",document.body.appendChild(e),this.fileImage=e}return this.fileImage}
90
+ /** 停止推流并释放资源 */stopLocal(){var e,t;this.isPushingLocalStream&&(this.isPushingLocalStream=!1,cancelAnimationFrame(this.rafId),null==(e=this.canvasStream)||e.getTracks().forEach(e=>e.stop()),this.canvasStream=null,null==(t=this.peerConnection)||t.getSenders().forEach(e=>{var t;try{null==(t=this.peerConnection)||t.removeTrack(e)}catch(n){w.error("错误日志:","移除音视频轨道失败=====>",n)}}),this.fileVideo&&(this.fileVideo.pause(),this.fileVideo.src=""))}}const Xe=async(e,t=600)=>{const n=e.map(e=>({urls:e,username:"yangyj",credential:"hb@2025@168"})).map(e=>((e,t=600)=>new Promise(n=>{const i=performance.now();let r=!1;const o=new RTCPeerConnection({iceServers:[e],iceTransportPolicy:"relay"});o.createDataChannel("test"),o.createOffer().then(e=>o.setLocalDescription(e)).catch(()=>{r||(r=!0,o.close(),n({...e,rtt:1/0}))}),o.onicecandidate=t=>{if(!r){if(t.candidate&&t.candidate.candidate.includes("relay")){const t=Math.trunc(performance.now()-i);r=!0,o.close(),n({...e,rtt:t})}null===t.candidate&&(r=!0,o.close(),n({...e,rtt:1/0}))}},setTimeout(()=>{r||(r=!0,o.close(),n({...e,rtt:1/0}))},t)}))(e,t).then(e=>e).catch(t=>(w.warn("警告日志:","中继计算超时=====>",t),{...e,rtt:1/0}))),i=await Promise.all(n);w.debug("调试日志:","信令计算结果======>",i);const r=i.filter(e=>e.rtt!==1/0);if(0===r.length)throw new Error("All TURN servers are unreachable or slow (RTT = Infinity).");const o=r.sort((e,t)=>e.rtt-t.rtt)[0];return{best:o?Ye(o):void 0,all:i.map(Ye)}},Ye=e=>({urls:e.urls,rtt:e.rtt}),Qe=e=>!(e.hostTurn&&0!==e.hostTurn.length||e.spareTurn&&0!==e.spareTurn.length);class Ze extends d{
91
+ // private cache: MapCache;
92
+ constructor(e){super(),i(this,"config",null),i(this,"signalingClient",null),i(this,"webRTCClient",null),i(this,"options"),i(this,"isConnected",!1),i(this,"isConnecting",!1),i(this,"connectCount",0),i(this,"MAX_COUNT",1),i(this,"timeout",null),
85
93
  /**
86
94
  * 处理 signal 消息,根据不同消息类型分发到 webRTCClient 或直接触发 SDK 事件
87
95
  * @param message 信令消息
@@ -92,11 +100,11 @@ i(this,"sendOffer",e=>{var t,n;if(this.config&&e&&e.length>0){const i=(null==(t=
92
100
  /** 发送 Answer 信令 */
93
101
  i(this,"sendAnswer",e=>{var t,n;if(this.config&&e&&e.length>0){const i=(null==(t=this.config.connectorAndRoomId)?void 0:t.get(this.config.roomId))??"";let r=this.config.targetId;i&&(r=i);const o={traceId:this.config.traceId,type:h.Answer,identity:h.Identity,roomId:this.config.roomId,senderId:this.config.myId,targetId:r,sdp:e};null==(n=this.signalingClient)||n.sendMessage(JSON.stringify(o))}}),
94
102
  /** 发送 ICE 候选信息 */
95
- i(this,"sendICEMessage",e=>{var t,n;if(!this.config)return;const i=(null==(t=this.config.connectorAndRoomId)?void 0:t.get(this.config.roomId))??"";let r=this.config.targetId;if(i&&(r=i),e&&e.length>0){const t={traceId:this.config.traceId,type:h.IceCandidates,identity:h.Identity,roomId:this.config.roomId,senderId:this.config.myId,targetId:r,ice:e};null==(n=this.signalingClient)||n.sendMessage(JSON.stringify(t))}}),this.options=e,void 0!==this.options.cacheTimeout&&this.options.cacheTimeout>0?this.cache=new Ze("screenCache",100,this.options.cacheTimeout):this.cache=new Ze("screenCache",100),this.options.connectorType!==p.LanForwarding&&(b(!!this.options.enableLogger),void 0!==this.options.enableLogger&&this.options.enableLogger&&void 0!==this.options.loggerLevel&&R(this.options.loggerLevel)),this.options.maxRecount&&(this.MAX_COUNT=this.options.maxRecount)}async initConfig(){var e,t;if(!this.options||0===Object.keys(this.options).length)throw g(u.OPTION_ERR,"option null");if(Qe(this.options))throw g(u.OPTION_ERR,"中继配置为空");const n=async(e,t)=>{if(0===e.length)return!1;try{const n=await(async e=>{var t,n;try{const i=await Xe(e);return{url:null==(t=i.best)?void 0:t.urls,rtt:null==(n=i.best)?void 0:n.rtt}}catch(i){return{error:i.message||"未知错误"}}})(e);return!(!n.url||"number"!=typeof n.rtt)&&(!(t&&n.rtt>150)&&(this.options.turnServerUri=n.url,this.cache.set(this.options.roomId,this.options.turnServerUri),this.options.turnKey=[n.url],!0))}catch(n){return!1}},i=!!(null==(e=this.options.hostTurn)?void 0:e.length)&&await n(this.options.hostTurn,!0);if(!i&&(null==(t=this.options.spareTurn)?void 0:t.length)){const e=(this.options.hostTurn??[]).concat(this.options.spareTurn??[]);if(!(await n(e,!1))){if(!this.options.turnServerUri)throw g(u.OPTION_ERR,"暂无可用TURN服务器");this.options.turnKey=[this.options.turnServerUri]}}else if(!i){if(!(await n(this.options.hostTurn??[],!1))){if(!this.options.turnServerUri)throw g(u.OPTION_ERR,"暂无可用TURN服务器");this.options.turnKey=[this.options.turnServerUri]}}}
96
- /** 开始连接 signal 服务 */startConnection(){this.prepareConnection().catch(e=>{w.error("错误信息:","sdk调试错误日志======>",e),this.emit(y.webrtcError,e)})}async prepareConnection(){var e;if(!this.isConnecting){this.isConnecting=!0;try{if(Qe(this.options)){if(!this.options.turnServerUri)return w.error("错误信息:","sdk调试错误日志======> 暂无可用TURN服务器"),void this.emit(y.webrtcError,g(u.OPTION_ERR,"暂无可用TURN服务器"))}else{if(this.cache.has(this.options.roomId)){const e=this.cache.get(this.options.roomId);this.options.turnServerUri=e,this.options.turnKey=[e]}else await this.initConfig()}this.initConnectConfig(),this.initSignalingClient(),null==(e=this.signalingClient)||e.start()}catch(t){throw this.isConnected=!1,t}finally{this.isConnecting=!1}}}async reconnect(){this.resetConfig();try{await this.prepareConnection()}catch(e){w.error("错误信息:","sdk调试错误日志======>",e),this.emit(y.webrtcError,e)}}initConnectConfig(e=!0){var t,n,i,r,o,s,a,c,d,l;e&&(this.config=new De(this.options)),this.config&&(this.webRTCClient=new $e(this.config)),null==(t=this.webRTCClient)||t.on(y.sendOffer,e=>this.sendOffer(e)),null==(n=this.webRTCClient)||n.on(y.sendAnswer,e=>this.sendAnswer(e)),null==(i=this.webRTCClient)||i.on(y.sendICEMessage,e=>this.sendICEMessage(e)),null==(r=this.webRTCClient)||r.on(y.streamTrack,e=>{w.debug("调试信息:","=========> EmitType.streamTrack callback"),this.emit(y.streamTrack,e)}),null==(o=this.webRTCClient)||o.on(y.iceConnectionState,e=>{this.emit(y.iceConnectionState,e),"connected"===e&&(this.isConnected=!0)}),null==(s=this.webRTCClient)||s.on(y.cloudStatusChanged,e=>this.emit(y.cloudStatusChanged,e)),null==(a=this.webRTCClient)||a.on(y.cloudClipData,e=>this.emit(y.cloudClipData,e)),null==(c=this.webRTCClient)||c.on(y.webrtcError,e=>{e.code===u.ICE_STATE&&this.connectCount<this.MAX_COUNT&&this.isConnected?(this.connectCount++,this.emit(y.reconnect),this.reconnect()):(w.error("错误信息:","sdk调试错误日志======>",e),this.emit(y.webrtcError,e))}),null==(d=this.webRTCClient)||d.on(y.cameraError,e=>{this.emit(y.cameraError,e)}),null==(l=this.webRTCClient)||l.on(y.statisticInfo,e=>{this.emit(y.statisticInfo,e)})}initSignalingClient(){this.config&&(this.signalingClient=new E(this.config),this.signalingClient.on(y.signalMessage,e=>this.handleSignaling(e)),this.signalingClient.on(y.webrtcError,e=>{w.error("错误信息:","sdk 信令调试错误日志======>",e),this.emit(y.webrtcError,e)}))}switchControl(e,t){var n;null==(n=this.signalingClient)||n.sendSwitchControlMessage(e,t)}updateConfig(e){this.config&&(this.config.roomId=e.roomId,this.config.mainRoomIdOfGroup=e.mainRoomIdOfGroup,this.config.subRoomIdsOfGroup=e.subRoomIdsOfGroup)}switchControlToMain(e){var t,n;null==(t=this.webRTCClient)||t.closeConnection(),this.webRTCClient=null,this.initConnectConfig(!1),null==(n=this.signalingClient)||n.sendSwitchControlToMainMessage(e)}resetConfig(){var e,t;this.sendSignOut(),null==(e=this.signalingClient)||e.close(),null==(t=this.webRTCClient)||t.closeConnection(),this.signalingClient=null,this.webRTCClient=null,this.config=null,this.isConnected=!1,this.isConnecting=!1}
103
+ i(this,"sendICEMessage",e=>{var t,n;if(!this.config)return;const i=(null==(t=this.config.connectorAndRoomId)?void 0:t.get(this.config.roomId))??"";let r=this.config.targetId;if(i&&(r=i),e&&e.length>0){const t={traceId:this.config.traceId,type:h.IceCandidates,identity:h.Identity,roomId:this.config.roomId,senderId:this.config.myId,targetId:r,ice:e};null==(n=this.signalingClient)||n.sendMessage(JSON.stringify(t))}}),this.options=e,this.options.connectorType!==p.LanForwarding&&(b(!!this.options.enableLogger),void 0!==this.options.enableLogger&&this.options.enableLogger&&void 0!==this.options.loggerLevel&&R(this.options.loggerLevel)),this.options.maxRecount&&(this.MAX_COUNT=this.options.maxRecount)}async initConfig(){var e,t;if(!this.options||0===Object.keys(this.options).length)throw g(u.OPTION_ERR,"option null");if(Qe(this.options))throw g(u.OPTION_ERR,"中继配置为空");const n=async(e,t)=>{if(0===e.length)return!1;try{const n=await(async e=>{var t,n;try{const i=await Xe(e);return{url:null==(t=i.best)?void 0:t.urls,rtt:null==(n=i.best)?void 0:n.rtt}}catch(i){return{error:i.message||"未知错误"}}})(e);return!(!n.url||"number"!=typeof n.rtt)&&(!(t&&n.rtt>150)&&(this.options.turnServerUri=n.url,this.options.turnKey=[n.url],!0))}catch(n){return!1}},i=!!(null==(e=this.options.hostTurn)?void 0:e.length)&&await n(this.options.hostTurn,!0);if(!i&&(null==(t=this.options.spareTurn)?void 0:t.length)){const e=(this.options.hostTurn??[]).concat(this.options.spareTurn??[]);if(!(await n(e,!1))){if(!this.options.turnServerUri)throw g(u.OPTION_ERR,"暂无可用TURN服务器");this.options.turnKey=[this.options.turnServerUri]}}else if(!i){if(!(await n(this.options.hostTurn??[],!1))){if(!this.options.turnServerUri)throw g(u.OPTION_ERR,"暂无可用TURN服务器");this.options.turnKey=[this.options.turnServerUri]}}}
104
+ /** 开始连接 signal 服务 */startConnection(){this.prepareConnection().catch(e=>{w.error("错误信息:","sdk调试错误日志======>",e),this.emit(y.webrtcError,e)})}async prepareConnection(){var e;if(!this.isConnecting){this.isConnecting=!0;try{if(Qe(this.options)){if(!this.options.turnServerUri)return w.error("错误信息:","sdk调试错误日志======> 暂无可用TURN服务器"),void this.emit(y.webrtcError,g(u.OPTION_ERR,"暂无可用TURN服务器"))}else await this.initConfig();this.initConnectConfig(),this.initSignalingClient(),null==(e=this.signalingClient)||e.start()}catch(t){throw this.isConnected=!1,t}finally{this.isConnecting=!1}}}async reconnect(){this.resetConfig();try{await this.prepareConnection()}catch(e){w.error("错误信息:","sdk调试错误日志======>",e),this.emit(y.webrtcError,e)}}initConnectConfig(e=!0){var t,n,i,r,o,s,a,c,d,l;e&&(this.config=new De(this.options)),this.config&&(this.webRTCClient=new qe(this.config)),null==(t=this.webRTCClient)||t.on(y.sendOffer,e=>this.sendOffer(e)),null==(n=this.webRTCClient)||n.on(y.sendAnswer,e=>this.sendAnswer(e)),null==(i=this.webRTCClient)||i.on(y.sendICEMessage,e=>this.sendICEMessage(e)),null==(r=this.webRTCClient)||r.on(y.streamTrack,e=>{w.debug("调试信息:","=========> EmitType.streamTrack callback"),this.emit(y.streamTrack,e)}),null==(o=this.webRTCClient)||o.on(y.iceConnectionState,e=>{this.emit(y.iceConnectionState,e),"connected"===e&&(this.isConnected=!0)}),null==(s=this.webRTCClient)||s.on(y.cloudStatusChanged,e=>this.emit(y.cloudStatusChanged,e)),null==(a=this.webRTCClient)||a.on(y.cloudClipData,e=>this.emit(y.cloudClipData,e)),null==(c=this.webRTCClient)||c.on(y.webrtcError,e=>{e.code===u.ICE_STATE&&this.connectCount<this.MAX_COUNT&&this.isConnected?(this.connectCount++,this.emit(y.reconnect),this.reconnect()):(w.error("错误信息:","sdk调试错误日志======>",e),this.emit(y.webrtcError,e))}),null==(d=this.webRTCClient)||d.on(y.cameraError,e=>{this.emit(y.cameraError,e)}),null==(l=this.webRTCClient)||l.on(y.statisticInfo,e=>{this.emit(y.statisticInfo,e)})}initSignalingClient(){this.config&&(this.signalingClient=new E(this.config),this.signalingClient.on(y.signalMessage,e=>this.handleSignaling(e)),this.signalingClient.on(y.webrtcError,e=>{w.error("错误信息:","sdk 信令调试错误日志======>",e),this.emit(y.webrtcError,e)}))}switchControl(e,t){var n;null==(n=this.signalingClient)||n.sendSwitchControlMessage(e,t)}updateConfig(e){this.config&&(this.config.roomId=e.roomId,this.config.mainRoomIdOfGroup=e.mainRoomIdOfGroup,this.config.subRoomIdsOfGroup=e.subRoomIdsOfGroup)}switchControlToMain(e){var t,n;null==(t=this.webRTCClient)||t.closeConnection(),this.webRTCClient=null,this.initConnectConfig(!1),null==(n=this.signalingClient)||n.sendSwitchControlToMainMessage(e)}resetConfig(){var e,t;this.sendSignOut(),null==(e=this.signalingClient)||e.close(),null==(t=this.webRTCClient)||t.closeConnection(),this.signalingClient=null,this.webRTCClient=null,this.config=null,this.isConnected=!1,this.isConnecting=!1}
97
105
  /** 停止连接,并发送退出信令 */stop(){var e,t;this.sendSignOut(),null==(e=this.signalingClient)||e.close(),null==(t=this.webRTCClient)||t.closeConnection(),this.removeAllListeners(),this.signalingClient=null,this.webRTCClient=null,this.config=null,this.connectCount=0,this.isConnected=!1,this.isConnecting=!1}
98
106
  /** 开始推流:触发媒体采集与轨道添加 */async startPush(){var e;try{await(null==(e=this.webRTCClient)?void 0:e.startPush())}catch(t){let e;e=t instanceof Error?t.message:String(t),this.emit(y.cameraError,C(m.CAMERA_STREAM_FAIL,e))}}async startPushLocal(e){var t;try{await(null==(t=this.webRTCClient)?void 0:t.startPushLocal(e))}catch(n){let e;e=n instanceof Error?n.message:String(n),this.emit(y.cameraError,C(m.LOCAL_STREAM_FAIL,e))}}stopPush(){var e;null==(e=this.webRTCClient)||e.stopPush()}stopPushLocal(){var e;null==(e=this.webRTCClient)||e.stopLocal()}
99
- /** 发送信道数据 */sendChannelData(e,t){var n;null==(n=this.webRTCClient)||n.sendChannelData(e,t)}sendControlEvent(e){var t;const n=new Be(e,0);null==(t=this.webRTCClient)||t.sendChannelData(je.ActionInput,n)}sendGroupAcceptControl(e,t){var n;null==(n=this.signalingClient)||n.sendGroupAcceptControl(e,t)}sendPong(){var e;const t={type:h.Pong},n=JSON.stringify(t);null==(e=this.signalingClient)||e.sendMessage(n)}sendSignOut(){var e,t;if(this.config)if(this.config.connectorType===p.LanForwarding){const t={type:h.GroupSignOut,identity:h.Identity,token:this.config.token,groupId:this.config.groupId};null==(e=this.signalingClient)||e.sendMessage(JSON.stringify(t))}else{const e={type:h.SignOut,identity:h.Identity,roomId:this.config.roomId,myId:this.config.myId};null==(t=this.signalingClient)||t.sendMessage(JSON.stringify(e))}}groupSendAction(e,t){var n,i;try{let r=null;switch(e){case je.ClickData:r=He.click(t);break;case je.ClipboardData:r=He.clipboard(t);break;case je.ActionInput:r=He.input(t,(null==(n=this.config)?void 0:n.myId)??"");break;case je.ActionChinese:r=He.chinese(t);break;case je.ActionRequestCloudDeviceInfo:r=He.requestCloudDeviceInfo();break;case je.ActionClarity:r=He.clarity(t);break;case je.ActionWheel:r=He.wheel(t);break;case je.ActionGesture:r=He.gesture(t);break;case je.ActionCommand:r=He.action(t);break;case je.ActionCommandEvent:r=He.switchAudio(t)}if(r){const e=JSON.stringify(r);null==(i=this.signalingClient)||i.sendGroupAction(e)}}catch(r){this.emit(y.webrtcError,g(u.DATACHANNEL_ERR,r))}}}const tt={
107
+ /** 发送信道数据 */sendChannelData(e,t){var n;null==(n=this.webRTCClient)||n.sendChannelData(e,t)}sendControlEvent(e){var t;const n=new Je(e,0);null==(t=this.webRTCClient)||t.sendChannelData(je.ActionInput,n)}sendGroupAcceptControl(e,t){var n;null==(n=this.signalingClient)||n.sendGroupAcceptControl(e,t)}sendPong(){var e;const t={type:h.Pong},n=JSON.stringify(t);null==(e=this.signalingClient)||e.sendMessage(n)}sendSignOut(){var e,t;if(this.config)if(this.config.connectorType===p.LanForwarding){const t={type:h.GroupSignOut,identity:h.Identity,token:this.config.token,groupId:this.config.groupId};null==(e=this.signalingClient)||e.sendMessage(JSON.stringify(t))}else{const e={type:h.SignOut,identity:h.Identity,roomId:this.config.roomId,myId:this.config.myId};null==(t=this.signalingClient)||t.sendMessage(JSON.stringify(e))}}groupSendAction(e,t){var n,i;try{let r=null;switch(e){case je.ClickData:r=He.click(t);break;case je.ClipboardData:r=He.clipboard(t);break;case je.ActionInput:r=He.input(t,(null==(n=this.config)?void 0:n.myId)??"");break;case je.ActionChinese:r=He.chinese(t);break;case je.ActionRequestCloudDeviceInfo:r=He.requestCloudDeviceInfo();break;case je.ActionClarity:r=He.clarity(t);break;case je.ActionWheel:r=He.wheel(t);break;case je.ActionGesture:r=He.gesture(t);break;case je.ActionCommand:r=He.action(t);break;case je.ActionCommandEvent:r=He.switchAudio(t)}if(r){const e=JSON.stringify(r);null==(i=this.signalingClient)||i.sendGroupAction(e)}}catch(r){this.emit(y.webrtcError,g(u.DATACHANNEL_ERR,r))}}}const et={
100
108
  // 数字键
101
109
  Digit1:8,Digit2:9,Digit3:10,Digit4:11,Digit5:12,Digit6:13,Digit7:14,Digit8:15,Digit9:16,Digit0:7,
102
110
  // 符号键(主键盘区)
@@ -114,7 +122,7 @@ F1:131,F2:132,F3:133,F4:134,F5:135,F6:136,F7:137,F8:138,F9:139,F10:140,F11:141,F
114
122
  // 数字小键盘
115
123
  Numpad0:7,Numpad1:8,Numpad2:9,Numpad3:10,Numpad4:11,Numpad5:12,Numpad6:13,Numpad7:14,Numpad8:15,Numpad9:16,NumpadAdd:157,NumpadSubtract:156,NumpadMultiply:155,NumpadDivide:154,NumpadDecimal:158,NumpadEnter:66,
116
124
  // 其他特殊键
117
- Insert:124,Delete:112,Home:122,End:123,PageUp:92,PageDown:93,ScrollLock:116,Pause:121,ContextMenu:117},nt=e=>{const t=tt[e.code]??-1,n=(e=>{let t=0;return e.shiftKey&&(t|=1),e.altKey&&(t|=2),e.ctrlKey&&(t|=4096),e.metaKey&&(t|=65536),t})(e);return{keyCode:t,meta:n}};function it(e,t,n,i,r,o,s,a){let c,d;-90===r?(d=t,c=n*e/i):(d=e,c=n*t/i);const l=(d-c)/2,h=d/2,p=l,u=d-l,f=h-l;if(-90===r){const e=ot(l,h,p,u,f,a);return-90===o?[s,e]:[t-e,s]}{const n=ot(l,h,p,u,f,s);if(-90===o){const[i,r]=function(e,t,n,i){const r=t/2,o=e/2,s=n-o,a=i-r;return[a+r,-s+o]}(e,t,n,a);return[i,r]}return[n,a]}}function rt(e,t,n,i,r,o,s,a){let c,d;return 0===r&&0===o?(c=s/e,d=a/t):-90===r&&0===o?(c=s/t,d=a/e):-90===r&&-90===o?(c=s/e*(i/n),d=a/t*(n/i)):(c=s/t*(i/n),d=a/e*(n/i)),[c,d]}function ot(e,t,n,i,r,o){return o>=n&&o<=t-.1?(o-e)*t/r:o===t?t:o>=t+.1&&o<=i?t+(o-t)*t/r:o}function st(e,n,i,r){const o=t.ref(!1),s=t.ref({}),a=t.ref({width:0,height:0}),c=t.ref(0),d=t.ref(0),l=t.ref(null),h=t.ref(0),p=t.computed(()=>i.value%180!=0),u=t.computed(()=>{let e=0,t=0;const n=p.value?a.value.height:a.value.width,i=p.value?a.value.width:a.value.height,r=s.value.width??720,o=s.value.height??1280,l=r/o,h=n/l;return h>i?(t=i,e=t*l):(e=n,t=h),c.value=r/e,d.value=o/t,{width:e,height:t}}),f=(e,t)=>{e.srcObject||(e.srcObject=new MediaStream);const n=e.srcObject;m(n,t),e.playsInline=!0,e.setAttribute("webkit-playsinline","true")},m=(e,t)=>{"video"===t.kind?(e.getVideoTracks().forEach(t=>{e.removeTrack(t),t.stop()}),e.addTrack(t)):"audio"===t.kind&&(e.getAudioTracks().some(e=>e.id===t.id)||e.addTrack(t))},g=()=>{o.value=!1;const e=n.value;e&&e.srcObject&&(e.srcObject.getTracks().forEach(e=>e.stop()),e.srcObject=null,e.cancelVideoFrameCallback(h.value))},C=()=>{if("visible"===document.visibilityState){const e=n.value;e&&e.srcObject&&e.srcObject.getTracks().forEach(e=>{"audio"!==e.kind||e.enabled||(e.enabled=!0)})}else{const e=n.value;e&&e.srcObject&&e.srcObject.getTracks().forEach(e=>{"audio"===e.kind&&e.enabled&&(e.enabled=!1)})}};return t.onMounted(()=>{document.addEventListener("visibilitychange",C)}),t.onBeforeUnmount(()=>{document.removeEventListener("visibilitychange",C),l.value&&e.value&&l.value.unobserve(e.value),g()}),{videoSize:u,remoteVideo:s,dimensions:a,widthRadio:c,heightRadio:d,screenStatus:o,initVideoContainer:()=>{e.value&&(l.value=new ResizeObserver(([e])=>{const{width:t,height:n}=e.contentRect;a.value={width:t,height:n}}),l.value.observe(e.value)),(()=>{const e=n.value;if(!e)return;const i=()=>{s.value={width:e.videoWidth,height:e.videoHeight},o.value=!0,r("loadedSuccess")};e.addEventListener("loadedmetadata",i),t.onBeforeUnmount(()=>{e.removeEventListener("loadedmetadata",i)})})()},startPlay:e=>{const t=n.value;t&&f(t,e)},stopPlay:g}}const at=((e,t)=>{const n=e.__vccOpts||e;for(const[i,r]of t)n[i]=r;return n})(t.defineComponent({__name:"index",props:{streamAngle:{default:0},videoAngle:{default:0},cursorType:{default:0},cloudDeviceSize:{default:()=>({width:0,height:0})},disabled:{type:Boolean,default:!0},bgColor:{default:"transparent"}},emits:["channelEvent","groupControlEvent","loadedSuccess"],setup(e,{expose:n,emit:i}){const r=i,o=e,{streamAngle:s,videoAngle:a,cursorType:c,cloudDeviceSize:d,disabled:l,bgColor:h}=t.toRefs(o),p=t.ref(null),u=t.ref(null),f=function(e){return t.computed(()=>{switch(e.value){case 1:return"circle-cursor";case 2:return"triangle-cursor";default:return"default-cursor"}})}(c),{videoSize:m,dimensions:g,widthRadio:C,initVideoContainer:y,startPlay:v,stopPlay:S}=st(p,u,a,r),{handleMouseDown:T,handleMouseMove:R,handleMouseEnter:b,handleMouseUp:w,handleMouseLeave:E,handleWheel:P}=function(e){const{remoteVideoElement:n,cloudDeviceSize:i,streamAngle:r,videoAngle:o,widthRadio:s,emit:a}=e,c=t.ref(!1),d=t.ref(0),l=t.ref(new Array(20).fill(0)),h=t.ref(new Array(10).fill(0)),p=(e,t)=>{if(!n.value)return;const s=Math.trunc(e.timeStamp-h.value[0]),c=n.value.getBoundingClientRect();let p=e.clientX-c.left,u=e.clientY-c.top;const f=i.value.width,m=i.value.height,g=it(c.width,c.height,f,m,o.value,r.value,p,u);if(!g||g.length<2)return;if(p=g[0],u=g[1],t===Ke.ACTION_MOVE){const e=l.value[10]-u,t=l.value[0]-p;if(Math.abs(e)<d.value&&Math.abs(t)<d.value)return}l.value[0]=p,l.value[10]=u;const C=rt(c.width,c.height,f,m,o.value,r.value,p,u),y=new We(t,0,C[0],C[1],s);a("channelEvent",je.ClickData,y)},u=e=>{c.value&&(c.value=!1,p(e,Ke.ACTION_UP),n.value&&n.value.releasePointerCapture(e.pointerId))};return{isPointerDown:c,handleMouseDown:e=>{c.value=!0,n.value&&n.value.setPointerCapture(e.pointerId),h.value[0]=e.timeStamp,d.value=Math.trunc(6/s.value),p(e,Ke.ACTION_DOWN)},handleMouseMove:e=>{if(!c.value)return;if(p(e,Ke.ACTION_MOVE),!n.value)return;const t=n.value.getBoundingClientRect(),{clientX:i,clientY:r}=e;(i<t.left||i>t.right||r<t.top||r>t.bottom)&&u(e)},handleMouseEnter:e=>{1!==e.buttons||c.value||(c.value=!0,n.value&&n.value.setPointerCapture(e.pointerId),h.value[0]=e.timeStamp,d.value=Math.trunc(6/s.value),p(e,Ke.ACTION_DOWN))},handleMouseUp:u,handleMouseLeave:e=>{c.value&&(p(e,Ke.ACTION_UP),c.value=!1,n.value&&n.value.releasePointerCapture(e.pointerId))},handleWheel:e=>{const t=-1*Math.sign(e.deltaY),n=new Je(t);a("channelEvent",je.ActionWheel,n)}}}({remoteVideoElement:u,cloudDeviceSize:d,streamAngle:s,videoAngle:a,widthRadio:C,emit:r}),{startListening:k,stopListening:I}=function(e,n){const i=t.ref(!1),r=e=>{const t=nt(e);n("channelEvent",je.ActionInput,t)};return{startListening:()=>{e&&(i.value=!0,document.addEventListener("keydown",r))},stopListening:()=>{e&&(i.value=!1,document.removeEventListener("keydown",r))}}}(l,r);!function(e,n){let i=null;t.onMounted(()=>{e.value&&(i=new ResizeObserver(e=>{for(const t of e){const{width:e,height:i}=t.contentRect;n.value={width:e,height:i}}}),i.observe(e.value))}),t.onUnmounted(()=>{null==i||i.disconnect()})}(p,g);const A=()=>{var e;(null==(e=u.value)?void 0:e.srcObject)&&(u.value.muted=!1)};return t.onMounted(()=>{document.addEventListener("click",A),y()}),t.onBeforeUnmount(()=>{document.removeEventListener("click",A)}),n({startPlay:v,stopPlay:S,remoteVideoElement:u}),(e,n)=>(t.openBlock(),t.createElementBlock("div",{ref_key:"videoContainer",ref:p,class:"flex flex-1 items-center justify-center",style:{width:"100%",height:"100%",position:"relative",overflow:"hidden"}},[t.createElementVNode("div",{ref:"keyboardArea",onPointerenter:n[6]||(n[6]=//@ts-ignore
125
+ Insert:124,Delete:112,Home:122,End:123,PageUp:92,PageDown:93,ScrollLock:116,Pause:121,ContextMenu:117},tt=e=>{const t=et[e.code]??-1,n=(e=>{let t=0;return e.shiftKey&&(t|=1),e.altKey&&(t|=2),e.ctrlKey&&(t|=4096),e.metaKey&&(t|=65536),t})(e);return{keyCode:t,meta:n}};function nt(e,t,n,i,r,o,s,a){let c,d;-90===r?(d=t,c=n*e/i):(d=e,c=n*t/i);const l=(d-c)/2,h=d/2,p=l,u=d-l,f=h-l;if(-90===r){const e=rt(l,h,p,u,f,a);return-90===o?[s,e]:[t-e,s]}{const n=rt(l,h,p,u,f,s);if(-90===o){const[i,r]=function(e,t,n,i){const r=t/2,o=e/2,s=n-o,a=i-r;return[a+r,-s+o]}(e,t,n,a);return[i,r]}return[n,a]}}function it(e,t,n,i,r,o,s,a){let c,d;return 0===r&&0===o?(c=s/e,d=a/t):-90===r&&0===o?(c=s/t,d=a/e):-90===r&&-90===o?(c=s/e*(i/n),d=a/t*(n/i)):(c=s/t*(i/n),d=a/e*(n/i)),[c,d]}function rt(e,t,n,i,r,o){return o>=n&&o<=t-.1?(o-e)*t/r:o===t?t:o>=t+.1&&o<=i?t+(o-t)*t/r:o}function ot(e,n,i,r){const o=t.ref(!1),s=t.ref({}),a=t.ref({width:0,height:0}),c=t.ref(0),d=t.ref(0),l=t.ref(null),h=t.computed(()=>i.value%180!=0),p=t.ref(0),u=t.computed(()=>{let e=0,t=0;const n=h.value?a.value.height:a.value.width,i=h.value?a.value.width:a.value.height,r=s.value.width??720,o=s.value.height??1280,l=r/o,p=n/l;return p>i?(t=i,e=t*l):(e=n,t=p),c.value=r/e,d.value=o/t,{width:e,height:t}}),f=(e,t)=>{e.srcObject||(e.srcObject=new MediaStream);const n=e.srcObject;m(n,t),e.playbackRate=1,e.playsInline=!0,e.disablePictureInPicture=!0,e.setAttribute("playsinline","true"),e.setAttribute("webkit-playsinline","true"),e.setAttribute("x5-video-player-type","h5"),e.setAttribute("x5-video-player-fullscreen","false"),e.setAttribute("x5-video-orientation","portraint"),e.preload="auto"},m=(e,t)=>{"video"===t.kind?(e.getVideoTracks().forEach(t=>{e.removeTrack(t),t.stop()}),e.addTrack(t)):"audio"===t.kind&&(e.getAudioTracks().some(e=>e.id===t.id)||e.addTrack(t))},g=()=>{o.value=!1;const e=n.value;e&&e.srcObject&&(e.srcObject.getTracks().forEach(e=>e.stop()),e.srcObject=null,p.value&&e.cancelVideoFrameCallback(p.value))},C=()=>{const e=n.value;e&&e.srcObject&&e.srcObject.getTracks().forEach(e=>{"audio"===e.kind&&(e.enabled="visible"===document.visibilityState)})};t.onMounted(()=>{document.addEventListener("visibilitychange",C)}),t.onBeforeUnmount(()=>{document.removeEventListener("visibilitychange",C),l.value&&e.value&&l.value.unobserve(e.value),g()});const y=e=>{const t=(n,i)=>{e.playbackRate=1.1,setTimeout(()=>{e.playbackRate=1},600),p.value=e.requestVideoFrameCallback(t)};p.value=e.requestVideoFrameCallback(t)};return{videoSize:u,remoteVideo:s,dimensions:a,widthRadio:c,heightRadio:d,screenStatus:o,initVideoContainer:()=>{e.value&&(l.value=new ResizeObserver(([e])=>{const{width:t,height:n}=e.contentRect;a.value={width:t,height:n}}),l.value.observe(e.value)),(()=>{const e=n.value;if(!e)return;const i=()=>{s.value={width:e.videoWidth,height:e.videoHeight},o.value=!0,r("loadedSuccess"),/Android|iPhone|iPad/i.test(navigator.userAgent)&&y(e)};e.addEventListener("loadedmetadata",i),t.onBeforeUnmount(()=>{e.removeEventListener("loadedmetadata",i),p.value&&e.cancelVideoFrameCallback(p.value)})})()},startPlay:e=>{const t=n.value;t&&f(t,e)},stopPlay:g}}const st=((e,t)=>{const n=e.__vccOpts||e;for(const[i,r]of t)n[i]=r;return n})(t.defineComponent({__name:"index",props:{streamAngle:{default:0},videoAngle:{default:0},cursorType:{default:0},cloudDeviceSize:{default:()=>({width:0,height:0})},disabled:{type:Boolean,default:!0},bgColor:{default:"transparent"}},emits:["channelEvent","groupControlEvent","loadedSuccess"],setup(e,{expose:n,emit:i}){const r=i,o=e,{streamAngle:s,videoAngle:a,cursorType:c,cloudDeviceSize:d,disabled:l,bgColor:h}=t.toRefs(o),p=t.ref(null),u=t.ref(null),f=function(e){return t.computed(()=>{switch(e.value){case 1:return"circle-cursor";case 2:return"triangle-cursor";default:return"default-cursor"}})}(c),{videoSize:m,dimensions:g,widthRadio:C,initVideoContainer:y,startPlay:v,stopPlay:S}=ot(p,u,a,r),{handleMouseDown:T,handleMouseMove:R,handleMouseEnter:b,handleMouseUp:w,handleMouseLeave:E,handleWheel:P}=function(e){const{remoteVideoElement:n,cloudDeviceSize:i,streamAngle:r,videoAngle:o,widthRadio:s,emit:a}=e,c=t.ref(!1),d=t.ref(0),l=t.ref(new Array(20).fill(0)),h=t.ref(new Array(10).fill(0)),p=(e,t)=>{if(!n.value)return;const s=Math.trunc(e.timeStamp-h.value[0]),c=n.value.getBoundingClientRect();let p=e.clientX-c.left,u=e.clientY-c.top;const f=i.value.width,m=i.value.height,g=nt(c.width,c.height,f,m,o.value,r.value,p,u);if(!g||g.length<2)return;if(p=g[0],u=g[1],t===Ke.ACTION_MOVE){const e=l.value[10]-u,t=l.value[0]-p;if(Math.abs(e)<d.value&&Math.abs(t)<d.value)return}l.value[0]=p,l.value[10]=u;const C=it(c.width,c.height,f,m,o.value,r.value,p,u),y=new We(t,0,C[0],C[1],s);a("channelEvent",je.ClickData,y)},u=e=>{c.value&&(c.value=!1,p(e,Ke.ACTION_UP),n.value&&n.value.releasePointerCapture(e.pointerId))};return{isPointerDown:c,handleMouseDown:e=>{c.value=!0,n.value&&n.value.setPointerCapture(e.pointerId),h.value[0]=e.timeStamp,d.value=Math.trunc(6/s.value),p(e,Ke.ACTION_DOWN)},handleMouseMove:e=>{if(!c.value)return;if(p(e,Ke.ACTION_MOVE),!n.value)return;const t=n.value.getBoundingClientRect(),{clientX:i,clientY:r}=e;(i<t.left||i>t.right||r<t.top||r>t.bottom)&&u(e)},handleMouseEnter:e=>{1!==e.buttons||c.value||(c.value=!0,n.value&&n.value.setPointerCapture(e.pointerId),h.value[0]=e.timeStamp,d.value=Math.trunc(6/s.value),p(e,Ke.ACTION_DOWN))},handleMouseUp:u,handleMouseLeave:e=>{c.value&&(p(e,Ke.ACTION_UP),c.value=!1,n.value&&n.value.releasePointerCapture(e.pointerId))},handleWheel:e=>{const t=-1*Math.sign(e.deltaY),n=new Be(t);a("channelEvent",je.ActionWheel,n)}}}({remoteVideoElement:u,cloudDeviceSize:d,streamAngle:s,videoAngle:a,widthRadio:C,emit:r}),{startListening:k,stopListening:I}=function(e,n){const i=t.ref(!1),r=e=>{const t=tt(e);n("channelEvent",je.ActionInput,t)};return{startListening:()=>{e&&(i.value=!0,document.addEventListener("keydown",r))},stopListening:()=>{e&&(i.value=!1,document.removeEventListener("keydown",r))}}}(l,r);!function(e,n){let i=null;t.onMounted(()=>{e.value&&(i=new ResizeObserver(e=>{for(const t of e){const{width:e,height:i}=t.contentRect;n.value={width:e,height:i}}}),i.observe(e.value))}),t.onUnmounted(()=>{null==i||i.disconnect()})}(p,g);const A=()=>{var e;(null==(e=u.value)?void 0:e.srcObject)&&(u.value.muted=!1)};return t.onMounted(()=>{document.addEventListener("click",A),y()}),t.onBeforeUnmount(()=>{document.removeEventListener("click",A)}),n({startPlay:v,stopPlay:S,remoteVideoElement:u}),(e,n)=>(t.openBlock(),t.createElementBlock("div",{ref_key:"videoContainer",ref:p,class:"flex flex-1 items-center justify-center",style:{width:"100%",height:"100%",position:"relative",overflow:"hidden"}},[t.createElementVNode("div",{ref:"keyboardArea",onPointerenter:n[6]||(n[6]=//@ts-ignore
118
126
  (...e)=>t.unref(k)&&t.unref(k)(...e)),onPointerleave:n[7]||(n[7]=//@ts-ignore
119
127
  (...e)=>t.unref(I)&&t.unref(I)(...e)),class:"vContainer",style:t.normalizeStyle([{height:t.unref(m).height+"px",width:t.unref(m).width+"px",transform:`rotate(${t.unref(a)}deg)`},{position:"relative",overflow:"hidden"}])},[t.createElementVNode("video",{ref_key:"remoteVideoElement",ref:u,class:t.normalizeClass(["video-control",[t.unref(f),{"no-events":t.unref(l)}]]),onPointerenter:n[0]||(n[0]=//@ts-ignore
120
128
  (...e)=>t.unref(b)&&t.unref(b)(...e)),onPointerdown:n[1]||(n[1]=//@ts-ignore
@@ -122,7 +130,7 @@ Insert:124,Delete:112,Home:122,End:123,PageUp:92,PageDown:93,ScrollLock:116,Paus
122
130
  (...e)=>t.unref(R)&&t.unref(R)(...e)),onPointerup:n[3]||(n[3]=//@ts-ignore
123
131
  (...e)=>t.unref(w)&&t.unref(w)(...e)),onPointerleave:n[4]||(n[4]=//@ts-ignore
124
132
  (...e)=>t.unref(E)&&t.unref(E)(...e)),onWheel:n[5]||(n[5]=//@ts-ignore
125
- (...e)=>t.unref(P)&&t.unref(P)(...e)),style:t.normalizeStyle({backgroundColor:`${t.unref(h)}`}),autoplay:"",playsinline:"",muted:"",disablePictureInPicture:!0},null,38)],36)],512))}}),[["__scopeId","data-v-26654e99"]]);class ct extends d{constructor(e){super(),i(this,"sdk"),i(this,"config"),this.config=e,this.sdk=new et(this.config),this.initSdk()}initSdk(){const e=this.config.roomId;this.sdk.removeAllListeners(),this.sdk.on(y.streamTrack,e=>{const t="video"===e.kind;this.emit(y.streamTrack,t,e)}),this.sdk.on(y.cloudStatusChanged,e=>{this.emit(y.cloudStatusChanged,e)}),this.sdk.on(y.iceConnectionState,t=>this.emit(y.iceConnectionState,e,t)),this.sdk.on(y.webrtcError,t=>{this.emit(y.webrtcError,e,t),this.stop()})}start(){this.sdk.startConnection()}stop(){this.sdk.stop(),this.sdk.removeAllListeners()}sendData(e,t){this.config.canOperate&&1===this.config.connectStatus&&this.sdk.sendChannelData(e,t)}sendControlData(e){this.config.canOperate&&1===this.config.connectStatus&&this.sdk.sendControlEvent(e)}groupSendAction(e,t){this.sdk.groupSendAction(e,t)}
133
+ (...e)=>t.unref(P)&&t.unref(P)(...e)),style:t.normalizeStyle({backgroundColor:`${t.unref(h)}`}),autoplay:"",playsinline:"",muted:"",disablePictureInPicture:!0},null,38)],36)],512))}}),[["__scopeId","data-v-26654e99"]]);class at extends d{constructor(e){super(),i(this,"sdk"),i(this,"config"),this.config=e,this.sdk=new Ze(this.config),this.initSdk()}initSdk(){const e=this.config.roomId;this.sdk.removeAllListeners(),this.sdk.on(y.streamTrack,e=>{const t="video"===e.kind;this.emit(y.streamTrack,t,e)}),this.sdk.on(y.cloudStatusChanged,e=>{this.emit(y.cloudStatusChanged,e)}),this.sdk.on(y.iceConnectionState,t=>this.emit(y.iceConnectionState,e,t)),this.sdk.on(y.webrtcError,t=>{this.emit(y.webrtcError,e,t),this.stop()})}start(){this.sdk.startConnection()}stop(){this.sdk.stop(),this.sdk.removeAllListeners()}sendData(e,t){this.config.canOperate&&1===this.config.connectStatus&&this.sdk.sendChannelData(e,t)}sendControlData(e){this.config.canOperate&&1===this.config.connectStatus&&this.sdk.sendControlEvent(e)}groupSendAction(e,t){this.sdk.groupSendAction(e,t)}
126
134
  /**
127
135
  * rtc群控环境下切换主从, 群控中每个被控者都是一个独立连接(websocket + webrtc)
128
136
  * 因此切换主从时每个连接向自己对应的信令服务发送此信令, 信令收到后将switchControl透传给目标roomId的云机.
@@ -134,4 +142,4 @@ Insert:124,Delete:112,Home:122,End:123,PageUp:92,PageDown:93,ScrollLock:116,Paus
134
142
  * 内网转发群控环境下切换主从, 群控中主控和所有从控处于同一连接(websocket)
135
143
  * 因此切换主从时只需要发送一次此信令, 告诉信令要将哪个房间切换为主控. 信令服务会判断主从关系变化, 然后将switchControl分别发送给本次切换对应的2台云机.
136
144
  * @param roomId
137
- */switchControlToMainMessage(e){this.sdk.switchControlToMain(e)}setGroupAcceptControl(e,t){this.sdk.sendGroupAcceptControl(e,t)}getRTCSdk(){return this.sdk}}e.ActionCommandEventType=Ge,e.ActionCommandEventValue=Ue,e.ActionCommandType=Fe,e.ActionType=Ke,e.ChannelDataType=je,e.ClarityData=class{constructor(e){i(this,"level"),this.level=e}},e.ConnectorType=p,e.ContainerDirection=ze,e.EmitType=y,e.GestureData=class{constructor(e){i(this,"mode"),this.mode=e}},e.GroupCtrlSocketManager=class{constructor(e){i(this,"config"),i(this,"websocketModeSdkController"),i(this,"isSynchronous",!0),this.config=e,b(!!this.config.enableLogger),void 0!==this.config.enableLogger&&this.config.enableLogger&&void 0!==this.config.loggerLevel&&R(this.config.loggerLevel),this.websocketModeSdkController=new ct(e)}getRTCSdk(){var e;return null==(e=this.websocketModeSdkController)?void 0:e.getRTCSdk()}startGroupControl(){var e,t;if(!(null==(e=this.config)?void 0:e.groupId))throw new Error("必须生成一个groupId");null==(t=this.websocketModeSdkController)||t.start()}stopControl(){var e;null==(e=this.websocketModeSdkController)||e.stop()}sendData(e,t){var n,i;null==(n=this.getRTCSdk())||n.sendChannelData(e,t),this.isSynchronous&&(null==(i=this.websocketModeSdkController)||i.groupSendAction(e,t))}sendControlEvent(e){var t,n;const i=new Be(e,0);null==(t=this.getRTCSdk())||t.sendChannelData(je.ActionInput,i),this.isSynchronous&&(null==(n=this.websocketModeSdkController)||n.groupSendAction(je.ActionInput,i))}switchToMainWebsocketMode(e){var t,n;this.config&&(e===this.config.mainRoomIdOfGroup||(this.updateConfig(e),null==(t=this.websocketModeSdkController)||t.updateConfig(this.config),null==(n=this.websocketModeSdkController)||n.switchControlToMainMessage(e)))}synchronousOperation(e){this.isSynchronous=e}setGroupAcceptControl(e,t){var n;null==(n=this.websocketModeSdkController)||n.setGroupAcceptControl(e,t)}updateConfig(e){if(this.config){if(this.config.subRoomIdsOfGroup){const t=this.config.subRoomIdsOfGroup.indexOf(e);-1!==t&&this.config.subRoomIdsOfGroup.splice(t,1)}this.config.mainRoomIdOfGroup&&(this.config.subRoomIdsOfGroup||(this.config.subRoomIdsOfGroup=[]),this.config.subRoomIdsOfGroup.push(this.config.mainRoomIdOfGroup)),this.config.mainRoomIdOfGroup=e,this.config.roomId=e}}},e.InputData=class{constructor(e){i(this,"text"),this.text=e}},e.KeyEventData=Be,e.RemotePlayer=at,e.TouchData=We,e.TrackEventData=class{constructor(e){i(this,"visible"),this.visible=e}},e.WebRTCSdk=et,e.WheelData=Je,e.getKeyEventData=nt,e.testMultipleTurnServers=Xe,e.transformCoordinate=it,e.valueToPercentage=rt,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})});
145
+ */switchControlToMainMessage(e){this.sdk.switchControlToMain(e)}setGroupAcceptControl(e,t){this.sdk.sendGroupAcceptControl(e,t)}getRTCSdk(){return this.sdk}}e.ActionCommandEventType=Ge,e.ActionCommandEventValue=Fe,e.ActionCommandType=Ue,e.ActionType=Ke,e.ChannelDataType=je,e.ClarityData=class{constructor(e){i(this,"level"),this.level=e}},e.ConnectorType=p,e.ContainerDirection=ze,e.EmitType=y,e.GestureData=class{constructor(e){i(this,"mode"),this.mode=e}},e.GroupCtrlSocketManager=class{constructor(e){i(this,"config"),i(this,"websocketModeSdkController"),i(this,"isSynchronous",!0),this.config=e,b(!!this.config.enableLogger),void 0!==this.config.enableLogger&&this.config.enableLogger&&void 0!==this.config.loggerLevel&&R(this.config.loggerLevel),this.websocketModeSdkController=new at(e)}getRTCSdk(){var e;return null==(e=this.websocketModeSdkController)?void 0:e.getRTCSdk()}startGroupControl(){var e,t;if(!(null==(e=this.config)?void 0:e.groupId))throw new Error("必须生成一个groupId");null==(t=this.websocketModeSdkController)||t.start()}stopControl(){var e;null==(e=this.websocketModeSdkController)||e.stop()}sendData(e,t){var n,i;null==(n=this.getRTCSdk())||n.sendChannelData(e,t),this.isSynchronous&&(null==(i=this.websocketModeSdkController)||i.groupSendAction(e,t))}sendControlEvent(e){var t,n;const i=new Je(e,0);null==(t=this.getRTCSdk())||t.sendChannelData(je.ActionInput,i),this.isSynchronous&&(null==(n=this.websocketModeSdkController)||n.groupSendAction(je.ActionInput,i))}switchToMainWebsocketMode(e){var t,n;this.config&&(e===this.config.mainRoomIdOfGroup||(this.updateConfig(e),null==(t=this.websocketModeSdkController)||t.updateConfig(this.config),null==(n=this.websocketModeSdkController)||n.switchControlToMainMessage(e)))}synchronousOperation(e){this.isSynchronous=e}setGroupAcceptControl(e,t){var n;null==(n=this.websocketModeSdkController)||n.setGroupAcceptControl(e,t)}updateConfig(e){if(this.config){if(this.config.subRoomIdsOfGroup){const t=this.config.subRoomIdsOfGroup.indexOf(e);-1!==t&&this.config.subRoomIdsOfGroup.splice(t,1)}this.config.mainRoomIdOfGroup&&(this.config.subRoomIdsOfGroup||(this.config.subRoomIdsOfGroup=[]),this.config.subRoomIdsOfGroup.push(this.config.mainRoomIdOfGroup)),this.config.mainRoomIdOfGroup=e,this.config.roomId=e}}},e.InputData=class{constructor(e){i(this,"text"),this.text=e}},e.KeyEventData=Je,e.RemotePlayer=st,e.TouchData=We,e.TrackEventData=class{constructor(e){i(this,"visible"),this.visible=e}},e.WebRTCSdk=Ze,e.WheelData=Be,e.getKeyEventData=tt,e.testMultipleTurnServers=Xe,e.transformCoordinate=nt,e.valueToPercentage=it,Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "yjz-web-sdk",
3
3
  "private": false,
4
- "version": "1.0.8-beta.12",
4
+ "version": "1.0.8-beta.14",
5
5
  "type": "module",
6
6
  "description": "针对于亚矩阵项目的云手机投屏和屏幕控制",
7
7
  "license": "Apache-2.0",
@@ -32,6 +32,7 @@
32
32
  "preview": "vite preview"
33
33
  },
34
34
  "dependencies": {
35
+ "element-plus": "^2.10.5",
35
36
  "eventemitter3": "^5.0.1",
36
37
  "terser": "^5.39.0",
37
38
  "vue": "^3.5.13",
@@ -1,20 +0,0 @@
1
- export declare class MapCache {
2
- private key;
3
- private maxSize;
4
- private defaultExpire;
5
- constructor(key: string, maxSize?: number, expireMs?: number);
6
- /** 从 localStorage 读取 Map(自动清理过期的 item) */
7
- getMap(): Map<string, any>;
8
- /** 保存 Map(每个值都有独立的 timestamp/expire) */
9
- private saveMap;
10
- /** 设置值(支持单项自定义过期时间) */
11
- set(key: string, value: any, expireMs?: number): void;
12
- /** 获取值(单项过期会自动清除) */
13
- get(key: string): any;
14
- /** 检查是否存在且未过期 */
15
- has(key: string): boolean;
16
- /** 删除 */
17
- delete(key: string): void;
18
- /** 清空 */
19
- clear(): void;
20
- }