@cloudflare/realtimekit-react-native 0.1.3 → 0.1.4-staging.10

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 (91) hide show
  1. package/lib/commonjs/AudioSampleHandler.js +61 -0
  2. package/lib/commonjs/AudioSampleHandler.js.map +1 -0
  3. package/lib/commonjs/BackgroundHandler.js +109 -0
  4. package/lib/commonjs/BackgroundHandler.js.map +1 -0
  5. package/lib/commonjs/DeviceInfo.js +37 -0
  6. package/lib/commonjs/DeviceInfo.js.map +1 -0
  7. package/lib/commonjs/LocalMediaError.js +18 -0
  8. package/lib/commonjs/LocalMediaError.js.map +1 -0
  9. package/lib/commonjs/LocalMediaHandler.js +791 -0
  10. package/lib/commonjs/LocalMediaHandler.js.map +1 -0
  11. package/lib/commonjs/LocalMediaInterfaces.js +2 -0
  12. package/lib/commonjs/LocalMediaInterfaces.js.map +1 -0
  13. package/lib/commonjs/LocalMediaUtils.js +298 -0
  14. package/lib/commonjs/LocalMediaUtils.js.map +1 -0
  15. package/lib/commonjs/NativeAudioManager.js +72 -0
  16. package/lib/commonjs/NativeAudioManager.js.map +1 -0
  17. package/lib/commonjs/PermissionHandler.js +157 -0
  18. package/lib/commonjs/PermissionHandler.js.map +1 -0
  19. package/lib/commonjs/ReactContext.js +116 -0
  20. package/lib/commonjs/ReactContext.js.map +1 -0
  21. package/lib/commonjs/ReactHooks.js +99 -0
  22. package/lib/commonjs/ReactHooks.js.map +1 -0
  23. package/lib/commonjs/index.js +95 -0
  24. package/lib/commonjs/index.js.map +1 -0
  25. package/lib/commonjs/utils/constants.js +7 -0
  26. package/lib/commonjs/utils/constants.js.map +1 -0
  27. package/lib/commonjs/utils/crypto.js +76 -0
  28. package/lib/commonjs/utils/crypto.js.map +1 -0
  29. package/lib/commonjs/utils/version.js +8 -0
  30. package/lib/commonjs/utils/version.js.map +1 -0
  31. package/lib/module/AudioSampleHandler.js +54 -0
  32. package/lib/module/AudioSampleHandler.js.map +1 -0
  33. package/lib/module/BackgroundHandler.js +103 -0
  34. package/lib/module/BackgroundHandler.js.map +1 -0
  35. package/lib/module/DeviceInfo.js +31 -0
  36. package/lib/module/DeviceInfo.js.map +1 -0
  37. package/lib/module/LocalMediaError.js +11 -0
  38. package/lib/module/LocalMediaError.js.map +1 -0
  39. package/lib/module/LocalMediaHandler.js +784 -0
  40. package/lib/module/LocalMediaHandler.js.map +1 -0
  41. package/lib/module/LocalMediaInterfaces.js +2 -0
  42. package/lib/module/LocalMediaInterfaces.js.map +1 -0
  43. package/lib/module/LocalMediaUtils.js +290 -0
  44. package/lib/module/LocalMediaUtils.js.map +1 -0
  45. package/lib/module/NativeAudioManager.js +65 -0
  46. package/lib/module/NativeAudioManager.js.map +1 -0
  47. package/lib/module/PermissionHandler.js +149 -0
  48. package/lib/module/PermissionHandler.js.map +1 -0
  49. package/lib/module/ReactContext.js +107 -0
  50. package/lib/module/ReactContext.js.map +1 -0
  51. package/lib/module/ReactHooks.js +75 -0
  52. package/lib/module/ReactHooks.js.map +1 -0
  53. package/lib/module/index.js +58 -0
  54. package/lib/module/index.js.map +1 -0
  55. package/lib/module/utils/constants.js +5 -0
  56. package/lib/module/utils/constants.js.map +1 -0
  57. package/lib/module/utils/crypto.js +74 -0
  58. package/lib/module/utils/crypto.js.map +1 -0
  59. package/lib/module/utils/version.js +2 -0
  60. package/lib/module/utils/version.js.map +1 -0
  61. package/lib/typescript/DeviceInfo.d.ts +9 -0
  62. package/lib/{LocalMediaHandler.d.ts → typescript/LocalMediaHandler.d.ts} +0 -4
  63. package/lib/{ReactHooks.d.ts → typescript/ReactHooks.d.ts} +2 -2
  64. package/lib/typescript/utils/constants.d.ts +1 -0
  65. package/lib/typescript/utils/version.d.ts +1 -0
  66. package/package.json +6 -7
  67. package/plugin/build/withRTK.js +43 -17
  68. package/plugin/src/withRTK.ts +55 -25
  69. package/android/src/main/res/values/strings.xml +0 -3
  70. package/lib/AudioSampleHandler.js +0 -57
  71. package/lib/BackgroundHandler.js +0 -100
  72. package/lib/LocalMediaError.js +0 -6
  73. package/lib/LocalMediaHandler.js +0 -860
  74. package/lib/LocalMediaInterfaces.js +0 -1
  75. package/lib/LocalMediaUtils.js +0 -288
  76. package/lib/NativeAudioManager.js +0 -93
  77. package/lib/PermissionHandler.js +0 -179
  78. package/lib/ReactContext.js +0 -90
  79. package/lib/ReactHooks.js +0 -80
  80. package/lib/index.js +0 -52
  81. package/lib/utils/crypto.js +0 -82
  82. /package/lib/{AudioSampleHandler.d.ts → typescript/AudioSampleHandler.d.ts} +0 -0
  83. /package/lib/{BackgroundHandler.d.ts → typescript/BackgroundHandler.d.ts} +0 -0
  84. /package/lib/{LocalMediaError.d.ts → typescript/LocalMediaError.d.ts} +0 -0
  85. /package/lib/{LocalMediaInterfaces.d.ts → typescript/LocalMediaInterfaces.d.ts} +0 -0
  86. /package/lib/{LocalMediaUtils.d.ts → typescript/LocalMediaUtils.d.ts} +0 -0
  87. /package/lib/{NativeAudioManager.d.ts → typescript/NativeAudioManager.d.ts} +0 -0
  88. /package/lib/{PermissionHandler.d.ts → typescript/PermissionHandler.d.ts} +0 -0
  89. /package/lib/{ReactContext.d.ts → typescript/ReactContext.d.ts} +0 -0
  90. /package/lib/{index.d.ts → typescript/index.d.ts} +0 -0
  91. /package/lib/{utils → typescript/utils}/crypto.d.ts +0 -0
@@ -1,860 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
11
- if (kind === "m") throw new TypeError("Private method is not writable");
12
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
13
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
14
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
15
- };
16
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
17
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
18
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
19
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
20
- };
21
- var _LocalMediaHandler_localMediaUtils, _LocalMediaHandler_appState, _LocalMediaHandler_appStateSubscription, _LocalMediaHandler_interval;
22
- /* eslint-disable @typescript-eslint/no-unused-vars */
23
- import { EventEmitter } from 'events';
24
- import LocalMediaUtils from './LocalMediaUtils';
25
- import { AppState, NativeEventEmitter, NativeModules, PermissionsAndroid, Platform, } from 'react-native';
26
- import BackgroundTimer from './BackgroundHandler';
27
- import InCallManger from './NativeAudioManager';
28
- import { setupPermissions } from './PermissionHandler';
29
- const { RTKHelper, BroadcastEventEmitter } = NativeModules;
30
- const broadcastEmitter = new NativeEventEmitter(BroadcastEventEmitter);
31
- // eslint-disable-next-line no-shadow
32
- export var MediaEvents;
33
- (function (MediaEvents) {
34
- MediaEvents[MediaEvents["AUDIO_TRACK_CHANGE"] = 0] = "AUDIO_TRACK_CHANGE";
35
- MediaEvents[MediaEvents["VIDEO_TRACK_CHANGE"] = 1] = "VIDEO_TRACK_CHANGE";
36
- MediaEvents[MediaEvents["SCREENSHARE_TRACK_CHANGE"] = 2] = "SCREENSHARE_TRACK_CHANGE";
37
- MediaEvents[MediaEvents["SCREENSHARE_ENDED"] = 3] = "SCREENSHARE_ENDED";
38
- MediaEvents[MediaEvents["DEVICE_CHANGE"] = 4] = "DEVICE_CHANGE";
39
- MediaEvents[MediaEvents["SCREENSHARE_STARTED"] = 5] = "SCREENSHARE_STARTED";
40
- MediaEvents[MediaEvents["MEDIA_PERMISSION_UPDATE"] = 6] = "MEDIA_PERMISSION_UPDATE";
41
- MediaEvents[MediaEvents["DEVICE_LIST_UPDATED"] = 7] = "DEVICE_LIST_UPDATED";
42
- })(MediaEvents || (MediaEvents = {}));
43
- function checkIfAudioTrackIsSilent(track) {
44
- //TODO
45
- return !!track;
46
- }
47
- class LocalMediaHandler extends EventEmitter {
48
- configureForeground() {
49
- return __awaiter(this, void 0, void 0, function* () {
50
- if (Platform.OS !== 'android')
51
- return;
52
- const val = yield RTKHelper.isForegroundServiceRunning();
53
- if (!val) {
54
- if (Platform.Version >= 33) {
55
- const res = yield PermissionsAndroid.request(PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS);
56
- if (res !== PermissionsAndroid.RESULTS.GRANTED) {
57
- console.warn('Permission required for screenshare notification');
58
- }
59
- }
60
- if (Platform.Version >= 26) {
61
- yield RTKHelper.createNotificationChannel();
62
- }
63
- try {
64
- yield RTKHelper.startService();
65
- }
66
- catch (e) {
67
- console.warn('Failed to start foreground service', e);
68
- }
69
- }
70
- });
71
- }
72
- constructor(localMediaUtils) {
73
- super();
74
- _LocalMediaHandler_localMediaUtils.set(this, void 0);
75
- _LocalMediaHandler_appState.set(this, void 0);
76
- _LocalMediaHandler_appStateSubscription.set(this, void 0);
77
- _LocalMediaHandler_interval.set(this, void 0);
78
- this._pendingScreenShare = false;
79
- this._handleAppStateChange = (nextAppState) => {
80
- if (__classPrivateFieldGet(this, _LocalMediaHandler_appState, "f").match(/inactive|background/) &&
81
- nextAppState === 'active') {
82
- BackgroundTimer.clearInterval(__classPrivateFieldGet(this, _LocalMediaHandler_interval, "f"));
83
- __classPrivateFieldSet(this, _LocalMediaHandler_interval, null, "f");
84
- if (this.videoTrack) {
85
- this.videoTrack.enabled = false;
86
- setTimeout(() => {
87
- if (this.videoTrack) {
88
- this.videoTrack.enabled = true;
89
- }
90
- }, 100);
91
- }
92
- }
93
- else {
94
- if (__classPrivateFieldGet(this, _LocalMediaHandler_interval, "f") === null) {
95
- if (this.screenShareEnabled || this._pendingScreenShare) {
96
- this.configureForeground();
97
- }
98
- }
99
- __classPrivateFieldSet(this, _LocalMediaHandler_interval, BackgroundTimer.setInterval(() => { }, 1000), "f");
100
- __classPrivateFieldSet(this, _LocalMediaHandler_appState, nextAppState, "f");
101
- }
102
- };
103
- __classPrivateFieldSet(this, _LocalMediaHandler_localMediaUtils, localMediaUtils, "f");
104
- __classPrivateFieldSet(this, _LocalMediaHandler_appState, '', "f");
105
- this.audioEnabled = true;
106
- this.videoEnabled = true;
107
- this.screenShareEnabled = false;
108
- this.permissions = { audio: 'NOT_REQUESTED', video: 'NOT_REQUESTED' };
109
- this.screenShareTracks = {
110
- audio: undefined,
111
- video: undefined,
112
- };
113
- this.currentDevices = {
114
- audio: undefined,
115
- video: undefined,
116
- speaker: undefined,
117
- };
118
- // LocalMediaUtils onDeviceChange with callback from native onAudioDeviceChanged events
119
- __classPrivateFieldGet(this, _LocalMediaHandler_localMediaUtils, "f").onDeviceChange((changedDevices) => __awaiter(this, void 0, void 0, function* () {
120
- yield this.onDeviceChange(changedDevices, false);
121
- }));
122
- if (Platform.OS === 'ios') {
123
- broadcastEmitter.addListener('iOS_BroadcastStarted', () => {
124
- this.oniOSBroadcastStart();
125
- });
126
- broadcastEmitter.addListener('iOS_BroadcastStopped', () => {
127
- this.oniOSBroadcastStop();
128
- });
129
- }
130
- InCallManger.start({});
131
- }
132
- conditionallyRestartAudio() {
133
- return __awaiter(this, void 0, void 0, function* () {
134
- var _a;
135
- if (!this.currentDevices.audio || !this.audioEnabled) {
136
- return;
137
- }
138
- // log.info('maybe_restart_audio: ');
139
- yield Promise.race([
140
- new Promise((resolve) => {
141
- var _a;
142
- return (_a = this.audioTrack) === null || _a === void 0 ? void 0 : _a.addEventListener('unmute', (e) => {
143
- resolve(e);
144
- });
145
- }),
146
- new Promise((resolve) => setTimeout(resolve, 50)),
147
- ]);
148
- const reacquireTrack = yield this.shouldReacquireTrack('audio');
149
- if (reacquireTrack) {
150
- this.removeMediaStreamTrackListeners(this.audioTrack);
151
- yield this.setupAudioStream((_a = this.currentDevices.audio) === null || _a === void 0 ? void 0 : _a.deviceId);
152
- this.addMediaStreamTrackListeners(this.audioTrack);
153
- this.emit('AUDIO_TRACK_CHANGE');
154
- }
155
- });
156
- }
157
- conditionallyRestartVideo() {
158
- return __awaiter(this, void 0, void 0, function* () {
159
- if (!this.currentDevices.video || !this.videoEnabled)
160
- return;
161
- // log.info('maybe_restart_video');
162
- yield Promise.race([
163
- new Promise((resolve) => { var _a; return (_a = this.videoTrack) === null || _a === void 0 ? void 0 : _a.addEventListener('unmute', resolve); }),
164
- new Promise((resolve) => setTimeout(resolve, 50)),
165
- ]);
166
- const reacquireTrack = yield this.shouldReacquireTrack('video');
167
- if (reacquireTrack) {
168
- this.removeMediaStreamTrackListeners(this.videoTrack);
169
- yield this.setupVideoStream(this.currentDevices.video.deviceId);
170
- this.addMediaStreamTrackListeners(this.videoTrack);
171
- this.emit('VIDEO_TRACK_CHANGE');
172
- }
173
- });
174
- }
175
- shouldReacquireTrack(kind) {
176
- return __awaiter(this, void 0, void 0, function* () {
177
- const workaroundWebKitBug1208516 = false;
178
- let mediaStreamTrack;
179
- let wasEnabled = false;
180
- if (kind === 'audio') {
181
- mediaStreamTrack = this.audioTrack;
182
- wasEnabled = this.audioEnabled;
183
- }
184
- else if (kind === 'video') {
185
- mediaStreamTrack = this.videoTrack;
186
- wasEnabled = this.videoEnabled;
187
- }
188
- if (!mediaStreamTrack)
189
- return false;
190
- if (!this.rawAudioTrack || !this.audioTrack)
191
- return true;
192
- if (!this.rawVideoTrack || !this.videoTrack)
193
- return true;
194
- const isStopped = mediaStreamTrack.readyState === 'ended';
195
- const isInadvertentlyStopped = isStopped && wasEnabled && workaroundWebKitBug1208516;
196
- let isSilentAudio = false;
197
- if (kind === 'audio') {
198
- isSilentAudio = yield checkIfAudioTrackIsSilent(this.audioTrack);
199
- }
200
- return mediaStreamTrack.muted || isInadvertentlyStopped || isSilentAudio;
201
- });
202
- }
203
- removeDocumentEventListeners() {
204
- return __awaiter(this, void 0, void 0, function* () { });
205
- }
206
- onUnmute(ev) {
207
- // log.info('Track unmuted', ev);
208
- }
209
- removeMediaStreamTrackListeners(mediaStreamTrack) {
210
- if (!mediaStreamTrack) {
211
- return undefined;
212
- }
213
- const conditionallyRestart = mediaStreamTrack.kind === 'audio'
214
- ? this.conditionallyRestartAudio
215
- : this.conditionallyRestartVideo;
216
- mediaStreamTrack.removeEventListener('ended', conditionallyRestart);
217
- mediaStreamTrack.removeEventListener('mute', conditionallyRestart);
218
- mediaStreamTrack.removeEventListener('unmute', this.onUnmute);
219
- return mediaStreamTrack;
220
- }
221
- addMediaStreamTrackListeners(mediaStreamTrack) {
222
- if (!mediaStreamTrack) {
223
- return null;
224
- }
225
- const conditionallyRestart = mediaStreamTrack.kind === 'audio'
226
- ? this.conditionallyRestartAudio
227
- : this.conditionallyRestartVideo;
228
- mediaStreamTrack.addEventListener('ended', conditionallyRestart);
229
- mediaStreamTrack.addEventListener('mute', conditionallyRestart);
230
- mediaStreamTrack.addEventListener('unmute', this.onUnmute);
231
- return mediaStreamTrack;
232
- }
233
- setupAudioStream(deviceId_1) {
234
- return __awaiter(this, arguments, void 0, function* (deviceId, forceStopTrack = false) {
235
- var _a, _b, _c;
236
- const audioDevices = __classPrivateFieldGet(this, _LocalMediaHandler_localMediaUtils, "f").getAudioDevices();
237
- if (!audioDevices.length) {
238
- return;
239
- }
240
- let audioDeviceId = deviceId;
241
- if (!audioDeviceId) {
242
- audioDeviceId = (yield this.getOperationalMicDeviceId()).deviceId;
243
- }
244
- if (((_a = this.currentDevices.audio) === null || _a === void 0 ? void 0 : _a.deviceId) !== audioDeviceId) {
245
- this.currentDevices.audio = __classPrivateFieldGet(this, _LocalMediaHandler_localMediaUtils, "f").getDeviceById(audioDeviceId, 'audioinput');
246
- }
247
- if (forceStopTrack) {
248
- (_b = this.audioTrack) === null || _b === void 0 ? void 0 : _b.stop();
249
- (_c = this.rawAudioTrack) === null || _c === void 0 ? void 0 : _c.stop();
250
- }
251
- try {
252
- this.rawAudioTrack = yield LocalMediaUtils.getAudioTrack();
253
- }
254
- catch (err) {
255
- console.warn('Failed to acquire audio track: ', err);
256
- this.rawAudioTrack = undefined;
257
- }
258
- this.setAudioTrack(this.rawAudioTrack);
259
- this.addMediaStreamTrackListeners(this.audioTrack);
260
- this.emit('AUDIO_TRACK_CHANGE');
261
- this.setDevice(this.currentDevices.audio);
262
- /**
263
- * NOTE(roerohan): Firefox does not show device labels until permissions are granted.
264
- * So, we need to repopulate the devices once permission is granted.
265
- */
266
- if (this.audioTrack && this.permissions.audio === 'NOT_REQUESTED') {
267
- yield __classPrivateFieldGet(this, _LocalMediaHandler_localMediaUtils, "f").repopulateAvailableDevices();
268
- }
269
- this.emit('DEVICE_CHANGE', {
270
- device: this.currentDevices.audio,
271
- });
272
- });
273
- }
274
- onVisibilityChange() {
275
- // pass
276
- }
277
- setupVideoStream(deviceId_1) {
278
- return __awaiter(this, arguments, void 0, function* (deviceId, forceStopTrack = false) {
279
- var _a, _b, _c;
280
- const videoDevices = __classPrivateFieldGet(this, _LocalMediaHandler_localMediaUtils, "f").getVideoDevices();
281
- if (!videoDevices.length) {
282
- return;
283
- }
284
- let videoDeviceId = deviceId;
285
- if (!videoDeviceId) {
286
- videoDeviceId = (yield this.getOperationalWebcamDeviceId()).deviceId;
287
- }
288
- if (((_a = this.currentDevices.video) === null || _a === void 0 ? void 0 : _a.deviceId) !== videoDeviceId) {
289
- this.currentDevices.video = __classPrivateFieldGet(this, _LocalMediaHandler_localMediaUtils, "f").getDeviceById(videoDeviceId, 'videoinput');
290
- }
291
- /**
292
- * NOTE(roerohan): this.videoEnabled is checked, so that upon device change,
293
- * the video track is not set when the user has turned off his camera.
294
- */
295
- if (this.videoEnabled) {
296
- const videoConstraints = LocalMediaUtils.getVideoConstraints({
297
- videoDeviceId,
298
- });
299
- if (!this.rawVideoTrack) {
300
- try {
301
- this.rawVideoTrack = yield LocalMediaUtils.getVideoTrack(videoConstraints);
302
- }
303
- catch (err) {
304
- console.warn('Failed to acquire video track: ', err);
305
- this.rawVideoTrack = undefined;
306
- }
307
- }
308
- this.setVideoTrack(this.rawVideoTrack);
309
- this.addMediaStreamTrackListeners(this.rawVideoTrack);
310
- this.emit('VIDEO_TRACK_CHANGE');
311
- }
312
- if (forceStopTrack) {
313
- (_b = this.videoTrack) === null || _b === void 0 ? void 0 : _b.stop();
314
- (_c = this.rawVideoTrack) === null || _c === void 0 ? void 0 : _c.stop();
315
- }
316
- /**
317
- * NOTE(roerohan): Firefox does not show device labels until permissions are granted.
318
- * So, we need to repopulate the devices once permission is granted.
319
- */
320
- if (this.videoTrack && this.permissions.video === 'NOT_REQUESTED') {
321
- yield __classPrivateFieldGet(this, _LocalMediaHandler_localMediaUtils, "f").repopulateAvailableDevices();
322
- }
323
- this.emit('DEVICE_CHANGE', {
324
- device: this.currentDevices.video,
325
- });
326
- });
327
- }
328
- setupSpeaker(deviceId) {
329
- return __awaiter(this, void 0, void 0, function* () {
330
- var _a;
331
- const speakerDevices = __classPrivateFieldGet(this, _LocalMediaHandler_localMediaUtils, "f").getSpeakerDevices();
332
- if (!speakerDevices.length) {
333
- return;
334
- }
335
- const lastDeviceIndex = speakerDevices.length - 1;
336
- const speakerDeviceId = deviceId !== null && deviceId !== void 0 ? deviceId : speakerDevices[lastDeviceIndex].deviceId;
337
- if (((_a = this.currentDevices.speaker) === null || _a === void 0 ? void 0 : _a.deviceId) !== speakerDeviceId) {
338
- // Audio Input devices are same as output devices in mobile
339
- this.currentDevices.audio = __classPrivateFieldGet(this, _LocalMediaHandler_localMediaUtils, "f").getDeviceById(speakerDeviceId, 'audioinput');
340
- this.currentDevices.speaker = this.currentDevices.audio;
341
- }
342
- yield this.setDevice(this.currentDevices.audio);
343
- this.emit('DEVICE_CHANGE', {
344
- device: this.currentDevices.speaker,
345
- });
346
- });
347
- }
348
- getOperationalWebcamDeviceId() {
349
- return __awaiter(this, void 0, void 0, function* () {
350
- let videoDevices = __classPrivateFieldGet(this, _LocalMediaHandler_localMediaUtils, "f").getVideoDevices();
351
- if (!videoDevices.length) {
352
- return { isOperational: false, deviceId: null };
353
- }
354
- /*
355
- NOTE(ravindra-dyte): Usually external devices come at the bottom,
356
- By reversing the deviceList and breaking on first operational device
357
- We are giving preference to external device
358
- */
359
- videoDevices = [...videoDevices].reverse();
360
- let operationalDeviceId = null;
361
- for (let deviceIndex = 0; deviceIndex < videoDevices.length; deviceIndex += 1) {
362
- try {
363
- operationalDeviceId = videoDevices[deviceIndex].deviceId;
364
- break;
365
- }
366
- catch (err) { }
367
- }
368
- return operationalDeviceId
369
- ? { isOperational: true, deviceId: operationalDeviceId }
370
- : { isOperational: false, deviceId: videoDevices[0].deviceId };
371
- });
372
- }
373
- getOperationalMicDeviceId() {
374
- return __awaiter(this, void 0, void 0, function* () {
375
- let audioDevices = __classPrivateFieldGet(this, _LocalMediaHandler_localMediaUtils, "f").getAudioDevices();
376
- if (!audioDevices.length) {
377
- return { isOperational: false, deviceId: null };
378
- }
379
- /*
380
- NOTE(ravindra-dyte): Usually external devices come at the bottom,
381
- By reversing the deviceList and breaking on first operational device
382
- We are giving preference to external device
383
- */
384
- audioDevices = [...audioDevices].reverse();
385
- let operationalDeviceId = null;
386
- for (let deviceIndex = 0; deviceIndex < audioDevices.length; deviceIndex += 1) {
387
- try {
388
- const audioTrack = yield LocalMediaUtils.getAudioTrack();
389
- const isSilent = yield checkIfAudioTrackIsSilent(audioTrack);
390
- audioTrack.stop();
391
- audioTrack.release();
392
- if (!isSilent) {
393
- operationalDeviceId = audioDevices[deviceIndex].deviceId;
394
- break;
395
- }
396
- }
397
- catch (err) {
398
- console.warn('Failed to acquire audio track: ', err);
399
- }
400
- }
401
- return operationalDeviceId
402
- ? { isOperational: true, deviceId: operationalDeviceId }
403
- : { isOperational: false, deviceId: audioDevices[0].deviceId };
404
- });
405
- }
406
- setupStreams(_a) {
407
- return __awaiter(this, arguments, void 0, function* ({ audio, video, }) {
408
- var _b, _c;
409
- try {
410
- const permResult = yield setupPermissions(audio, video);
411
- this.permissions.video = permResult.camera;
412
- this.permissions.audio = permResult.microphone;
413
- }
414
- catch (val) {
415
- this.permissions.video = (_b = val.camera) !== null && _b !== void 0 ? _b : false;
416
- this.permissions.audio = (_c = val.microphone) !== null && _c !== void 0 ? _c : false;
417
- }
418
- this.emit('MEDIA_PERMISSION_UPDATE', {
419
- kind: 'audio',
420
- message: this.permissions.audio,
421
- });
422
- this.emit('MEDIA_PERMISSION_UPDATE', {
423
- kind: 'video',
424
- message: this.permissions.video,
425
- });
426
- const constraints = {};
427
- if (!this.currentDevices) {
428
- this.currentDevices = {
429
- audio: undefined,
430
- video: undefined,
431
- speaker: undefined,
432
- };
433
- }
434
- if (audio) {
435
- const audioDevices = __classPrivateFieldGet(this, _LocalMediaHandler_localMediaUtils, "f").getAudioDevices();
436
- if (audioDevices.length !== 0) {
437
- const audioDeviceId = (yield this.getOperationalMicDeviceId()).deviceId;
438
- this.currentDevices.audio = __classPrivateFieldGet(this, _LocalMediaHandler_localMediaUtils, "f").getDeviceById(audioDeviceId, 'audioinput');
439
- constraints.audio = true;
440
- }
441
- }
442
- if (video) {
443
- const videoDevices = __classPrivateFieldGet(this, _LocalMediaHandler_localMediaUtils, "f").getVideoDevices();
444
- if (videoDevices.length !== 0) {
445
- const videoDeviceId = (yield this.getOperationalWebcamDeviceId())
446
- .deviceId;
447
- this.currentDevices.video = __classPrivateFieldGet(this, _LocalMediaHandler_localMediaUtils, "f").getDeviceById(videoDeviceId, 'videoinput');
448
- const videoConstraints = LocalMediaUtils.getVideoConstraints({
449
- videoDeviceId,
450
- });
451
- constraints.video = videoConstraints.video;
452
- }
453
- }
454
- if (audio)
455
- yield this.setupAudioStream();
456
- if (video)
457
- yield this.setupVideoStream();
458
- if (this.audioTrack)
459
- this.audioEnabled = true;
460
- else
461
- this.audioEnabled = false;
462
- if (this.videoTrack)
463
- this.videoEnabled = true;
464
- else
465
- this.videoEnabled = false;
466
- this.screenShareEnabled = false;
467
- // Setting default audio output to speaker
468
- yield this.setupSpeaker();
469
- // Setup Foreground Service after handling permissions
470
- if (Platform.OS === 'android') {
471
- __classPrivateFieldSet(this, _LocalMediaHandler_appStateSubscription, AppState.addEventListener('change', this._handleAppStateChange), "f");
472
- }
473
- });
474
- }
475
- stopScreenShareTracks(tracks = {}) {
476
- var _a, _b, _c, _d;
477
- const { audio = true, video = true } = tracks;
478
- if (audio) {
479
- (_b = (_a = this.screenShareTracks) === null || _a === void 0 ? void 0 : _a.audio) === null || _b === void 0 ? void 0 : _b.stop();
480
- }
481
- if (video) {
482
- (_d = (_c = this.screenShareTracks) === null || _c === void 0 ? void 0 : _c.video) === null || _d === void 0 ? void 0 : _d.stop();
483
- }
484
- if (audio && video) {
485
- this.screenShareEnabled = false;
486
- }
487
- }
488
- removeScreenShareTracks(tracks) {
489
- var _a;
490
- (_a = this.screenShareTracks.video) === null || _a === void 0 ? void 0 : _a.removeEventListener('ended', this.onScreenShareEnded);
491
- this.stopScreenShareTracks(tracks);
492
- this.screenShareTracks = {
493
- audio: undefined,
494
- video: undefined,
495
- };
496
- }
497
- setAudioTrack(audioTrack) {
498
- if (audioTrack === this.audioTrack) {
499
- return;
500
- }
501
- if (audioTrack === undefined) {
502
- this.stopAudioTrack();
503
- }
504
- this.audioTrack = audioTrack;
505
- }
506
- setVideoTrack(videoTrack) {
507
- if (videoTrack === this.videoTrack) {
508
- return;
509
- }
510
- if (videoTrack === undefined) {
511
- this.stopVideoTrack();
512
- }
513
- this.videoTrack = videoTrack;
514
- }
515
- setScreenShareTracks(tracks) {
516
- var _a;
517
- const { audio, video } = tracks;
518
- // console.log('SetScreenshare called');
519
- if (!audio || !video) {
520
- this.stopScreenShareTracks({ audio: !!audio, video: !!video });
521
- }
522
- this.screenShareTracks = tracks;
523
- (_a = this.screenShareTracks.video) === null || _a === void 0 ? void 0 : _a.addEventListener('ended', this.onScreenShareEnded.bind(this));
524
- }
525
- onScreenShareEnded() {
526
- this.emit('SCREENSHARE_ENDED');
527
- }
528
- disableAudio() {
529
- return __awaiter(this, void 0, void 0, function* () {
530
- yield this.toggleAudio();
531
- });
532
- }
533
- enableAudio() {
534
- return __awaiter(this, void 0, void 0, function* () {
535
- yield this.toggleAudio();
536
- });
537
- }
538
- toggleAudio() {
539
- return __awaiter(this, void 0, void 0, function* () {
540
- var _a, _b;
541
- if (this.permissions.audio !== 'ACCEPTED') {
542
- try {
543
- const permResult = yield setupPermissions(true, false);
544
- this.permissions.audio = permResult.microphone;
545
- }
546
- catch (val) {
547
- this.permissions.audio = (_a = val.microphone) !== null && _a !== void 0 ? _a : false;
548
- }
549
- }
550
- this.emit('MEDIA_PERMISSION_UPDATE', {
551
- kind: 'audio',
552
- message: this.permissions.audio,
553
- });
554
- if (this.permissions.audio === 'DENIED' ||
555
- this.permissions.audio === 'NOT_REQUESTED') {
556
- this.audioEnabled = false;
557
- return;
558
- }
559
- if (this.audioEnabled) {
560
- this.audioEnabled = false;
561
- if (this.audioTrack) {
562
- this.audioTrack.enabled = this.audioEnabled;
563
- }
564
- return;
565
- }
566
- try {
567
- /**
568
- * NOTE (@madhugb): We need to setup new stream,
569
- * if the audio track is not preset or it has ended
570
- */
571
- if (!this.audioTrack || this.audioTrack.readyState === 'ended') {
572
- yield this.setupAudioStream((_b = this.currentDevices.audio) === null || _b === void 0 ? void 0 : _b.deviceId);
573
- }
574
- // if we still can't get a track after setting up audio stream
575
- // do not toggle the audio state
576
- if (!this.audioTrack) {
577
- this.audioEnabled = false;
578
- return;
579
- }
580
- this.audioEnabled = true;
581
- }
582
- catch (ex) {
583
- this.audioEnabled = false;
584
- this.audioTrack = undefined;
585
- this.rawAudioTrack = undefined;
586
- }
587
- if (this.audioTrack) {
588
- this.audioTrack.enabled = true;
589
- }
590
- });
591
- }
592
- enableVideo() {
593
- return __awaiter(this, void 0, void 0, function* () {
594
- yield this.toggleVideo();
595
- });
596
- }
597
- disableVideo() {
598
- return __awaiter(this, void 0, void 0, function* () {
599
- yield this.toggleVideo();
600
- });
601
- }
602
- toggleVideo() {
603
- return __awaiter(this, void 0, void 0, function* () {
604
- var _a, _b;
605
- if (this.permissions.video !== 'ACCEPTED') {
606
- try {
607
- const permResult = yield setupPermissions(false, true);
608
- this.permissions.video = permResult.camera;
609
- }
610
- catch (val) {
611
- this.permissions.video = (_a = val.camera) !== null && _a !== void 0 ? _a : false;
612
- }
613
- }
614
- this.emit('MEDIA_PERMISSION_UPDATE', {
615
- kind: 'video',
616
- message: this.permissions.video,
617
- });
618
- if (this.permissions.video === 'DENIED' ||
619
- this.permissions.video === 'NOT_REQUESTED') {
620
- this.videoEnabled = false;
621
- return;
622
- }
623
- if (this.videoEnabled) {
624
- this.removeVideoTrack();
625
- this.videoEnabled = false;
626
- return;
627
- }
628
- /**
629
- * NOTE(roerohan): The videoEnabled flag is used inside the setupVideoStream method
630
- * hence it must be set to true first.
631
- */
632
- this.videoEnabled = true;
633
- yield this.setupVideoStream((_b = this.currentDevices.video) === null || _b === void 0 ? void 0 : _b.deviceId);
634
- });
635
- }
636
- setAudioDevice(device) {
637
- return __awaiter(this, void 0, void 0, function* () {
638
- yield this.setupAudioStream(device.deviceId);
639
- });
640
- }
641
- setVideoDevice(device) {
642
- return __awaiter(this, void 0, void 0, function* () {
643
- if (this.videoEnabled) {
644
- this.removeVideoTrack();
645
- }
646
- yield this.setupVideoStream(device.deviceId);
647
- });
648
- }
649
- setSpeakerDevice(device) {
650
- return __awaiter(this, void 0, void 0, function* () {
651
- yield this.setupSpeaker(device.deviceId);
652
- });
653
- }
654
- setDevice(route) {
655
- return __awaiter(this, void 0, void 0, function* () {
656
- yield __classPrivateFieldGet(this, _LocalMediaHandler_localMediaUtils, "f").chooseAudioRoute(route.deviceId);
657
- });
658
- }
659
- oniOSBroadcastStart() {
660
- return __awaiter(this, void 0, void 0, function* () {
661
- this.setScreenShareTracks(yield LocalMediaUtils.getScreenShareTracks());
662
- this.screenShareEnabled = true;
663
- this.emit('SCREENSHARE_TRACK_CHANGE');
664
- });
665
- }
666
- oniOSBroadcastStop() {
667
- return __awaiter(this, void 0, void 0, function* () {
668
- if (this.screenShareEnabled) {
669
- this.removeScreenShareTracks();
670
- this.emit('SCREENSHARE_TRACK_CHANGE');
671
- return;
672
- }
673
- });
674
- }
675
- toggleScreenShare() {
676
- return __awaiter(this, void 0, void 0, function* () {
677
- if (this.screenShareEnabled && Platform.OS !== 'ios') {
678
- this.removeScreenShareTracks();
679
- try {
680
- yield RTKHelper.stopService();
681
- }
682
- catch (e) {
683
- console.warn('Failed to stop foreground service', e);
684
- }
685
- return;
686
- }
687
- if (Platform.OS === 'ios' && this.screenShareEnabled) {
688
- NativeModules.RTKScreensharePickerView.showScreenSharePickerView();
689
- return;
690
- }
691
- if (Platform.OS === 'android') {
692
- this._pendingScreenShare = true;
693
- yield this.configureForeground();
694
- try {
695
- this.setScreenShareTracks(yield LocalMediaUtils.getScreenShareTracks());
696
- this.screenShareEnabled = true;
697
- }
698
- catch (e) {
699
- console.warn('Failed to start screenshare', e);
700
- this.screenShareEnabled = false;
701
- yield RTKHelper.stopService();
702
- this._pendingScreenShare = false;
703
- }
704
- finally {
705
- this._pendingScreenShare = false;
706
- }
707
- }
708
- if (Platform.OS === 'ios') {
709
- NativeModules.RTKScreensharePickerView.showScreenSharePickerView();
710
- }
711
- });
712
- }
713
- enableScreenShare() {
714
- return __awaiter(this, void 0, void 0, function* () {
715
- yield this.toggleScreenShare();
716
- });
717
- }
718
- disableScreenShare() {
719
- return __awaiter(this, void 0, void 0, function* () {
720
- yield this.toggleScreenShare();
721
- });
722
- }
723
- getAllDevices() {
724
- return __classPrivateFieldGet(this, _LocalMediaHandler_localMediaUtils, "f").availableDevices;
725
- }
726
- getCurrentDevices() {
727
- return this.currentDevices;
728
- }
729
- getDeviceById(deviceId, kind) {
730
- return __classPrivateFieldGet(this, _LocalMediaHandler_localMediaUtils, "f").getDeviceById(deviceId, kind);
731
- }
732
- getAudioDevices() {
733
- return __classPrivateFieldGet(this, _LocalMediaHandler_localMediaUtils, "f").getAudioDevices();
734
- }
735
- getVideoDevices() {
736
- return __classPrivateFieldGet(this, _LocalMediaHandler_localMediaUtils, "f").getVideoDevices();
737
- }
738
- getSpeakerDevices() {
739
- return __classPrivateFieldGet(this, _LocalMediaHandler_localMediaUtils, "f").getSpeakerDevices();
740
- }
741
- onDeviceChange(changedDevices, forceDeviceChange) {
742
- return __awaiter(this, void 0, void 0, function* () {
743
- let addedDevice;
744
- let removedDevice;
745
- if (changedDevices.added.length)
746
- [addedDevice] = changedDevices.added;
747
- if (changedDevices.removed.length)
748
- [removedDevice] = changedDevices.removed;
749
- /**
750
- * NOTE(roerohan): forceStopTrack is set required to be set to true for firefox.
751
- * https://stackoverflow.com/questions/59068146/navigator-mediadevices-getusermedia-api-rejecting-with-error-notreadableerror
752
- * forceStopTrack is the second argument of setupAudioStream and setupVideoStream.
753
- */
754
- if (addedDevice) {
755
- if (addedDevice.kind === 'audioinput') {
756
- if (this.permissions.audio === 'DENIED' ||
757
- this.permissions.audio === 'NOT_REQUESTED') {
758
- yield this.setupSpeaker(addedDevice.deviceId);
759
- }
760
- else {
761
- yield this.setupAudioStream(addedDevice.deviceId);
762
- }
763
- }
764
- else if (addedDevice.kind === 'videoinput') {
765
- yield this.setupVideoStream(addedDevice.deviceId);
766
- }
767
- else if (addedDevice.kind === 'audiooutput') {
768
- yield this.setupSpeaker(addedDevice.deviceId);
769
- }
770
- this.emit('AUDIO_TRACK_CHANGE');
771
- }
772
- if (removedDevice) {
773
- if (removedDevice.kind === 'audioinput') {
774
- if (this.permissions.audio === 'DENIED' ||
775
- this.permissions.audio === 'NOT_REQUESTED') {
776
- yield this.setupSpeaker();
777
- }
778
- else {
779
- yield this.setupAudioStream();
780
- }
781
- }
782
- else if (removedDevice.kind === 'videoinput') {
783
- yield this.setupVideoStream();
784
- }
785
- else if (removedDevice.kind === 'audiooutput') {
786
- yield this.setupSpeaker();
787
- }
788
- this.emit('AUDIO_TRACK_CHANGE');
789
- }
790
- if (changedDevices.added.length || changedDevices.removed.length) {
791
- this.emit('DEVICE_LIST_UPDATED', changedDevices);
792
- }
793
- });
794
- }
795
- static init(_) {
796
- return __awaiter(this, void 0, void 0, function* () {
797
- const localMediaUtils = yield LocalMediaUtils.init();
798
- return new LocalMediaHandler(localMediaUtils);
799
- });
800
- }
801
- emit(event, ...args) {
802
- return super.emit(event, ...args);
803
- }
804
- on(event, listener) {
805
- return super.on(event, listener);
806
- }
807
- destruct() {
808
- // TODO: Do not remove native broadcast listeners when going OFF_STAGE in webinar
809
- // this.#localMediaUtils.destruct();
810
- if (Platform.OS === 'android')
811
- __classPrivateFieldGet(this, _LocalMediaHandler_appStateSubscription, "f").remove();
812
- BackgroundTimer.stop();
813
- try {
814
- if (Platform.OS === 'android')
815
- RTKHelper.stopService();
816
- }
817
- catch (_err) { }
818
- InCallManger.stop(undefined);
819
- // NOTE: This is a no-op, it's functions are handled in web-core
820
- // this.destructMediaHandler();
821
- }
822
- destructMediaHandler() {
823
- return __awaiter(this, void 0, void 0, function* () {
824
- this.removeAllTracks();
825
- this.removeAllListeners();
826
- });
827
- }
828
- removeAllTracks() {
829
- this.removeAudioTrack();
830
- this.removeVideoTrack();
831
- this.removeScreenShareTracks();
832
- }
833
- stopAudioTrack() {
834
- var _a, _b, _c, _d;
835
- (_a = this.rawAudioTrack) === null || _a === void 0 ? void 0 : _a.stop();
836
- (_b = this.audioTrack) === null || _b === void 0 ? void 0 : _b.stop();
837
- (_c = this.rawAudioTrack) === null || _c === void 0 ? void 0 : _c.release();
838
- (_d = this.audioTrack) === null || _d === void 0 ? void 0 : _d.release();
839
- this.audioEnabled = false;
840
- }
841
- removeAudioTrack() {
842
- this.stopAudioTrack();
843
- this.audioTrack = undefined;
844
- this.rawAudioTrack = undefined;
845
- }
846
- stopVideoTrack() {
847
- var _a, _b, _c, _d;
848
- (_a = this.rawVideoTrack) === null || _a === void 0 ? void 0 : _a.stop();
849
- (_b = this.videoTrack) === null || _b === void 0 ? void 0 : _b.stop();
850
- (_c = this.rawVideoTrack) === null || _c === void 0 ? void 0 : _c.release();
851
- (_d = this.videoTrack) === null || _d === void 0 ? void 0 : _d.release();
852
- }
853
- removeVideoTrack() {
854
- this.stopVideoTrack();
855
- this.videoTrack = undefined;
856
- this.rawVideoTrack = undefined;
857
- }
858
- }
859
- _LocalMediaHandler_localMediaUtils = new WeakMap(), _LocalMediaHandler_appState = new WeakMap(), _LocalMediaHandler_appStateSubscription = new WeakMap(), _LocalMediaHandler_interval = new WeakMap();
860
- export default LocalMediaHandler;