@realsee/live 0.4.0-beta.6 → 0.5.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/live/controller.d.ts +75 -38
- package/dist/live/createLive.d.ts +5 -3
- package/dist/live/createLiveReact.d.ts +49 -3
- package/dist/live/live.d.ts +162 -0
- package/dist/realsee-live.cjs.development.js +1228 -747
- package/dist/realsee-live.cjs.development.js.map +1 -1
- package/dist/realsee-live.cjs.production.js +1 -1
- package/dist/realsee-live.cjs.production.js.map +1 -1
- package/dist/realsee-live.esm.js +1232 -751
- package/dist/realsee-live.esm.js.map +1 -1
- package/dist/realsee-live.umd.development.js +1701 -1149
- package/dist/realsee-live.umd.development.js.map +1 -1
- package/dist/realsee-live.umd.production.js +1 -1
- package/dist/realsee-live.umd.production.js.map +1 -1
- package/dist/typings/live/EventType.d.ts +17 -33
- package/dist/typings/live/LiveConnectOptions.d.ts +7 -0
- package/dist/typings/live/LiveErrorType.d.ts +9 -0
- package/dist/typings/live/LiveOptions.d.ts +5 -12
- package/dist/typings/live/LiveState.d.ts +15 -0
- package/dist/typings/live/index.d.ts +1 -1
- package/dist/typings/react/index.d.ts +0 -1
- package/dist/utils/RobustWebSocket.d.ts +130 -0
- package/dist/utils/logger.d.ts +16 -0
- package/docs/assets/search.js +1 -1
- package/docs/index.html +1 -1
- package/docs/interfaces/LiveOptions.html +16 -19
- package/docs/modules.html +34 -40
- package/package.json +4 -3
- package/dist/typings/live/Live.d.ts +0 -128
- package/dist/typings/react/LiveReact.d.ts +0 -164
- package/docs/interfaces/Live.html +0 -116
- package/docs/interfaces/LiveReact.html +0 -52
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var JSBridge = require('@realsee/jsbridge-x');
|
|
6
|
-
var amazonChimeSdkJs = require('amazon-chime-sdk-js');
|
|
7
6
|
var TRTC = require('trtc-js-sdk');
|
|
7
|
+
var amazonChimeSdkJs = require('amazon-chime-sdk-js');
|
|
8
8
|
var React = require('react');
|
|
9
9
|
|
|
10
10
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
@@ -131,6 +131,31 @@ class Subscribe {
|
|
|
131
131
|
class CoreRTC extends Subscribe {
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
+
/******************************************************************************
|
|
135
|
+
Copyright (c) Microsoft Corporation.
|
|
136
|
+
|
|
137
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
138
|
+
purpose with or without fee is hereby granted.
|
|
139
|
+
|
|
140
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
141
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
142
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
143
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
144
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
145
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
146
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
147
|
+
***************************************************************************** */
|
|
148
|
+
|
|
149
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
150
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
151
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
152
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
153
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
154
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
155
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
134
159
|
/**
|
|
135
160
|
* rtc 类型
|
|
136
161
|
*/
|
|
@@ -184,24 +209,21 @@ class BrowserRTC extends CoreRTC {
|
|
|
184
209
|
client: null,
|
|
185
210
|
stream: null,
|
|
186
211
|
};
|
|
187
|
-
this.join =
|
|
212
|
+
this.join = (options) => __awaiter(this, void 0, void 0, function* () {
|
|
188
213
|
var _a;
|
|
189
214
|
this.emit('joinWillStart');
|
|
190
|
-
const createClientOptions =
|
|
215
|
+
const createClientOptions = yield this._getVoiceSign({
|
|
191
216
|
voiceId: options.voiceId,
|
|
192
217
|
roomId: options.roomId,
|
|
193
218
|
userId: options.userId,
|
|
194
219
|
});
|
|
195
220
|
// 1. 创建client
|
|
196
|
-
this._trtc.client = TRTC__default["default"].createClient({
|
|
197
|
-
mode: 'rtc',
|
|
198
|
-
...createClientOptions,
|
|
199
|
-
});
|
|
221
|
+
this._trtc.client = TRTC__default["default"].createClient(Object.assign({ mode: 'rtc' }, createClientOptions));
|
|
200
222
|
(_a = this._trtc.client) === null || _a === void 0 ? void 0 : _a.enableAudioVolumeEvaluation();
|
|
201
223
|
// 2. 订阅事件
|
|
202
224
|
this._registerRtcEvent();
|
|
203
225
|
// 3. 加入语音房间
|
|
204
|
-
let result =
|
|
226
|
+
let result = yield new Promise((resolve) => {
|
|
205
227
|
var _a;
|
|
206
228
|
(_a = this._trtc.client) === null || _a === void 0 ? void 0 : _a.join({ roomId: Number(options.voiceId) }).then(() => resolve(true)).catch(() => resolve(false));
|
|
207
229
|
});
|
|
@@ -215,12 +237,12 @@ class BrowserRTC extends CoreRTC {
|
|
|
215
237
|
video: false,
|
|
216
238
|
});
|
|
217
239
|
// 5. 初始化本地流
|
|
218
|
-
result =
|
|
240
|
+
result = yield new Promise((resolve) => {
|
|
219
241
|
var _a;
|
|
220
242
|
(_a = this._trtc.stream) === null || _a === void 0 ? void 0 : _a.initialize().then(() => resolve(true)).catch(() => resolve(false));
|
|
221
243
|
});
|
|
222
244
|
// 6. 发布本地流
|
|
223
|
-
result =
|
|
245
|
+
result = yield new Promise((resolve) => {
|
|
224
246
|
var _a;
|
|
225
247
|
(_a = this._trtc.client) === null || _a === void 0 ? void 0 : _a.publish(this._trtc.stream).then(() => resolve(true)).catch(() => resolve(false));
|
|
226
248
|
});
|
|
@@ -228,7 +250,7 @@ class BrowserRTC extends CoreRTC {
|
|
|
228
250
|
if (this.joined)
|
|
229
251
|
this.emit('joined');
|
|
230
252
|
return result;
|
|
231
|
-
};
|
|
253
|
+
});
|
|
232
254
|
this._handleStreamAdded = (event) => {
|
|
233
255
|
var _a;
|
|
234
256
|
const remoteStream = event.stream;
|
|
@@ -256,17 +278,17 @@ class BrowserRTC extends CoreRTC {
|
|
|
256
278
|
document.body.appendChild(this.$dom);
|
|
257
279
|
}
|
|
258
280
|
quit() {
|
|
259
|
-
return new Promise(
|
|
281
|
+
return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () {
|
|
260
282
|
var _a, _b;
|
|
261
283
|
this.joined = false;
|
|
262
284
|
if (this._trtc.stream) {
|
|
263
|
-
|
|
285
|
+
yield ((_a = this._trtc.client) === null || _a === void 0 ? void 0 : _a.unpublish(this._trtc.stream));
|
|
264
286
|
this._trtc.stream.stop();
|
|
265
287
|
this._trtc.stream.close();
|
|
266
288
|
this._trtc.stream = null;
|
|
267
289
|
}
|
|
268
290
|
(_b = this._trtc.client) === null || _b === void 0 ? void 0 : _b.leave().then(() => (this._trtc.client = null)).then(() => resolve(true)).catch(() => resolve(false));
|
|
269
|
-
});
|
|
291
|
+
}));
|
|
270
292
|
}
|
|
271
293
|
detectMicro() {
|
|
272
294
|
return new Promise((resolve) => {
|
|
@@ -438,65 +460,64 @@ class BrowserRTC4Chime extends CoreRTC {
|
|
|
438
460
|
* @param options
|
|
439
461
|
* @returns
|
|
440
462
|
*/
|
|
441
|
-
|
|
442
|
-
return
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
}
|
|
463
|
+
join(options) {
|
|
464
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
465
|
+
return new Promise((success, fail) => __awaiter(this, void 0, void 0, function* () {
|
|
466
|
+
var _a;
|
|
467
|
+
this.emit('joinWillStart');
|
|
468
|
+
try {
|
|
469
|
+
// 取签名
|
|
470
|
+
const { sdkAppId, userId, roomId, userSig } = yield this._getVoiceSign(Object.assign(Object.assign({}, options), { roomId: options.roomId || 0 }));
|
|
471
|
+
this.userId = userId;
|
|
472
|
+
const { attendence, vendor_wrapper, } = JSON.parse(decodeURIComponent(userSig));
|
|
473
|
+
// 初始化配置
|
|
474
|
+
const configuration = new amazonChimeSdkJs.MeetingSessionConfiguration({
|
|
475
|
+
Meeting: vendor_wrapper,
|
|
476
|
+
}, {
|
|
477
|
+
Attendee: {
|
|
478
|
+
ExternalUserId: attendence.external_user_id,
|
|
479
|
+
AttendeeId: attendence.attendee_id,
|
|
480
|
+
JoinToken: attendence.join_token,
|
|
481
|
+
},
|
|
482
|
+
});
|
|
483
|
+
// 初始化会议会话
|
|
484
|
+
this.meetingSession = new amazonChimeSdkJs.DefaultMeetingSession(configuration, this.logger, this.deviceController);
|
|
485
|
+
// 注册事件
|
|
486
|
+
this._registerRtcEvent();
|
|
487
|
+
// 绑定监听器
|
|
488
|
+
this.meetingSession.audioVideo.addDeviceChangeObserver(this.deviceChangeObserver);
|
|
489
|
+
this.meetingSession.audioVideo.addObserver(this.audioVideoObserver);
|
|
490
|
+
// 绑定播放器
|
|
491
|
+
this.meetingSession.audioVideo.bindAudioElement(this.$audio);
|
|
492
|
+
const observer = {
|
|
493
|
+
audioVideoDidStart: () => {
|
|
494
|
+
var _a;
|
|
495
|
+
(_a = this.meetingSession) === null || _a === void 0 ? void 0 : _a.audioVideo.realtimeMuteLocalAudio();
|
|
496
|
+
this.joined = true;
|
|
497
|
+
this.emit('joined');
|
|
498
|
+
success(true);
|
|
499
|
+
},
|
|
500
|
+
audioVideoDidStop: () => {
|
|
501
|
+
this.joined = false;
|
|
502
|
+
success(false);
|
|
503
|
+
},
|
|
504
|
+
};
|
|
505
|
+
this.meetingSession.audioVideo.addObserver(observer);
|
|
506
|
+
// 选择语音输入设备
|
|
507
|
+
const audioInputDevices = yield this.deviceController.listAudioInputDevices(true);
|
|
508
|
+
const defaultAudioInput = audioInputDevices.find((device) => device.deviceId === 'default');
|
|
509
|
+
const otherAudioInput = audioInputDevices.find((device) => device.deviceId !== '');
|
|
510
|
+
this.audioInput = defaultAudioInput || otherAudioInput;
|
|
511
|
+
yield this.meetingSession.audioVideo.chooseVideoInputDevice(null);
|
|
512
|
+
yield this.meetingSession.audioVideo.chooseAudioInputDevice(((_a = this.audioInput) === null || _a === void 0 ? void 0 : _a.deviceId) || 'default');
|
|
513
|
+
this.meetingSession.audioVideo.start();
|
|
514
|
+
}
|
|
515
|
+
catch (e) {
|
|
516
|
+
this.emit('error', e);
|
|
517
|
+
this.logger.error(e.message);
|
|
518
|
+
success(false);
|
|
519
|
+
}
|
|
520
|
+
}));
|
|
500
521
|
});
|
|
501
522
|
}
|
|
502
523
|
quit() {
|
|
@@ -526,36 +547,40 @@ class BrowserRTC4Chime extends CoreRTC {
|
|
|
526
547
|
(_b = this.meetingSession) === null || _b === void 0 ? void 0 : _b.audioVideo.stop();
|
|
527
548
|
});
|
|
528
549
|
}
|
|
529
|
-
|
|
530
|
-
return
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
.
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
550
|
+
detectMicro() {
|
|
551
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
552
|
+
return new Promise((resolve) => {
|
|
553
|
+
const rule = { audio: true, video: false };
|
|
554
|
+
try {
|
|
555
|
+
navigator.mediaDevices
|
|
556
|
+
.getUserMedia(rule)
|
|
557
|
+
.then(() => resolve(true))
|
|
558
|
+
.catch(() => resolve(false));
|
|
559
|
+
}
|
|
560
|
+
catch (e) {
|
|
561
|
+
this.logger.error(e.message);
|
|
562
|
+
resolve(false);
|
|
563
|
+
}
|
|
564
|
+
});
|
|
542
565
|
});
|
|
543
566
|
}
|
|
544
|
-
|
|
567
|
+
toggleMicro(flag) {
|
|
545
568
|
var _a, _b, _c;
|
|
546
|
-
|
|
547
|
-
(
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
569
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
570
|
+
if (flag) {
|
|
571
|
+
(_a = this.meetingSession) === null || _a === void 0 ? void 0 : _a.audioVideo.realtimeUnmuteLocalAudio();
|
|
572
|
+
}
|
|
573
|
+
else {
|
|
574
|
+
(_b = this.meetingSession) === null || _b === void 0 ? void 0 : _b.audioVideo.realtimeMuteLocalAudio();
|
|
575
|
+
}
|
|
576
|
+
const muted = (_c = this.meetingSession) === null || _c === void 0 ? void 0 : _c.audioVideo.realtimeIsLocalAudioMuted();
|
|
577
|
+
if (muted !== undefined) {
|
|
578
|
+
return flag !== muted;
|
|
579
|
+
}
|
|
580
|
+
else {
|
|
581
|
+
return false;
|
|
582
|
+
}
|
|
583
|
+
});
|
|
559
584
|
}
|
|
560
585
|
shock() {
|
|
561
586
|
throw new Error('Method not implemented.');
|
|
@@ -604,51 +629,59 @@ class VRWebViewRTC extends CoreRTC {
|
|
|
604
629
|
get jsBridge() {
|
|
605
630
|
return this.options.jsBridge;
|
|
606
631
|
}
|
|
607
|
-
|
|
608
|
-
this
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
else {
|
|
617
|
-
if (res.code === exports.RTCJoinedInfoCodeEnum.Success) {
|
|
618
|
-
this.emit('joined');
|
|
619
|
-
this.joined = true;
|
|
632
|
+
join(options) {
|
|
633
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
634
|
+
this.emit('joinWillStart');
|
|
635
|
+
const { sdkAppId, userId, userSig } = yield this.options.getVoiceSign(options);
|
|
636
|
+
this.type = options.type;
|
|
637
|
+
const [res, error] = yield this.jsBridge.callAndBackfeed(`live/join?sdkAppID=${sdkAppId}&userID=${userId}&roomID=${Number(options.voiceId)}&userSig=${userSig}`);
|
|
638
|
+
if (!res) {
|
|
639
|
+
this.emit('error', error ? error : new Error('加入房间失败:未知异常。'));
|
|
640
|
+
this.joined = false;
|
|
620
641
|
}
|
|
621
642
|
else {
|
|
622
|
-
|
|
623
|
-
|
|
643
|
+
if (res.code === exports.RTCJoinedInfoCodeEnum.Success) {
|
|
644
|
+
this.emit('joined');
|
|
645
|
+
this.joined = true;
|
|
646
|
+
}
|
|
647
|
+
else {
|
|
648
|
+
this.emit('error', res);
|
|
649
|
+
this.joined = false;
|
|
650
|
+
}
|
|
624
651
|
}
|
|
625
|
-
|
|
626
|
-
|
|
652
|
+
return this.joined;
|
|
653
|
+
});
|
|
627
654
|
}
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
655
|
+
quit() {
|
|
656
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
657
|
+
const [res, error] = yield this.jsBridge.callAndBackfeed('live/quit');
|
|
658
|
+
if (res === null) {
|
|
659
|
+
this.emit('error', error ? error : new Error('退出房间失败:未知异常。'));
|
|
660
|
+
}
|
|
661
|
+
this.joined = false;
|
|
662
|
+
return !!res;
|
|
663
|
+
});
|
|
635
664
|
}
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
665
|
+
detectMicro() {
|
|
666
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
667
|
+
const [res, error] = yield this.jsBridge.detectMicro();
|
|
668
|
+
if (res === null) {
|
|
669
|
+
this.emit('error', error ? error : new Error('麦克风监测异常!'));
|
|
670
|
+
return false;
|
|
671
|
+
}
|
|
672
|
+
return res;
|
|
673
|
+
});
|
|
643
674
|
}
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
675
|
+
toggleMicro(flag) {
|
|
676
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
677
|
+
const [res, error] = yield this.jsBridge.callAndBackfeed(`live/toggleMicro?flag=${!!flag ? 1 : 0}`);
|
|
678
|
+
if (res === null) {
|
|
679
|
+
this.emit('error', error ? error : new Error('麦克风监测异常!'));
|
|
680
|
+
return false;
|
|
681
|
+
}
|
|
682
|
+
this.micro = res;
|
|
683
|
+
return res;
|
|
684
|
+
});
|
|
652
685
|
}
|
|
653
686
|
shock() {
|
|
654
687
|
this.jsBridge.shock(1);
|
|
@@ -891,6 +924,51 @@ function parseWSClsErr(code) {
|
|
|
891
924
|
return exports.WebSocketCloseError.Err_unknown;
|
|
892
925
|
}
|
|
893
926
|
|
|
927
|
+
function getDefaultExportFromCjs (x) {
|
|
928
|
+
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
function createCommonjsModule(fn) {
|
|
932
|
+
var module = { exports: {} };
|
|
933
|
+
return fn(module, module.exports), module.exports;
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
var LogLevel_1 = createCommonjsModule(function (module, exports) {
|
|
937
|
+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
938
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
939
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
940
|
+
exports.LogLevel = void 0;
|
|
941
|
+
var LogLevel;
|
|
942
|
+
(function (LogLevel) {
|
|
943
|
+
LogLevel[LogLevel["DEBUG"] = 0] = "DEBUG";
|
|
944
|
+
LogLevel[LogLevel["INFO"] = 1] = "INFO";
|
|
945
|
+
LogLevel[LogLevel["WARN"] = 2] = "WARN";
|
|
946
|
+
LogLevel[LogLevel["ERROR"] = 3] = "ERROR";
|
|
947
|
+
LogLevel[LogLevel["OFF"] = 4] = "OFF";
|
|
948
|
+
})(LogLevel = exports.LogLevel || (exports.LogLevel = {}));
|
|
949
|
+
exports.default = LogLevel;
|
|
950
|
+
|
|
951
|
+
});
|
|
952
|
+
|
|
953
|
+
var LogLevel = /*@__PURE__*/getDefaultExportFromCjs(LogLevel_1);
|
|
954
|
+
|
|
955
|
+
var LiveState;
|
|
956
|
+
(function (LiveState) {
|
|
957
|
+
LiveState[LiveState["NOTINITIALIZED"] = -1] = "NOTINITIALIZED";
|
|
958
|
+
/**
|
|
959
|
+
* 正在链接中
|
|
960
|
+
*/
|
|
961
|
+
LiveState[LiveState["CONNECTING"] = 0] = "CONNECTING";
|
|
962
|
+
/**
|
|
963
|
+
* 已经链接并且可以通讯
|
|
964
|
+
*/
|
|
965
|
+
LiveState[LiveState["OPEN"] = 1] = "OPEN";
|
|
966
|
+
/**
|
|
967
|
+
* 连接已关闭或者链接失败
|
|
968
|
+
*/
|
|
969
|
+
LiveState[LiveState["CLOSED"] = 3] = "CLOSED";
|
|
970
|
+
})(LiveState || (LiveState = {}));
|
|
971
|
+
|
|
894
972
|
function appendUri(uri, query) {
|
|
895
973
|
const hasQuery = uri.indexOf('?') !== -1;
|
|
896
974
|
const newQuery = Object.keys(query).reduce((accu, curr, idx) => `${accu}${(idx === 0 && !hasQuery) ? '?' : '&'}${curr}=${query[curr]}`, '');
|
|
@@ -1035,692 +1113,1115 @@ function equal(value, other, opt) {
|
|
|
1035
1113
|
return isDeepEqual(value, other);
|
|
1036
1114
|
}
|
|
1037
1115
|
|
|
1038
|
-
|
|
1116
|
+
/**
|
|
1117
|
+
* 输出格式化日志
|
|
1118
|
+
*/
|
|
1119
|
+
// 获取当前时间
|
|
1120
|
+
const getTime = () => {
|
|
1121
|
+
const date = new Date();
|
|
1122
|
+
const year = date.getFullYear();
|
|
1123
|
+
const month = (date.getMonth() + 1).toString().padStart(2, '0'); //月份是从0开始的
|
|
1124
|
+
const day = date.getDate().toString().padStart(2, '0');
|
|
1125
|
+
const hour = date.getHours().toString().padStart(2, '0');
|
|
1126
|
+
const min = date.getMinutes().toString().padStart(2, '0');
|
|
1127
|
+
const sec = date.getSeconds().toString().padStart(2, '0');
|
|
1128
|
+
const ms = date.getMilliseconds();
|
|
1129
|
+
return `[${year}-${month}-${day} ${hour}:${min}:${sec}.${ms}]`;
|
|
1130
|
+
};
|
|
1131
|
+
var LOG_LEVEL;
|
|
1132
|
+
(function (LOG_LEVEL) {
|
|
1133
|
+
LOG_LEVEL["info"] = "INFO";
|
|
1134
|
+
LOG_LEVEL["log"] = "LOG";
|
|
1135
|
+
LOG_LEVEL["error"] = "ERROR";
|
|
1136
|
+
LOG_LEVEL["warn"] = "WARN";
|
|
1137
|
+
})(LOG_LEVEL || (LOG_LEVEL = {}));
|
|
1138
|
+
// 输出日志
|
|
1139
|
+
const echo = (logLevel, args = []) => {
|
|
1140
|
+
args.unshift(`Realsee Live ${getTime()} <${logLevel}> `);
|
|
1141
|
+
switch (logLevel) {
|
|
1142
|
+
case LOG_LEVEL.info:
|
|
1143
|
+
return console.info(...args);
|
|
1144
|
+
case LOG_LEVEL.error:
|
|
1145
|
+
return console.error(...args);
|
|
1146
|
+
case LOG_LEVEL.warn:
|
|
1147
|
+
return console.warn(...args);
|
|
1148
|
+
default:
|
|
1149
|
+
return console.log(...args);
|
|
1150
|
+
}
|
|
1151
|
+
};
|
|
1152
|
+
const log = (...args) => echo(LOG_LEVEL.log, args);
|
|
1153
|
+
const info = (...args) => echo(LOG_LEVEL.info, args);
|
|
1154
|
+
const error = (...args) => echo(LOG_LEVEL.error, args);
|
|
1155
|
+
const warn = (...args) => echo(LOG_LEVEL.warn, args);
|
|
1156
|
+
const logger = {
|
|
1157
|
+
log,
|
|
1158
|
+
info,
|
|
1159
|
+
error,
|
|
1160
|
+
warn,
|
|
1161
|
+
};
|
|
1162
|
+
var logger$1 = logger;
|
|
1163
|
+
|
|
1164
|
+
/**
|
|
1165
|
+
* 具有鲁棒性的WebSocket封装
|
|
1166
|
+
* 1、自动重连
|
|
1167
|
+
* 2、可根据网络情况进行重连
|
|
1168
|
+
*/
|
|
1169
|
+
class RobustWebSocket extends Subscribe {
|
|
1039
1170
|
constructor(options) {
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
this.
|
|
1043
|
-
|
|
1171
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
|
1172
|
+
super();
|
|
1173
|
+
this._options = {
|
|
1174
|
+
timeout: 10000,
|
|
1175
|
+
shouldReconnect: (event, ws) => {
|
|
1176
|
+
if (event.code === 1008 || event.code === 1011)
|
|
1177
|
+
return;
|
|
1178
|
+
return [0, 3000, 10000][ws.attempts];
|
|
1179
|
+
},
|
|
1180
|
+
should1000Reconnect: false,
|
|
1181
|
+
ignoreConnectivityEvents: false,
|
|
1182
|
+
automaticOpen: false,
|
|
1183
|
+
};
|
|
1184
|
+
this._attempts = 0;
|
|
1185
|
+
this._reconnects = -1;
|
|
1186
|
+
this._reconnectWhenOnlineAgain = false;
|
|
1187
|
+
this._explicitlyClosed = false;
|
|
1188
|
+
this._connectivityEventsAttached = false;
|
|
1044
1189
|
/**
|
|
1045
|
-
*
|
|
1190
|
+
* 清理连接中的请求
|
|
1046
1191
|
*/
|
|
1047
|
-
this.
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
live.emit('ws.readyStateUpdate', this.readyState);
|
|
1053
|
-
}
|
|
1054
|
-
break;
|
|
1055
|
-
}
|
|
1056
|
-
const readyState = this.webSocket.readyState;
|
|
1057
|
-
if (readyState !== this.readyState) {
|
|
1058
|
-
this.readyState = readyState;
|
|
1059
|
-
live.emit('ws.readyStateUpdate', this.readyState);
|
|
1060
|
-
}
|
|
1061
|
-
} while (false);
|
|
1062
|
-
return this.readyState;
|
|
1192
|
+
this._clearPendingReconnectIfNeeded = () => {
|
|
1193
|
+
if (this._pendingReconnect) {
|
|
1194
|
+
clearTimeout(this._pendingReconnect);
|
|
1195
|
+
this._pendingReconnect = undefined;
|
|
1196
|
+
}
|
|
1063
1197
|
};
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1198
|
+
/**
|
|
1199
|
+
* 当网页连接上网络进行重连
|
|
1200
|
+
* @param event
|
|
1201
|
+
*/
|
|
1202
|
+
this._online = (event) => {
|
|
1203
|
+
if (this._reconnectWhenOnlineAgain) {
|
|
1204
|
+
this._clearPendingReconnectIfNeeded();
|
|
1205
|
+
this._reconnect(event);
|
|
1070
1206
|
}
|
|
1071
|
-
return true;
|
|
1072
1207
|
};
|
|
1073
1208
|
/**
|
|
1074
|
-
*
|
|
1209
|
+
* 当网页断开网络进行关闭
|
|
1075
1210
|
*/
|
|
1076
|
-
this.
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1211
|
+
this._offline = () => {
|
|
1212
|
+
var _a;
|
|
1213
|
+
this._reconnectWhenOnlineAgain = true;
|
|
1214
|
+
(_a = this._realWebSocket) === null || _a === void 0 ? void 0 : _a.close(1000);
|
|
1215
|
+
};
|
|
1216
|
+
/**
|
|
1217
|
+
* 解除网络监听事件
|
|
1218
|
+
*/
|
|
1219
|
+
this._detachConnectivityEvents = () => {
|
|
1220
|
+
if (this._connectivityEventsAttached) {
|
|
1221
|
+
globalThis === null || globalThis === void 0 ? void 0 : globalThis.removeEventListener('online', this._online);
|
|
1222
|
+
globalThis === null || globalThis === void 0 ? void 0 : globalThis.removeEventListener('offline', this._offline);
|
|
1223
|
+
this._connectivityEventsAttached = false;
|
|
1224
|
+
}
|
|
1225
|
+
};
|
|
1226
|
+
/**
|
|
1227
|
+
* 注册网络监听事件
|
|
1228
|
+
*/
|
|
1229
|
+
this._attachConnectivityEvents = () => {
|
|
1230
|
+
if (!this._connectivityEventsAttached) {
|
|
1231
|
+
globalThis === null || globalThis === void 0 ? void 0 : globalThis.addEventListener('online', this._online);
|
|
1232
|
+
globalThis === null || globalThis === void 0 ? void 0 : globalThis.addEventListener('offline', this._offline);
|
|
1233
|
+
this._connectivityEventsAttached = true;
|
|
1082
1234
|
}
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1235
|
+
};
|
|
1236
|
+
/**
|
|
1237
|
+
* 发送消息
|
|
1238
|
+
* @param data
|
|
1239
|
+
* @returns
|
|
1240
|
+
*/
|
|
1241
|
+
this.send = (data) => { var _a; return (_a = this._realWebSocket) === null || _a === void 0 ? void 0 : _a.send(data); };
|
|
1242
|
+
/**
|
|
1243
|
+
* 关闭连接
|
|
1244
|
+
* @param code 代码
|
|
1245
|
+
* @param reason 原因
|
|
1246
|
+
* @returns
|
|
1247
|
+
*/
|
|
1248
|
+
this.close = (code, reason) => {
|
|
1249
|
+
var _a;
|
|
1250
|
+
if (typeof code !== 'number') {
|
|
1251
|
+
reason = code;
|
|
1252
|
+
code = 1000;
|
|
1086
1253
|
}
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1254
|
+
this._clearPendingReconnectIfNeeded();
|
|
1255
|
+
this._reconnectWhenOnlineAgain = false;
|
|
1256
|
+
this._explicitlyClosed = true;
|
|
1257
|
+
this._detachConnectivityEvents();
|
|
1258
|
+
return (_a = this._realWebSocket) === null || _a === void 0 ? void 0 : _a.close(code, reason);
|
|
1259
|
+
};
|
|
1260
|
+
/**
|
|
1261
|
+
* 进行ws连接
|
|
1262
|
+
*/
|
|
1263
|
+
this.open = (url) => {
|
|
1264
|
+
var _a, _b;
|
|
1265
|
+
if (url) {
|
|
1266
|
+
this._url = url;
|
|
1090
1267
|
}
|
|
1091
|
-
if (this.
|
|
1092
|
-
this.
|
|
1093
|
-
this.
|
|
1268
|
+
if (((_a = this._realWebSocket) === null || _a === void 0 ? void 0 : _a.readyState) !== WebSocket.OPEN &&
|
|
1269
|
+
((_b = this._realWebSocket) === null || _b === void 0 ? void 0 : _b.readyState) !== WebSocket.CONNECTING) {
|
|
1270
|
+
this._clearPendingReconnectIfNeeded();
|
|
1271
|
+
this._reconnectWhenOnlineAgain = false;
|
|
1272
|
+
this._explicitlyClosed = false;
|
|
1273
|
+
this._createWebSocket();
|
|
1094
1274
|
}
|
|
1095
|
-
this.webSocket.close();
|
|
1096
|
-
this.webSocket = undefined;
|
|
1097
|
-
return true;
|
|
1098
1275
|
};
|
|
1099
|
-
|
|
1276
|
+
/**
|
|
1277
|
+
* 创建ws连接
|
|
1278
|
+
*/
|
|
1279
|
+
this._createWebSocket = () => {
|
|
1280
|
+
var _a, _b, _c;
|
|
1281
|
+
const newUrl = typeof this._url === 'string' ? this._url : (_a = this._url) === null || _a === void 0 ? void 0 : _a.call(this, this);
|
|
1282
|
+
if (!newUrl)
|
|
1283
|
+
return;
|
|
1284
|
+
this._pendingReconnect = undefined;
|
|
1285
|
+
this._realWebSocket = new WebSocket(newUrl, this._protocols || undefined);
|
|
1286
|
+
this._attempts = this._attempts + 1;
|
|
1287
|
+
this.emit('connecting', new CustomEvent('connecting', {
|
|
1288
|
+
detail: { attempts: this._attempts, reconnects: this._reconnects },
|
|
1289
|
+
}));
|
|
1290
|
+
const timeoutCallback = () => {
|
|
1291
|
+
this._connectTimeout = undefined;
|
|
1292
|
+
this._detachConnectivityEvents();
|
|
1293
|
+
this.emit('timeout', new CustomEvent('connecting', {
|
|
1294
|
+
detail: {
|
|
1295
|
+
attempts: this._attempts,
|
|
1296
|
+
reconnects: this._reconnects,
|
|
1297
|
+
},
|
|
1298
|
+
}));
|
|
1299
|
+
};
|
|
1300
|
+
this._connectTimeout = setTimeout(timeoutCallback, (_b = this._options) === null || _b === void 0 ? void 0 : _b.timeout);
|
|
1301
|
+
this._dispatchWebSocketEvent();
|
|
1302
|
+
if (!((_c = this._options) === null || _c === void 0 ? void 0 : _c.ignoreConnectivityEvents)) {
|
|
1303
|
+
this._attachConnectivityEvents();
|
|
1304
|
+
}
|
|
1305
|
+
};
|
|
1306
|
+
/**
|
|
1307
|
+
* 分发ws事件
|
|
1308
|
+
*/
|
|
1309
|
+
this._dispatchWebSocketEvent = () => {
|
|
1310
|
+
var _a, _b, _c, _d;
|
|
1311
|
+
(_a = this._realWebSocket) === null || _a === void 0 ? void 0 : _a.addEventListener('open', this._webSocketOpenHandler);
|
|
1312
|
+
(_b = this._realWebSocket) === null || _b === void 0 ? void 0 : _b.addEventListener('close', this._webSocketCloseHandler);
|
|
1313
|
+
(_c = this._realWebSocket) === null || _c === void 0 ? void 0 : _c.addEventListener('error', this._webSocketErrorHandler);
|
|
1314
|
+
(_d = this._realWebSocket) === null || _d === void 0 ? void 0 : _d.addEventListener('message', this._webSocketMessageHandler);
|
|
1315
|
+
};
|
|
1316
|
+
/**
|
|
1317
|
+
* ws连接事件
|
|
1318
|
+
* @returns
|
|
1319
|
+
*/
|
|
1320
|
+
this._webSocketOpenHandler = (event) => {
|
|
1321
|
+
if (this._connectTimeout) {
|
|
1322
|
+
clearTimeout(this._connectTimeout);
|
|
1323
|
+
this._connectTimeout = undefined;
|
|
1324
|
+
}
|
|
1325
|
+
const reconnects = ++this._reconnects;
|
|
1326
|
+
const attempts = this._attempts;
|
|
1327
|
+
this._attempts = 0;
|
|
1328
|
+
this._reconnectWhenOnlineAgain = false;
|
|
1329
|
+
return this.emit('open', Object.assign(event, { detail: { reconnects, attempts } }));
|
|
1330
|
+
};
|
|
1331
|
+
/**
|
|
1332
|
+
* ws 关闭事件
|
|
1333
|
+
* @param event
|
|
1334
|
+
* @returns
|
|
1335
|
+
*/
|
|
1336
|
+
this._webSocketCloseHandler = (event) => {
|
|
1337
|
+
this._reconnect(event);
|
|
1338
|
+
return this.emit('close', event);
|
|
1339
|
+
};
|
|
1340
|
+
/**
|
|
1341
|
+
* ws 异常
|
|
1342
|
+
* @param event
|
|
1343
|
+
* @returns
|
|
1344
|
+
*/
|
|
1345
|
+
this._webSocketErrorHandler = (event) => {
|
|
1346
|
+
return this.emit('error', new CustomEvent('error', { detail: { error: event } }));
|
|
1347
|
+
};
|
|
1348
|
+
/**
|
|
1349
|
+
* ws消息
|
|
1350
|
+
* @param event
|
|
1351
|
+
* @returns
|
|
1352
|
+
*/
|
|
1353
|
+
this._webSocketMessageHandler = (event) => {
|
|
1354
|
+
return this.emit('message', event);
|
|
1355
|
+
};
|
|
1356
|
+
if (options) {
|
|
1357
|
+
this.setOptions(options);
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
get attempts() {
|
|
1361
|
+
return this._attempts;
|
|
1362
|
+
}
|
|
1363
|
+
setOptions(options) {
|
|
1364
|
+
if (!options)
|
|
1365
|
+
return;
|
|
1366
|
+
this._url = options.url;
|
|
1367
|
+
this._protocols = options.protocols;
|
|
1368
|
+
const opts = Object.assign(this._options, options.robustOptions || {});
|
|
1369
|
+
if (typeof (opts === null || opts === void 0 ? void 0 : opts.timeout) !== 'number') {
|
|
1370
|
+
throw new Error('timeout must be the number of milliseconds to timeout a connection attempt');
|
|
1371
|
+
}
|
|
1372
|
+
if (typeof (opts === null || opts === void 0 ? void 0 : opts.shouldReconnect) !== 'function') {
|
|
1373
|
+
throw new Error('shouldReconnect must be a function that returns the number of milliseconds to wait for a reconnect attempt, or null or undefined to not reconnect.');
|
|
1374
|
+
}
|
|
1375
|
+
this._options = opts;
|
|
1376
|
+
if (this._options.automaticOpen) {
|
|
1377
|
+
this._createWebSocket();
|
|
1378
|
+
}
|
|
1100
1379
|
}
|
|
1101
1380
|
/**
|
|
1102
|
-
*
|
|
1103
|
-
* @param
|
|
1104
|
-
* @
|
|
1381
|
+
* 进行重连
|
|
1382
|
+
* @param event
|
|
1383
|
+
* @returns
|
|
1105
1384
|
*/
|
|
1106
|
-
|
|
1107
|
-
var _a, _b, _c;
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
* 自己的状态变化
|
|
1113
|
-
*/
|
|
1114
|
-
case exports.Command.SelfUserInfo: {
|
|
1115
|
-
const selfInfo = data;
|
|
1116
|
-
if (equal(this.selfUserInfo, selfInfo, { deep: true }))
|
|
1117
|
-
return;
|
|
1118
|
-
this.selfUserInfo = selfInfo;
|
|
1119
|
-
live.emit('selfInfoUpdate', this.selfUserInfo, frontRequestId);
|
|
1120
|
-
break;
|
|
1121
|
-
}
|
|
1122
|
-
/**
|
|
1123
|
-
* 房间信息变化
|
|
1124
|
-
*/
|
|
1125
|
-
case exports.Command.RoomInfo: {
|
|
1126
|
-
const roomInfo = data;
|
|
1127
|
-
this.roomInfo = Object.assign({}, roomInfo);
|
|
1128
|
-
live.emit('readyKeyframeSync', (roomInfo.last_frame || {}));
|
|
1129
|
-
break;
|
|
1130
|
-
}
|
|
1131
|
-
/**
|
|
1132
|
-
* 语音信息变化
|
|
1133
|
-
*/
|
|
1134
|
-
case exports.Command.RTCInfo: {
|
|
1135
|
-
const { voice_id: voiceId, type } = data;
|
|
1136
|
-
/* 如果已经进入语音房间,则不重复进入 --> "RTCInfo" 指令可能会下发多次 */
|
|
1137
|
-
if (live.$RTC.joined) {
|
|
1138
|
-
break;
|
|
1139
|
-
}
|
|
1140
|
-
live.$RTC.join({
|
|
1141
|
-
voiceId,
|
|
1142
|
-
userId: ((_a = this.selfUserInfo) === null || _a === void 0 ? void 0 : _a.id) || '',
|
|
1143
|
-
roomId: (_b = this.roomInfo) === null || _b === void 0 ? void 0 : _b.info.room_code,
|
|
1144
|
-
type,
|
|
1145
|
-
});
|
|
1146
|
-
// 加入房间后 麦克风默认就开启了:需要发个指令。
|
|
1147
|
-
live.updateStatus(exports.BuiltinEventType.UserChange, exports.BuiltinActionType.UserMicroStatus, {
|
|
1148
|
-
status: exports.MicroStatus.OPEN,
|
|
1149
|
-
});
|
|
1150
|
-
break;
|
|
1151
|
-
}
|
|
1152
|
-
/**
|
|
1153
|
-
* 房间用户列表变化
|
|
1154
|
-
*/
|
|
1155
|
-
case exports.Command.UserList: {
|
|
1156
|
-
const userList = data;
|
|
1157
|
-
this.userList = userList;
|
|
1158
|
-
live.emit('userListUpdate', this.userList, frontRequestId);
|
|
1159
|
-
break;
|
|
1160
|
-
}
|
|
1161
|
-
/**
|
|
1162
|
-
* 自定义事件广播
|
|
1163
|
-
*/
|
|
1164
|
-
case exports.Command.CustomEvent: {
|
|
1165
|
-
const evtMsg = data;
|
|
1166
|
-
live.emit('broadcast', evtMsg, frontRequestId);
|
|
1167
|
-
break;
|
|
1168
|
-
}
|
|
1169
|
-
/**
|
|
1170
|
-
* 帧数据同步
|
|
1171
|
-
*/
|
|
1172
|
-
case exports.Command.KeyframeSync: {
|
|
1173
|
-
const remoteKeyframes = data;
|
|
1174
|
-
// 此处做一层 diff,仅跟本地数据不一致的情况下才广播数据。
|
|
1175
|
-
const keyframes = Object.keys(remoteKeyframes).reduce((accu, curr) => {
|
|
1176
|
-
if (equal(remoteKeyframes[curr], this.keyframes[curr], { deep: true })) {
|
|
1177
|
-
return accu;
|
|
1178
|
-
}
|
|
1179
|
-
const params = [
|
|
1180
|
-
remoteKeyframes[curr],
|
|
1181
|
-
this.keyframes[curr],
|
|
1182
|
-
frontRequestId,
|
|
1183
|
-
];
|
|
1184
|
-
const evtName = curr;
|
|
1185
|
-
live.keyframes.emit(evtName, ...params);
|
|
1186
|
-
this.keyframes[curr] = remoteKeyframes[curr];
|
|
1187
|
-
accu[curr] = remoteKeyframes[curr];
|
|
1188
|
-
return accu;
|
|
1189
|
-
}, {});
|
|
1190
|
-
live.emit('keyframes', keyframes, frontRequestId);
|
|
1191
|
-
break;
|
|
1192
|
-
}
|
|
1193
|
-
/**
|
|
1194
|
-
* 内置消息
|
|
1195
|
-
*/
|
|
1196
|
-
case exports.Command.BuiltinMsg: {
|
|
1197
|
-
const builtinMsg = data;
|
|
1198
|
-
live.emit('builtinEvent', builtinMsg);
|
|
1199
|
-
if (builtinMsg.event_type === exports.BuiltinEventType.UserChange) {
|
|
1200
|
-
live.emit('userChange', builtinMsg);
|
|
1201
|
-
}
|
|
1202
|
-
if (builtinMsg.event_type === exports.BuiltinEventType.RoomChange) {
|
|
1203
|
-
live.emit('roomChange', builtinMsg);
|
|
1204
|
-
}
|
|
1205
|
-
/**
|
|
1206
|
-
* 下发指令自己操作麦克风
|
|
1207
|
-
*/
|
|
1208
|
-
if (builtinMsg.event_type === exports.BuiltinEventType.UserChange &&
|
|
1209
|
-
builtinMsg.action === exports.BuiltinActionType.UserMicroStatus) {
|
|
1210
|
-
live.toggleMicro(builtinMsg.data.status === exports.MicroStatus.OPEN);
|
|
1211
|
-
}
|
|
1212
|
-
/**
|
|
1213
|
-
* 如果下发指令退出房间,则 关闭麦克风 及 销毁 WebSocket
|
|
1214
|
-
*/
|
|
1215
|
-
if (builtinMsg.event_type === exports.BuiltinEventType.RoomChange &&
|
|
1216
|
-
builtinMsg.action === exports.BuiltinActionType.RoomClose) {
|
|
1217
|
-
(_c = this.options.rtc) === null || _c === void 0 ? void 0 : _c.quit();
|
|
1218
|
-
this.disposeWebSocket();
|
|
1219
|
-
}
|
|
1220
|
-
break;
|
|
1221
|
-
}
|
|
1222
|
-
/**
|
|
1223
|
-
* 被踢出房间
|
|
1224
|
-
*/
|
|
1225
|
-
case exports.Command.UserKickOut: {
|
|
1226
|
-
live.emit('kickOut');
|
|
1227
|
-
break;
|
|
1228
|
-
}
|
|
1229
|
-
/**
|
|
1230
|
-
* 其它未知广播
|
|
1231
|
-
*/
|
|
1232
|
-
default: {
|
|
1233
|
-
console.warn('unknown command: ', command);
|
|
1234
|
-
}
|
|
1235
|
-
}
|
|
1385
|
+
_reconnect(event) {
|
|
1386
|
+
var _a, _b, _c, _d;
|
|
1387
|
+
if ((!((_a = this._options) === null || _a === void 0 ? void 0 : _a.should1000Reconnect) && event.code === 1000) ||
|
|
1388
|
+
this._explicitlyClosed) {
|
|
1389
|
+
this._attempts = 0;
|
|
1390
|
+
return;
|
|
1236
1391
|
}
|
|
1237
|
-
|
|
1238
|
-
|
|
1392
|
+
if (((_b = globalThis === null || globalThis === void 0 ? void 0 : globalThis.navigator) === null || _b === void 0 ? void 0 : _b.onLine) === false) {
|
|
1393
|
+
this._reconnectWhenOnlineAgain = true;
|
|
1394
|
+
return;
|
|
1239
1395
|
}
|
|
1396
|
+
const delay = (_d = (_c = this._options) === null || _c === void 0 ? void 0 : _c.shouldReconnect) === null || _d === void 0 ? void 0 : _d.call(_c, event, this);
|
|
1397
|
+
if (typeof delay === 'number') {
|
|
1398
|
+
this._pendingReconnect = setTimeout(this._createWebSocket, delay);
|
|
1399
|
+
}
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
class LiveController extends Subscribe {
|
|
1404
|
+
constructor() {
|
|
1405
|
+
super();
|
|
1406
|
+
/**
|
|
1407
|
+
* ws代理器
|
|
1408
|
+
*/
|
|
1409
|
+
this._ws = new RobustWebSocket();
|
|
1410
|
+
/**
|
|
1411
|
+
* 带看连接状态
|
|
1412
|
+
*/
|
|
1413
|
+
this._state = LiveState.NOTINITIALIZED;
|
|
1414
|
+
/**
|
|
1415
|
+
* 添加事件监听
|
|
1416
|
+
*/
|
|
1417
|
+
this._addWebSocketEventListeners = () => {
|
|
1418
|
+
this._ws.on('close', this._handleCloseEvent);
|
|
1419
|
+
this._ws.on('connecting', this._handleConnectingEvent);
|
|
1420
|
+
this._ws.on('error', this._handleErrorEvent);
|
|
1421
|
+
this._ws.on('message', this._handleMessageEvent);
|
|
1422
|
+
this._ws.on('open', this._handleOpenEvent);
|
|
1423
|
+
this._ws.on('timeout', this._handleTimeoutEvent);
|
|
1424
|
+
};
|
|
1425
|
+
/**
|
|
1426
|
+
* 移除事件监听
|
|
1427
|
+
*/
|
|
1428
|
+
this._removeWebSocketEventListeners = () => {
|
|
1429
|
+
this._ws.off('close', this._handleCloseEvent);
|
|
1430
|
+
this._ws.off('connecting', this._handleConnectingEvent);
|
|
1431
|
+
this._ws.off('error', this._handleErrorEvent);
|
|
1432
|
+
this._ws.off('message', this._handleMessageEvent);
|
|
1433
|
+
this._ws.off('open', this._handleOpenEvent);
|
|
1434
|
+
this._ws.off('timeout', this._handleTimeoutEvent);
|
|
1435
|
+
};
|
|
1436
|
+
/**
|
|
1437
|
+
* 处理房间关闭事件
|
|
1438
|
+
* @param event
|
|
1439
|
+
*/
|
|
1440
|
+
this._handleCloseEvent = (event) => {
|
|
1441
|
+
logger$1.info(`live room closed bacause of ${event.code}-${event.reason || parseWSClsErr(event.code)}`);
|
|
1442
|
+
this.state = LiveState.CLOSED;
|
|
1443
|
+
};
|
|
1444
|
+
/**
|
|
1445
|
+
* 连接中
|
|
1446
|
+
* @param event
|
|
1447
|
+
*/
|
|
1448
|
+
this._handleConnectingEvent = (event) => {
|
|
1449
|
+
logger$1.info(`live room is connecting`, event.detail);
|
|
1450
|
+
this.state = LiveState.CONNECTING;
|
|
1451
|
+
};
|
|
1452
|
+
/**
|
|
1453
|
+
* 连接发送异常
|
|
1454
|
+
* @param event
|
|
1455
|
+
*/
|
|
1456
|
+
this._handleErrorEvent = (event) => {
|
|
1457
|
+
logger$1.error(`live room error`, event);
|
|
1458
|
+
this.state = LiveState.CLOSED;
|
|
1459
|
+
};
|
|
1460
|
+
/**
|
|
1461
|
+
* 接收到消息
|
|
1462
|
+
* @param event
|
|
1463
|
+
*/
|
|
1464
|
+
this._handleMessageEvent = (event) => {
|
|
1465
|
+
// logger.info('live room received message ', event.data);
|
|
1466
|
+
let message = (() => {
|
|
1467
|
+
try {
|
|
1468
|
+
return JSON.parse(event.data);
|
|
1469
|
+
}
|
|
1470
|
+
catch (e) {
|
|
1471
|
+
return event.data;
|
|
1472
|
+
}
|
|
1473
|
+
})();
|
|
1474
|
+
this.emit('message', message);
|
|
1475
|
+
};
|
|
1476
|
+
/**
|
|
1477
|
+
* 连接建立成功
|
|
1478
|
+
* @param event
|
|
1479
|
+
*/
|
|
1480
|
+
this._handleOpenEvent = (event) => {
|
|
1481
|
+
logger$1.info('live room open', event.detail);
|
|
1482
|
+
this.state = LiveState.OPEN;
|
|
1483
|
+
};
|
|
1484
|
+
/**
|
|
1485
|
+
* 处理超时
|
|
1486
|
+
* @param event
|
|
1487
|
+
*/
|
|
1488
|
+
this._handleTimeoutEvent = (event) => {
|
|
1489
|
+
logger$1.error('live room connect timeout!', event.detail);
|
|
1490
|
+
this.state = LiveState.CLOSED;
|
|
1491
|
+
};
|
|
1492
|
+
/**
|
|
1493
|
+
* 释放资源,释放之后需要重新实例化
|
|
1494
|
+
* @returns
|
|
1495
|
+
*/
|
|
1496
|
+
this.dispose = () => __awaiter(this, void 0, void 0, function* () {
|
|
1497
|
+
this._removeWebSocketEventListeners();
|
|
1498
|
+
return yield this.close('live room close by controller disposed!');
|
|
1499
|
+
});
|
|
1500
|
+
/**
|
|
1501
|
+
* 开启房间链接
|
|
1502
|
+
* @param url 房间链接
|
|
1503
|
+
* @returns
|
|
1504
|
+
*/
|
|
1505
|
+
this.open = (url) => this._ws.open(url);
|
|
1506
|
+
/**
|
|
1507
|
+
* 关闭房间
|
|
1508
|
+
* @param code
|
|
1509
|
+
* @param reason
|
|
1510
|
+
*/
|
|
1511
|
+
this.close = (code, reason) => new Promise((resolve) => {
|
|
1512
|
+
this._ws.once('close', () => resolve(true));
|
|
1513
|
+
this._ws.close(code, reason);
|
|
1514
|
+
});
|
|
1515
|
+
this._addWebSocketEventListeners();
|
|
1516
|
+
}
|
|
1517
|
+
set state(state) {
|
|
1518
|
+
const prevState = JSON.parse(JSON.stringify(this._state));
|
|
1519
|
+
this._state = state;
|
|
1520
|
+
this.emit('stateChange', this.state, prevState);
|
|
1521
|
+
}
|
|
1522
|
+
get state() {
|
|
1523
|
+
return this._state;
|
|
1240
1524
|
}
|
|
1241
1525
|
/**
|
|
1242
1526
|
* 发送数据
|
|
1243
1527
|
* @param data
|
|
1244
1528
|
*/
|
|
1245
|
-
sendMessage(data) {
|
|
1246
|
-
if (
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1529
|
+
sendMessage(data = '') {
|
|
1530
|
+
if (data === undefined || data === null || data === '') {
|
|
1531
|
+
throw new Error('live message is empty!');
|
|
1532
|
+
}
|
|
1533
|
+
if (this.state === LiveState.OPEN) {
|
|
1534
|
+
return this._ws.send(JSON.stringify(data));
|
|
1535
|
+
}
|
|
1536
|
+
else {
|
|
1537
|
+
throw new Error('live has not yet been initialized!');
|
|
1538
|
+
}
|
|
1251
1539
|
}
|
|
1252
1540
|
}
|
|
1253
1541
|
|
|
1254
1542
|
const unimplementedGetVoiceSign = (params) => Promise.reject('unimplemented method GetVoiceSign');
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1543
|
+
const createLiveMsg = (command, data = {}, toUserIds = []) => ({
|
|
1544
|
+
command,
|
|
1545
|
+
front_request_id: uuid(),
|
|
1546
|
+
data: Object.assign(Object.assign({}, data), { to_user_ids: Array.isArray(toUserIds) ? toUserIds : [toUserIds] }),
|
|
1547
|
+
});
|
|
1548
|
+
const _clearLiveInstanceIfNeed = () => {
|
|
1549
|
+
var _a, _b;
|
|
1550
|
+
if (window === null || window === void 0 ? void 0 : window.__Realsee_Live__) {
|
|
1551
|
+
(_b = (_a = window === null || window === void 0 ? void 0 : window.__Realsee_Live__) === null || _a === void 0 ? void 0 : _a.dispose) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
1552
|
+
window.__Realsee_Live__ = null;
|
|
1553
|
+
}
|
|
1554
|
+
};
|
|
1555
|
+
class Live extends Subscribe {
|
|
1556
|
+
constructor(opts) {
|
|
1557
|
+
var _a;
|
|
1558
|
+
super();
|
|
1559
|
+
/**
|
|
1560
|
+
* 带看的配置
|
|
1561
|
+
*/
|
|
1562
|
+
this._options = {};
|
|
1563
|
+
/**
|
|
1564
|
+
* 帧数据监听
|
|
1565
|
+
*/
|
|
1566
|
+
this.keyframes = new Subscribe();
|
|
1567
|
+
/**
|
|
1568
|
+
* 内置的一些数据
|
|
1569
|
+
*/
|
|
1570
|
+
this._buildInData = {
|
|
1571
|
+
keyframes: {},
|
|
1572
|
+
};
|
|
1573
|
+
/**
|
|
1574
|
+
* 根据键值取帧数据
|
|
1575
|
+
* @param key 帧数据的键值
|
|
1576
|
+
* @returns
|
|
1577
|
+
*/
|
|
1578
|
+
this.getFramesByKey = (key) => this.snapshot[key];
|
|
1579
|
+
/**
|
|
1580
|
+
* 发送帧数据(需要能够被序列化)
|
|
1581
|
+
* @param key 帧数据键值
|
|
1582
|
+
* @param frame 帧数据本体
|
|
1583
|
+
* @returns
|
|
1584
|
+
*/
|
|
1585
|
+
this.sendKeyframe = (key, frame) => {
|
|
1586
|
+
if (this.state !== LiveState.OPEN)
|
|
1587
|
+
return false;
|
|
1588
|
+
this._buildInData.keyframes = Object.assign(Object.assign({}, this._buildInData.keyframes), { [key]: frame });
|
|
1589
|
+
const liveMsg = createLiveMsg(exports.Command.KeyframeSync, this.snapshot);
|
|
1590
|
+
try {
|
|
1591
|
+
this._controller.sendMessage(liveMsg);
|
|
1592
|
+
return true;
|
|
1593
|
+
}
|
|
1594
|
+
catch (e) {
|
|
1595
|
+
logger$1.error(e);
|
|
1596
|
+
return false;
|
|
1597
|
+
}
|
|
1598
|
+
};
|
|
1599
|
+
/**
|
|
1600
|
+
* 带看控制器
|
|
1601
|
+
*/
|
|
1602
|
+
this._controller = new LiveController();
|
|
1603
|
+
/**
|
|
1604
|
+
* 添加带看控制的事件监听
|
|
1605
|
+
*/
|
|
1606
|
+
this._addLiveControllerEventListeners = () => {
|
|
1607
|
+
this._controller.on('stateChange', this._handleStateChange);
|
|
1608
|
+
this._controller.on('message', this._handleMessage);
|
|
1609
|
+
};
|
|
1610
|
+
/**
|
|
1611
|
+
* 移除带看控制的事件监听
|
|
1612
|
+
*/
|
|
1613
|
+
this._removeLiveControllerEventListeners = () => {
|
|
1614
|
+
this._controller.off('stateChange', this._handleStateChange);
|
|
1615
|
+
this._controller.off('message', this._handleMessage);
|
|
1616
|
+
};
|
|
1617
|
+
/**
|
|
1618
|
+
* 带看状态变化
|
|
1619
|
+
* @param state
|
|
1620
|
+
* @returns
|
|
1621
|
+
*/
|
|
1622
|
+
this._handleStateChange = (state, prevState) => this.emit('stateChange', state, prevState);
|
|
1623
|
+
this._handleMessage = (liveMsg) => __awaiter(this, void 0, void 0, function* () {
|
|
1624
|
+
var _b, _c, _d, _e, _f, _g;
|
|
1625
|
+
if (typeof liveMsg === 'object') {
|
|
1626
|
+
const { command, data, frontRequestId, code, message } = liveMsg;
|
|
1627
|
+
if (code === 'SUCCESS') {
|
|
1628
|
+
switch (command) {
|
|
1629
|
+
/**
|
|
1630
|
+
* 自己的状态变化
|
|
1631
|
+
*/
|
|
1632
|
+
case exports.Command.SelfUserInfo: {
|
|
1633
|
+
const selfInfo = data;
|
|
1634
|
+
if (!equal(this.selfInfo, selfInfo, { deep: true })) {
|
|
1635
|
+
this._buildInData.selfInfo = selfInfo;
|
|
1636
|
+
this.emit('selfInfoUpdate', this._buildInData.selfInfo, frontRequestId);
|
|
1637
|
+
}
|
|
1309
1638
|
break;
|
|
1310
1639
|
}
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1640
|
+
/**
|
|
1641
|
+
* 房间信息变化
|
|
1642
|
+
*/
|
|
1643
|
+
case exports.Command.RoomInfo: {
|
|
1644
|
+
const roomInfo = data;
|
|
1645
|
+
this._buildInData.roomInfo = Object.assign({}, roomInfo);
|
|
1646
|
+
this.emit('readyKeyframeSync', (roomInfo.last_frame || {}));
|
|
1316
1647
|
break;
|
|
1317
1648
|
}
|
|
1649
|
+
/**
|
|
1650
|
+
* 语音信息变化
|
|
1651
|
+
*/
|
|
1652
|
+
case exports.Command.RTCInfo: {
|
|
1653
|
+
const { voice_id: voiceId, type } = data;
|
|
1654
|
+
if (!((_b = this.$RTC) === null || _b === void 0 ? void 0 : _b.joined)) {
|
|
1655
|
+
const result = yield ((_c = this.$RTC) === null || _c === void 0 ? void 0 : _c.join({
|
|
1656
|
+
voiceId,
|
|
1657
|
+
userId: ((_d = this.selfInfo) === null || _d === void 0 ? void 0 : _d.id) || '',
|
|
1658
|
+
roomId: (_e = this.roomInfo) === null || _e === void 0 ? void 0 : _e.info.room_code,
|
|
1659
|
+
type,
|
|
1660
|
+
}));
|
|
1661
|
+
if (result) {
|
|
1662
|
+
const status = (_f = this._options.initialMicroStatus) !== null && _f !== void 0 ? _f : exports.MicroStatus.OPEN;
|
|
1663
|
+
yield ((_g = this.$RTC) === null || _g === void 0 ? void 0 : _g.toggleMicro(status === exports.MicroStatus.OPEN));
|
|
1664
|
+
}
|
|
1665
|
+
else {
|
|
1666
|
+
logger$1.error('加入语音房间失败');
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
else {
|
|
1670
|
+
logger$1.warn('已加入语音房间,无需重复加入!');
|
|
1671
|
+
}
|
|
1672
|
+
break;
|
|
1673
|
+
}
|
|
1674
|
+
/**
|
|
1675
|
+
* 房间用户列表变化
|
|
1676
|
+
*/
|
|
1677
|
+
case exports.Command.UserList: {
|
|
1678
|
+
const userList = data;
|
|
1679
|
+
this._buildInData.userList = userList;
|
|
1680
|
+
this.emit('userListUpdate', this.userList, frontRequestId);
|
|
1681
|
+
break;
|
|
1682
|
+
}
|
|
1683
|
+
/**
|
|
1684
|
+
* 自定义事件广播
|
|
1685
|
+
*/
|
|
1686
|
+
case exports.Command.CustomEvent: {
|
|
1687
|
+
const evtMsg = data;
|
|
1688
|
+
this.emit('broadcast', evtMsg, frontRequestId);
|
|
1689
|
+
break;
|
|
1690
|
+
}
|
|
1691
|
+
/**
|
|
1692
|
+
* 帧数据同步
|
|
1693
|
+
*/
|
|
1694
|
+
case exports.Command.KeyframeSync: {
|
|
1695
|
+
const remoteKeyframes = data;
|
|
1696
|
+
// 此处做一层 diff,仅跟本地数据不一致的情况下才广播数据。
|
|
1697
|
+
const keyframes = Object.keys(remoteKeyframes).reduce((accu, curr) => {
|
|
1698
|
+
if (equal(remoteKeyframes[curr], this._buildInData.keyframes[curr], {
|
|
1699
|
+
deep: true,
|
|
1700
|
+
})) {
|
|
1701
|
+
return accu;
|
|
1702
|
+
}
|
|
1703
|
+
const params = [
|
|
1704
|
+
remoteKeyframes[curr],
|
|
1705
|
+
this._buildInData.keyframes[curr],
|
|
1706
|
+
frontRequestId,
|
|
1707
|
+
];
|
|
1708
|
+
const evtName = curr;
|
|
1709
|
+
this.keyframes.emit(evtName, ...params);
|
|
1710
|
+
this._buildInData.keyframes[curr] = remoteKeyframes[curr];
|
|
1711
|
+
accu[curr] = remoteKeyframes[curr];
|
|
1712
|
+
return accu;
|
|
1713
|
+
}, {});
|
|
1714
|
+
this.emit('keyframes', keyframes, frontRequestId);
|
|
1715
|
+
break;
|
|
1716
|
+
}
|
|
1717
|
+
/**
|
|
1718
|
+
* 内置消息
|
|
1719
|
+
*/
|
|
1720
|
+
case exports.Command.BuiltinMsg: {
|
|
1721
|
+
const builtinMsg = data;
|
|
1722
|
+
this.emit('builtinEvent', builtinMsg);
|
|
1723
|
+
if (builtinMsg.event_type === exports.BuiltinEventType.UserChange) {
|
|
1724
|
+
this.emit('userChange', builtinMsg);
|
|
1725
|
+
}
|
|
1726
|
+
if (builtinMsg.event_type === exports.BuiltinEventType.RoomChange) {
|
|
1727
|
+
this.emit('roomChange', builtinMsg);
|
|
1728
|
+
}
|
|
1729
|
+
/**
|
|
1730
|
+
* 下发指令自己操作麦克风
|
|
1731
|
+
*/
|
|
1732
|
+
if (builtinMsg.event_type === exports.BuiltinEventType.UserChange &&
|
|
1733
|
+
builtinMsg.action === exports.BuiltinActionType.UserMicroStatus) {
|
|
1734
|
+
yield this.toggleMicro(builtinMsg.data.status === exports.MicroStatus.OPEN);
|
|
1735
|
+
}
|
|
1736
|
+
/**
|
|
1737
|
+
* 如果下发指令退出房间,则 关闭麦克风 及 销毁 WebSocket
|
|
1738
|
+
*/
|
|
1739
|
+
if (builtinMsg.event_type === exports.BuiltinEventType.RoomChange &&
|
|
1740
|
+
builtinMsg.action === exports.BuiltinActionType.RoomClose) {
|
|
1741
|
+
yield this.exit();
|
|
1742
|
+
}
|
|
1743
|
+
break;
|
|
1744
|
+
}
|
|
1745
|
+
/**
|
|
1746
|
+
* 被踢出房间
|
|
1747
|
+
*/
|
|
1748
|
+
case exports.Command.UserKickOut: {
|
|
1749
|
+
this.emit('kickOut');
|
|
1750
|
+
break;
|
|
1751
|
+
}
|
|
1752
|
+
/**
|
|
1753
|
+
* 其它未知广播
|
|
1754
|
+
*/
|
|
1318
1755
|
default: {
|
|
1319
|
-
|
|
1756
|
+
console.warn('unknown command: ', command);
|
|
1320
1757
|
}
|
|
1321
1758
|
}
|
|
1322
1759
|
}
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
if (!options.getVoiceSign) {
|
|
1326
|
-
throw new Error('GetVoiceSign method must be passed when using built-in RTC instances');
|
|
1327
|
-
}
|
|
1328
|
-
const getVoiceSign = (_b = options.getVoiceSign) !== null && _b !== void 0 ? _b : unimplementedGetVoiceSign;
|
|
1329
|
-
if (!jsBridge) {
|
|
1330
|
-
throw new Error('jsBridge instance must be passed when using built-in RTC instances');
|
|
1331
|
-
}
|
|
1332
|
-
// vrwebview 默认
|
|
1333
|
-
if ((isRealseeVRWebview && (isAndroid || isIOS)) || isWxMiniProgram) {
|
|
1334
|
-
liveController.options.rtc = new VRWebViewRTC({
|
|
1335
|
-
jsBridge,
|
|
1336
|
-
getVoiceSign,
|
|
1337
|
-
});
|
|
1338
|
-
}
|
|
1339
|
-
else {
|
|
1340
|
-
// 其它终端使用
|
|
1341
|
-
liveController.options.rtc =
|
|
1342
|
-
options.builtInRTCType === exports.BuiltInRTCType.RealseeXChimeRTC
|
|
1343
|
-
? new BrowserRTC4Chime({ getVoiceSign })
|
|
1344
|
-
: new BrowserRTC({ getVoiceSign });
|
|
1345
|
-
}
|
|
1760
|
+
else {
|
|
1761
|
+
this.emit('error', liveMsg);
|
|
1346
1762
|
}
|
|
1347
1763
|
}
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
if (
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
return liveController.readyState;
|
|
1377
|
-
}
|
|
1378
|
-
get url() {
|
|
1379
|
-
var _a;
|
|
1380
|
-
return ((_a = liveController.webSocket) === null || _a === void 0 ? void 0 : _a.url) || '';
|
|
1381
|
-
}
|
|
1382
|
-
get selfInfo() {
|
|
1383
|
-
return liveController.selfUserInfo;
|
|
1384
|
-
}
|
|
1385
|
-
get userList() {
|
|
1386
|
-
return liveController.userList || [];
|
|
1387
|
-
}
|
|
1388
|
-
get snapshot() {
|
|
1389
|
-
return liveController.keyframes || {};
|
|
1390
|
-
}
|
|
1391
|
-
get $RTC() {
|
|
1392
|
-
return liveController.options.rtc;
|
|
1393
|
-
}
|
|
1394
|
-
get jsBridge() {
|
|
1395
|
-
return liveController.options.jsBridge;
|
|
1396
|
-
}
|
|
1397
|
-
async setSelfInfo(userInfo) {
|
|
1398
|
-
if (this.readyState !== exports.WebSocketState.OPEN) {
|
|
1399
|
-
return new Error('The connection is not open and ready to communicate.');
|
|
1400
|
-
}
|
|
1401
|
-
try {
|
|
1402
|
-
return await this.updateStatus(exports.BuiltinEventType.UserChange, exports.BuiltinActionType.UserInfo, userInfo);
|
|
1403
|
-
}
|
|
1404
|
-
catch (error) {
|
|
1405
|
-
return error;
|
|
1764
|
+
});
|
|
1765
|
+
/**
|
|
1766
|
+
* 清理带看缓存的数据
|
|
1767
|
+
*/
|
|
1768
|
+
this._clearLiveData = () => {
|
|
1769
|
+
this._buildInData = { keyframes: {} };
|
|
1770
|
+
};
|
|
1771
|
+
/**
|
|
1772
|
+
* 连接带看
|
|
1773
|
+
* @param options
|
|
1774
|
+
* @returns
|
|
1775
|
+
*/
|
|
1776
|
+
this.connect = (options = {}) => __awaiter(this, void 0, void 0, function* () {
|
|
1777
|
+
var _h, _j, _k, _l;
|
|
1778
|
+
// 检查 url 和 票据获取接口实现
|
|
1779
|
+
this._options.url = (_j = (_h = options.url) !== null && _h !== void 0 ? _h : this._options.url) !== null && _j !== void 0 ? _j : '';
|
|
1780
|
+
this._options.getTicket = (_k = options.getTicket) !== null && _k !== void 0 ? _k : this._options.getTicket;
|
|
1781
|
+
this._options.initialMicroStatus =
|
|
1782
|
+
(_l = options.rtcMicStatus) !== null && _l !== void 0 ? _l : this._options.initialMicroStatus;
|
|
1783
|
+
if (!/^ws(s):\/\//.test(this._options.url) ||
|
|
1784
|
+
typeof this._options.getTicket !== 'function') {
|
|
1785
|
+
if (!/^ws(s):\/\//.test(this._options.url)) {
|
|
1786
|
+
return new Error('Illegal realsee live room link');
|
|
1787
|
+
}
|
|
1788
|
+
if (typeof this._options.getTicket !== 'function') {
|
|
1789
|
+
return new Error('getTicket muse be function');
|
|
1790
|
+
}
|
|
1791
|
+
return false;
|
|
1406
1792
|
}
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1793
|
+
const { force = false } = options;
|
|
1794
|
+
// 检查是否已有实例在使用
|
|
1795
|
+
const currentState = this.state;
|
|
1796
|
+
if (currentState === LiveState.CONNECTING ||
|
|
1797
|
+
currentState === LiveState.OPEN) {
|
|
1798
|
+
if (force) {
|
|
1799
|
+
try {
|
|
1800
|
+
yield this._controller.close('force close by connect');
|
|
1801
|
+
}
|
|
1802
|
+
catch (e) {
|
|
1803
|
+
console.warn(e);
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
else {
|
|
1807
|
+
return new Error('已有Live实例正在连接中,请勿重复连接!');
|
|
1808
|
+
}
|
|
1414
1809
|
}
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1810
|
+
// 建立连接
|
|
1811
|
+
this._clearLiveData();
|
|
1812
|
+
const url = appendUri(this._options.url, {
|
|
1813
|
+
ticket: yield this._options.getTicket(),
|
|
1814
|
+
force: Number(!!force),
|
|
1815
|
+
});
|
|
1816
|
+
this._controller.open(url);
|
|
1418
1817
|
return true;
|
|
1419
|
-
}
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1818
|
+
});
|
|
1819
|
+
/**
|
|
1820
|
+
* 退出带看
|
|
1821
|
+
* @returns
|
|
1822
|
+
*/
|
|
1823
|
+
this.exit = () => __awaiter(this, void 0, void 0, function* () {
|
|
1824
|
+
var _m;
|
|
1825
|
+
this._clearLiveData();
|
|
1826
|
+
try {
|
|
1827
|
+
/** 退出强制关闭语音 */
|
|
1828
|
+
(_m = this.$RTC) === null || _m === void 0 ? void 0 : _m.quit();
|
|
1829
|
+
yield this.updateStatus(exports.BuiltinEventType.RoomChange, exports.BuiltinActionType.RoomClose, {});
|
|
1423
1830
|
}
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
const front_request_id = customEvent.front_request_id;
|
|
1427
|
-
liveController.sendMessage(customEvent);
|
|
1428
|
-
const timeoutId = timeout
|
|
1429
|
-
? setTimeout(() => {
|
|
1430
|
-
reject(new Error('RESPONSE TIMEOUT'));
|
|
1431
|
-
this.off('broadcast', broadcast);
|
|
1432
|
-
}, timeout)
|
|
1433
|
-
: undefined;
|
|
1434
|
-
const broadcast = (data, frontRequestId) => {
|
|
1435
|
-
if (frontRequestId !== front_request_id)
|
|
1436
|
-
return;
|
|
1437
|
-
this.off('broadcast', broadcast);
|
|
1438
|
-
resolve(data);
|
|
1439
|
-
if (timeoutId)
|
|
1440
|
-
clearInterval(timeoutId);
|
|
1441
|
-
};
|
|
1442
|
-
this.on('broadcast', broadcast);
|
|
1443
|
-
});
|
|
1444
|
-
}
|
|
1445
|
-
async updateStatus(evtType, atnType, status, toUserIds) {
|
|
1446
|
-
// TODO 统一规则,不能联合类型
|
|
1447
|
-
if (this.readyState !== exports.WebSocketState.OPEN) {
|
|
1448
|
-
return false;
|
|
1831
|
+
catch (e) {
|
|
1832
|
+
logger$1.warn(e);
|
|
1449
1833
|
}
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1834
|
+
return yield this._controller.close('user exit');
|
|
1835
|
+
});
|
|
1836
|
+
/**
|
|
1837
|
+
* 销毁带看
|
|
1838
|
+
* @returns
|
|
1839
|
+
*/
|
|
1840
|
+
this.dispose = () => __awaiter(this, void 0, void 0, function* () {
|
|
1841
|
+
this._removeLiveControllerEventListeners();
|
|
1842
|
+
this._clearLiveData();
|
|
1843
|
+
return yield this._controller.dispose();
|
|
1844
|
+
});
|
|
1845
|
+
/**
|
|
1846
|
+
* 设置自己的用户信息
|
|
1847
|
+
* @param userInfo
|
|
1848
|
+
* @returns
|
|
1849
|
+
*/
|
|
1850
|
+
this.setSelfInfo = (userInfo) => __awaiter(this, void 0, void 0, function* () {
|
|
1851
|
+
return yield this.updateStatus(exports.BuiltinEventType.UserChange, exports.BuiltinActionType.UserInfo, userInfo);
|
|
1852
|
+
});
|
|
1455
1853
|
// 仅用于用户自己的麦克风控制
|
|
1456
|
-
|
|
1457
|
-
var
|
|
1458
|
-
if (!((
|
|
1854
|
+
this.toggleMicro = (microStatus) => __awaiter(this, void 0, void 0, function* () {
|
|
1855
|
+
var _o, _p, _q;
|
|
1856
|
+
if (!((_p = (_o = this.selfInfo) === null || _o === void 0 ? void 0 : _o.permission) === null || _p === void 0 ? void 0 : _p.control_own_micro))
|
|
1459
1857
|
return false;
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1858
|
+
const result = yield ((_q = this.$RTC) === null || _q === void 0 ? void 0 : _q.toggleMicro(microStatus));
|
|
1859
|
+
if (result) {
|
|
1860
|
+
yield this.updateStatus(exports.BuiltinEventType.UserChange, exports.BuiltinActionType.UserMicroStatus, {
|
|
1861
|
+
status: microStatus ? exports.MicroStatus.OPEN : exports.MicroStatus.CLOSE,
|
|
1862
|
+
}, []);
|
|
1863
|
+
}
|
|
1864
|
+
return result;
|
|
1865
|
+
});
|
|
1866
|
+
/**
|
|
1867
|
+
* 控制别人的麦
|
|
1868
|
+
* @param microStatus
|
|
1869
|
+
* @param toUserIds
|
|
1870
|
+
* @returns
|
|
1871
|
+
*/
|
|
1872
|
+
this.forbidMicro = (microStatus, toUserIds) => __awaiter(this, void 0, void 0, function* () {
|
|
1873
|
+
var _r, _s;
|
|
1874
|
+
if (typeof this._options.canForbidUserMicro === 'function' &&
|
|
1875
|
+
!this._options.canForbidUserMicro(toUserIds)) {
|
|
1469
1876
|
return false;
|
|
1470
1877
|
}
|
|
1471
|
-
if (!((
|
|
1878
|
+
if (!((_s = (_r = this.selfInfo) === null || _r === void 0 ? void 0 : _r.permission) === null || _s === void 0 ? void 0 : _s.control_other_micro)) {
|
|
1472
1879
|
return false;
|
|
1473
1880
|
}
|
|
1474
|
-
return
|
|
1881
|
+
return yield this.updateStatus(exports.BuiltinEventType.UserChange, exports.BuiltinActionType.UserMicroStatus, {
|
|
1475
1882
|
status: microStatus,
|
|
1476
1883
|
}, toUserIds);
|
|
1477
|
-
}
|
|
1884
|
+
});
|
|
1478
1885
|
/**
|
|
1479
|
-
*
|
|
1886
|
+
* 控制别人的同步全量帧数据权限
|
|
1887
|
+
* @param sync
|
|
1888
|
+
* @param toUserIds
|
|
1889
|
+
* @returns
|
|
1480
1890
|
*/
|
|
1481
|
-
|
|
1482
|
-
var
|
|
1483
|
-
if (
|
|
1484
|
-
!
|
|
1891
|
+
this.forbidSync = (sync, toUserIds) => __awaiter(this, void 0, void 0, function* () {
|
|
1892
|
+
var _t, _u;
|
|
1893
|
+
if (typeof this._options.canForbidUserSync === 'function' &&
|
|
1894
|
+
!this._options.canForbidUserSync(toUserIds)) {
|
|
1485
1895
|
return false;
|
|
1486
1896
|
}
|
|
1487
|
-
if (!((
|
|
1897
|
+
if (!((_u = (_t = this.selfInfo) === null || _t === void 0 ? void 0 : _t.permission) === null || _u === void 0 ? void 0 : _u.control_other_sync)) {
|
|
1488
1898
|
return false;
|
|
1489
1899
|
}
|
|
1490
|
-
return
|
|
1491
|
-
}
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1900
|
+
return yield this.updateStatus(exports.BuiltinEventType.UserChange, exports.BuiltinActionType.UserPermission, { sync_frame: sync }, toUserIds);
|
|
1901
|
+
});
|
|
1902
|
+
/**
|
|
1903
|
+
* 把用户踢出带看
|
|
1904
|
+
* @param toUserIds
|
|
1905
|
+
* @returns
|
|
1906
|
+
*/
|
|
1907
|
+
this.kick = (toUserIds) => __awaiter(this, void 0, void 0, function* () {
|
|
1908
|
+
var _v, _w;
|
|
1909
|
+
if (typeof this._options.canForbidUserKick === 'function' &&
|
|
1910
|
+
!this._options.canForbidUserKick(toUserIds)) {
|
|
1496
1911
|
return false;
|
|
1497
1912
|
}
|
|
1498
|
-
if (!((
|
|
1913
|
+
if (!((_w = (_v = this.selfInfo) === null || _v === void 0 ? void 0 : _v.permission) === null || _w === void 0 ? void 0 : _w.change_other_status)) {
|
|
1499
1914
|
return false;
|
|
1500
1915
|
}
|
|
1501
|
-
return
|
|
1916
|
+
return yield this.updateStatus(exports.BuiltinEventType.UserChange, exports.BuiltinActionType.UserStatus, {
|
|
1502
1917
|
status: 'KICK_OUT',
|
|
1503
1918
|
}, toUserIds);
|
|
1504
|
-
}
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1919
|
+
});
|
|
1920
|
+
this._addLiveControllerEventListeners();
|
|
1921
|
+
this._options = Object.assign({ initialMicroStatus: exports.MicroStatus.OPEN }, opts);
|
|
1922
|
+
// 第一步检查jsbridge
|
|
1923
|
+
this._options.jsBridge = (() => {
|
|
1924
|
+
if (opts.jsBridge)
|
|
1925
|
+
return opts.jsBridge;
|
|
1926
|
+
if (opts.useBuiltInJsBridge)
|
|
1927
|
+
return new JSBridge__default["default"]();
|
|
1928
|
+
return undefined;
|
|
1929
|
+
})();
|
|
1930
|
+
// 第二步检查getVoiceSign
|
|
1931
|
+
this._options.getVoiceSign = (_a = opts.getVoiceSign) !== null && _a !== void 0 ? _a : unimplementedGetVoiceSign;
|
|
1932
|
+
// 第二步检查rtc
|
|
1933
|
+
this._options.rtc = (() => {
|
|
1934
|
+
// 优先取rtc实例
|
|
1935
|
+
if (opts.rtc)
|
|
1936
|
+
return opts.rtc;
|
|
1937
|
+
// 取指定的内部rtc类型
|
|
1938
|
+
if (opts.rtcType) {
|
|
1939
|
+
if (!opts.getVoiceSign) {
|
|
1940
|
+
logger$1.error('GetVoiceSign method must be passed when using built-in RTC instances');
|
|
1941
|
+
}
|
|
1942
|
+
switch (opts.rtcType) {
|
|
1943
|
+
case exports.RTCType.RealseeVRWebViewRTC: {
|
|
1944
|
+
// 内置的 VRWebViewRTC
|
|
1945
|
+
if (this._options.jsBridge) {
|
|
1946
|
+
return new VRWebViewRTC({
|
|
1947
|
+
jsBridge: this._options.jsBridge,
|
|
1948
|
+
getVoiceSign: this._options.getVoiceSign,
|
|
1949
|
+
});
|
|
1950
|
+
}
|
|
1951
|
+
else {
|
|
1952
|
+
logger$1.error('JsBridge instance must be passed when using built-in VRWebViewRTC instances');
|
|
1953
|
+
return undefined;
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
case exports.RTCType.RealseeBrowserChimeRTC: {
|
|
1957
|
+
// 内置的 RealseeBrowserChimeRTC
|
|
1958
|
+
return new BrowserRTC4Chime({
|
|
1959
|
+
getVoiceSign: this._options.getVoiceSign,
|
|
1960
|
+
logLevel: opts.__debug__ ? LogLevel.DEBUG : LogLevel.ERROR,
|
|
1961
|
+
});
|
|
1962
|
+
}
|
|
1963
|
+
case exports.RTCType.RealseeBrowserRTC: {
|
|
1964
|
+
// 内置的 RealseeBrowserRTC
|
|
1965
|
+
return new BrowserRTC({
|
|
1966
|
+
getVoiceSign: this._options.getVoiceSign,
|
|
1967
|
+
});
|
|
1968
|
+
}
|
|
1969
|
+
default: {
|
|
1970
|
+
logger$1.error('unknown built-in RTC type');
|
|
1971
|
+
return undefined;
|
|
1972
|
+
}
|
|
1539
1973
|
}
|
|
1540
1974
|
}
|
|
1541
|
-
//
|
|
1542
|
-
if (
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
if (options.getTicket) {
|
|
1546
|
-
liveController.options.getTicket = options.getTicket;
|
|
1547
|
-
}
|
|
1548
|
-
if (!liveController.options.url ||
|
|
1549
|
-
!liveController.options.url.startsWith('ws')) {
|
|
1550
|
-
const error = new Error(`WebSocket URL 未配置或格式不合法:"${liveController.options.url}"`);
|
|
1551
|
-
this.emit('ws.error', { type: exports.WebSocketErrorType.IllegalURL, error });
|
|
1552
|
-
return error;
|
|
1553
|
-
}
|
|
1554
|
-
if (!liveController.options.getTicket) {
|
|
1555
|
-
const error = new Error(`getTicket() 未配置!`);
|
|
1556
|
-
this.emit('ws.error', { type: exports.WebSocketErrorType.IllegalArgs, error });
|
|
1557
|
-
return error;
|
|
1558
|
-
}
|
|
1559
|
-
// 连接锁
|
|
1560
|
-
liveController.connecting = true;
|
|
1561
|
-
// 连接前销毁之前绑定的事件
|
|
1562
|
-
liveController.disposeWebSocket();
|
|
1563
|
-
this.emit('ws.beforeConnect');
|
|
1564
|
-
const url = force || options.url || !this.url
|
|
1565
|
-
? appendUri(liveController.options.url, {
|
|
1566
|
-
ticket: await liveController.options.getTicket(),
|
|
1567
|
-
force: Number(!!force),
|
|
1568
|
-
})
|
|
1569
|
-
: this.url;
|
|
1570
|
-
liveController.webSocket = new WebSocket(url);
|
|
1571
|
-
liveController.onEvtOpnListener = () => {
|
|
1572
|
-
liveController.checkReadyState(this);
|
|
1573
|
-
this.emit('ws.afterConnect');
|
|
1574
|
-
};
|
|
1575
|
-
liveController.onEvtMsgListener = (evt) => {
|
|
1576
|
-
liveController.checkReadyState(this);
|
|
1577
|
-
try {
|
|
1578
|
-
const liveMsg = parseLiveMsg(evt.data);
|
|
1579
|
-
if (liveMsg === false)
|
|
1580
|
-
return;
|
|
1581
|
-
liveController.handleMessage(liveMsg, this);
|
|
1975
|
+
// 都不满足时取内置
|
|
1976
|
+
if (opts.useBuiltInRTC) {
|
|
1977
|
+
if (!opts.getVoiceSign) {
|
|
1978
|
+
logger$1.error('GetVoiceSign method must be passed when using built-in RTC instances');
|
|
1582
1979
|
}
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
}
|
|
1980
|
+
if (this._options.jsBridge) {
|
|
1981
|
+
if ((isRealseeVRWebview && (isAndroid || isIOS)) || isWxMiniProgram) {
|
|
1982
|
+
return new VRWebViewRTC({
|
|
1983
|
+
jsBridge: this._options.jsBridge,
|
|
1984
|
+
getVoiceSign: this._options.getVoiceSign,
|
|
1985
|
+
});
|
|
1986
|
+
}
|
|
1987
|
+
else {
|
|
1988
|
+
// 其它终端使用
|
|
1989
|
+
return opts.builtInRTCType === exports.BuiltInRTCType.RealseeXChimeRTC
|
|
1990
|
+
? new BrowserRTC4Chime({
|
|
1991
|
+
getVoiceSign: this._options.getVoiceSign,
|
|
1992
|
+
})
|
|
1993
|
+
: new BrowserRTC({ getVoiceSign: this._options.getVoiceSign });
|
|
1994
|
+
}
|
|
1590
1995
|
}
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
}
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
return;
|
|
1601
|
-
// 异常退出不一定会触发'error'事件,根据 evt.code 一些类型的退出也算是 error 行为
|
|
1602
|
-
const errMsg = parseWSClsErr(code);
|
|
1603
|
-
live.emit('ws.error', {
|
|
1604
|
-
target: evt,
|
|
1605
|
-
type: exports.WebSocketErrorType.Close,
|
|
1606
|
-
closeError: errMsg,
|
|
1607
|
-
});
|
|
1608
|
-
};
|
|
1609
|
-
liveController.webSocket.addEventListener('open', liveController.onEvtOpnListener);
|
|
1610
|
-
liveController.webSocket.addEventListener('message', liveController.onEvtMsgListener);
|
|
1611
|
-
liveController.webSocket.addEventListener('error', liveController.onEvtErrListener);
|
|
1612
|
-
liveController.webSocket.addEventListener('close', liveController.onEvtCLEListener);
|
|
1613
|
-
return await new Promise((resolve, reject) => {
|
|
1614
|
-
const success = () => {
|
|
1615
|
-
resolve(true);
|
|
1616
|
-
liveController.connecting = false;
|
|
1617
|
-
this.off('ws.error', fail);
|
|
1618
|
-
};
|
|
1619
|
-
const fail = (error) => {
|
|
1620
|
-
reject(error.error
|
|
1621
|
-
? error.error
|
|
1622
|
-
: new Error('WebSocket connection failed!'));
|
|
1623
|
-
liveController.connecting = false;
|
|
1624
|
-
this.off('ws.afterConnect', success);
|
|
1625
|
-
};
|
|
1626
|
-
this.once('ws.afterConnect', success);
|
|
1627
|
-
this.once('ws.error', fail);
|
|
1628
|
-
});
|
|
1996
|
+
else {
|
|
1997
|
+
logger$1.error('jsBridge instance must be passed when using built-in RTC instances');
|
|
1998
|
+
return undefined;
|
|
1999
|
+
}
|
|
2000
|
+
}
|
|
2001
|
+
return undefined;
|
|
2002
|
+
})();
|
|
2003
|
+
if (!this._options.rtc) {
|
|
2004
|
+
logger$1.warn('unused rtc');
|
|
1629
2005
|
}
|
|
1630
|
-
|
|
1631
|
-
|
|
2006
|
+
// 第三步进行自动连接
|
|
2007
|
+
if (this._options.url && this._options.getTicket) {
|
|
2008
|
+
this.connect();
|
|
2009
|
+
}
|
|
2010
|
+
if (this._options.__debug__) {
|
|
2011
|
+
Object.assign(window, { $liveController: this._controller, $live: this });
|
|
1632
2012
|
}
|
|
1633
2013
|
}
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
2014
|
+
get options() {
|
|
2015
|
+
return Object.freeze(this._options || {});
|
|
2016
|
+
}
|
|
2017
|
+
/**
|
|
2018
|
+
* 带看状态
|
|
2019
|
+
*/
|
|
2020
|
+
get state() {
|
|
2021
|
+
return this._controller.state;
|
|
2022
|
+
}
|
|
2023
|
+
/**
|
|
2024
|
+
* 兼容老逻辑
|
|
2025
|
+
* @deprecated 请直接读取 state 属性字段,未来将移除该属性
|
|
2026
|
+
*/
|
|
2027
|
+
get readyState() {
|
|
2028
|
+
return this._controller.state;
|
|
2029
|
+
}
|
|
2030
|
+
/**
|
|
2031
|
+
* 获取当前WebSocket连接的URL。(注意:这个是WebSocket连接的完整连接,附带一些query参数)。
|
|
2032
|
+
* @deprecated 带看不需要关注底层ws的相关信息,未来将移除
|
|
2033
|
+
*/
|
|
2034
|
+
get url() {
|
|
2035
|
+
return this.options.url;
|
|
2036
|
+
}
|
|
2037
|
+
/**
|
|
2038
|
+
* 获取当前live使用的RTC实例
|
|
2039
|
+
*/
|
|
2040
|
+
get $RTC() {
|
|
2041
|
+
return this._options.rtc;
|
|
2042
|
+
}
|
|
2043
|
+
/**
|
|
2044
|
+
* 获取当前live使用的jsBridge实例
|
|
2045
|
+
*/
|
|
2046
|
+
get jsBridge() {
|
|
2047
|
+
return this._options.jsBridge;
|
|
2048
|
+
}
|
|
2049
|
+
/**
|
|
2050
|
+
* 当前帧数据快照
|
|
2051
|
+
*/
|
|
2052
|
+
get snapshot() {
|
|
2053
|
+
return this._buildInData.keyframes;
|
|
2054
|
+
}
|
|
2055
|
+
/**
|
|
2056
|
+
* 当前用户信息
|
|
2057
|
+
*/
|
|
2058
|
+
get selfInfo() {
|
|
2059
|
+
return this._buildInData.selfInfo;
|
|
2060
|
+
}
|
|
2061
|
+
/**
|
|
2062
|
+
* 当前用户列表
|
|
2063
|
+
*/
|
|
2064
|
+
get userList() {
|
|
2065
|
+
return this._buildInData.userList || [];
|
|
2066
|
+
}
|
|
2067
|
+
/**
|
|
2068
|
+
* 当前带看房间信息
|
|
2069
|
+
*/
|
|
2070
|
+
get roomInfo() {
|
|
2071
|
+
return this._buildInData.roomInfo;
|
|
2072
|
+
}
|
|
2073
|
+
/**
|
|
2074
|
+
* 修改状态
|
|
2075
|
+
* @param evtType
|
|
2076
|
+
* @param atnType
|
|
2077
|
+
* @param status
|
|
2078
|
+
* @param toUserIds
|
|
2079
|
+
* @returns
|
|
2080
|
+
*/
|
|
2081
|
+
updateStatus(evtType, atnType, status, toUserIds) {
|
|
2082
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
2083
|
+
if (this.state !== LiveState.OPEN)
|
|
2084
|
+
return false;
|
|
2085
|
+
const data = Object.assign({ event_type: evtType, action: atnType }, { data: status });
|
|
2086
|
+
const liveMsg = createLiveMsg(exports.Command.BuiltinMsg, data, toUserIds);
|
|
2087
|
+
try {
|
|
2088
|
+
this._controller.sendMessage(liveMsg);
|
|
2089
|
+
return true;
|
|
2090
|
+
}
|
|
2091
|
+
catch (e) {
|
|
2092
|
+
logger$1.error(e);
|
|
2093
|
+
return false;
|
|
2094
|
+
}
|
|
2095
|
+
});
|
|
2096
|
+
}
|
|
2097
|
+
/**
|
|
2098
|
+
* 自定义广播
|
|
2099
|
+
* @param request 广播请求的数据
|
|
2100
|
+
* @param toUserIds
|
|
2101
|
+
* @param timeout
|
|
2102
|
+
* @returns
|
|
2103
|
+
*/
|
|
2104
|
+
broadcast(request, toUserIds, timeout) {
|
|
2105
|
+
if (this.state !== LiveState.OPEN)
|
|
2106
|
+
return false;
|
|
2107
|
+
return new Promise((resolve, reject) => {
|
|
2108
|
+
const customEvent = createLiveMsg(exports.Command.CustomEvent, request, toUserIds);
|
|
2109
|
+
const front_request_id = customEvent.front_request_id;
|
|
2110
|
+
const timeoutId = timeout
|
|
2111
|
+
? setTimeout(() => {
|
|
2112
|
+
reject(new Error('RESPONSE TIMEOUT'));
|
|
2113
|
+
this.off('broadcast', broadcastRes);
|
|
2114
|
+
}, timeout)
|
|
2115
|
+
: undefined;
|
|
2116
|
+
const broadcastRes = (data, frontRequestId) => {
|
|
2117
|
+
if (frontRequestId !== front_request_id)
|
|
2118
|
+
return;
|
|
2119
|
+
if (timeoutId)
|
|
2120
|
+
clearTimeout(timeoutId);
|
|
2121
|
+
this.off('broadcast', broadcastRes);
|
|
2122
|
+
resolve(data);
|
|
2123
|
+
};
|
|
2124
|
+
this.on('broadcast', broadcastRes);
|
|
2125
|
+
try {
|
|
2126
|
+
this._controller.sendMessage(customEvent);
|
|
2127
|
+
}
|
|
2128
|
+
catch (e) {
|
|
2129
|
+
reject(e);
|
|
2130
|
+
}
|
|
2131
|
+
});
|
|
1639
2132
|
}
|
|
1640
|
-
return live;
|
|
1641
2133
|
}
|
|
1642
2134
|
|
|
2135
|
+
/**
|
|
2136
|
+
* 创建`Live`实例
|
|
2137
|
+
* @param opts
|
|
2138
|
+
* @returns
|
|
2139
|
+
*/
|
|
2140
|
+
const createLive = (opts) => {
|
|
2141
|
+
_clearLiveInstanceIfNeed();
|
|
2142
|
+
return new Live(opts);
|
|
2143
|
+
};
|
|
2144
|
+
|
|
1643
2145
|
/**
|
|
1644
2146
|
* 创建 {@link LiveReact} 实例,并提供 `React` 技术栈相关工具链。
|
|
1645
2147
|
*/
|
|
1646
2148
|
function createLiveReact(options) {
|
|
1647
|
-
const LiveContext =
|
|
2149
|
+
const LiveContext = React.createContext(null);
|
|
1648
2150
|
const live = createLive(options);
|
|
1649
2151
|
const jsBridge = live.jsBridge;
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
2152
|
+
const LiveProvider = (props) => (React__default["default"].createElement(LiveContext.Provider, { value: live }, props.children));
|
|
2153
|
+
/**
|
|
2154
|
+
* 使用live实例
|
|
2155
|
+
* @returns
|
|
2156
|
+
*/
|
|
2157
|
+
const useLiveInstance = () => {
|
|
1654
2158
|
const context = React__default["default"].useContext(LiveContext);
|
|
1655
2159
|
if (!context)
|
|
1656
2160
|
throw new Error('LiveProvider never found.');
|
|
1657
2161
|
return context;
|
|
1658
|
-
}
|
|
2162
|
+
};
|
|
1659
2163
|
/**
|
|
2164
|
+
* 不建议这样使用
|
|
1660
2165
|
* @deprecated
|
|
1661
2166
|
* @returns
|
|
1662
2167
|
*/
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
return live.$RTC;
|
|
1669
|
-
}
|
|
2168
|
+
const unsafe__useLiveInstance = React.useCallback(() => useLiveInstance(), [useLiveInstance]);
|
|
2169
|
+
/**
|
|
2170
|
+
* 使用rtc实例
|
|
2171
|
+
*/
|
|
2172
|
+
const useRTCInstance = React.useCallback(() => useLiveInstance().$RTC, [useLiveInstance]);
|
|
1670
2173
|
/**
|
|
2174
|
+
* 不建议这样使用
|
|
1671
2175
|
* @deprecated
|
|
1672
2176
|
* @returns
|
|
1673
2177
|
*/
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
return () => live.off('ws.beforeConnect', onWSBeforeConnect);
|
|
1688
|
-
}, [live]);
|
|
1689
|
-
return state;
|
|
1690
|
-
}
|
|
1691
|
-
function useKeyframeUpdateCallback(name, callback, deps = []) {
|
|
2178
|
+
const unsafe__useRTCInstance = React.useCallback(() => useRTCInstance(), [useRTCInstance]);
|
|
2179
|
+
/**
|
|
2180
|
+
* 带看连接操作
|
|
2181
|
+
*/
|
|
2182
|
+
const useConnect = React.useCallback((options) => __awaiter(this, void 0, void 0, function* () { return yield useLiveInstance().connect(options); }), []);
|
|
2183
|
+
/**
|
|
2184
|
+
*
|
|
2185
|
+
* @param name
|
|
2186
|
+
* @param callback
|
|
2187
|
+
* @param deps
|
|
2188
|
+
* @returns
|
|
2189
|
+
*/
|
|
2190
|
+
function useKeyframeUpdateCallback(key, callback, deps = []) {
|
|
1692
2191
|
const live = useLiveInstance();
|
|
1693
2192
|
const dependencyList = [live, name, ...deps];
|
|
1694
|
-
const dispose = () => live.keyframes.off(
|
|
2193
|
+
const dispose = () => live.keyframes.off(key, callback);
|
|
1695
2194
|
React__default["default"].useEffect(() => {
|
|
1696
|
-
live.keyframes.on(
|
|
2195
|
+
live.keyframes.on(key, callback);
|
|
1697
2196
|
return dispose;
|
|
1698
2197
|
}, dependencyList);
|
|
1699
2198
|
return dispose;
|
|
1700
2199
|
}
|
|
2200
|
+
/**
|
|
2201
|
+
* 带看的一些操作
|
|
2202
|
+
* @returns
|
|
2203
|
+
*/
|
|
1701
2204
|
function useLiveAction() {
|
|
1702
2205
|
const live = useLiveInstance();
|
|
2206
|
+
const connect = React__default["default"].useCallback((options) => __awaiter(this, void 0, void 0, function* () { return yield live.connect(options); }), [live]);
|
|
1703
2207
|
const toggleMicro = React__default["default"].useCallback((microStatus) => live.toggleMicro(microStatus), [live]);
|
|
1704
|
-
const broadcast = React__default["default"].useCallback((data, toUserIds, timeout = 0) => live.broadcast(data, toUserIds, timeout), [live]);
|
|
1705
|
-
const exit = React__default["default"].useCallback(() => live.exit(), [live]);
|
|
1706
|
-
const kick = React__default["default"].useCallback((toUserIds) => live.kick(toUserIds), [live]);
|
|
1707
|
-
const forbidMicro = React__default["default"].useCallback((micro, toUserIds) => live.forbidMicro(micro, toUserIds), [live]);
|
|
1708
|
-
|
|
1709
|
-
// (sync: boolean, toUserIds?: string | string[] | undefined) =>
|
|
1710
|
-
// live.forbidSync(sync, toUserIds),
|
|
1711
|
-
// [live],
|
|
1712
|
-
// );
|
|
2208
|
+
const broadcast = React__default["default"].useCallback((data, toUserIds, timeout = 0) => __awaiter(this, void 0, void 0, function* () { return yield live.broadcast(data, toUserIds, timeout); }), [live]);
|
|
2209
|
+
const exit = React__default["default"].useCallback(() => __awaiter(this, void 0, void 0, function* () { return yield live.exit(); }), [live]);
|
|
2210
|
+
const kick = React__default["default"].useCallback((toUserIds) => __awaiter(this, void 0, void 0, function* () { return yield live.kick(toUserIds); }), [live]);
|
|
2211
|
+
const forbidMicro = React__default["default"].useCallback((micro, toUserIds = []) => __awaiter(this, void 0, void 0, function* () { return yield live.forbidMicro(micro, toUserIds); }), [live]);
|
|
2212
|
+
const forbidSync = React__default["default"].useCallback((sync, toUserIds = []) => live.forbidSync(sync, toUserIds), [live]);
|
|
1713
2213
|
const getFramesByKey = React__default["default"].useCallback((key) => live.getFramesByKey(key), [live]);
|
|
1714
2214
|
const sendKeyframe = React__default["default"].useCallback((key, frame) => live.sendKeyframe(key, frame), [live]);
|
|
1715
2215
|
const setSelfInfo = React__default["default"].useCallback((userInfo) => live.setSelfInfo(userInfo), [live]);
|
|
1716
2216
|
const updateStatus = React__default["default"].useCallback((evtType, atnType, status, toUserIds) => live.updateStatus(evtType, atnType, status, toUserIds), [live]);
|
|
1717
2217
|
return {
|
|
2218
|
+
connect,
|
|
1718
2219
|
broadcast,
|
|
1719
2220
|
exit,
|
|
1720
2221
|
kick,
|
|
1721
2222
|
toggleMicro,
|
|
1722
2223
|
forbidMicro,
|
|
1723
|
-
|
|
2224
|
+
forbidSync,
|
|
1724
2225
|
sendKeyframe,
|
|
1725
2226
|
getFramesByKey,
|
|
1726
2227
|
setSelfInfo,
|
|
@@ -1751,16 +2252,16 @@ function createLiveReact(options) {
|
|
|
1751
2252
|
return dispose;
|
|
1752
2253
|
}
|
|
1753
2254
|
/**
|
|
1754
|
-
*
|
|
2255
|
+
* 带看状态
|
|
1755
2256
|
* @returns
|
|
1756
2257
|
*/
|
|
1757
|
-
function
|
|
2258
|
+
function useLiveState() {
|
|
1758
2259
|
const live = useLiveInstance();
|
|
1759
|
-
const [state, updateState] = React__default["default"].useState(live.
|
|
2260
|
+
const [state, updateState] = React__default["default"].useState(live.state);
|
|
1760
2261
|
React__default["default"].useEffect(() => {
|
|
1761
|
-
const
|
|
1762
|
-
live.on('
|
|
1763
|
-
return () => live.off('
|
|
2262
|
+
const stateChange = (state) => updateState(state);
|
|
2263
|
+
live.on('stateChange', stateChange);
|
|
2264
|
+
return () => live.off('stateChange', stateChange);
|
|
1764
2265
|
}, [live]);
|
|
1765
2266
|
return state;
|
|
1766
2267
|
}
|
|
@@ -1797,12 +2298,12 @@ function createLiveReact(options) {
|
|
|
1797
2298
|
live.on('selfInfoUpdate', selfInfoUpdate);
|
|
1798
2299
|
return () => live.off('selfInfoUpdate', selfInfoUpdate);
|
|
1799
2300
|
}, [live]);
|
|
1800
|
-
const setState = React__default["default"].useCallback(
|
|
1801
|
-
return
|
|
1802
|
-
}, [live]);
|
|
2301
|
+
const setState = React__default["default"].useCallback((userInfo) => __awaiter(this, void 0, void 0, function* () {
|
|
2302
|
+
return yield live.setSelfInfo(userInfo);
|
|
2303
|
+
}), [live]);
|
|
1803
2304
|
return [state, setState];
|
|
1804
2305
|
}
|
|
1805
|
-
function
|
|
2306
|
+
function useKeyframesSnapshot() {
|
|
1806
2307
|
const live = useLiveInstance();
|
|
1807
2308
|
const [state, setState] = React__default["default"].useState(live.snapshot);
|
|
1808
2309
|
React__default["default"].useEffect(() => {
|
|
@@ -1822,43 +2323,23 @@ function createLiveReact(options) {
|
|
|
1822
2323
|
}, [live]);
|
|
1823
2324
|
return state;
|
|
1824
2325
|
}
|
|
1825
|
-
/**
|
|
1826
|
-
*
|
|
1827
|
-
* @param name
|
|
1828
|
-
* @param callback
|
|
1829
|
-
* @param deps
|
|
1830
|
-
* @returns
|
|
1831
|
-
* @deprecated
|
|
1832
|
-
*/
|
|
1833
|
-
function useWebSocketEventCallback(name, callback, deps = []) {
|
|
1834
|
-
const live = useLiveInstance();
|
|
1835
|
-
const dispose = () => live.off(name, callback);
|
|
1836
|
-
const dependencyList = [live, name, ...deps];
|
|
1837
|
-
React__default["default"].useEffect(() => {
|
|
1838
|
-
live.on(name, callback);
|
|
1839
|
-
return dispose;
|
|
1840
|
-
}, dependencyList);
|
|
1841
|
-
return dispose;
|
|
1842
|
-
}
|
|
1843
2326
|
return {
|
|
1844
2327
|
live,
|
|
1845
2328
|
jsBridge,
|
|
1846
2329
|
LiveProvider,
|
|
1847
2330
|
unsafe__useLiveInstance,
|
|
1848
2331
|
unsafe__useRTCInstance,
|
|
1849
|
-
useCurrentWebSocketUrl,
|
|
1850
2332
|
useConnect,
|
|
1851
2333
|
useKeyframe,
|
|
1852
2334
|
useKeyframeUpdateCallback,
|
|
1853
2335
|
useLiveAction,
|
|
1854
2336
|
useLiveEventCallback,
|
|
1855
|
-
|
|
2337
|
+
useLiveState,
|
|
1856
2338
|
useRTCAction,
|
|
1857
2339
|
useRTCEventCallback,
|
|
1858
2340
|
useSelfInfo,
|
|
1859
|
-
|
|
2341
|
+
useKeyframesSnapshot,
|
|
1860
2342
|
useUserList,
|
|
1861
|
-
useWebSocketEventCallback,
|
|
1862
2343
|
};
|
|
1863
2344
|
}
|
|
1864
2345
|
|