yjz-web-sdk 1.0.8-beta.11 → 1.0.8-beta.13

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.
@@ -1,8 +1,8 @@
1
1
  import { EventEmitter } from 'eventemitter3';
2
2
  import { SignalingClient } from './signal/SignalingClient';
3
3
  import { WebRTCClient } from './rtc/WebRTCClient';
4
- import { WebRTCConfig } from './rtc/WebRTCConfig';
5
4
  import type { WebRTCConfigOptions } from './rtc/WebRTCConfig';
5
+ import { WebRTCConfig } from './rtc/WebRTCConfig';
6
6
  import { ConnectorType } from './data/MessageType';
7
7
  import { ChannelDataType } from './data/WebrtcDataType';
8
8
  export declare class WebRTCSdk extends EventEmitter {
@@ -25,13 +25,13 @@ 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
35
  private getRotatedStream;
36
36
  private setVideoParams;
37
37
  stopPush(): void;
@@ -1,4 +1,5 @@
1
1
  import { ConnectorType } from '../data/MessageType';
2
+ import { LogLevel } from "../util/Logger.ts";
2
3
  export interface WebRTCConfigOptions {
3
4
  signalServerUrl: string;
4
5
  myId?: string;
@@ -30,6 +31,8 @@ export interface WebRTCConfigOptions {
30
31
  connectorAndRoomId?: Map<string, string>;
31
32
  groupId?: string;
32
33
  cacheTimeout?: number;
34
+ enableLogger?: boolean;
35
+ loggerLevel?: LogLevel;
33
36
  }
34
37
  export declare class WebRTCConfig {
35
38
  signalServerUrl: string;
@@ -0,0 +1,20 @@
1
+ export declare enum LogLevel {
2
+ DEBUG = 10,
3
+ INFO = 20,
4
+ WARN = 30,
5
+ ERROR = 40,
6
+ OFF = 100
7
+ }
8
+ export declare function setLogLevel(level: LogLevel): void;
9
+ export declare function enableLog(enable: boolean): void;
10
+ export declare function setNamespace(ns: string): void;
11
+ declare class LoggerCore {
12
+ private canLog;
13
+ private log;
14
+ debug(...args: any[]): void;
15
+ info(...args: any[]): void;
16
+ warn(...args: any[]): void;
17
+ error(...args: any[]): void;
18
+ }
19
+ export declare const Logger: LoggerCore;
20
+ export {};
@@ -359,6 +359,83 @@ var EmitType = /* @__PURE__ */ ((EmitType2) => {
359
359
  EmitType2["groupError"] = "groupError";
360
360
  return EmitType2;
361
361
  })(EmitType || {});
362
+ var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
363
+ LogLevel2[LogLevel2["DEBUG"] = 10] = "DEBUG";
364
+ LogLevel2[LogLevel2["INFO"] = 20] = "INFO";
365
+ LogLevel2[LogLevel2["WARN"] = 30] = "WARN";
366
+ LogLevel2[LogLevel2["ERROR"] = 40] = "ERROR";
367
+ LogLevel2[LogLevel2["OFF"] = 100] = "OFF";
368
+ return LogLevel2;
369
+ })(LogLevel || {});
370
+ let globalLogLevel = 10;
371
+ let globalEnable = true;
372
+ let globalNamespace = "SDK";
373
+ function setLogLevel(level) {
374
+ globalLogLevel = level;
375
+ }
376
+ function enableLog(enable) {
377
+ globalEnable = enable;
378
+ }
379
+ const levelStyle = {
380
+ [
381
+ 10
382
+ /* DEBUG */
383
+ ]: "color: #999",
384
+ [
385
+ 20
386
+ /* INFO */
387
+ ]: "color: #2b90d9",
388
+ [
389
+ 30
390
+ /* WARN */
391
+ ]: "color: #e6a23c",
392
+ [
393
+ 40
394
+ /* ERROR */
395
+ ]: "color: #f56c6c",
396
+ [
397
+ 100
398
+ /* OFF */
399
+ ]: "color: inherit"
400
+ };
401
+ class LoggerCore {
402
+ canLog(level) {
403
+ return globalEnable && level >= globalLogLevel;
404
+ }
405
+ log(level, ...args) {
406
+ if (!this.canLog(level)) return;
407
+ const levelName = LogLevel[level];
408
+ const prefix = `%c[${globalNamespace}] [${levelName}]`;
409
+ const style = levelStyle[level];
410
+ switch (level) {
411
+ case 10:
412
+ console.log(prefix, style, ...args);
413
+ break;
414
+ case 20:
415
+ console.info(prefix, style, ...args);
416
+ break;
417
+ case 30:
418
+ console.warn(prefix, style, ...args);
419
+ break;
420
+ case 40:
421
+ console.error(prefix, style, ...args);
422
+ break;
423
+ }
424
+ }
425
+ debug(...args) {
426
+ this.log(10, ...args);
427
+ }
428
+ info(...args) {
429
+ this.log(20, ...args);
430
+ }
431
+ warn(...args) {
432
+ this.log(30, ...args);
433
+ }
434
+ error(...args) {
435
+ this.log(40, ...args);
436
+ }
437
+ }
438
+ const Logger = new LoggerCore();
362
439
  class SignalingClient extends EventEmitter {
363
440
  constructor(config) {
364
441
  super();
@@ -388,6 +465,7 @@ class SignalingClient extends EventEmitter {
388
465
  this.webSocket = null;
389
466
  };
390
467
  this.webSocket.onerror = (event) => {
468
+ Logger.error("错误日志:", `信令服务器连接失败或者已断开=======>${this.config.signalServerUrl}`);
391
469
  this.emit(EmitType.webrtcError, createWebRtcError(FailCode.SOCKET, event));
392
470
  };
393
471
  this.webSocket.onmessage = (event) => {
@@ -402,6 +480,7 @@ class SignalingClient extends EventEmitter {
402
480
  this.clearTime();
403
481
  if (this.timeout === null) {
404
482
  this.timeout = setTimeout(() => {
483
+ Logger.error("错误日志:", `远端云机未响应=======>${this.config.roomId}`);
405
484
  this.emit(EmitType.webrtcError, createWebRtcError(FailCode.STATE_ERR, ""));
406
485
  this.timeout = null;
407
486
  }, 6e3);
@@ -452,6 +531,7 @@ class SignalingClient extends EventEmitter {
452
531
  connectorType: this.config.connectorType
453
532
  };
454
533
  const jsonMessage = JSON.stringify(message);
534
+ Logger.debug("调试日志:", `屏控登录信息====>${jsonMessage}`);
455
535
  this.sendMessage(jsonMessage);
456
536
  }
457
537
  sendSwitchControlMessage(roomId, connectorType) {
@@ -463,7 +543,7 @@ class SignalingClient extends EventEmitter {
463
543
  targetId: this.config.myId
464
544
  };
465
545
  const jsonMessage = JSON.stringify(message);
466
- console.log(`===> sendSwitchControlMessage: ${jsonMessage}`);
546
+ Logger.debug("调试日志:", `切换主控信令消息====>${jsonMessage}`);
467
547
  this.sendMessage(jsonMessage);
468
548
  }
469
549
  sendSwitchControlToMainMessage(roomId) {
@@ -474,6 +554,7 @@ class SignalingClient extends EventEmitter {
474
554
  roomId
475
555
  };
476
556
  const jsonMessage = JSON.stringify(message);
557
+ Logger.debug("调试日志:", `切换主控信令消息====>${jsonMessage}`);
477
558
  this.sendMessage(jsonMessage);
478
559
  }
479
560
  sendGroupAcceptControl(roomIds, acceptControl) {
@@ -485,6 +566,7 @@ class SignalingClient extends EventEmitter {
485
566
  isAccept: acceptControl
486
567
  };
487
568
  const jsonMessage = JSON.stringify(message);
569
+ Logger.debug("调试日志:", `修改控制状态====>${jsonMessage}`);
488
570
  this.sendMessage(jsonMessage);
489
571
  }
490
572
  sendGroupAction(action) {
@@ -499,6 +581,7 @@ class SignalingClient extends EventEmitter {
499
581
  traceId: tid
500
582
  };
501
583
  const jsonMessage = JSON.stringify(message);
584
+ Logger.debug("调试日志:", `发送群控事件====>${jsonMessage}`);
502
585
  this.sendMessage(jsonMessage);
503
586
  }
504
587
  sendGroupSignInMessage() {
@@ -513,8 +596,8 @@ class SignalingClient extends EventEmitter {
513
596
  groupId: "group_0001",
514
597
  token: this.config.token
515
598
  };
516
- console.log("sendGroupSignInMessage==>", message);
517
599
  const jsonMessage = JSON.stringify(message);
600
+ Logger.debug("调试日志:", `群控登录信息====>${jsonMessage}`);
518
601
  this.sendMessage(jsonMessage);
519
602
  }
520
603
  }
@@ -3165,20 +3248,29 @@ class WebRTCConfig {
3165
3248
  }
3166
3249
  }
3167
3250
  const setRemoteDescriptionWithHandleOffer = (peerConnection, sdp2, sendAnswer, onError) => {
3251
+ Logger.info("信息日志:", "设置远程offer Description=======>");
3168
3252
  const description = new RTCSessionDescription({ type: "offer", sdp: sdp2 });
3169
3253
  peerConnection.setRemoteDescription(description).then(() => createAnswer(peerConnection, sendAnswer, onError)).catch((error) => onError == null ? void 0 : onError(createWebRtcError(FailCode.HANDLE_OFFER, error)));
3170
3254
  };
3171
3255
  const createAnswer = (peerConnection, sendAnswer, onError) => {
3256
+ Logger.info("信息日志:", "创建webrtcAnswer=======>");
3172
3257
  peerConnection.createAnswer().then((answer) => setLocalDescriptionWithCreateAnswer(peerConnection, answer, sendAnswer, onError)).catch((error) => onError == null ? void 0 : onError(createWebRtcError(FailCode.CREATE_ANSWER, error)));
3173
3258
  };
3174
3259
  const setLocalDescriptionWithCreateAnswer = (peerConnection, answer, sendAnswer, onError) => {
3175
- peerConnection.setLocalDescription(answer).then(() => {
3176
- sendAnswer == null ? void 0 : sendAnswer(answer.sdp ?? "");
3260
+ var _a;
3261
+ Logger.info("信息日志:", "设置本地answer Description=======>");
3262
+ let sdp2 = (_a = answer.sdp) == null ? void 0 : _a.replace(
3263
+ /a=rtpmap:\d+ opus\/48000\/2\r\n/g,
3264
+ "$&a=ptime:0\r\na=maxptime:10\r\n"
3265
+ );
3266
+ peerConnection.setLocalDescription({ type: answer.type, sdp: sdp2 }).then(() => {
3267
+ sendAnswer == null ? void 0 : sendAnswer(sdp2 ?? "");
3177
3268
  }).catch((error) => {
3178
3269
  onError == null ? void 0 : onError(createWebRtcError(FailCode.LOCAL_DES, error));
3179
3270
  });
3180
3271
  };
3181
3272
  const createPeerConnection = (config) => {
3273
+ Logger.info("信息日志:", "初始化 Webrtc PeerConnection=======>");
3182
3274
  const iceServers = [
3183
3275
  { urls: config.stunServerUri },
3184
3276
  {
@@ -3189,7 +3281,7 @@ const createPeerConnection = (config) => {
3189
3281
  ];
3190
3282
  const peerConnectionConfig = {
3191
3283
  iceServers,
3192
- iceTransportPolicy: "relay",
3284
+ iceTransportPolicy: "all",
3193
3285
  bundlePolicy: "max-bundle"
3194
3286
  };
3195
3287
  return new RTCPeerConnection(peerConnectionConfig);
@@ -3204,6 +3296,7 @@ const configPeerConnection = (peerConnection, onICEMessage, onTrack, onConnectSt
3204
3296
  sdpMid: event.candidate.sdpMid,
3205
3297
  sdpMLineIndex: event.candidate.sdpMLineIndex
3206
3298
  };
3299
+ Logger.debug("信息日志:", `webrtc 生成的icecandidate===>${JSON.stringify(candidateObj)}`);
3207
3300
  onICEMessage(JSON.stringify(candidateObj));
3208
3301
  };
3209
3302
  peerConnection.onconnectionstatechange = () => {
@@ -3211,12 +3304,14 @@ const configPeerConnection = (peerConnection, onICEMessage, onTrack, onConnectSt
3211
3304
  if (!state) {
3212
3305
  return;
3213
3306
  }
3307
+ Logger.debug("信息日志:", `webrtc p2p连接状态===>`, state);
3214
3308
  if (state === "failed" || state === "disconnected" || state === "closed") {
3215
3309
  onError == null ? void 0 : onError(createWebRtcError(FailCode.ICE_STATE, "failed"));
3216
3310
  }
3217
3311
  onConnectState == null ? void 0 : onConnectState(state);
3218
3312
  };
3219
3313
  peerConnection.ontrack = (event) => {
3314
+ Logger.debug("信息日志:", "webrtc p2p连接后获取的音视频track");
3220
3315
  const track = event.track;
3221
3316
  track.contentHint = "motion";
3222
3317
  onTrack == null ? void 0 : onTrack(track);
@@ -3235,14 +3330,21 @@ const createOffer = async (peerConnection, sendOfferMessage) => {
3235
3330
  }
3236
3331
  };
3237
3332
  const setLocalDescriptionWithCreateOffer = async (peerConnection, offer, sendOfferMessage) => {
3333
+ var _a;
3334
+ Logger.info("信息日志:", "设置本地offer Description=======>");
3238
3335
  try {
3239
- await peerConnection.setLocalDescription(offer);
3240
- sendOfferMessage(offer.sdp ?? "");
3336
+ const sdp2 = (_a = offer.sdp) == null ? void 0 : _a.replace(
3337
+ /a=rtpmap:\d+ opus\/48000\/2\r\n/g,
3338
+ "$&a=ptime:0\r\na=maxptime:10\r\n"
3339
+ );
3340
+ await peerConnection.setLocalDescription({ type: offer.type, sdp: sdp2 });
3341
+ sendOfferMessage(sdp2 ?? "");
3241
3342
  } catch (err) {
3242
3343
  throw new Error("摄像头视频流添加失败");
3243
3344
  }
3244
3345
  };
3245
3346
  const addIceCandidate = (peerConnection, candidate, onError) => {
3347
+ Logger.info("信息日志:", "接收远程ice 并设置=======>");
3246
3348
  peerConnection.addIceCandidate(candidate).catch((err) => onError == null ? void 0 : onError(createWebRtcError(FailCode.HANDLE_ICE, err)));
3247
3349
  };
3248
3350
  var ChannelDataType = /* @__PURE__ */ ((ChannelDataType2) => {
@@ -3522,14 +3624,14 @@ class WebRTCClient extends EventEmitter {
3522
3624
  this.config = config;
3523
3625
  this.ua = navigator.userAgent;
3524
3626
  }
3525
- async startPush() {
3627
+ async startPush(useBackCamera = true) {
3526
3628
  if (this.isPushingStream) return;
3527
3629
  if (this.isPushingLocalStream) {
3528
3630
  this.stopLocal();
3529
3631
  }
3530
3632
  try {
3531
3633
  this.isPushingStream = true;
3532
- await this.readyCapture();
3634
+ await this.readyCapture(useBackCamera);
3533
3635
  } catch (err) {
3534
3636
  this.isPushingStream = false;
3535
3637
  let errorMessage;
@@ -3606,6 +3708,7 @@ class WebRTCClient extends EventEmitter {
3606
3708
  }
3607
3709
  }
3608
3710
  closeConnection() {
3711
+ Logger.info("信息日志:", "关闭webrtc连接=======>");
3609
3712
  if (this.statsTimer) {
3610
3713
  clearInterval(this.statsTimer);
3611
3714
  this.statsTimer = void 0;
@@ -3649,11 +3752,17 @@ class WebRTCClient extends EventEmitter {
3649
3752
  this.peerConnection = null;
3650
3753
  }
3651
3754
  }
3652
- async readyCapture() {
3755
+ async readyCapture(useBackCamera) {
3653
3756
  this.resetPeerConnection();
3757
+ Logger.info("信息日志:", "启用摄像头推流到云机=======>", useBackCamera);
3654
3758
  try {
3655
3759
  this.localStream = await navigator.mediaDevices.getUserMedia({
3656
- video: { width: { ideal: 640 }, height: { ideal: 480 } },
3760
+ video: {
3761
+ width: { ideal: 720 },
3762
+ height: { ideal: 540 },
3763
+ facingMode: useBackCamera ? { ideal: "environment" } : { ideal: "user" },
3764
+ frameRate: { ideal: 20, max: 30 }
3765
+ },
3657
3766
  audio: true
3658
3767
  });
3659
3768
  const senders = [];
@@ -3664,11 +3773,12 @@ class WebRTCClient extends EventEmitter {
3664
3773
  const sender = this.peerConnection.addTrack(track, rotatedStream);
3665
3774
  senders.push(sender);
3666
3775
  });
3667
- senders.forEach((sender) => this.setVideoParams(sender));
3668
3776
  await createOffer(this.peerConnection, (sdp2) => {
3669
3777
  this.emit(EmitType.sendOffer, sdp2);
3670
3778
  });
3779
+ senders.forEach((sender) => this.setVideoParams(sender));
3671
3780
  } catch (err) {
3781
+ console.log("err===>", err);
3672
3782
  if (err instanceof DOMException) {
3673
3783
  switch (err.name) {
3674
3784
  case "NotAllowedError":
@@ -3701,11 +3811,11 @@ class WebRTCClient extends EventEmitter {
3701
3811
  ctx.clearRect(0, 0, canvas.width, canvas.height);
3702
3812
  ctx.save();
3703
3813
  ctx.translate(canvas.width / 2, canvas.height / 2);
3704
- ctx.rotate(Math.PI / 2);
3814
+ ctx.rotate(-Math.PI / 2);
3705
3815
  ctx.drawImage(video, -width / 2, -height / 2, width, height);
3706
3816
  ctx.restore();
3707
3817
  };
3708
- const fps = 30;
3818
+ const fps = 25;
3709
3819
  const frameInterval = 1e3 / fps;
3710
3820
  let lastTime = 0;
3711
3821
  let rafId;
@@ -3725,21 +3835,46 @@ class WebRTCClient extends EventEmitter {
3725
3835
  });
3726
3836
  return stream;
3727
3837
  }
3838
+ // private async setVideoParams(sender: RTCRtpSender) {
3839
+ // Logger.info('信息日志:', '设置推流视频参数=======>')
3840
+ // const params = sender.getParameters();
3841
+ // params.degradationPreference = 'balanced';
3842
+ // const isMobile = /Android|iPhone|iPad/i.test(navigator.userAgent);
3843
+ // params.encodings.forEach(encoding => {
3844
+ // encoding.maxBitrate = isMobile ? 800000 : 1000000;
3845
+ // encoding.priority = 'high';
3846
+ // encoding.scaleResolutionDownBy = 1.0;
3847
+ // });
3848
+ // await sender.setParameters(params);
3849
+ // }
3728
3850
  async setVideoParams(sender) {
3729
3851
  const params = sender.getParameters();
3852
+ const isMobile = /Android|iPhone|iPad/i.test(navigator.userAgent);
3853
+ const targetBitrate = isMobile ? 6e5 : 18e5;
3854
+ const targetFramerate = 30;
3730
3855
  params.degradationPreference = "maintain-resolution";
3856
+ if (!params.encodings || params.encodings.length === 0) {
3857
+ params.encodings = [{}];
3858
+ }
3859
+ console.log("params.codecs===>", params.codecs);
3731
3860
  params.encodings.forEach((encoding) => {
3732
- encoding.maxBitrate = 1e6;
3733
- encoding.priority = "high";
3861
+ encoding.maxBitrate = targetBitrate;
3862
+ encoding.maxFramerate = targetFramerate;
3734
3863
  encoding.scaleResolutionDownBy = 1;
3864
+ encoding.priority = "high";
3735
3865
  });
3736
- await sender.setParameters(params);
3866
+ try {
3867
+ await sender.setParameters(params);
3868
+ Logger.info("信息日志:", `设置推流视频参数成功:${targetBitrate / 1e3}kbps / ${targetFramerate}fps`);
3869
+ } catch (e) {
3870
+ Logger.error("设置推流参数失败:", e);
3871
+ }
3737
3872
  }
3738
3873
  stopPush() {
3739
3874
  var _a, _b, _c;
3740
3875
  if (!this.isPushingStream) return;
3741
3876
  this.isPushingStream = false;
3742
- console.log("dsanduashdsuad");
3877
+ Logger.info("信息日志:", "停止推流到云机=======>");
3743
3878
  (_a = this.localStream) == null ? void 0 : _a.getTracks().forEach((track) => track.stop());
3744
3879
  this.localStream = null;
3745
3880
  (_b = this.rotatedStream) == null ? void 0 : _b.getTracks().forEach((track) => track.stop());
@@ -3780,10 +3915,11 @@ class WebRTCClient extends EventEmitter {
3780
3915
  handleDataChannelMessage(event) {
3781
3916
  const data = JSON.parse(event.data);
3782
3917
  if (data.type === ChannelDataType.ActionCommandEvent) {
3783
- const { action, value } = JSON.parse(data.data);
3918
+ const { action, value, cameraId } = JSON.parse(data.data);
3784
3919
  if (action === "ACTION_CONTROL_VIDEO") {
3920
+ console.log("cameraId===>", cameraId, cameraId !== 0);
3785
3921
  if (value === "ENABLE") {
3786
- this.startPush();
3922
+ this.startPush(Number(cameraId) === 0);
3787
3923
  } else {
3788
3924
  this.stopPush();
3789
3925
  this.stopLocal();
@@ -3949,6 +4085,7 @@ class WebRTCClient extends EventEmitter {
3949
4085
  }
3950
4086
  }
3951
4087
  startCanvasStream(fps = 30) {
4088
+ Logger.info("信息日志:", "初始化,使用本地文件推流到云机=======>");
3952
4089
  const canvas = this.getCanvas();
3953
4090
  const ctx = canvas.getContext("2d");
3954
4091
  const media = this.currentMedia;
@@ -4015,7 +4152,7 @@ class WebRTCClient extends EventEmitter {
4015
4152
  try {
4016
4153
  (_a2 = this.peerConnection) == null ? void 0 : _a2.removeTrack(sender);
4017
4154
  } catch (e) {
4018
- console.warn("removeTrack error:", e);
4155
+ Logger.error("错误日志:", `移除音视频轨道失败=====>`, e);
4019
4156
  }
4020
4157
  });
4021
4158
  if (this.fileVideo) {
@@ -4072,12 +4209,12 @@ const testMultipleTurnServers = async (servers, timeoutMs = 600) => {
4072
4209
  }));
4073
4210
  const testPromises = turnServers.map(
4074
4211
  (cfg) => testTurnServer(cfg, timeoutMs).then((res) => res).catch((err) => {
4075
- console.warn(`Test failed for ${cfg.urls}:`, err);
4212
+ Logger.warn("警告日志:", `中继计算超时=====>`, err);
4076
4213
  return { ...cfg, rtt: Infinity };
4077
4214
  })
4078
4215
  );
4079
4216
  const results = await Promise.all(testPromises);
4080
- console.log("results===>", results);
4217
+ Logger.debug("调试日志:", `信令计算结果======>`, results);
4081
4218
  const available = results.filter((r) => r.rtt !== Infinity);
4082
4219
  if (available.length === 0) {
4083
4220
  throw new Error("All TURN servers are unreachable or slow (RTT = Infinity).");
@@ -4240,6 +4377,7 @@ class WebRTCSdk extends EventEmitter {
4240
4377
  __publicField(this, "handleSignaling", (message) => {
4241
4378
  var _a, _b, _c, _d, _e, _f, _g;
4242
4379
  if (!this.config) return;
4380
+ Logger.debug("调试信息:", `信令消息=========>`, message);
4243
4381
  switch (message.type) {
4244
4382
  case MessageType.Peers:
4245
4383
  this.config.myId = message.myId;
@@ -4267,7 +4405,6 @@ class WebRTCSdk extends EventEmitter {
4267
4405
  }
4268
4406
  break;
4269
4407
  case MessageType.SignOut:
4270
- console.log("SignOutSignOutSignOutSignOutSignOutSignOutSignOutSignOut");
4271
4408
  if (message.myId === this.config.myId) {
4272
4409
  (_d = this.webRTCClient) == null ? void 0 : _d.closeConnection();
4273
4410
  (_e = this.signalingClient) == null ? void 0 : _e.close();
@@ -4395,6 +4532,14 @@ class WebRTCSdk extends EventEmitter {
4395
4532
  } else {
4396
4533
  this.cache = new MapCache("screenCache", 100);
4397
4534
  }
4535
+ if (this.options.connectorType !== ConnectorType.LanForwarding) {
4536
+ enableLog(!!this.options.enableLogger);
4537
+ if (this.options.enableLogger !== void 0 && this.options.enableLogger) {
4538
+ if (this.options.loggerLevel !== void 0) {
4539
+ setLogLevel(this.options.loggerLevel);
4540
+ }
4541
+ }
4542
+ }
4398
4543
  if (this.options.maxRecount) {
4399
4544
  this.MAX_COUNT = this.options.maxRecount;
4400
4545
  }
@@ -4451,6 +4596,7 @@ class WebRTCSdk extends EventEmitter {
4451
4596
  /** 开始连接 signal 服务 */
4452
4597
  startConnection() {
4453
4598
  this.prepareConnection().catch((err) => {
4599
+ Logger.error("错误信息:", `sdk调试错误日志======>`, err);
4454
4600
  this.emit(EmitType.webrtcError, err);
4455
4601
  });
4456
4602
  }
@@ -4461,6 +4607,7 @@ class WebRTCSdk extends EventEmitter {
4461
4607
  try {
4462
4608
  if (areTurnListsEmpty(this.options)) {
4463
4609
  if (!this.options.turnServerUri) {
4610
+ Logger.error("错误信息:", `sdk调试错误日志======> 暂无可用TURN服务器`);
4464
4611
  this.emit(EmitType.webrtcError, createWebRtcError(FailCode.OPTION_ERR, "暂无可用TURN服务器"));
4465
4612
  return;
4466
4613
  }
@@ -4489,6 +4636,7 @@ class WebRTCSdk extends EventEmitter {
4489
4636
  try {
4490
4637
  await this.prepareConnection();
4491
4638
  } catch (e) {
4639
+ Logger.error("错误信息:", `sdk调试错误日志======>`, e);
4492
4640
  this.emit(EmitType.webrtcError, e);
4493
4641
  }
4494
4642
  }
@@ -4504,7 +4652,7 @@ class WebRTCSdk extends EventEmitter {
4504
4652
  (_b = this.webRTCClient) == null ? void 0 : _b.on(EmitType.sendAnswer, (sdp2) => this.sendAnswer(sdp2));
4505
4653
  (_c = this.webRTCClient) == null ? void 0 : _c.on(EmitType.sendICEMessage, (candidate) => this.sendICEMessage(candidate));
4506
4654
  (_d = this.webRTCClient) == null ? void 0 : _d.on(EmitType.streamTrack, (track) => {
4507
- console.log("=========> ON EmitType.streamTrack WebRTCSdk");
4655
+ Logger.debug("调试信息:", "=========> EmitType.streamTrack callback");
4508
4656
  this.emit(EmitType.streamTrack, track);
4509
4657
  });
4510
4658
  (_e = this.webRTCClient) == null ? void 0 : _e.on(EmitType.iceConnectionState, (state) => {
@@ -4527,6 +4675,7 @@ class WebRTCSdk extends EventEmitter {
4527
4675
  this.emit(EmitType.reconnect);
4528
4676
  this.reconnect();
4529
4677
  } else {
4678
+ Logger.error("错误信息:", `sdk调试错误日志======>`, err);
4530
4679
  this.emit(EmitType.webrtcError, err);
4531
4680
  }
4532
4681
  });
@@ -4542,6 +4691,7 @@ class WebRTCSdk extends EventEmitter {
4542
4691
  this.signalingClient = new SignalingClient(this.config);
4543
4692
  this.signalingClient.on(EmitType.signalMessage, (message) => this.handleSignaling(message));
4544
4693
  this.signalingClient.on(EmitType.webrtcError, (err) => {
4694
+ Logger.error("错误信息:", `sdk 信令调试错误日志======>`, err);
4545
4695
  this.emit(EmitType.webrtcError, err);
4546
4696
  });
4547
4697
  }
@@ -4960,8 +5110,8 @@ function useRemoteVideo(videoContainer, remoteVideoElement, videoAngle, emit) {
4960
5110
  const widthRadio = ref(0);
4961
5111
  const heightRadio = ref(0);
4962
5112
  const resizeObserver = ref(null);
4963
- const frameCallbackId = ref(0);
4964
5113
  const isRotated = computed(() => videoAngle.value % 180 !== 0);
5114
+ const frameCallbackId = ref(0);
4965
5115
  const videoSize = computed(() => {
4966
5116
  let width = 0;
4967
5117
  let height = 0;
@@ -5000,10 +5150,15 @@ function useRemoteVideo(videoContainer, remoteVideoElement, videoAngle, emit) {
5000
5150
  };
5001
5151
  screenStatus.value = true;
5002
5152
  emit("loadedSuccess");
5153
+ const isMobile = /Android|iPhone|iPad/i.test(navigator.userAgent);
5154
+ if (isMobile) {
5155
+ startVideoFrameCallback(video);
5156
+ }
5003
5157
  };
5004
5158
  video.addEventListener("loadedmetadata", handleMetadata);
5005
5159
  onBeforeUnmount(() => {
5006
5160
  video.removeEventListener("loadedmetadata", handleMetadata);
5161
+ if (frameCallbackId.value) video.cancelVideoFrameCallback(frameCallbackId.value);
5007
5162
  });
5008
5163
  };
5009
5164
  const initVideoContainer = () => {
@@ -5021,8 +5176,15 @@ function useRemoteVideo(videoContainer, remoteVideoElement, videoAngle, emit) {
5021
5176
  }
5022
5177
  const mediaStream = videoEl.srcObject;
5023
5178
  updateTrack(mediaStream, newTrack);
5179
+ videoEl.playbackRate = 1;
5024
5180
  videoEl.playsInline = true;
5181
+ videoEl.disablePictureInPicture = true;
5182
+ videoEl.setAttribute("playsinline", "true");
5025
5183
  videoEl.setAttribute("webkit-playsinline", "true");
5184
+ videoEl.setAttribute("x5-video-player-type", "h5");
5185
+ videoEl.setAttribute("x5-video-player-fullscreen", "false");
5186
+ videoEl.setAttribute("x5-video-orientation", "portraint");
5187
+ videoEl.preload = "auto";
5026
5188
  };
5027
5189
  const updateTrack = (stream, newTrack) => {
5028
5190
  if (newTrack.kind === "video") {
@@ -5035,8 +5197,6 @@ function useRemoteVideo(videoContainer, remoteVideoElement, videoAngle, emit) {
5035
5197
  if (!stream.getAudioTracks().some((t) => t.id === newTrack.id)) {
5036
5198
  stream.addTrack(newTrack);
5037
5199
  }
5038
- } else {
5039
- console.warn("不支持的 track 类型:", newTrack.kind);
5040
5200
  }
5041
5201
  };
5042
5202
  const stopPlay = () => {
@@ -5045,29 +5205,17 @@ function useRemoteVideo(videoContainer, remoteVideoElement, videoAngle, emit) {
5045
5205
  if (video && video.srcObject) {
5046
5206
  video.srcObject.getTracks().forEach((track) => track.stop());
5047
5207
  video.srcObject = null;
5048
- video.cancelVideoFrameCallback(frameCallbackId.value);
5208
+ if (frameCallbackId.value) video.cancelVideoFrameCallback(frameCallbackId.value);
5049
5209
  }
5050
5210
  };
5051
5211
  const handleVisibilityChange = () => {
5052
- if (document.visibilityState === "visible") {
5053
- const video = remoteVideoElement.value;
5054
- if (video && video.srcObject) {
5055
- video.srcObject.getTracks().forEach((track) => {
5056
- if (track.kind === "audio" && !track.enabled) {
5057
- track.enabled = true;
5058
- }
5059
- });
5060
- }
5061
- } else {
5062
- const video = remoteVideoElement.value;
5063
- if (video && video.srcObject) {
5064
- video.srcObject.getTracks().forEach((track) => {
5065
- if (track.kind === "audio" && track.enabled) {
5066
- track.enabled = false;
5067
- }
5068
- });
5212
+ const video = remoteVideoElement.value;
5213
+ if (!video || !video.srcObject) return;
5214
+ video.srcObject.getTracks().forEach((track) => {
5215
+ if (track.kind === "audio") {
5216
+ track.enabled = document.visibilityState === "visible";
5069
5217
  }
5070
- }
5218
+ });
5071
5219
  };
5072
5220
  onMounted(() => {
5073
5221
  document.addEventListener("visibilitychange", handleVisibilityChange);
@@ -5079,6 +5227,16 @@ function useRemoteVideo(videoContainer, remoteVideoElement, videoAngle, emit) {
5079
5227
  }
5080
5228
  stopPlay();
5081
5229
  });
5230
+ const startVideoFrameCallback = (video) => {
5231
+ const handleFrame = (_now, _metadata) => {
5232
+ video.playbackRate = 1.1;
5233
+ setTimeout(() => {
5234
+ video.playbackRate = 1;
5235
+ }, 600);
5236
+ frameCallbackId.value = video.requestVideoFrameCallback(handleFrame);
5237
+ };
5238
+ frameCallbackId.value = video.requestVideoFrameCallback(handleFrame);
5239
+ };
5082
5240
  return {
5083
5241
  videoSize,
5084
5242
  remoteVideo,
@@ -5358,7 +5516,6 @@ class SdkController extends EventEmitter {
5358
5516
  const id = this.config.roomId;
5359
5517
  this.sdk.removeAllListeners();
5360
5518
  this.sdk.on(EmitType.streamTrack, (track) => {
5361
- console.log("=========> ON EmitType.streamTrack SdkController");
5362
5519
  const isVideo = track.kind === "video";
5363
5520
  this.emit(EmitType.streamTrack, isVideo, track);
5364
5521
  });
@@ -5425,6 +5582,12 @@ class GroupCtrlSocketManager {
5425
5582
  __publicField(this, "websocketModeSdkController");
5426
5583
  __publicField(this, "isSynchronous", true);
5427
5584
  this.config = config;
5585
+ enableLog(!!this.config.enableLogger);
5586
+ if (this.config.enableLogger !== void 0 && this.config.enableLogger) {
5587
+ if (this.config.loggerLevel !== void 0) {
5588
+ setLogLevel(this.config.loggerLevel);
5589
+ }
5590
+ }
5428
5591
  this.websocketModeSdkController = new SdkController(config);
5429
5592
  }
5430
5593
  getRTCSdk() {