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