@realsee/live 0.3.0-alpha.4 → 0.4.0-alpha.3

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.
Files changed (147) hide show
  1. package/dist/index.d.ts +4 -0
  2. package/dist/live/controller.d.ts +43 -0
  3. package/{lib → dist/live}/createLive.d.ts +6 -6
  4. package/dist/live/createLiveReact.d.ts +6 -0
  5. package/dist/realsee-live.cjs.development.js +1813 -0
  6. package/dist/realsee-live.cjs.development.js.map +1 -0
  7. package/dist/realsee-live.cjs.js +7 -0
  8. package/dist/realsee-live.cjs.production.js +2 -0
  9. package/dist/realsee-live.cjs.production.js.map +1 -0
  10. package/dist/realsee-live.esm.js +1797 -0
  11. package/dist/realsee-live.esm.js.map +1 -0
  12. package/dist/realsee-live.umd.development.js +52136 -0
  13. package/dist/realsee-live.umd.development.js.map +1 -0
  14. package/dist/realsee-live.umd.production.js +2 -0
  15. package/dist/realsee-live.umd.production.js.map +1 -0
  16. package/{lib/RTC → dist/rtc}/BrowserRTC.d.ts +29 -30
  17. package/{lib/RTC → dist/rtc}/BrowserRTC4Chime.d.ts +55 -53
  18. package/dist/rtc/CoreRTC.d.ts +23 -0
  19. package/{lib/RTC → dist/rtc}/VRWebViewRTC.d.ts +22 -23
  20. package/dist/rtc/index.d.ts +5 -0
  21. package/{lib/typings/Chime → dist/typings/chime}/AttendeeResponse.d.ts +5 -5
  22. package/{lib/typings/Chime → dist/typings/chime}/MeetingResponse.d.ts +12 -12
  23. package/{lib/typings/Chime → dist/typings/chime}/MeetingSessionConfigurationOptions.d.ts +16 -16
  24. package/dist/typings/chime/index.d.ts +3 -0
  25. package/dist/typings/index.d.ts +4 -0
  26. package/{lib/typings → dist/typings/live}/EventType.d.ts +90 -89
  27. package/{lib/typings → dist/typings/live}/GetVoiceSign.d.ts +17 -11
  28. package/{lib/typings → dist/typings/live}/Live.d.ts +123 -122
  29. package/{lib/typings → dist/typings/live}/LiveMsg.d.ts +119 -119
  30. package/{lib/typings → dist/typings/live}/LiveOptions.d.ts +65 -46
  31. package/{lib/typings → dist/typings/live}/RoomInfo.d.ts +13 -13
  32. package/{lib/typings → dist/typings/live}/UserInfo.d.ts +87 -87
  33. package/dist/typings/live/UserVolume.d.ts +7 -0
  34. package/{lib/typings → dist/typings/live}/WebSocket.d.ts +78 -78
  35. package/dist/typings/live/index.d.ts +9 -0
  36. package/{lib/createLiveReact.d.ts → dist/typings/react/LiveReact.d.ts} +162 -160
  37. package/dist/typings/react/RTCActionReactCallback.d.ts +2 -0
  38. package/dist/typings/react/index.d.ts +2 -0
  39. package/dist/typings/rtc/VRWebViewRTCOptions.d.ts +6 -0
  40. package/{lib/typings/RTCEventType.d.ts → dist/typings/rtc/eventType.d.ts} +29 -35
  41. package/dist/typings/rtc/index.d.ts +5 -0
  42. package/{lib/typings/RTCJoinedInfo.d.ts → dist/typings/rtc/joinedInfo.d.ts} +34 -28
  43. package/{lib/typings/RTCProtocol.d.ts → dist/typings/rtc/protocol.d.ts} +53 -42
  44. package/dist/typings/rtc/type.d.ts +8 -0
  45. package/{lib/shared-utils → dist/utils}/appendUri.d.ts +1 -1
  46. package/dist/utils/clientDetector.d.ts +4 -0
  47. package/{lib/shared-utils → dist/utils}/equal.d.ts +10 -11
  48. package/{lib/shared-utils/Subscribe.d.ts → dist/utils/subscribe.d.ts} +75 -76
  49. package/{lib/shared-utils → dist/utils}/uuid.d.ts +4 -4
  50. package/package.json +21 -33
  51. package/docs/.nojekyll +0 -1
  52. package/docs/assets/custom.css +0 -43
  53. package/docs/assets/highlight.css +0 -127
  54. package/docs/assets/icons.css +0 -1043
  55. package/docs/assets/icons.png +0 -0
  56. package/docs/assets/icons@2x.png +0 -0
  57. package/docs/assets/main.js +0 -52
  58. package/docs/assets/search.js +0 -1
  59. package/docs/assets/style.css +0 -1413
  60. package/docs/assets/widgets.png +0 -0
  61. package/docs/assets/widgets@2x.png +0 -0
  62. package/docs/classes/RTCProtocol.BrowserRTC.html +0 -60
  63. package/docs/classes/RTCProtocol.BrowserRTC4Chime.html +0 -66
  64. package/docs/classes/RTCProtocol.RTCExample.html +0 -62
  65. package/docs/classes/RTCProtocol.VRWebViewRTC.html +0 -60
  66. package/docs/classes/shared_utils.Subscribe.html +0 -56
  67. package/docs/enums/RTCProtocol.RTCJoinedInfoCodeEnum.html +0 -9
  68. package/docs/enums/RTCProtocol.RTCType.html +0 -1
  69. package/docs/enums/live.BuiltinActionType.html +0 -15
  70. package/docs/enums/live.BuiltinEventType.html +0 -7
  71. package/docs/enums/live.Command.html +0 -7
  72. package/docs/enums/live.MemUserStatus.html +0 -1
  73. package/docs/enums/live.MicroStatus.html +0 -3
  74. package/docs/enums/live.UserStatus.html +0 -9
  75. package/docs/enums/live.WebSocketCloseError.html +0 -19
  76. package/docs/enums/live.WebSocketErrorType.html +0 -1
  77. package/docs/enums/live.WebSocketState.html +0 -13
  78. package/docs/index.html +0 -382
  79. package/docs/interfaces/RTCProtocol.GetVoiceSignReturnType.html +0 -1
  80. package/docs/interfaces/RTCProtocol.RTCJoinedInfo.html +0 -1
  81. package/docs/interfaces/RTCProtocol.RTCProtocol-1.html +0 -60
  82. package/docs/interfaces/RTCProtocol.VRWebViewRTCOptions.html +0 -1
  83. package/docs/interfaces/live.Live.html +0 -119
  84. package/docs/interfaces/live.LiveOptions.html +0 -22
  85. package/docs/interfaces/live.LiveReact.html +0 -52
  86. package/docs/modules/RTCProtocol.html +0 -17
  87. package/docs/modules/live.html +0 -103
  88. package/docs/modules/shared_utils.html +0 -10
  89. package/docs/modules.html +0 -1
  90. package/lib/RTC/BrowserRTC.js +0 -169
  91. package/lib/RTC/BrowserRTC.js.map +0 -1
  92. package/lib/RTC/BrowserRTC4Chime.js +0 -299
  93. package/lib/RTC/BrowserRTC4Chime.js.map +0 -1
  94. package/lib/RTC/VRWebViewRTC.js +0 -125
  95. package/lib/RTC/VRWebViewRTC.js.map +0 -1
  96. package/lib/RTC/index.d.ts +0 -22
  97. package/lib/RTC/index.js +0 -50
  98. package/lib/RTC/index.js.map +0 -1
  99. package/lib/createLive.js +0 -590
  100. package/lib/createLive.js.map +0 -1
  101. package/lib/createLiveReact.js +0 -212
  102. package/lib/createLiveReact.js.map +0 -1
  103. package/lib/index.d.ts +0 -2
  104. package/lib/index.js +0 -8
  105. package/lib/index.js.map +0 -1
  106. package/lib/shared-utils/Subscribe.js +0 -134
  107. package/lib/shared-utils/Subscribe.js.map +0 -1
  108. package/lib/shared-utils/appendUri.js +0 -13
  109. package/lib/shared-utils/appendUri.js.map +0 -1
  110. package/lib/shared-utils/equal.js +0 -92
  111. package/lib/shared-utils/equal.js.map +0 -1
  112. package/lib/shared-utils/uuid.js +0 -17
  113. package/lib/shared-utils/uuid.js.map +0 -1
  114. package/lib/typings/Chime/AttendeeResponse.js +0 -3
  115. package/lib/typings/Chime/AttendeeResponse.js.map +0 -1
  116. package/lib/typings/Chime/MeetingResponse.js +0 -3
  117. package/lib/typings/Chime/MeetingResponse.js.map +0 -1
  118. package/lib/typings/Chime/MeetingSessionConfigurationOptions.js +0 -3
  119. package/lib/typings/Chime/MeetingSessionConfigurationOptions.js.map +0 -1
  120. package/lib/typings/EventType.js +0 -3
  121. package/lib/typings/EventType.js.map +0 -1
  122. package/lib/typings/GetVoiceSign.js +0 -3
  123. package/lib/typings/GetVoiceSign.js.map +0 -1
  124. package/lib/typings/Live.js +0 -3
  125. package/lib/typings/Live.js.map +0 -1
  126. package/lib/typings/LiveMsg.js +0 -111
  127. package/lib/typings/LiveMsg.js.map +0 -1
  128. package/lib/typings/LiveOptions.js +0 -3
  129. package/lib/typings/LiveOptions.js.map +0 -1
  130. package/lib/typings/RTCEventType.js +0 -3
  131. package/lib/typings/RTCEventType.js.map +0 -1
  132. package/lib/typings/RTCJoinedInfo.js +0 -23
  133. package/lib/typings/RTCJoinedInfo.js.map +0 -1
  134. package/lib/typings/RTCProtocol.js +0 -9
  135. package/lib/typings/RTCProtocol.js.map +0 -1
  136. package/lib/typings/RoomInfo.js +0 -3
  137. package/lib/typings/RoomInfo.js.map +0 -1
  138. package/lib/typings/UserInfo.js +0 -31
  139. package/lib/typings/UserInfo.js.map +0 -1
  140. package/lib/typings/VRWebViewRTCOptions.d.ts +0 -6
  141. package/lib/typings/VRWebViewRTCOptions.js +0 -3
  142. package/lib/typings/VRWebViewRTCOptions.js.map +0 -1
  143. package/lib/typings/WebSocket.js +0 -107
  144. package/lib/typings/WebSocket.js.map +0 -1
  145. package/umd/RTCProtocol.543610f0.js +0 -1
  146. package/umd/createLive.1ecf7dd4.js +0 -1
  147. package/umd/createLiveReact.9075a8fd.js +0 -1
@@ -0,0 +1,1813 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var amazonChimeSdkJs = require('amazon-chime-sdk-js');
6
+ var TRTC = require('trtc-js-sdk');
7
+ var React = require('react');
8
+
9
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
10
+
11
+ var TRTC__default = /*#__PURE__*/_interopDefaultLegacy(TRTC);
12
+ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
13
+
14
+ const EVENT_SYMBOL = Symbol('$$REALSEE_LIVE_EVENT$$');
15
+ function __generateEventIfNotExisted(instance) {
16
+ if (!instance[EVENT_SYMBOL]) {
17
+ instance[EVENT_SYMBOL] = {};
18
+ }
19
+ return instance[EVENT_SYMBOL];
20
+ }
21
+ function __removeEventIfNotExisted(instance) {
22
+ if (!instance[EVENT_SYMBOL]) {
23
+ delete instance[EVENT_SYMBOL];
24
+ }
25
+ }
26
+ /**
27
+ * 监听者模式
28
+ * @template T 预设的监听回调类型
29
+ * @example
30
+ * ```
31
+ * new Subscribe<{
32
+ * "foo": [arg1: number, arg2: string],
33
+ * "bar": [arg: boolean],
34
+ * }>()
35
+ * ```
36
+ */
37
+ class Subscribe {
38
+ /**
39
+ * 判断是否注册了事件
40
+ * @param name 事件类型
41
+ */
42
+ hasListener(name) {
43
+ const events = __generateEventIfNotExisted(this);
44
+ return events && events[name] && events[name].length > 0;
45
+ }
46
+ /**
47
+ * 注册事件
48
+ * @param name 事件类型
49
+ * @param callback 事件回调函数
50
+ * @param once 是否只执行一次
51
+ * @returns 解除事件
52
+ * @template K 预设的监听事件名称
53
+ * @template C 回调函数函数上下文
54
+ */
55
+ on(name, callback, once) {
56
+ const events = __generateEventIfNotExisted(this);
57
+ if (!events[name])
58
+ events[name] = [];
59
+ events[name].push([callback, once || false]);
60
+ return () => this.off(name, callback);
61
+ }
62
+ /**
63
+ * 注册事件(是否只执行一次)
64
+ * @param name 事件类型
65
+ * @param callback 事件回调函数
66
+ * @returns 解除事件
67
+ * @template K 预设的监听事件名称
68
+ * @template C 回调函数函数上下文
69
+ */
70
+ once(name, callback) {
71
+ return this.on(name, callback, true);
72
+ }
73
+ /**
74
+ * 解除事件
75
+ *
76
+ * 如果 name 不传的话解除对应所有事件
77
+ * 如果 name, callback 不传的话解除所有name的所有事件
78
+ * @param name 事件类型
79
+ * @param callback 事件回调函数
80
+ * @template K 预设的监听事件名称
81
+ */
82
+ off(name, callback) {
83
+ if (name === undefined) {
84
+ __removeEventIfNotExisted(this);
85
+ return;
86
+ }
87
+ const events = __generateEventIfNotExisted(this);
88
+ if (!events[name])
89
+ events[name] = [];
90
+ if (callback === undefined) {
91
+ events[name].length = 0;
92
+ return;
93
+ }
94
+ let index = 0;
95
+ for (; index < events[name].length; index++) {
96
+ if (events[name][index][0] === callback)
97
+ break;
98
+ }
99
+ if (index < events[name].length) {
100
+ events[name].splice(index, 1);
101
+ }
102
+ }
103
+ /**
104
+ * 触发事件
105
+ * @param name 事件类型
106
+ * @param data 触发事件的数据
107
+ * @returns canceled 是否被触发取消
108
+ * @template K 预设的监听事件名称
109
+ */
110
+ emit(name, ...data) {
111
+ let canceled = false;
112
+ const events = __generateEventIfNotExisted(this);
113
+ const event = events[name] || [];
114
+ for (let one of event.slice()) {
115
+ const [callback, once = false] = one;
116
+ const result = callback(...data);
117
+ if (once)
118
+ this.off(name, callback);
119
+ if (result === false)
120
+ canceled = true;
121
+ }
122
+ return canceled;
123
+ }
124
+ }
125
+
126
+ /**
127
+ * rtc 基础抽象类
128
+ */
129
+ class CoreRTC extends Subscribe {
130
+ }
131
+
132
+ /**
133
+ * rtc 类型
134
+ */
135
+ exports.RTCType = void 0;
136
+ (function (RTCType) {
137
+ RTCType["RealseeBrowserRTC"] = "RealseeBrowserRTC";
138
+ RTCType["RealseeVRWebViewRTC"] = "RealseeVRWebViewRTC";
139
+ RTCType["RealseeBrowserChimeRTC"] = "RealseeBrowserChimeRTC";
140
+ })(exports.RTCType || (exports.RTCType = {}));
141
+
142
+ // uuid
143
+ function S4() {
144
+ return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
145
+ }
146
+ /**
147
+ * 基于伪随机数生成 **uuid**。
148
+ */
149
+ function uuid() {
150
+ // then to call it, plus stitch in '4' in the third group
151
+ return (S4() +
152
+ S4() +
153
+ '-' +
154
+ S4() +
155
+ '-4' +
156
+ S4().substr(0, 3) +
157
+ '-' +
158
+ S4() +
159
+ '-' +
160
+ S4() +
161
+ S4() +
162
+ S4()).toLowerCase();
163
+ }
164
+
165
+ class BrowserRTC extends CoreRTC {
166
+ constructor(options) {
167
+ super();
168
+ this.type = exports.RTCType.RealseeBrowserRTC;
169
+ this.joined = false;
170
+ this.micro = false;
171
+ this.voiceId = '';
172
+ this._getVoiceSign = () => {
173
+ throw new Error('方法 getVoiceSign 未实现');
174
+ };
175
+ this.$dom = document.createElement('div');
176
+ this._trtc = {
177
+ client: null,
178
+ stream: null,
179
+ };
180
+ this.join = async (options) => {
181
+ var _a;
182
+ this.emit('joinWillStart');
183
+ const createClientOptions = await this._getVoiceSign({
184
+ voiceId: options.voiceId,
185
+ roomId: options.roomId,
186
+ userId: options.userId,
187
+ });
188
+ // 1. 创建client
189
+ this._trtc.client = TRTC__default["default"].createClient({
190
+ mode: 'rtc',
191
+ ...createClientOptions,
192
+ });
193
+ (_a = this._trtc.client) === null || _a === void 0 ? void 0 : _a.enableAudioVolumeEvaluation();
194
+ // 2. 订阅事件
195
+ this._registerRtcEvent();
196
+ // 3. 加入语音房间
197
+ let result = await new Promise((resolve) => {
198
+ var _a;
199
+ (_a = this._trtc.client) === null || _a === void 0 ? void 0 : _a.join({ roomId: Number(options.voiceId) }).then(() => resolve(true)).catch(() => resolve(false));
200
+ });
201
+ this.joined = result;
202
+ if (!result)
203
+ return false; // 进房失败
204
+ // 4. 创建本地流
205
+ this._trtc.stream = TRTC__default["default"].createStream({
206
+ userId: createClientOptions.userId,
207
+ audio: true,
208
+ video: false,
209
+ });
210
+ // 5. 初始化本地流
211
+ result = await new Promise((resolve) => {
212
+ var _a;
213
+ (_a = this._trtc.stream) === null || _a === void 0 ? void 0 : _a.initialize().then(() => resolve(true)).catch(() => resolve(false));
214
+ });
215
+ // 6. 发布本地流
216
+ result = await new Promise((resolve) => {
217
+ var _a;
218
+ (_a = this._trtc.client) === null || _a === void 0 ? void 0 : _a.publish(this._trtc.stream).then(() => resolve(true)).catch(() => resolve(false));
219
+ });
220
+ this.joined = result;
221
+ if (this.joined)
222
+ this.emit('joined');
223
+ return result;
224
+ };
225
+ this._handleStreamAdded = (event) => {
226
+ var _a;
227
+ const remoteStream = event.stream;
228
+ console.log('远端流增加: ' + remoteStream.getId());
229
+ //订阅远端流
230
+ (_a = this._trtc.client) === null || _a === void 0 ? void 0 : _a.subscribe(remoteStream);
231
+ };
232
+ this._handleStreamSubscribed = (event) => {
233
+ const remoteStream = event.stream;
234
+ console.log('远端流订阅成功:' + remoteStream.getId());
235
+ const playId = remoteStream.getId();
236
+ const domId = `rs-rtc-remote_stream-${playId}`;
237
+ const dom = document.createElement('div');
238
+ dom.id = domId;
239
+ this.$dom.appendChild(dom);
240
+ // 播放远端流
241
+ remoteStream.play(domId);
242
+ };
243
+ this._getVoiceSign = options.getVoiceSign;
244
+ this._initParentDom();
245
+ }
246
+ _initParentDom() {
247
+ this.$dom.id = `rs-rtc-${uuid()}`;
248
+ this.$dom.style.display = 'none';
249
+ document.body.appendChild(this.$dom);
250
+ }
251
+ quit() {
252
+ return new Promise(async (resolve) => {
253
+ var _a, _b;
254
+ this.joined = false;
255
+ if (this._trtc.stream) {
256
+ await ((_a = this._trtc.client) === null || _a === void 0 ? void 0 : _a.unpublish(this._trtc.stream));
257
+ this._trtc.stream.stop();
258
+ this._trtc.stream.close();
259
+ this._trtc.stream = null;
260
+ }
261
+ (_b = this._trtc.client) === null || _b === void 0 ? void 0 : _b.leave().then(() => (this._trtc.client = null)).then(() => resolve(true)).catch(() => resolve(false));
262
+ });
263
+ }
264
+ detectMicro() {
265
+ return new Promise((resolve) => {
266
+ const rule = { audio: true, video: false };
267
+ try {
268
+ navigator.mediaDevices
269
+ .getUserMedia(rule)
270
+ .then(() => resolve(true))
271
+ .catch(() => resolve(false));
272
+ }
273
+ catch (e) {
274
+ console.error(e);
275
+ resolve(false);
276
+ }
277
+ });
278
+ }
279
+ toggleMicro(flag) {
280
+ var _a, _b, _c, _d;
281
+ return Promise.resolve((flag
282
+ ? (_b = (_a = this._trtc) === null || _a === void 0 ? void 0 : _a.stream) === null || _b === void 0 ? void 0 : _b.unmuteAudio()
283
+ : (_d = (_c = this._trtc) === null || _c === void 0 ? void 0 : _c.stream) === null || _d === void 0 ? void 0 : _d.muteAudio()) || false);
284
+ }
285
+ shock() {
286
+ throw new Error('Method not implemented.');
287
+ }
288
+ _registerRtcEvent() {
289
+ var _a, _b, _c, _d;
290
+ (_a = this._trtc.client) === null || _a === void 0 ? void 0 : _a.on('stream-added', this._handleStreamAdded);
291
+ (_b = this._trtc.client) === null || _b === void 0 ? void 0 : _b.on('stream-subscribed', this._handleStreamSubscribed);
292
+ (_c = this._trtc.client) === null || _c === void 0 ? void 0 : _c.on('audio-volume', (event) => this.emit('userVolumes', [
293
+ { userId: event.userId, audioVolume: event.audioVolume },
294
+ ]));
295
+ (_d = this._trtc.client) === null || _d === void 0 ? void 0 : _d.on('error', (event) => this.emit('error', event));
296
+ }
297
+ }
298
+
299
+ /**
300
+ * amazon-chime-sdk-js 适配的rtc实现
301
+ */
302
+ class BrowserRTC4Chime extends CoreRTC {
303
+ constructor(options) {
304
+ super();
305
+ this.type = exports.RTCType.RealseeBrowserChimeRTC;
306
+ this.joined = false;
307
+ this.micro = false;
308
+ this.voiceId = '';
309
+ this.userId = '';
310
+ this.deviceChangeObserver = {};
311
+ this.audioVideoObserver = {};
312
+ this._getVoiceSign = () => {
313
+ throw new Error('方法 getVoiceSign 未实现');
314
+ };
315
+ this.$dom = document.createElement('div');
316
+ this.$audio = document.createElement('audio');
317
+ /**
318
+ * 对audio标签初始化
319
+ */
320
+ this._initDom = () => {
321
+ this.$audio.id = `rs-rtc-${uuid()}`;
322
+ this.$dom.id = `rs-rtc-${uuid()}`;
323
+ this.$dom.appendChild(this.$audio);
324
+ document.body.appendChild(this.$dom);
325
+ };
326
+ /**
327
+ * 初始化事件监听器
328
+ */
329
+ this.initObservers = () => {
330
+ // 输入输出设备变化的监听器
331
+ this.deviceChangeObserver = {
332
+ audioInputsChanged: (freshAudioInputDeviceList) => {
333
+ // An array of MediaDeviceInfo objects
334
+ freshAudioInputDeviceList === null || freshAudioInputDeviceList === void 0 ? void 0 : freshAudioInputDeviceList.forEach((mediaDeviceInfo) => {
335
+ this.logger.info(`Device ID: ${mediaDeviceInfo.deviceId} Microphone: ${mediaDeviceInfo.label}`);
336
+ });
337
+ },
338
+ audioOutputsChanged: (freshAudioOutputDeviceList) => {
339
+ this.logger.info(`Audio outputs updated: ${freshAudioOutputDeviceList}`);
340
+ },
341
+ videoInputsChanged: (freshVideoInputDeviceList) => {
342
+ this.logger.info(`Video inputs updated: ${freshVideoInputDeviceList}`);
343
+ },
344
+ audioInputMuteStateChanged: (device, muted) => {
345
+ this.logger.info(`Device ${device.toString()} ${muted ? 'is muted in hardware' : 'is not muted'}`);
346
+ },
347
+ };
348
+ // 流变化监听器
349
+ this.audioVideoObserver = {
350
+ audioVideoDidStart: () => {
351
+ this.logger.info('Started');
352
+ },
353
+ audioVideoDidStop: (sessionStatus) => {
354
+ // See the "Stopping a session" section for details.
355
+ this.logger.info(`Stopped with a session status code: ${sessionStatus.statusCode()}`);
356
+ },
357
+ audioVideoDidStartConnecting: (reconnecting) => {
358
+ if (reconnecting) {
359
+ // e.g. the WiFi connection is dropped.
360
+ this.logger.info('Attempting to reconnect');
361
+ }
362
+ },
363
+ };
364
+ };
365
+ /**
366
+ * 注册rtc事件
367
+ */
368
+ this._registerRtcEvent = () => {
369
+ var _a, _b, _c, _d, _e, _f;
370
+ const presentAttendeeId = ((_c = (_b = (_a = this.meetingSession) === null || _a === void 0 ? void 0 : _a.configuration) === null || _b === void 0 ? void 0 : _b.credentials) === null || _c === void 0 ? void 0 : _c.attendeeId) || '';
371
+ if (presentAttendeeId) {
372
+ // 处理音量变化
373
+ const roster = new Map();
374
+ const getUserVolumes = () => {
375
+ const result = [];
376
+ roster.forEach((v, k) => {
377
+ result.push({
378
+ userId: v.userId,
379
+ volume: v.muted || v.signalStrength === 0 || !Boolean(v.volume)
380
+ ? 0
381
+ : v.volume,
382
+ });
383
+ });
384
+ return result;
385
+ };
386
+ (_d = this.meetingSession) === null || _d === void 0 ? void 0 : _d.audioVideo.realtimeSubscribeToAttendeeIdPresence((presentAttendeeId, present, externalUserId) => {
387
+ var _a;
388
+ if (!present) {
389
+ roster.delete(presentAttendeeId);
390
+ this.emit('userVolumes', getUserVolumes());
391
+ return;
392
+ }
393
+ (_a = this.meetingSession) === null || _a === void 0 ? void 0 : _a.audioVideo.realtimeSubscribeToVolumeIndicator(presentAttendeeId, (attendeeId, volume, muted, signalStrength) => {
394
+ const baseAttendeeId = new amazonChimeSdkJs.DefaultModality(attendeeId).base();
395
+ if (baseAttendeeId !== attendeeId) {
396
+ // Optional: Do not include the content attendee (attendee-id#content) in the roster.
397
+ // See the "Screen and content share" section for details.
398
+ return;
399
+ }
400
+ roster.set(attendeeId, {
401
+ userId: externalUserId || attendeeId,
402
+ volume,
403
+ muted,
404
+ signalStrength,
405
+ });
406
+ this.emit('userVolumes', getUserVolumes());
407
+ });
408
+ });
409
+ // 弱网
410
+ (_e = this.meetingSession) === null || _e === void 0 ? void 0 : _e.audioVideo.realtimeSubscribeToVolumeIndicator(presentAttendeeId, (attendeeId, volume, muted, signalStrength) => {
411
+ const baseAttendeeId = new amazonChimeSdkJs.DefaultModality(attendeeId).base();
412
+ if (baseAttendeeId === attendeeId) {
413
+ if (signalStrength !== null && signalStrength !== 1) {
414
+ this.emit('weakNetwork');
415
+ }
416
+ }
417
+ });
418
+ // 报错
419
+ (_f = this.meetingSession) === null || _f === void 0 ? void 0 : _f.audioVideo.realtimeSubscribeToFatalError((error) => this.emit('error', error));
420
+ }
421
+ };
422
+ // 挂载签名钩子
423
+ this._getVoiceSign = options.getVoiceSign;
424
+ this._initDom();
425
+ this.logger = new amazonChimeSdkJs.ConsoleLogger('WebRTCLogger', options.logLevel || amazonChimeSdkJs.LogLevel.OFF);
426
+ this.deviceController = new amazonChimeSdkJs.DefaultDeviceController(this.logger);
427
+ this.initObservers();
428
+ }
429
+ /**
430
+ * 加入语音会议
431
+ * @param options
432
+ * @returns
433
+ */
434
+ async join(options) {
435
+ return new Promise(async (success, fail) => {
436
+ var _a;
437
+ this.emit('joinWillStart');
438
+ try {
439
+ // 取签名
440
+ const { sdkAppId, userId, roomId, userSig } = await this._getVoiceSign({
441
+ ...options,
442
+ roomId: options.roomId || 0,
443
+ });
444
+ this.userId = userId;
445
+ const { attendence, vendor_wrapper, } = JSON.parse(decodeURIComponent(userSig));
446
+ // 初始化配置
447
+ const configuration = new amazonChimeSdkJs.MeetingSessionConfiguration({
448
+ Meeting: vendor_wrapper,
449
+ }, {
450
+ Attendee: {
451
+ ExternalUserId: attendence.external_user_id,
452
+ AttendeeId: attendence.attendee_id,
453
+ JoinToken: attendence.join_token,
454
+ },
455
+ });
456
+ // 初始化会议会话
457
+ this.meetingSession = new amazonChimeSdkJs.DefaultMeetingSession(configuration, this.logger, this.deviceController);
458
+ // 注册事件
459
+ this._registerRtcEvent();
460
+ // 绑定监听器
461
+ this.meetingSession.audioVideo.addDeviceChangeObserver(this.deviceChangeObserver);
462
+ this.meetingSession.audioVideo.addObserver(this.audioVideoObserver);
463
+ // 绑定播放器
464
+ this.meetingSession.audioVideo.bindAudioElement(this.$audio);
465
+ const observer = {
466
+ audioVideoDidStart: () => {
467
+ var _a;
468
+ (_a = this.meetingSession) === null || _a === void 0 ? void 0 : _a.audioVideo.realtimeMuteLocalAudio();
469
+ this.joined = true;
470
+ this.emit('joined');
471
+ success(true);
472
+ },
473
+ audioVideoDidStop: () => {
474
+ this.joined = false;
475
+ success(false);
476
+ },
477
+ };
478
+ this.meetingSession.audioVideo.addObserver(observer);
479
+ // 选择语音输入设备
480
+ const audioInputDevices = await this.deviceController.listAudioInputDevices(true);
481
+ const defaultAudioInput = audioInputDevices.find((device) => device.deviceId === 'default');
482
+ const otherAudioInput = audioInputDevices.find((device) => device.deviceId !== '');
483
+ this.audioInput = defaultAudioInput || otherAudioInput;
484
+ await this.meetingSession.audioVideo.chooseVideoInputDevice(null);
485
+ await this.meetingSession.audioVideo.chooseAudioInputDevice(((_a = this.audioInput) === null || _a === void 0 ? void 0 : _a.deviceId) || 'default');
486
+ this.meetingSession.audioVideo.start();
487
+ }
488
+ catch (e) {
489
+ this.emit('error', e);
490
+ this.logger.error(e.message);
491
+ success(false);
492
+ }
493
+ });
494
+ }
495
+ quit() {
496
+ return new Promise((success, fail) => {
497
+ var _a, _b;
498
+ this.joined = false;
499
+ const observer = {
500
+ audioVideoDidStop: (sessionStatus) => {
501
+ const sessionStatusCode = sessionStatus.statusCode();
502
+ if (sessionStatusCode === amazonChimeSdkJs.MeetingSessionStatusCode.Left) {
503
+ /*
504
+ - You called meetingSession.audioVideo.stop().
505
+ - When closing a browser window or page, Chime SDK attempts to leave the session.
506
+ */
507
+ this.logger.info('You left the session');
508
+ success(true);
509
+ }
510
+ else {
511
+ this.logger.info(`Stopped with a session status code: ${sessionStatusCode}`);
512
+ success(true);
513
+ }
514
+ },
515
+ };
516
+ (_a = this.meetingSession) === null || _a === void 0 ? void 0 : _a.audioVideo.addObserver(observer);
517
+ (_b = this.meetingSession) === null || _b === void 0 ? void 0 : _b.audioVideo.stop();
518
+ });
519
+ }
520
+ async detectMicro() {
521
+ return new Promise((resolve) => {
522
+ const rule = { audio: true, video: false };
523
+ try {
524
+ navigator.mediaDevices
525
+ .getUserMedia(rule)
526
+ .then(() => resolve(true))
527
+ .catch(() => resolve(false));
528
+ }
529
+ catch (e) {
530
+ this.logger.error(e.message);
531
+ resolve(false);
532
+ }
533
+ });
534
+ }
535
+ async toggleMicro(flag) {
536
+ var _a, _b, _c;
537
+ if (flag) {
538
+ (_a = this.meetingSession) === null || _a === void 0 ? void 0 : _a.audioVideo.realtimeUnmuteLocalAudio();
539
+ }
540
+ else {
541
+ (_b = this.meetingSession) === null || _b === void 0 ? void 0 : _b.audioVideo.realtimeMuteLocalAudio();
542
+ }
543
+ const muted = (_c = this.meetingSession) === null || _c === void 0 ? void 0 : _c.audioVideo.realtimeIsLocalAudioMuted();
544
+ if (muted !== undefined) {
545
+ return flag !== muted;
546
+ }
547
+ else {
548
+ return false;
549
+ }
550
+ }
551
+ shock() {
552
+ throw new Error('Method not implemented.');
553
+ }
554
+ }
555
+
556
+ /**
557
+ * rtc加入返回值code枚举
558
+ */
559
+ exports.RTCJoinedInfoCodeEnum = void 0;
560
+ (function (RTCJoinedInfoCodeEnum) {
561
+ /**
562
+ * 成功
563
+ */
564
+ RTCJoinedInfoCodeEnum[RTCJoinedInfoCodeEnum["Success"] = 0] = "Success";
565
+ /**
566
+ * 失败
567
+ */
568
+ RTCJoinedInfoCodeEnum[RTCJoinedInfoCodeEnum["Failure"] = 1] = "Failure";
569
+ /**
570
+ * 重复加入
571
+ */
572
+ RTCJoinedInfoCodeEnum[RTCJoinedInfoCodeEnum["ReJoin"] = 2] = "ReJoin";
573
+ /**
574
+ * 无麦克风权限
575
+ */
576
+ RTCJoinedInfoCodeEnum[RTCJoinedInfoCodeEnum["NoMicroPermission"] = 3] = "NoMicroPermission";
577
+ })(exports.RTCJoinedInfoCodeEnum || (exports.RTCJoinedInfoCodeEnum = {}));
578
+
579
+ class VRWebViewRTC extends CoreRTC {
580
+ constructor({ jsBridge, getVoiceSign }) {
581
+ super();
582
+ this.type = exports.RTCType.RealseeVRWebViewRTC;
583
+ this.joined = false;
584
+ this.micro = false;
585
+ this.voiceId = '';
586
+ this.options = { jsBridge, getVoiceSign };
587
+ this.jsBridge.callAndListen('live/userVolumes', (userVolumes) => {
588
+ this.emit('userVolumes', userVolumes);
589
+ });
590
+ this.jsBridge.callAndListen('live/weakNetwork', (weakNetwork) => {
591
+ if (weakNetwork)
592
+ this.emit('weakNetwork');
593
+ });
594
+ }
595
+ get jsBridge() {
596
+ return this.options.jsBridge;
597
+ }
598
+ async join(options) {
599
+ this.emit('joinWillStart');
600
+ const { sdkAppId, userId, userSig } = await this.options.getVoiceSign(options);
601
+ this.type = options.type;
602
+ const [res, error] = await this.jsBridge.callAndBackfeed(`live/join?sdkAppID=${sdkAppId}&userID=${userId}&roomID=${Number(options.voiceId)}&userSig=${userSig}`);
603
+ if (!res) {
604
+ this.emit('error', error ? error : new Error('加入房间失败:未知异常。'));
605
+ this.joined = false;
606
+ }
607
+ else {
608
+ if (res.code === exports.RTCJoinedInfoCodeEnum.Success) {
609
+ this.emit('joined');
610
+ this.joined = true;
611
+ }
612
+ else {
613
+ this.emit('error', res);
614
+ this.joined = false;
615
+ }
616
+ }
617
+ return this.joined;
618
+ }
619
+ async quit() {
620
+ const [res, error] = await this.jsBridge.callAndBackfeed('live/quit');
621
+ if (res === null) {
622
+ this.emit('error', error ? error : new Error('退出房间失败:未知异常。'));
623
+ }
624
+ this.joined = false;
625
+ return !!res;
626
+ }
627
+ async detectMicro() {
628
+ const [res, error] = await this.jsBridge.detectMicro();
629
+ if (res === null) {
630
+ this.emit('error', error ? error : new Error('麦克风监测异常!'));
631
+ return false;
632
+ }
633
+ return res;
634
+ }
635
+ async toggleMicro(flag) {
636
+ const [res, error] = await this.jsBridge.callAndBackfeed(`live/toggleMicro?flag=${!!flag ? 1 : 0}`);
637
+ if (res === null) {
638
+ this.emit('error', error ? error : new Error('麦克风监测异常!'));
639
+ return false;
640
+ }
641
+ this.micro = res;
642
+ return res;
643
+ }
644
+ shock() {
645
+ this.jsBridge.shock(1);
646
+ }
647
+ }
648
+
649
+ /**
650
+ * WebSocket 通信指令
651
+ * - 下行:服务端推送数据
652
+ * - 上行:客户端上报数据
653
+ */
654
+ exports.Command = void 0;
655
+ (function (Command) {
656
+ /* 当前用户信息:下行 */
657
+ Command["SelfUserInfo"] = "SELF_USER_INFO";
658
+ /* 房间信息:下行 */
659
+ Command["RoomInfo"] = "ROOM_INFO";
660
+ /* RTC信息:下行 */
661
+ Command["RTCInfo"] = "RTC_INFO";
662
+ /* 用户列表:下行 */
663
+ Command["UserList"] = "USER_LIST";
664
+ /* 内置消息:下行、上行 */
665
+ Command["BuiltinMsg"] = "BUILTIN_MSG";
666
+ /* 自定义广播事件消息:下行、上行 */
667
+ Command["CustomEvent"] = "CUSTOM_EVENT";
668
+ /* 帧数据同步:下行、上行 */
669
+ Command["KeyframeSync"] = "KEYFRAME_SYNC";
670
+ /* 被踢出房间:下行 */
671
+ Command["UserKickOut"] = "USER_KICK_OUT";
672
+ })(exports.Command || (exports.Command = {}));
673
+ /**
674
+ * 内置事件类型。
675
+ */
676
+ exports.BuiltinEventType = void 0;
677
+ (function (BuiltinEventType) {
678
+ /**
679
+ * 变更用户状态。
680
+ */
681
+ BuiltinEventType["UserChange"] = "user_change";
682
+ /**
683
+ * 变更房间状态。
684
+ */
685
+ BuiltinEventType["RoomChange"] = "room_change";
686
+ })(exports.BuiltinEventType || (exports.BuiltinEventType = {}));
687
+ /**
688
+ * 内置事件行为类型。
689
+ */
690
+ exports.BuiltinActionType = void 0;
691
+ (function (BuiltinActionType) {
692
+ /**
693
+ * 修改麦克风状态。
694
+ */
695
+ BuiltinActionType["UserMicroStatus"] = "change_micro_status";
696
+ /**
697
+ * 同步当前用户状态:客户端麦克风状态已经修改成功,通知服务端
698
+ */
699
+ BuiltinActionType["UserMicroStatusSync"] = "sync_micro_status";
700
+ /**
701
+ * 调整某些用户的权限。
702
+ */
703
+ BuiltinActionType["UserPermission"] = "change_permission";
704
+ /**
705
+ * 用户状态发生改变。
706
+ */
707
+ BuiltinActionType["UserStatus"] = "change_status";
708
+ /**
709
+ * 更新用户信息。
710
+ */
711
+ BuiltinActionType["UserInfo"] = "change_info";
712
+ /**
713
+ * 关闭房间。
714
+ */
715
+ BuiltinActionType["RoomClose"] = "close";
716
+ })(exports.BuiltinActionType || (exports.BuiltinActionType = {}));
717
+ /**
718
+ * 麦克风状态。
719
+ */
720
+ exports.MicroStatus = void 0;
721
+ (function (MicroStatus) {
722
+ MicroStatus["OPEN"] = "OPEN";
723
+ MicroStatus["CLOSE"] = "CLOSE";
724
+ })(exports.MicroStatus || (exports.MicroStatus = {}));
725
+ /**
726
+ * 解析下后端数据格式。
727
+ * @param jsonTxt - JSON序列化后的文本。
728
+ * @returns false 标识解析失败;解析成功返回 {@link LiveMsg} 实例。
729
+ */
730
+ function parseLiveMsg(jsonTxt) {
731
+ try {
732
+ const msg = JSON.parse(jsonTxt);
733
+ const resMsg = {
734
+ code: msg.code,
735
+ message: msg.message,
736
+ command: msg.command,
737
+ roomCode: msg.room_code,
738
+ appID: msg.app_id,
739
+ requestId: msg.request_id,
740
+ frontRequestId: msg.front_request_id,
741
+ triggerUserID: msg.trigger_user_id,
742
+ data: msg.data || {},
743
+ };
744
+ const undefinedKeys = Object.keys(resMsg).filter((key) => resMsg[key] === undefined);
745
+ if (undefinedKeys.length > 0) {
746
+ console.warn(`推送数据格式异常:${undefinedKeys.join(" ")} 值不存在!`);
747
+ }
748
+ return resMsg;
749
+ }
750
+ catch (error) {
751
+ // notcare? 过滤掉所有不符合规范的数据
752
+ return false;
753
+ }
754
+ }
755
+
756
+ /**
757
+ * 用户当前状态枚举。
758
+ */
759
+ exports.UserStatus = void 0;
760
+ (function (UserStatus) {
761
+ /**
762
+ * 正常
763
+ */
764
+ UserStatus[UserStatus["Normal"] = 0] = "Normal";
765
+ /**
766
+ * 被移除
767
+ */
768
+ UserStatus[UserStatus["Removed"] = 1] = "Removed";
769
+ /**
770
+ * 被替换
771
+ */
772
+ UserStatus[UserStatus["Replaced"] = 2] = "Replaced";
773
+ })(exports.UserStatus || (exports.UserStatus = {}));
774
+ exports.MemUserStatus = void 0;
775
+ (function (MemUserStatus) {
776
+ MemUserStatus["WAIT_ENTER"] = "WAIT_ENTER";
777
+ MemUserStatus["ONLINE"] = "ONLINE";
778
+ MemUserStatus["LEAVE"] = "LEAVE";
779
+ MemUserStatus["KICK_OUT"] = "KICK_OUT";
780
+ MemUserStatus["BE_REPLACE"] = "BE_REPLACE";
781
+ MemUserStatus["EXCEPTION"] = "EXCEPTION";
782
+ })(exports.MemUserStatus || (exports.MemUserStatus = {}));
783
+
784
+ /**
785
+ * WebSocket 连接状态枚举
786
+ */
787
+ exports.WebSocketState = void 0;
788
+ (function (WebSocketState) {
789
+ /**
790
+ * 尚未初始化
791
+ */
792
+ WebSocketState[WebSocketState["NOTINITIALIZED"] = -1] = "NOTINITIALIZED";
793
+ /**
794
+ * 正在链接中
795
+ */
796
+ WebSocketState[WebSocketState["CONNECTING"] = 0] = "CONNECTING";
797
+ /**
798
+ * 已经链接并且可以通讯
799
+ */
800
+ WebSocketState[WebSocketState["OPEN"] = 1] = "OPEN";
801
+ /**
802
+ * 连接正在关闭
803
+ */
804
+ WebSocketState[WebSocketState["CLOSING"] = 2] = "CLOSING";
805
+ /**
806
+ * 连接已关闭或者没有链接成功
807
+ */
808
+ WebSocketState[WebSocketState["CLOSED"] = 3] = "CLOSED";
809
+ })(exports.WebSocketState || (exports.WebSocketState = {}));
810
+ exports.WebSocketErrorType = void 0;
811
+ (function (WebSocketErrorType) {
812
+ WebSocketErrorType["Error"] = "Error";
813
+ WebSocketErrorType["Close"] = "Close";
814
+ WebSocketErrorType["MicroAuth"] = "MicroAuth";
815
+ WebSocketErrorType["DuplicateConnect"] = "DuplicateConnect";
816
+ WebSocketErrorType["IllegalURL"] = "IllegalURL";
817
+ WebSocketErrorType["Unknown"] = "Unknown";
818
+ WebSocketErrorType["IllegalArgs"] = "IllegalArgs";
819
+ })(exports.WebSocketErrorType || (exports.WebSocketErrorType = {}));
820
+ /**
821
+ * WebSocket 异常关闭枚举:https://developer.mozilla.org/zh-CN/docs/Web/API/CloseEvent。
822
+ */
823
+ exports.WebSocketCloseError = void 0;
824
+ (function (WebSocketCloseError) {
825
+ /**
826
+ * 终端离开, 可能因为服务端错误, 也可能因为浏览器正从打开连接的页面跳转离开。
827
+ */
828
+ WebSocketCloseError["Err_1001"] = "CLOSE_GOING_AWAY";
829
+ /**
830
+ * 由于协议错误而中断连接。
831
+ */
832
+ WebSocketCloseError["Err_1002"] = "CLOSE_PROTOCOL_ERROR";
833
+ /**
834
+ * 由于接收到不允许的数据类型而断开连接 (如仅接收文本数据的终端接收到了二进制数据)。
835
+ */
836
+ WebSocketCloseError["Err_1003"] = "CLOSE_UNSUPPORTED";
837
+ /**
838
+ * 安全因素或WebSocket连接次数达到上限。
839
+ */
840
+ WebSocketCloseError["Err_1006"] = "CLOSE_ABNORMAL";
841
+ /**
842
+ * 由于收到了格式不符的数据而断开连接 (如文本消息中包含了非 UTF-8 数据)。
843
+ */
844
+ WebSocketCloseError["Err_1007"] = "Unsupported Data";
845
+ /**
846
+ * 由于收到不符合约定的数据而断开连接。
847
+ */
848
+ WebSocketCloseError["Err_1008"] = "Policy Violation";
849
+ /**
850
+ * 由于收到过大的数据帧而断开连接。
851
+ */
852
+ WebSocketCloseError["Err_1009"] = "CLOSE_TOO_LARGE";
853
+ /**
854
+ * 未知错误。
855
+ */
856
+ WebSocketCloseError["Err_unknown"] = "unknown";
857
+ })(exports.WebSocketCloseError || (exports.WebSocketCloseError = {}));
858
+ function parseWSClsErr(code) {
859
+ switch (code) {
860
+ case 1001: {
861
+ return exports.WebSocketCloseError.Err_1001;
862
+ }
863
+ case 1002: {
864
+ return exports.WebSocketCloseError.Err_1002;
865
+ }
866
+ case 1003: {
867
+ return exports.WebSocketCloseError.Err_1003;
868
+ }
869
+ case 1006: {
870
+ return exports.WebSocketCloseError.Err_1006;
871
+ }
872
+ case 1007: {
873
+ return exports.WebSocketCloseError.Err_1007;
874
+ }
875
+ case 1008: {
876
+ return exports.WebSocketCloseError.Err_1008;
877
+ }
878
+ case 1009: {
879
+ return exports.WebSocketCloseError.Err_1009;
880
+ }
881
+ }
882
+ return exports.WebSocketCloseError.Err_unknown;
883
+ }
884
+
885
+ function appendUri(uri, query) {
886
+ const hasQuery = uri.indexOf('?') !== -1;
887
+ const newQuery = Object.keys(query).reduce((accu, curr, idx) => `${accu}${(idx === 0 && !hasQuery) ? '?' : '&'}${curr}=${query[curr]}`, '');
888
+ return uri + newQuery;
889
+ }
890
+
891
+ /**
892
+ * 判断是否是真实的对象类型
893
+ * @param value
894
+ * @returns
895
+ */
896
+ function isTrulyObject(value) {
897
+ return Object.prototype.toString.call(value) === '[object Object]';
898
+ }
899
+ /**
900
+ * 判断基础类型是否相等
901
+ * @param value
902
+ * @param other
903
+ * @returns
904
+ */
905
+ function baseIsEqual(value, other) {
906
+ if (value === other)
907
+ return true;
908
+ if (typeof value !== typeof other)
909
+ return false;
910
+ if (Number.isNaN(value) && Number.isNaN(other))
911
+ return true;
912
+ return false;
913
+ }
914
+ /**
915
+ * 对象浅比较
916
+ * @param value
917
+ * @param other
918
+ * @returns
919
+ */
920
+ function objEqualShallow(value, other) {
921
+ const valueProps = Object.getOwnPropertyNames(value);
922
+ const otherProps = Object.getOwnPropertyNames(other);
923
+ if (valueProps.length !== otherProps.length)
924
+ return false;
925
+ for (let i = 0, len = valueProps.length; i < len; i++) {
926
+ const propName = valueProps[i];
927
+ if (!baseIsEqual(value[propName], other[propName]))
928
+ return false;
929
+ }
930
+ return true;
931
+ }
932
+ /**
933
+ * 数组浅比较
934
+ * @param value
935
+ * @param other
936
+ * @returns
937
+ */
938
+ function arrayEqualShallow(value, other) {
939
+ if (value.length !== other.length)
940
+ return false;
941
+ for (let i = 0, len = value.length; i < len; i++) {
942
+ if (!baseIsEqual(value[i], other[i]))
943
+ return false;
944
+ }
945
+ return true;
946
+ }
947
+ /**
948
+ * 变量浅比较
949
+ * @param value
950
+ * @param other
951
+ * @returns
952
+ */
953
+ function isShallowEqual(value, other) {
954
+ if (baseIsEqual(value, other))
955
+ return true;
956
+ if (isTrulyObject(value) && isTrulyObject(other))
957
+ return objEqualShallow(value, other);
958
+ if (Array.isArray(value) && Array.isArray(other))
959
+ return arrayEqualShallow(value, other);
960
+ return false;
961
+ }
962
+ /**
963
+ * 对象深比较
964
+ * @param value
965
+ * @param other
966
+ * @returns
967
+ */
968
+ function isDeepEqual(value, other) {
969
+ if (baseIsEqual(value, other))
970
+ return true;
971
+ if (isTrulyObject(value) && isTrulyObject(other))
972
+ return objEqualDeep(value, other);
973
+ if (Array.isArray(value) && Array.isArray(other))
974
+ return arrayEqualDeep(value, other);
975
+ return false;
976
+ }
977
+ /**
978
+ * 数组深比较
979
+ * @param value
980
+ * @param other
981
+ * @returns
982
+ */
983
+ function arrayEqualDeep(value, other) {
984
+ if (value.length !== other.length)
985
+ return false;
986
+ for (let i = 0, len = value.length; i < len; i++) {
987
+ if (!isDeepEqual(value[i], other[i]))
988
+ return false;
989
+ }
990
+ return true;
991
+ }
992
+ /**
993
+ * 对象深比较
994
+ * @param value
995
+ * @param other
996
+ * @returns
997
+ */
998
+ function objEqualDeep(value, other) {
999
+ const valueProps = Object.getOwnPropertyNames(value);
1000
+ const otherProps = Object.getOwnPropertyNames(other);
1001
+ if (valueProps.length !== otherProps.length)
1002
+ return false;
1003
+ for (let i = 0, len = valueProps.length; i < len; i++) {
1004
+ const propName = valueProps[i];
1005
+ if (!isDeepEqual(value[propName], other[propName]))
1006
+ return false;
1007
+ }
1008
+ return true;
1009
+ }
1010
+ /**
1011
+ * 对象比较。
1012
+ * @param value 第一个比较的值。
1013
+ * @param other 第二个比较的值。
1014
+ * @param options 可选参数,可选项:`deep` 是否深比较。
1015
+ * @returns {boolean} 是否相等。
1016
+ */
1017
+ function equal(value, other, opt) {
1018
+ if (!opt.deep)
1019
+ return isShallowEqual(value, other);
1020
+ return isDeepEqual(value, other);
1021
+ }
1022
+
1023
+ class LiveController {
1024
+ constructor(options) {
1025
+ this.readyState = exports.WebSocketState.NOTINITIALIZED;
1026
+ this.canSync = true;
1027
+ this.connecting = false;
1028
+ this.keyframes = {};
1029
+ /**
1030
+ * 检测 WebSocket.readyState 状态
1031
+ */
1032
+ this.checkReadyState = (live) => {
1033
+ do {
1034
+ if (!this.webSocket) {
1035
+ if (this.readyState !== exports.WebSocketState.NOTINITIALIZED) {
1036
+ this.readyState = exports.WebSocketState.NOTINITIALIZED;
1037
+ live.emit('ws.readyStateUpdate', this.readyState);
1038
+ }
1039
+ break;
1040
+ }
1041
+ const readyState = this.webSocket.readyState;
1042
+ if (readyState !== this.readyState) {
1043
+ this.readyState = readyState;
1044
+ live.emit('ws.readyStateUpdate', this.readyState);
1045
+ }
1046
+ } while (false);
1047
+ return this.readyState;
1048
+ };
1049
+ this.dispose = () => {
1050
+ this.disposeWebSocket();
1051
+ this.connecting = false;
1052
+ if (this.healthCheckId) {
1053
+ clearInterval(this.healthCheckId);
1054
+ this.healthCheckId = undefined;
1055
+ }
1056
+ };
1057
+ /**
1058
+ * 销毁WebSocket相关依赖。
1059
+ */
1060
+ this.disposeWebSocket = () => {
1061
+ if (!this.webSocket)
1062
+ return;
1063
+ if (this.onEvtOpnListener) {
1064
+ this.webSocket.removeEventListener('open', this.onEvtOpnListener);
1065
+ this.onEvtOpnListener = undefined;
1066
+ }
1067
+ if (this.onEvtMsgListener) {
1068
+ this.webSocket.removeEventListener('message', this.onEvtMsgListener);
1069
+ this.onEvtMsgListener = undefined;
1070
+ }
1071
+ if (this.onEvtErrListener) {
1072
+ this.webSocket.removeEventListener('error', this.onEvtErrListener);
1073
+ this.onEvtErrListener = undefined;
1074
+ }
1075
+ if (this.onEvtCLEListener) {
1076
+ this.webSocket.removeEventListener('close', this.onEvtCLEListener);
1077
+ this.onEvtCLEListener = undefined;
1078
+ }
1079
+ this.webSocket.close();
1080
+ this.webSocket = undefined;
1081
+ };
1082
+ this.options = Object.assign({ autoConnect: true, healthCheck: 3000 }, options);
1083
+ }
1084
+ /**
1085
+ * 解析数据
1086
+ * @param liveMsg
1087
+ * @param live
1088
+ */
1089
+ handleMessage(liveMsg, live) {
1090
+ var _a, _b, _c;
1091
+ const { command, data, frontRequestId, code, message } = liveMsg;
1092
+ if (code === 'SUCCESS') {
1093
+ switch (command) {
1094
+ /**
1095
+ * 自己的状态变化
1096
+ */
1097
+ case exports.Command.SelfUserInfo: {
1098
+ const selfInfo = data;
1099
+ if (equal(this.selfUserInfo, selfInfo, { deep: true }))
1100
+ return;
1101
+ this.selfUserInfo = selfInfo;
1102
+ live.emit('selfInfoUpdate', this.selfUserInfo, frontRequestId);
1103
+ break;
1104
+ }
1105
+ /**
1106
+ * 房间信息变化
1107
+ */
1108
+ case exports.Command.RoomInfo: {
1109
+ const roomInfo = data;
1110
+ this.roomInfo = Object.assign({}, roomInfo);
1111
+ live.emit('readyKeyframeSync', (roomInfo.last_frame || {}));
1112
+ break;
1113
+ }
1114
+ /**
1115
+ * 语音信息变化
1116
+ */
1117
+ case exports.Command.RTCInfo: {
1118
+ const { voice_id: voiceId, type } = data;
1119
+ /* 如果已经进入语音房间,则不重复进入 --> "RTCInfo" 指令可能会下发多次 */
1120
+ if (live.$RTC.joined) {
1121
+ break;
1122
+ }
1123
+ live.$RTC.join({
1124
+ voiceId,
1125
+ userId: ((_a = this.selfUserInfo) === null || _a === void 0 ? void 0 : _a.id) || '',
1126
+ roomId: (_b = this.roomInfo) === null || _b === void 0 ? void 0 : _b.info.room_code,
1127
+ type,
1128
+ });
1129
+ // 加入房间后 麦克风默认就开启了:需要发个指令。
1130
+ live.updateStatus(exports.BuiltinEventType.UserChange, exports.BuiltinActionType.UserMicroStatus, {
1131
+ status: exports.MicroStatus.OPEN,
1132
+ });
1133
+ break;
1134
+ }
1135
+ /**
1136
+ * 房间用户列表变化
1137
+ */
1138
+ case exports.Command.UserList: {
1139
+ const userList = data;
1140
+ this.userList = userList;
1141
+ live.emit('userListUpdate', this.userList, frontRequestId);
1142
+ break;
1143
+ }
1144
+ /**
1145
+ * 自定义事件广播
1146
+ */
1147
+ case exports.Command.CustomEvent: {
1148
+ const evtMsg = data;
1149
+ live.emit('broadcast', evtMsg, frontRequestId);
1150
+ break;
1151
+ }
1152
+ /**
1153
+ * 帧数据同步
1154
+ */
1155
+ case exports.Command.KeyframeSync: {
1156
+ const remoteKeyframes = data;
1157
+ // 此处做一层 diff,仅跟本地数据不一致的情况下才广播数据。
1158
+ const keyframes = Object.keys(remoteKeyframes).reduce((accu, curr) => {
1159
+ if (equal(remoteKeyframes[curr], this.keyframes[curr], { deep: true })) {
1160
+ return accu;
1161
+ }
1162
+ const params = [
1163
+ remoteKeyframes[curr],
1164
+ this.keyframes[curr],
1165
+ frontRequestId,
1166
+ ];
1167
+ const evtName = curr;
1168
+ live.keyframes.emit(evtName, ...params);
1169
+ this.keyframes[curr] = remoteKeyframes[curr];
1170
+ accu[curr] = remoteKeyframes[curr];
1171
+ return accu;
1172
+ }, {});
1173
+ live.emit('keyframes', keyframes, frontRequestId);
1174
+ break;
1175
+ }
1176
+ /**
1177
+ * 内置消息
1178
+ */
1179
+ case exports.Command.BuiltinMsg: {
1180
+ const builtinMsg = data;
1181
+ live.emit('builtinEvent', builtinMsg);
1182
+ if (builtinMsg.event_type === exports.BuiltinEventType.UserChange) {
1183
+ live.emit('userChange', builtinMsg);
1184
+ }
1185
+ if (builtinMsg.event_type === exports.BuiltinEventType.RoomChange) {
1186
+ live.emit('roomChange', builtinMsg);
1187
+ }
1188
+ /**
1189
+ * 下发指令自己操作麦克风
1190
+ */
1191
+ if (builtinMsg.event_type === exports.BuiltinEventType.UserChange &&
1192
+ builtinMsg.action === exports.BuiltinActionType.UserMicroStatus) {
1193
+ live.toggleMicro(builtinMsg.data.status === exports.MicroStatus.OPEN);
1194
+ }
1195
+ /**
1196
+ * 如果下发指令退出房间,则 关闭麦克风 及 销毁 WebSocket
1197
+ */
1198
+ if (builtinMsg.event_type === exports.BuiltinEventType.RoomChange &&
1199
+ builtinMsg.action === exports.BuiltinActionType.RoomClose) {
1200
+ (_c = this.options.rtc) === null || _c === void 0 ? void 0 : _c.quit();
1201
+ this.disposeWebSocket();
1202
+ }
1203
+ break;
1204
+ }
1205
+ /**
1206
+ * 被踢出房间
1207
+ */
1208
+ case exports.Command.UserKickOut: {
1209
+ live.emit('kickOut');
1210
+ break;
1211
+ }
1212
+ /**
1213
+ * 其它未知广播
1214
+ */
1215
+ default: {
1216
+ console.warn('unknown command: ', command);
1217
+ }
1218
+ }
1219
+ }
1220
+ else {
1221
+ live.emit('error', liveMsg);
1222
+ }
1223
+ }
1224
+ /**
1225
+ * 发送数据
1226
+ * @param data
1227
+ */
1228
+ sendMessage(data) {
1229
+ if (!this.webSocket)
1230
+ return console.warn('WebSocket has not yet been initialized!');
1231
+ if (!data)
1232
+ return console.warn('WebSocket messages is empty!');
1233
+ this.webSocket.send(JSON.stringify(data));
1234
+ }
1235
+ }
1236
+
1237
+ const unimplementedGetVoiceSign = (params) => Promise.reject('unimplemented method GetVoiceSign');
1238
+ /**
1239
+ * 创建 `live` 实例。
1240
+ */
1241
+ function createLive(options) {
1242
+ const liveController = new LiveController(options);
1243
+ const createLiveMsg = (command, data = {}, toUserIds) => {
1244
+ toUserIds = toUserIds
1245
+ ? Array.isArray(toUserIds)
1246
+ ? toUserIds
1247
+ : [toUserIds]
1248
+ : [];
1249
+ if (toUserIds)
1250
+ data['to_user_ids'] = toUserIds;
1251
+ return { command, front_request_id: uuid(), data };
1252
+ };
1253
+ class LiveTpl extends Subscribe {
1254
+ constructor() {
1255
+ var _a;
1256
+ super();
1257
+ this.keyframes = new Subscribe();
1258
+ // 没有传rtc实例时
1259
+ if (!options.rtc) {
1260
+ // 取指定的内部rtc类型
1261
+ if (options.rtcType) {
1262
+ if (!options.getVoiceSign) {
1263
+ throw new Error('GetVoiceSign method must be passed when using built-in RTC instances');
1264
+ }
1265
+ const getVoiceSign = (_a = options.getVoiceSign) !== null && _a !== void 0 ? _a : unimplementedGetVoiceSign;
1266
+ switch (options.rtcType) {
1267
+ case exports.RTCType.RealseeVRWebViewRTC: {
1268
+ // 内置的 VRWebViewRTC
1269
+ if (!options.jsBridge) {
1270
+ throw new Error('JsBridge instance must be passed when using built-in VRWebViewRTC instances');
1271
+ }
1272
+ liveController.options.rtc = new VRWebViewRTC({
1273
+ jsBridge: options.jsBridge,
1274
+ getVoiceSign,
1275
+ });
1276
+ break;
1277
+ }
1278
+ case exports.RTCType.RealseeBrowserChimeRTC: {
1279
+ // 内置的 RealseeBrowserChimeRTC
1280
+ liveController.options.rtc = new BrowserRTC4Chime({
1281
+ getVoiceSign,
1282
+ logLevel: options.__debug__ ? amazonChimeSdkJs.LogLevel.DEBUG : amazonChimeSdkJs.LogLevel.ERROR,
1283
+ });
1284
+ break;
1285
+ }
1286
+ case exports.RTCType.RealseeBrowserRTC: {
1287
+ // 内置的 RealseeBrowserRTC
1288
+ liveController.options.rtc = new BrowserRTC({
1289
+ getVoiceSign,
1290
+ });
1291
+ break;
1292
+ }
1293
+ default: {
1294
+ throw new Error('unknown built-in RTC type');
1295
+ }
1296
+ }
1297
+ }
1298
+ }
1299
+ if (!liveController.options.rtc) {
1300
+ console.warn('unused rtc');
1301
+ }
1302
+ // 默认自动连接
1303
+ if (liveController.options.url && liveController.options.getTicket) {
1304
+ this.connect();
1305
+ }
1306
+ // 健康检查:WHY --> 在某些WebView特殊场景下 WebSocket.readyState 发生变化时不会出发error\close等事件;
1307
+ // 因此,开启一个定时任务监测 WebSocket.readyState 状态的更新
1308
+ const healthCheck = ((healthCheck) => {
1309
+ if (!healthCheck)
1310
+ return 0;
1311
+ if (healthCheck === true)
1312
+ return 3000;
1313
+ const duration = Number(healthCheck);
1314
+ if (duration > 0)
1315
+ return duration;
1316
+ return 3000;
1317
+ })(liveController.options.healthCheck);
1318
+ if (healthCheck) {
1319
+ liveController.healthCheckId = setInterval(() => liveController.checkReadyState(this), healthCheck);
1320
+ }
1321
+ }
1322
+ get options() {
1323
+ return Object.freeze(Object.assign({}, liveController.options));
1324
+ }
1325
+ get readyState() {
1326
+ liveController.checkReadyState(this);
1327
+ return liveController.readyState;
1328
+ }
1329
+ get url() {
1330
+ var _a;
1331
+ return ((_a = liveController.webSocket) === null || _a === void 0 ? void 0 : _a.url) || '';
1332
+ }
1333
+ get selfInfo() {
1334
+ return liveController.selfUserInfo;
1335
+ }
1336
+ get userList() {
1337
+ return liveController.userList || [];
1338
+ }
1339
+ get snapshot() {
1340
+ return liveController.keyframes || {};
1341
+ }
1342
+ get $RTC() {
1343
+ return liveController.options.rtc;
1344
+ }
1345
+ async setSelfInfo(userInfo) {
1346
+ if (this.readyState !== exports.WebSocketState.OPEN) {
1347
+ return new Error('The connection is not open and ready to communicate.');
1348
+ }
1349
+ try {
1350
+ return await this.updateStatus(exports.BuiltinEventType.UserChange, exports.BuiltinActionType.UserInfo, userInfo);
1351
+ }
1352
+ catch (error) {
1353
+ return error;
1354
+ }
1355
+ }
1356
+ getFramesByKey(key) {
1357
+ return liveController.keyframes[key];
1358
+ }
1359
+ sendKeyframe(key, frame) {
1360
+ if (this.readyState !== exports.WebSocketState.OPEN) {
1361
+ return new Error('The connection is not open and ready to communicate.');
1362
+ }
1363
+ liveController.keyframes[key] = frame;
1364
+ const liveMsg = createLiveMsg(exports.Command.KeyframeSync, this.snapshot);
1365
+ liveController.sendMessage(liveMsg);
1366
+ return true;
1367
+ }
1368
+ broadcast(data, toUserIds, timeout) {
1369
+ if (this.readyState !== exports.WebSocketState.OPEN) {
1370
+ return new Error('The connection is not open and ready to communicate.');
1371
+ }
1372
+ return new Promise((resolve, reject) => {
1373
+ const customEvent = createLiveMsg(exports.Command.CustomEvent, data, toUserIds);
1374
+ const front_request_id = customEvent.front_request_id;
1375
+ liveController.sendMessage(customEvent);
1376
+ const timeoutId = timeout
1377
+ ? setTimeout(() => {
1378
+ reject(new Error('RESPONSE TIMEOUT'));
1379
+ this.off('broadcast', broadcast);
1380
+ }, timeout)
1381
+ : undefined;
1382
+ const broadcast = (data, frontRequestId) => {
1383
+ if (frontRequestId !== front_request_id)
1384
+ return;
1385
+ this.off('broadcast', broadcast);
1386
+ resolve(data);
1387
+ if (timeoutId)
1388
+ clearInterval(timeoutId);
1389
+ };
1390
+ this.on('broadcast', broadcast);
1391
+ });
1392
+ }
1393
+ async updateStatus(evtType, atnType, status, toUserIds) {
1394
+ // TODO 统一规则,不能联合类型
1395
+ if (this.readyState !== exports.WebSocketState.OPEN) {
1396
+ return false;
1397
+ }
1398
+ const data = Object.assign({ event_type: evtType, action: atnType }, { data: status });
1399
+ const liveMsg = createLiveMsg(exports.Command.BuiltinMsg, data, toUserIds);
1400
+ liveController.sendMessage(liveMsg);
1401
+ return true;
1402
+ }
1403
+ // 仅用于用户自己的麦克风控制
1404
+ async toggleMicro(microStatus) {
1405
+ var _a, _b;
1406
+ if (!((_b = (_a = this.selfInfo) === null || _a === void 0 ? void 0 : _a.permission) === null || _b === void 0 ? void 0 : _b.control_own_micro))
1407
+ return false;
1408
+ await this.$RTC.toggleMicro(microStatus);
1409
+ return await this.updateStatus(exports.BuiltinEventType.UserChange, exports.BuiltinActionType.UserMicroStatus, {
1410
+ status: microStatus ? exports.MicroStatus.OPEN : exports.MicroStatus.CLOSE,
1411
+ }, []);
1412
+ }
1413
+ async forbidMicro(microStatus, toUserIds) {
1414
+ var _a, _b;
1415
+ if (liveController.options.canForbidUserMicro &&
1416
+ !liveController.options.canForbidUserMicro(toUserIds)) {
1417
+ return false;
1418
+ }
1419
+ if (!((_b = (_a = this.selfInfo) === null || _a === void 0 ? void 0 : _a.permission) === null || _b === void 0 ? void 0 : _b.control_other_micro)) {
1420
+ return false;
1421
+ }
1422
+ return await this.updateStatus(exports.BuiltinEventType.UserChange, exports.BuiltinActionType.UserMicroStatus, {
1423
+ status: microStatus,
1424
+ }, toUserIds);
1425
+ }
1426
+ /**
1427
+ * @deprecated 暂不可用
1428
+ */
1429
+ async forbidSync(sync, toUserIds) {
1430
+ var _a, _b;
1431
+ if (liveController.options.canForbidUserSync &&
1432
+ !liveController.options.canForbidUserSync(toUserIds)) {
1433
+ return false;
1434
+ }
1435
+ if (!((_b = (_a = this.selfInfo) === null || _a === void 0 ? void 0 : _a.permission) === null || _b === void 0 ? void 0 : _b.control_other_sync)) {
1436
+ return false;
1437
+ }
1438
+ return await this.updateStatus(exports.BuiltinEventType.UserChange, exports.BuiltinActionType.UserPermission, { sync_frame: sync }, toUserIds);
1439
+ }
1440
+ async kick(toUserIds) {
1441
+ var _a, _b;
1442
+ if (liveController.options.canForbidUserKick &&
1443
+ !liveController.options.canForbidUserKick(toUserIds)) {
1444
+ return false;
1445
+ }
1446
+ if (!((_b = (_a = this.selfInfo) === null || _a === void 0 ? void 0 : _a.permission) === null || _b === void 0 ? void 0 : _b.change_other_status)) {
1447
+ return false;
1448
+ }
1449
+ return await this.updateStatus(exports.BuiltinEventType.UserChange, exports.BuiltinActionType.UserStatus, {
1450
+ status: 'KICK_OUT',
1451
+ }, toUserIds);
1452
+ }
1453
+ async exit() {
1454
+ /** 退出强制关闭语音(?) */
1455
+ await this.$RTC.quit();
1456
+ return await this.updateStatus(exports.BuiltinEventType.RoomChange, exports.BuiltinActionType.RoomClose, {});
1457
+ }
1458
+ async connect(options = {}) {
1459
+ // 连接 WebSocket 前验证麦克风权限
1460
+ const microAuth = await this.$RTC.detectMicro();
1461
+ if (!microAuth) {
1462
+ const error = new Error('系统监测麦克风未授权~');
1463
+ this.emit('ws.error', { type: exports.WebSocketErrorType.MicroAuth, error });
1464
+ return error;
1465
+ }
1466
+ // WebSocket 正在连接中,规避重复连接
1467
+ if (liveController.connecting) {
1468
+ const error = new Error('WebSocket 正在连接中,请勿重复连接 ...');
1469
+ this.emit('ws.error', {
1470
+ type: exports.WebSocketErrorType.DuplicateConnect,
1471
+ error,
1472
+ });
1473
+ return error;
1474
+ }
1475
+ // 非强制连接场景下,如果已经完成 WebSocket 连接则不执行后续逻辑
1476
+ const { force } = options;
1477
+ if (!force) {
1478
+ if (this.readyState === exports.WebSocketState.CONNECTING ||
1479
+ this.readyState === exports.WebSocketState.OPEN) {
1480
+ return true;
1481
+ }
1482
+ }
1483
+ // WebSocket URL 逻辑
1484
+ if (options.url) {
1485
+ liveController.options.url = options.url;
1486
+ }
1487
+ if (options.getTicket) {
1488
+ liveController.options.getTicket = options.getTicket;
1489
+ }
1490
+ if (!liveController.options.url ||
1491
+ !liveController.options.url.startsWith('ws')) {
1492
+ const error = new Error(`WebSocket URL 未配置或格式不合法:"${liveController.options.url}"`);
1493
+ this.emit('ws.error', { type: exports.WebSocketErrorType.IllegalURL, error });
1494
+ return error;
1495
+ }
1496
+ if (!liveController.options.getTicket) {
1497
+ const error = new Error(`getTicket() 未配置!`);
1498
+ this.emit('ws.error', { type: exports.WebSocketErrorType.IllegalArgs, error });
1499
+ return error;
1500
+ }
1501
+ // 连接锁
1502
+ liveController.connecting = true;
1503
+ // 连接前销毁之前绑定的事件
1504
+ liveController.disposeWebSocket();
1505
+ this.emit('ws.beforeConnect');
1506
+ const url = force || options.url || !this.url
1507
+ ? appendUri(liveController.options.url, {
1508
+ ticket: await liveController.options.getTicket(),
1509
+ force: Number(!!force),
1510
+ })
1511
+ : this.url;
1512
+ liveController.webSocket = new WebSocket(url);
1513
+ liveController.onEvtOpnListener = () => {
1514
+ liveController.checkReadyState(this);
1515
+ this.emit('ws.afterConnect');
1516
+ };
1517
+ liveController.onEvtMsgListener = (evt) => {
1518
+ liveController.checkReadyState(this);
1519
+ try {
1520
+ const liveMsg = parseLiveMsg(evt.data);
1521
+ if (liveMsg === false)
1522
+ return;
1523
+ liveController.handleMessage(liveMsg, this);
1524
+ }
1525
+ catch (error) {
1526
+ // 未知错误
1527
+ this.emit('ws.error', {
1528
+ type: exports.WebSocketErrorType.Unknown,
1529
+ error,
1530
+ target: evt,
1531
+ });
1532
+ }
1533
+ };
1534
+ liveController.onEvtErrListener = (evt) => {
1535
+ live.emit('ws.error', { type: exports.WebSocketErrorType.Error, target: evt });
1536
+ liveController.checkReadyState(this);
1537
+ };
1538
+ liveController.onEvtCLEListener = (evt) => {
1539
+ liveController.checkReadyState(this);
1540
+ const code = Number(evt.code);
1541
+ if (code === 1000)
1542
+ return;
1543
+ // 异常退出不一定会触发'error'事件,根据 evt.code 一些类型的退出也算是 error 行为
1544
+ const errMsg = parseWSClsErr(code);
1545
+ live.emit('ws.error', {
1546
+ target: evt,
1547
+ type: exports.WebSocketErrorType.Close,
1548
+ closeError: errMsg,
1549
+ });
1550
+ };
1551
+ liveController.webSocket.addEventListener('open', liveController.onEvtOpnListener);
1552
+ liveController.webSocket.addEventListener('message', liveController.onEvtMsgListener);
1553
+ liveController.webSocket.addEventListener('error', liveController.onEvtErrListener);
1554
+ liveController.webSocket.addEventListener('close', liveController.onEvtCLEListener);
1555
+ return await new Promise((resolve, reject) => {
1556
+ const success = () => {
1557
+ resolve(true);
1558
+ liveController.connecting = false;
1559
+ this.off('ws.error', fail);
1560
+ };
1561
+ const fail = (error) => {
1562
+ reject(error.error
1563
+ ? error.error
1564
+ : new Error('WebSocket connection failed!'));
1565
+ liveController.connecting = false;
1566
+ this.off('ws.afterConnect', success);
1567
+ };
1568
+ this.once('ws.afterConnect', success);
1569
+ this.once('ws.error', fail);
1570
+ });
1571
+ }
1572
+ async revoke() {
1573
+ return true;
1574
+ }
1575
+ }
1576
+ const live = new LiveTpl();
1577
+ // 如果是调试环境则将内部状态暴露出来
1578
+ if (options.__debug__) {
1579
+ Object.assign(live, { __controller__: liveController });
1580
+ Object.assign(window, { $live: live });
1581
+ }
1582
+ return live;
1583
+ }
1584
+
1585
+ /**
1586
+ * 创建 {@link LiveReact} 实例,并提供 `React` 技术栈相关工具链。
1587
+ */
1588
+ function createLiveReact(options) {
1589
+ const LiveContext = React__default["default"].createContext(null);
1590
+ const live = createLive(options);
1591
+ function LiveProvider(props) {
1592
+ return (React__default["default"].createElement(LiveContext.Provider, { value: props.live || live }, props.children));
1593
+ }
1594
+ function useLiveInstance() {
1595
+ const context = React__default["default"].useContext(LiveContext);
1596
+ if (!context)
1597
+ throw new Error('LiveProvider never found.');
1598
+ return context;
1599
+ }
1600
+ /**
1601
+ * @deprecated
1602
+ * @returns
1603
+ */
1604
+ function unsafe__useLiveInstance() {
1605
+ return useLiveInstance();
1606
+ }
1607
+ function useRTCInstance() {
1608
+ const live = useLiveInstance();
1609
+ return live.$RTC;
1610
+ }
1611
+ /**
1612
+ * @deprecated
1613
+ * @returns
1614
+ */
1615
+ function unsafe__useRTCInstance() {
1616
+ return useRTCInstance();
1617
+ }
1618
+ function useConnect() {
1619
+ const live = useLiveInstance();
1620
+ return async (options) => await live.connect(options);
1621
+ }
1622
+ function useCurrentWebSocketUrl() {
1623
+ const live = useLiveInstance();
1624
+ const [state, setState] = React__default["default"].useState(undefined);
1625
+ React__default["default"].useEffect(() => {
1626
+ const onWSBeforeConnect = () => setState(live.url);
1627
+ live.on('ws.beforeConnect', onWSBeforeConnect);
1628
+ return () => live.off('ws.beforeConnect', onWSBeforeConnect);
1629
+ }, [live]);
1630
+ return state;
1631
+ }
1632
+ function useKeyframeUpdateCallback(name, callback, deps = []) {
1633
+ const live = useLiveInstance();
1634
+ const dependencyList = [live, name, ...deps];
1635
+ const dispose = () => live.keyframes.off(name, callback);
1636
+ React__default["default"].useEffect(() => {
1637
+ live.keyframes.on(name, callback);
1638
+ return dispose;
1639
+ }, dependencyList);
1640
+ return dispose;
1641
+ }
1642
+ function useLiveAction() {
1643
+ const live = useLiveInstance();
1644
+ const toggleMicro = React__default["default"].useCallback((microStatus) => live.toggleMicro(microStatus), [live]);
1645
+ const broadcast = React__default["default"].useCallback((data, toUserIds, timeout = 0) => live.broadcast(data, toUserIds, timeout), [live]);
1646
+ const exit = React__default["default"].useCallback(() => live.exit(), [live]);
1647
+ const kick = React__default["default"].useCallback((toUserIds) => live.kick(toUserIds), [live]);
1648
+ const forbidMicro = React__default["default"].useCallback((micro, toUserIds) => live.forbidMicro(micro, toUserIds), [live]);
1649
+ // const forbidSync = React.useCallback(
1650
+ // (sync: boolean, toUserIds?: string | string[] | undefined) =>
1651
+ // live.forbidSync(sync, toUserIds),
1652
+ // [live],
1653
+ // );
1654
+ const getFramesByKey = React__default["default"].useCallback((key) => live.getFramesByKey(key), [live]);
1655
+ const sendKeyframe = React__default["default"].useCallback((key, frame) => live.sendKeyframe(key, frame), [live]);
1656
+ const setSelfInfo = React__default["default"].useCallback((userInfo) => live.setSelfInfo(userInfo), [live]);
1657
+ const updateStatus = React__default["default"].useCallback((evtType, atnType, status, toUserIds) => live.updateStatus(evtType, atnType, status, toUserIds), [live]);
1658
+ return {
1659
+ broadcast,
1660
+ exit,
1661
+ kick,
1662
+ toggleMicro,
1663
+ forbidMicro,
1664
+ // forbidSync,
1665
+ sendKeyframe,
1666
+ getFramesByKey,
1667
+ setSelfInfo,
1668
+ updateStatus,
1669
+ };
1670
+ }
1671
+ function useKeyframe(key) {
1672
+ const live = useLiveInstance();
1673
+ const [state, updateState] = React__default["default"].useState(live.getFramesByKey(key));
1674
+ React__default["default"].useEffect(() => {
1675
+ const onUpdate = (nextKeyframes) => updateState(nextKeyframes);
1676
+ const evtName = key;
1677
+ const callback = onUpdate;
1678
+ live.keyframes.on(evtName, callback);
1679
+ return () => live.keyframes.off(evtName, callback);
1680
+ }, [live]);
1681
+ const setState = React__default["default"].useCallback((frame) => live.sendKeyframe(key, frame), [live]);
1682
+ return [state, setState];
1683
+ }
1684
+ function useLiveEventCallback(name, callback, deps = []) {
1685
+ const live = useLiveInstance();
1686
+ const dispose = () => live.off(name, callback);
1687
+ const dependencyList = [live, name, ...deps];
1688
+ React__default["default"].useEffect(() => {
1689
+ live.on(name, callback);
1690
+ return dispose;
1691
+ }, dependencyList);
1692
+ return dispose;
1693
+ }
1694
+ /**
1695
+ * @deprecated
1696
+ * @returns
1697
+ */
1698
+ function useReadyState() {
1699
+ const live = useLiveInstance();
1700
+ const [state, updateState] = React__default["default"].useState(live.readyState);
1701
+ React__default["default"].useEffect(() => {
1702
+ const readyStateUpdate = (readyState) => updateState(readyState);
1703
+ live.on('ws.readyStateUpdate', readyStateUpdate);
1704
+ return () => live.off('ws.readyStateUpdate', readyStateUpdate);
1705
+ }, [live]);
1706
+ return state;
1707
+ }
1708
+ function useRTCAction() {
1709
+ const live = useLiveInstance();
1710
+ const join = React__default["default"].useCallback((options) => live.$RTC.join(options), [live]);
1711
+ const quit = React__default["default"].useCallback(() => live.$RTC.quit(), [live]);
1712
+ const shock = React__default["default"].useCallback(() => { var _a, _b; return (_b = (_a = live.$RTC).shock) === null || _b === void 0 ? void 0 : _b.call(_a); }, [live]);
1713
+ const toggleMicro = React__default["default"].useCallback((flag) => live.$RTC.toggleMicro(flag), [live]);
1714
+ const detectMicro = React__default["default"].useCallback(() => live.$RTC.detectMicro(), [live]);
1715
+ return {
1716
+ join,
1717
+ quit,
1718
+ shock,
1719
+ toggleMicro,
1720
+ detectMicro,
1721
+ };
1722
+ }
1723
+ function useRTCEventCallback(name, callback, deps = []) {
1724
+ const live = useLiveInstance();
1725
+ const dispose = () => live.$RTC.off(name, callback);
1726
+ const dependencyList = [live, name, ...deps];
1727
+ React__default["default"].useEffect(() => {
1728
+ live.$RTC.on(name, callback);
1729
+ return dispose;
1730
+ }, dependencyList);
1731
+ return dispose;
1732
+ }
1733
+ function useSelfInfo() {
1734
+ const live = useLiveInstance();
1735
+ const [state, updateState] = React__default["default"].useState(live.selfInfo || {});
1736
+ const selfInfoUpdate = (userInfo) => updateState(userInfo);
1737
+ React__default["default"].useEffect(() => {
1738
+ live.on('selfInfoUpdate', selfInfoUpdate);
1739
+ return () => live.off('selfInfoUpdate', selfInfoUpdate);
1740
+ }, [live]);
1741
+ const setState = React__default["default"].useCallback(async (userInfo) => {
1742
+ return await live.setSelfInfo(userInfo);
1743
+ }, [live]);
1744
+ return [state, setState];
1745
+ }
1746
+ function useSnapshot() {
1747
+ const live = useLiveInstance();
1748
+ const [state, setState] = React__default["default"].useState(live.snapshot);
1749
+ React__default["default"].useEffect(() => {
1750
+ const onKeyframes = (keyframes) => setState(keyframes);
1751
+ live.on('keyframes', onKeyframes);
1752
+ return () => live.off('keyframes', onKeyframes);
1753
+ });
1754
+ return state;
1755
+ }
1756
+ function useUserList() {
1757
+ const live = useLiveInstance();
1758
+ const [state, updateState] = React__default["default"].useState(live.userList);
1759
+ const userListUpdate = (userList) => updateState(userList);
1760
+ React__default["default"].useEffect(() => {
1761
+ live.on('userListUpdate', userListUpdate);
1762
+ return () => live.off('userListUpdate', userListUpdate);
1763
+ }, [live]);
1764
+ return state;
1765
+ }
1766
+ /**
1767
+ *
1768
+ * @param name
1769
+ * @param callback
1770
+ * @param deps
1771
+ * @returns
1772
+ * @deprecated
1773
+ */
1774
+ function useWebSocketEventCallback(name, callback, deps = []) {
1775
+ const live = useLiveInstance();
1776
+ const dispose = () => live.off(name, callback);
1777
+ const dependencyList = [live, name, ...deps];
1778
+ React__default["default"].useEffect(() => {
1779
+ live.on(name, callback);
1780
+ return dispose;
1781
+ }, dependencyList);
1782
+ return dispose;
1783
+ }
1784
+ return {
1785
+ live,
1786
+ LiveProvider,
1787
+ unsafe__useLiveInstance,
1788
+ unsafe__useRTCInstance,
1789
+ useCurrentWebSocketUrl,
1790
+ useConnect,
1791
+ useKeyframe,
1792
+ useKeyframeUpdateCallback,
1793
+ useLiveAction,
1794
+ useLiveEventCallback,
1795
+ useReadyState,
1796
+ useRTCAction,
1797
+ useRTCEventCallback,
1798
+ useSelfInfo,
1799
+ useSnapshot,
1800
+ useUserList,
1801
+ useWebSocketEventCallback,
1802
+ };
1803
+ }
1804
+
1805
+ exports.BrowserRTC = BrowserRTC;
1806
+ exports.BrowserRTC4Chime = BrowserRTC4Chime;
1807
+ exports.CoreRTC = CoreRTC;
1808
+ exports.VRWebViewRTC = VRWebViewRTC;
1809
+ exports.createLive = createLive;
1810
+ exports.createLiveReact = createLiveReact;
1811
+ exports.parseLiveMsg = parseLiveMsg;
1812
+ exports.parseWSClsErr = parseWSClsErr;
1813
+ //# sourceMappingURL=realsee-live.cjs.development.js.map