vani-meeting-client-native 0.3.7-beta6 → 0.3.7-beta8
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/MeetingHandler.d.ts +2 -1
- package/lib/MeetingHandler.js +9 -1
- package/lib/inter-communication-handler/CommunicationHandler.d.ts +3 -0
- package/lib/inter-communication-handler/CommunicationHandler.js +64 -5
- package/lib/model/MeetingStartRequest.d.ts +6 -0
- package/lib/model/MeetingStartRequest.js +7 -0
- package/lib/model/PeerConnection.d.ts +5 -0
- package/lib/user-media-handler/UserMediaHandler.js +39 -10
- package/lib/utility/DynamicLibHelper.js +5 -1
- package/lib/utility/DynamicLibHelper.native.js +5 -1
- package/lib/utility/DynamicLibHelper.node.d.ts +1 -0
- package/lib/utility/DynamicLibHelper.node.js +36 -1
- package/lib/video-call-handler/BaseVideoCallHandler.d.ts +2 -0
- package/lib/video-call-handler/BaseVideoCallHandler.js +9 -0
- package/lib/video-call-handler/MediaAdaptationManager.d.ts +40 -0
- package/lib/video-call-handler/MediaAdaptationManager.js +405 -0
- package/lib/video-call-handler/SFUHandler.js +101 -52
- package/lib/video-call-handler/WebrtcHandler.d.ts +22 -0
- package/lib/video-call-handler/WebrtcHandler.js +766 -109
- package/lib/websocket-handler/WebsocketHandler.d.ts +2 -1
- package/lib/websocket-handler/WebsocketHandler.js +10 -7
- package/package.json +1 -1
package/lib/MeetingHandler.d.ts
CHANGED
|
@@ -29,6 +29,7 @@ export declare class MeetingHandler {
|
|
|
29
29
|
muteUser(userId?: string): Promise<TaskResponse>;
|
|
30
30
|
getClientStats: () => Promise<TrackStats[] | undefined>;
|
|
31
31
|
resumeCamera(userId?: string): Promise<TaskResponse>;
|
|
32
|
+
refetchTrackForParticipant: (participant: Participant) => Promise<void>;
|
|
32
33
|
unmute(userId?: string): Promise<TaskResponse>;
|
|
33
34
|
resumeStreamWithoutAdding(streamKind: TrackKind): TaskResponse | undefined;
|
|
34
35
|
pauseStreamWithoutStopping(streamKind: TrackKind): TaskResponse | undefined;
|
|
@@ -47,7 +48,7 @@ export declare class MeetingHandler {
|
|
|
47
48
|
getAllTracks(): Track[];
|
|
48
49
|
getTracksByParticipantId(participantId: string): Track[];
|
|
49
50
|
isWebScoketConnected(): boolean;
|
|
50
|
-
isStartMeetingCalled: () =>
|
|
51
|
+
isStartMeetingCalled: () => boolean;
|
|
51
52
|
sendMessage(message: MessagePayload): TaskResponse;
|
|
52
53
|
getOldMessages(): Promise<void>;
|
|
53
54
|
onOldMessages(data: any): Promise<void>;
|
package/lib/MeetingHandler.js
CHANGED
|
@@ -103,9 +103,16 @@ var MeetingHandler = /** @class */ (function () {
|
|
|
103
103
|
}
|
|
104
104
|
});
|
|
105
105
|
}); };
|
|
106
|
+
this.refetchTrackForParticipant = function (participant) { return __awaiter(_this, void 0, void 0, function () {
|
|
107
|
+
var _a;
|
|
108
|
+
return __generator(this, function (_b) {
|
|
109
|
+
(_a = this.communicationHandler) === null || _a === void 0 ? void 0 : _a.refetchTrackForParticipant(participant);
|
|
110
|
+
return [2 /*return*/];
|
|
111
|
+
});
|
|
112
|
+
}); };
|
|
106
113
|
this.isStartMeetingCalled = function () {
|
|
107
114
|
var _a;
|
|
108
|
-
(_a = _this.communicationHandler) === null || _a === void 0 ? void 0 : _a.isStartAndSetupWithServerCalled;
|
|
115
|
+
return (_a = _this.communicationHandler) === null || _a === void 0 ? void 0 : _a.isStartAndSetupWithServerCalled;
|
|
109
116
|
};
|
|
110
117
|
this.restartTransport = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
111
118
|
var _a;
|
|
@@ -206,6 +213,7 @@ var MeetingHandler = /** @class */ (function () {
|
|
|
206
213
|
this.userMediaHandler = new UserMediaHandler(this.meetingStartRequest, this.communicationHandler);
|
|
207
214
|
}
|
|
208
215
|
if (isVideoRequired === false && isAudioRequired === false) {
|
|
216
|
+
this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("startLocalStream return");
|
|
209
217
|
return [2 /*return*/];
|
|
210
218
|
}
|
|
211
219
|
this.userMediaHandler.startLocalStream(isVideoRequired, isAudioRequired, shouldAddTrackImmediately, userMediaPayload);
|
|
@@ -25,11 +25,13 @@ export declare class CommunicationHandler {
|
|
|
25
25
|
emitMessageToSource(emitType: VaniEvent, payload: any): Promise<void>;
|
|
26
26
|
getEventEmitter(): VaniEventListener;
|
|
27
27
|
onAudioVideoStatusUpdated(data: any): void;
|
|
28
|
+
refetchTrackForParticipant: (participant: Participant) => Promise<void>;
|
|
28
29
|
restartTransport: () => Promise<void>;
|
|
29
30
|
updateSelfParticipantUserId(): void;
|
|
30
31
|
getSelfParticipant(): Participant | undefined;
|
|
31
32
|
downloadParticipantsData(): void;
|
|
32
33
|
onServerParticipants(data: any): void;
|
|
34
|
+
isWebScoketConnected(): boolean;
|
|
33
35
|
getAllParticipants(): Participant[];
|
|
34
36
|
participantByUserId(userId: string): Participant | undefined;
|
|
35
37
|
onStartParticipantMeetingCalled: (participantData: any) => Promise<void>;
|
|
@@ -64,6 +66,7 @@ export declare class CommunicationHandler {
|
|
|
64
66
|
onIceCandidateDisconnected(): void;
|
|
65
67
|
checkIfInternetReachable: (count: number) => void;
|
|
66
68
|
private onApiResponded;
|
|
69
|
+
onPing: () => Promise<void>;
|
|
67
70
|
restartSFU: () => Promise<void>;
|
|
68
71
|
onSFUInitDone: () => Promise<void>;
|
|
69
72
|
private reloadSFUCleanUpDone;
|
|
@@ -34,6 +34,22 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
34
34
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
|
+
var __read = (this && this.__read) || function (o, n) {
|
|
38
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
39
|
+
if (!m) return o;
|
|
40
|
+
var i = m.call(o), r, ar = [], e;
|
|
41
|
+
try {
|
|
42
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
43
|
+
}
|
|
44
|
+
catch (error) { e = { error: error }; }
|
|
45
|
+
finally {
|
|
46
|
+
try {
|
|
47
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
48
|
+
}
|
|
49
|
+
finally { if (e) throw e.error; }
|
|
50
|
+
}
|
|
51
|
+
return ar;
|
|
52
|
+
};
|
|
37
53
|
import { VaniEvent, MessagePayload, LogLevel } from "..";
|
|
38
54
|
import { Participant } from "../model/Participant";
|
|
39
55
|
import * as log from 'loglevel';
|
|
@@ -51,6 +67,13 @@ var CommunicationHandler = /** @class */ (function () {
|
|
|
51
67
|
this.allTracks = [];
|
|
52
68
|
this.allSelfTracksForRestartSFU = undefined;
|
|
53
69
|
this.isReachable = true;
|
|
70
|
+
this.refetchTrackForParticipant = function (participant) { return __awaiter(_this, void 0, void 0, function () {
|
|
71
|
+
var _a;
|
|
72
|
+
return __generator(this, function (_b) {
|
|
73
|
+
(_a = this.videoCallHandler) === null || _a === void 0 ? void 0 : _a.participantAudioVideoStatusUpdated(participant);
|
|
74
|
+
return [2 /*return*/];
|
|
75
|
+
});
|
|
76
|
+
}); };
|
|
54
77
|
this.restartTransport = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
55
78
|
var _a;
|
|
56
79
|
return __generator(this, function (_b) {
|
|
@@ -122,6 +145,14 @@ var CommunicationHandler = /** @class */ (function () {
|
|
|
122
145
|
});
|
|
123
146
|
;
|
|
124
147
|
};
|
|
148
|
+
this.onPing = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
149
|
+
var _a;
|
|
150
|
+
return __generator(this, function (_b) {
|
|
151
|
+
this === null || this === void 0 ? void 0 : this.emitMessageToSource(VaniEvent.OnNewPingFromServer, {});
|
|
152
|
+
(_a = this.videoCallHandler) === null || _a === void 0 ? void 0 : _a.onPing();
|
|
153
|
+
return [2 /*return*/];
|
|
154
|
+
});
|
|
155
|
+
}); };
|
|
125
156
|
this.restartSFU = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
126
157
|
var messageJson;
|
|
127
158
|
var _a;
|
|
@@ -203,6 +234,7 @@ var CommunicationHandler = /** @class */ (function () {
|
|
|
203
234
|
if (participant) {
|
|
204
235
|
participant.isVideoEnable = data.message.participant.isVideoEnable;
|
|
205
236
|
participant.isAudioEnable = data.message.participant.isAudioEnable;
|
|
237
|
+
this.refetchTrackForParticipant(participant);
|
|
206
238
|
this.emitMessageToSource(VaniEvent.OnAudioVideoStatusUpdated, participant);
|
|
207
239
|
}
|
|
208
240
|
}
|
|
@@ -248,7 +280,7 @@ var CommunicationHandler = /** @class */ (function () {
|
|
|
248
280
|
if (data && data.message) {
|
|
249
281
|
var userIds = "";
|
|
250
282
|
Object.entries(data.message).forEach(function (_a) {
|
|
251
|
-
var userId =
|
|
283
|
+
var _b = __read(_a, 2), userId = _b[0], participant = _b[1];
|
|
252
284
|
userIds = userIds + " " + userId;
|
|
253
285
|
_this.meetingStartRequest && _this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("addParticipantIfNotExist from onServerParticipants", data);
|
|
254
286
|
_this.addParticipantIfNotExist(participant, false);
|
|
@@ -261,6 +293,13 @@ var CommunicationHandler = /** @class */ (function () {
|
|
|
261
293
|
this.emitMessageToSource(VaniEvent.OnAllParticipants, this.allParticipants);
|
|
262
294
|
}
|
|
263
295
|
};
|
|
296
|
+
CommunicationHandler.prototype.isWebScoketConnected = function () {
|
|
297
|
+
var _a;
|
|
298
|
+
if (this.websocketCallHandler) {
|
|
299
|
+
return (_a = this.websocketCallHandler) === null || _a === void 0 ? void 0 : _a.isWebScoketConnected();
|
|
300
|
+
}
|
|
301
|
+
return false;
|
|
302
|
+
};
|
|
264
303
|
CommunicationHandler.prototype.getAllParticipants = function () {
|
|
265
304
|
return this.allParticipants;
|
|
266
305
|
};
|
|
@@ -638,12 +677,32 @@ var CommunicationHandler = /** @class */ (function () {
|
|
|
638
677
|
}
|
|
639
678
|
};
|
|
640
679
|
CommunicationHandler.prototype.cleanup = function () {
|
|
680
|
+
var _a;
|
|
641
681
|
return __awaiter(this, void 0, void 0, function () {
|
|
682
|
+
var participant;
|
|
642
683
|
var _this = this;
|
|
643
|
-
return __generator(this, function (
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
684
|
+
return __generator(this, function (_b) {
|
|
685
|
+
try {
|
|
686
|
+
if (this.meetingStartRequest) {
|
|
687
|
+
participant = this.participantByUserId((_a = this.meetingStartRequest) === null || _a === void 0 ? void 0 : _a.userId);
|
|
688
|
+
if (participant) {
|
|
689
|
+
participant.getPeerConnections().forEach(function (peerConnection, eachUserId) {
|
|
690
|
+
try {
|
|
691
|
+
if (peerConnection && peerConnection.rtcPeerConnection) {
|
|
692
|
+
peerConnection.rtcPeerConnection.close();
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
catch (err) { }
|
|
696
|
+
});
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
catch (err) {
|
|
701
|
+
}
|
|
702
|
+
if (this.getSelfParticipant())
|
|
703
|
+
this.selfTracks.forEach(function (eachTrack) {
|
|
704
|
+
_this.removeTrack(eachTrack, false);
|
|
705
|
+
});
|
|
647
706
|
this.allSelfTracksForRestartSFU = undefined;
|
|
648
707
|
this.eventEmitter.removeAllListeners();
|
|
649
708
|
this.videoCallHandler = undefined;
|
|
@@ -15,6 +15,11 @@ export declare enum LogLevel {
|
|
|
15
15
|
None = "none",
|
|
16
16
|
Debug = "Debug"
|
|
17
17
|
}
|
|
18
|
+
export declare enum DeviceTier {
|
|
19
|
+
low = "low",
|
|
20
|
+
mid = "mid",
|
|
21
|
+
high = "high"
|
|
22
|
+
}
|
|
18
23
|
export declare class MeetingStartRequest {
|
|
19
24
|
roomId: string;
|
|
20
25
|
userId: string;
|
|
@@ -35,6 +40,7 @@ export declare class MeetingStartRequest {
|
|
|
35
40
|
maxBitRateConfig: number;
|
|
36
41
|
renewUserIdOnEveryReconnection: boolean;
|
|
37
42
|
maxAudioBitrateConfig: number;
|
|
43
|
+
deviceTier: DeviceTier;
|
|
38
44
|
logLevel: LogLevel;
|
|
39
45
|
dynamicWebSocketFetchBaseUrl?: string;
|
|
40
46
|
isRecordingUser: boolean;
|
|
@@ -19,6 +19,12 @@ export var LogLevel;
|
|
|
19
19
|
LogLevel["None"] = "none";
|
|
20
20
|
LogLevel["Debug"] = "Debug";
|
|
21
21
|
})(LogLevel || (LogLevel = {}));
|
|
22
|
+
export var DeviceTier;
|
|
23
|
+
(function (DeviceTier) {
|
|
24
|
+
DeviceTier["low"] = "low";
|
|
25
|
+
DeviceTier["mid"] = "mid";
|
|
26
|
+
DeviceTier["high"] = "high";
|
|
27
|
+
})(DeviceTier || (DeviceTier = {}));
|
|
22
28
|
var MeetingStartRequest = /** @class */ (function () {
|
|
23
29
|
function MeetingStartRequest(_roomId, _userId, _appId, _wssUrl, _shouldIgnoreCaseForRoomId) {
|
|
24
30
|
if (_shouldIgnoreCaseForRoomId === void 0) { _shouldIgnoreCaseForRoomId = false; }
|
|
@@ -35,6 +41,7 @@ var MeetingStartRequest = /** @class */ (function () {
|
|
|
35
41
|
this.maxBitRateConfig = 620000;
|
|
36
42
|
this.renewUserIdOnEveryReconnection = false;
|
|
37
43
|
this.maxAudioBitrateConfig = -1;
|
|
44
|
+
this.deviceTier = DeviceTier.mid;
|
|
38
45
|
this.logLevel = LogLevel.None;
|
|
39
46
|
this.isRecordingUser = false;
|
|
40
47
|
this.meetingType = MeetingType.SFU;
|
|
@@ -49,6 +49,17 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
49
49
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
50
50
|
}
|
|
51
51
|
};
|
|
52
|
+
var __values = (this && this.__values) || function(o) {
|
|
53
|
+
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
54
|
+
if (m) return m.call(o);
|
|
55
|
+
if (o && typeof o.length === "number") return {
|
|
56
|
+
next: function () {
|
|
57
|
+
if (o && i >= o.length) o = void 0;
|
|
58
|
+
return { value: o && o[i++], done: !o };
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
62
|
+
};
|
|
52
63
|
import log from 'loglevel';
|
|
53
64
|
import { CameraFacingMode, LogLevel, VaniEvent } from "..";
|
|
54
65
|
import { Base } from "../base/Base";
|
|
@@ -97,14 +108,18 @@ var UserMediaHandler = /** @class */ (function (_super) {
|
|
|
97
108
|
this.meetingStartRequest.audioInDevice = undefined;
|
|
98
109
|
}
|
|
99
110
|
}
|
|
100
|
-
|
|
111
|
+
if (oldTrack) {
|
|
112
|
+
canFetchAudioIn = true;
|
|
113
|
+
}
|
|
101
114
|
_f.label = 2;
|
|
102
115
|
case 2:
|
|
103
116
|
oldVideoTrack = (_c = this.communicationHandler) === null || _c === void 0 ? void 0 : _c.getSelfTrackByType(TrackKind.Video);
|
|
104
117
|
isCameraDeviceFound = false;
|
|
105
118
|
canFetchVideoIn = false;
|
|
106
119
|
if (!(oldVideoTrack || (!oldVideoTrack && ((_d = this.meetingStartRequest) === null || _d === void 0 ? void 0 : _d.cameraDevice)))) return [3 /*break*/, 4];
|
|
107
|
-
|
|
120
|
+
if (oldVideoTrack) {
|
|
121
|
+
canFetchVideoIn = true;
|
|
122
|
+
}
|
|
108
123
|
return [4 /*yield*/, this.getDevice(GetDevicesType.VideoIn)];
|
|
109
124
|
case 3:
|
|
110
125
|
cameraDevices = _f.sent();
|
|
@@ -199,6 +214,7 @@ var UserMediaHandler = /** @class */ (function (_super) {
|
|
|
199
214
|
return __generator(this, function (_b) {
|
|
200
215
|
switch (_b.label) {
|
|
201
216
|
case 0:
|
|
217
|
+
this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("startLocalStream ", isVideoRequired, isVideoRequired);
|
|
202
218
|
if (isVideoRequired === false && isAudioRequired === false) {
|
|
203
219
|
this.isVideoAudioFetchInProgress = false;
|
|
204
220
|
(_a = this.communicationHandler) === null || _a === void 0 ? void 0 : _a.emitMessageToSource(VaniEvent.OnPermissionApproved, {});
|
|
@@ -209,6 +225,7 @@ var UserMediaHandler = /** @class */ (function (_super) {
|
|
|
209
225
|
}
|
|
210
226
|
this.userMediaPayload = userMediaPayload;
|
|
211
227
|
if (this.isVideoAudioFetchInProgress) {
|
|
228
|
+
this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("Already fetching stream. So request ignored", isVideoRequired, isVideoRequired);
|
|
212
229
|
log.log("Already fetching stream. So request ignored");
|
|
213
230
|
return [2 /*return*/];
|
|
214
231
|
}
|
|
@@ -234,6 +251,7 @@ var UserMediaHandler = /** @class */ (function (_super) {
|
|
|
234
251
|
// isAudioRequired = false;
|
|
235
252
|
// }
|
|
236
253
|
// }
|
|
254
|
+
this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("startLocalStream startCapturingStream calling", isVideoRequired, isVideoRequired);
|
|
237
255
|
this.startCapturingStream(isVideoRequired, isAudioRequired, shouldAddTrackImmediately, userMediaPayload);
|
|
238
256
|
return [2 /*return*/];
|
|
239
257
|
}
|
|
@@ -265,6 +283,7 @@ var UserMediaHandler = /** @class */ (function (_super) {
|
|
|
265
283
|
UserMediaHandler.prototype.startCapturingStream = function (isVideoRequired, isAudioRequired, shouldAddTrackImmediately, userMediaPayload) {
|
|
266
284
|
var _this = this;
|
|
267
285
|
var _a, _b, _c, _d, _e;
|
|
286
|
+
this.meetingStartRequest && this.meetingStartRequest.logLevel === LogLevel.Debug && console.log("startCapturingStream called", isVideoRequired, isVideoRequired);
|
|
268
287
|
if (!userMediaPayload) {
|
|
269
288
|
userMediaPayload = {};
|
|
270
289
|
}
|
|
@@ -479,18 +498,28 @@ var UserMediaHandler = /** @class */ (function (_super) {
|
|
|
479
498
|
};
|
|
480
499
|
UserMediaHandler.prototype.getDevice = function (type) {
|
|
481
500
|
return __awaiter(this, void 0, void 0, function () {
|
|
482
|
-
var deviceInfos, devices,
|
|
483
|
-
|
|
484
|
-
|
|
501
|
+
var deviceInfos, devices, deviceInfos_1, deviceInfos_1_1, deviceInfo;
|
|
502
|
+
var e_1, _a;
|
|
503
|
+
return __generator(this, function (_b) {
|
|
504
|
+
switch (_b.label) {
|
|
485
505
|
case 0: return [4 /*yield*/, navigator.mediaDevices.enumerateDevices()];
|
|
486
506
|
case 1:
|
|
487
|
-
deviceInfos =
|
|
507
|
+
deviceInfos = _b.sent();
|
|
488
508
|
devices = [];
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
509
|
+
try {
|
|
510
|
+
for (deviceInfos_1 = __values(deviceInfos), deviceInfos_1_1 = deviceInfos_1.next(); !deviceInfos_1_1.done; deviceInfos_1_1 = deviceInfos_1.next()) {
|
|
511
|
+
deviceInfo = deviceInfos_1_1.value;
|
|
512
|
+
if (deviceInfo.kind === type) {
|
|
513
|
+
devices.push({ id: deviceInfo.deviceId, label: deviceInfo.label });
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
518
|
+
finally {
|
|
519
|
+
try {
|
|
520
|
+
if (deviceInfos_1_1 && !deviceInfos_1_1.done && (_a = deviceInfos_1.return)) _a.call(deviceInfos_1);
|
|
493
521
|
}
|
|
522
|
+
finally { if (e_1) throw e_1.error; }
|
|
494
523
|
}
|
|
495
524
|
return [2 /*return*/, devices];
|
|
496
525
|
}
|
|
@@ -106,7 +106,11 @@ var DynamicLibHelper = /** @class */ (function () {
|
|
|
106
106
|
try {
|
|
107
107
|
if (meetingStartRequest && meetingStartRequest.iceServers) {
|
|
108
108
|
meetingStartRequest && meetingStartRequest.logLevel === LogLevel.Debug && console.log("Webrtc-" + "Ice Servers", meetingStartRequest.iceServers);
|
|
109
|
-
return new (require("react-native-webrtc").RTCPeerConnection)({ iceServers: meetingStartRequest.iceServers
|
|
109
|
+
return new (require("react-native-webrtc").RTCPeerConnection)({ iceServers: meetingStartRequest.iceServers,
|
|
110
|
+
iceTransportPolicy: 'all',
|
|
111
|
+
bundlePolicy: 'max-bundle',
|
|
112
|
+
rtcpMuxPolicy: 'require',
|
|
113
|
+
});
|
|
110
114
|
}
|
|
111
115
|
else {
|
|
112
116
|
return new (require("react-native-webrtc").RTCPeerConnection)();
|
|
@@ -106,7 +106,11 @@ var DynamicLibHelper = /** @class */ (function () {
|
|
|
106
106
|
try {
|
|
107
107
|
if (meetingStartRequest && meetingStartRequest.iceServers) {
|
|
108
108
|
meetingStartRequest && meetingStartRequest.logLevel === LogLevel.Debug && console.log("Webrtc-" + "Ice Servers", meetingStartRequest.iceServers);
|
|
109
|
-
return new (require("react-native-webrtc").RTCPeerConnection)({ iceServers: meetingStartRequest.iceServers
|
|
109
|
+
return new (require("react-native-webrtc").RTCPeerConnection)({ iceServers: meetingStartRequest.iceServers,
|
|
110
|
+
iceTransportPolicy: 'all',
|
|
111
|
+
bundlePolicy: 'max-bundle',
|
|
112
|
+
rtcpMuxPolicy: 'require',
|
|
113
|
+
});
|
|
110
114
|
}
|
|
111
115
|
else {
|
|
112
116
|
return new (require("react-native-webrtc").RTCPeerConnection)();
|
|
@@ -6,4 +6,5 @@ export declare class DynamicLibHelper {
|
|
|
6
6
|
getMediaDevicesVariable(meetingStartRequest: MeetingStartRequest): any;
|
|
7
7
|
getMediaStreamVariable(meetingStartRequest: MeetingStartRequest): any;
|
|
8
8
|
getRTCPeerConnection(meetingStartRequest: MeetingStartRequest): RTCPeerConnection;
|
|
9
|
+
setOpusSdpParams: (sdp: string) => string;
|
|
9
10
|
}
|
|
@@ -38,6 +38,37 @@ import { LogLevel, MeetingType } from '..';
|
|
|
38
38
|
import * as log from 'loglevel';
|
|
39
39
|
var DynamicLibHelper = /** @class */ (function () {
|
|
40
40
|
function DynamicLibHelper() {
|
|
41
|
+
this.setOpusSdpParams = function (sdp) {
|
|
42
|
+
var _a;
|
|
43
|
+
var lines = sdp.split('\r\n');
|
|
44
|
+
// 1. Find Opus payload type e.g. "a=rtpmap:111 opus/48000/2"
|
|
45
|
+
var opusLine = lines.find(function (l) { return /a=rtpmap:\d+ opus/i.test(l); });
|
|
46
|
+
if (!opusLine)
|
|
47
|
+
return sdp; // no Opus found, return unchanged
|
|
48
|
+
var payloadType = (_a = opusLine.match(/a=rtpmap:(\d+)/)) === null || _a === void 0 ? void 0 : _a[1];
|
|
49
|
+
if (!payloadType)
|
|
50
|
+
return sdp;
|
|
51
|
+
var fmtpPrefix = "a=fmtp:".concat(payloadType);
|
|
52
|
+
var opusConfig = [
|
|
53
|
+
'minptime=10',
|
|
54
|
+
'maxaveragebitrate=32000',
|
|
55
|
+
'useinbandfec=1',
|
|
56
|
+
'usedtx=1',
|
|
57
|
+
'stereo=0',
|
|
58
|
+
'maxplaybackrate=16000', // Wideband — voice optimized
|
|
59
|
+
].join(';');
|
|
60
|
+
var existingFmtpIndex = lines.findIndex(function (l) { return l.startsWith(fmtpPrefix); });
|
|
61
|
+
if (existingFmtpIndex >= 0) {
|
|
62
|
+
// Replace existing fmtp line
|
|
63
|
+
lines[existingFmtpIndex] = "".concat(fmtpPrefix, " ").concat(opusConfig);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
// Insert new fmtp line right after the rtpmap line
|
|
67
|
+
var rtpmapIndex = lines.findIndex(function (l) { return l === opusLine; });
|
|
68
|
+
lines.splice(rtpmapIndex + 1, 0, "".concat(fmtpPrefix, " ").concat(opusConfig));
|
|
69
|
+
}
|
|
70
|
+
return lines.join('\r\n');
|
|
71
|
+
};
|
|
41
72
|
}
|
|
42
73
|
DynamicLibHelper.prototype.getReactNativeWebrtcPlugin = function (meetingStartRequest) {
|
|
43
74
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -106,7 +137,11 @@ var DynamicLibHelper = /** @class */ (function () {
|
|
|
106
137
|
DynamicLibHelper.prototype.getRTCPeerConnection = function (meetingStartRequest) {
|
|
107
138
|
if (meetingStartRequest && meetingStartRequest.iceServers) {
|
|
108
139
|
meetingStartRequest && meetingStartRequest.logLevel === LogLevel.Debug && console.log("Webrtc-" + "Ice Servers", meetingStartRequest.iceServers);
|
|
109
|
-
return new RTCPeerConnection({ iceServers: meetingStartRequest.iceServers
|
|
140
|
+
return new RTCPeerConnection({ iceServers: meetingStartRequest.iceServers,
|
|
141
|
+
iceTransportPolicy: 'all',
|
|
142
|
+
bundlePolicy: 'max-bundle',
|
|
143
|
+
rtcpMuxPolicy: 'require',
|
|
144
|
+
});
|
|
110
145
|
}
|
|
111
146
|
else {
|
|
112
147
|
return new RTCPeerConnection();
|
|
@@ -18,6 +18,7 @@ export declare abstract class BaseVideoCallHandler extends Base {
|
|
|
18
18
|
abstract createDataChannel(): any;
|
|
19
19
|
abstract sendMessageViaDataChannel(messagePayload: any): any;
|
|
20
20
|
onAllParticipants(participants: Participant[]): Promise<void>;
|
|
21
|
+
onPing(): Promise<void>;
|
|
21
22
|
onParticipantStartMeetingCalled(participants: Participant): Promise<void>;
|
|
22
23
|
onUserJoined(participants: Participant): Promise<void>;
|
|
23
24
|
onUserLeft(participants: Participant): Promise<void>;
|
|
@@ -25,6 +26,7 @@ export declare abstract class BaseVideoCallHandler extends Base {
|
|
|
25
26
|
resumeProducerOrConsumerForTrack(track: Track): Promise<void>;
|
|
26
27
|
pauseProducerOrConsumerForTrack(track: Track): Promise<void>;
|
|
27
28
|
reconnectedWithoutPing(): void;
|
|
29
|
+
participantAudioVideoStatusUpdated(participant: Participant): void;
|
|
28
30
|
updateSpatialForTrack(track: Track, spatialLayerIndex: number): Promise<void>;
|
|
29
31
|
cleanup(shouldStopTracks?: boolean): Promise<void>;
|
|
30
32
|
restartTransport(): void;
|
|
@@ -75,6 +75,13 @@ var BaseVideoCallHandler = /** @class */ (function (_super) {
|
|
|
75
75
|
});
|
|
76
76
|
});
|
|
77
77
|
};
|
|
78
|
+
BaseVideoCallHandler.prototype.onPing = function () {
|
|
79
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
80
|
+
return __generator(this, function (_a) {
|
|
81
|
+
return [2 /*return*/];
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
};
|
|
78
85
|
BaseVideoCallHandler.prototype.onParticipantStartMeetingCalled = function (participants) {
|
|
79
86
|
return __awaiter(this, void 0, void 0, function () {
|
|
80
87
|
return __generator(this, function (_a) {
|
|
@@ -114,6 +121,8 @@ var BaseVideoCallHandler = /** @class */ (function (_super) {
|
|
|
114
121
|
};
|
|
115
122
|
BaseVideoCallHandler.prototype.reconnectedWithoutPing = function () {
|
|
116
123
|
};
|
|
124
|
+
BaseVideoCallHandler.prototype.participantAudioVideoStatusUpdated = function (participant) {
|
|
125
|
+
};
|
|
117
126
|
BaseVideoCallHandler.prototype.updateSpatialForTrack = function (track, spatialLayerIndex) {
|
|
118
127
|
return __awaiter(this, void 0, void 0, function () {
|
|
119
128
|
return __generator(this, function (_a) {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { DeviceTier } from '../model/MeetingStartRequest';
|
|
2
|
+
export type NetworkProfile = 'good' | 'degraded' | 'poor' | 'critical';
|
|
3
|
+
export interface ResolvedConfig {
|
|
4
|
+
videoEnabled: boolean;
|
|
5
|
+
videoWidth: number;
|
|
6
|
+
videoHeight: number;
|
|
7
|
+
videoFrameRate: number;
|
|
8
|
+
opusBitrate: number;
|
|
9
|
+
opusPtime: number;
|
|
10
|
+
opusFec: boolean;
|
|
11
|
+
opusDtx: boolean;
|
|
12
|
+
opusMaxPlaybackRate: number;
|
|
13
|
+
opusComplexity: number;
|
|
14
|
+
}
|
|
15
|
+
export declare class MediaAdaptationManager {
|
|
16
|
+
private readonly getPeerConnections;
|
|
17
|
+
private readonly getVideoTrack;
|
|
18
|
+
private readonly onProfileChange;
|
|
19
|
+
private readonly deviceTier;
|
|
20
|
+
private networkProfile;
|
|
21
|
+
private handle;
|
|
22
|
+
private tickCount;
|
|
23
|
+
private badSamples;
|
|
24
|
+
private goodSamples;
|
|
25
|
+
constructor(getPeerConnections: () => RTCPeerConnection[], getVideoTrack: () => any | null, onProfileChange: (profile: NetworkProfile, config: ResolvedConfig) => void, deviceTier?: DeviceTier);
|
|
26
|
+
start(): Promise<void>;
|
|
27
|
+
stop(): void;
|
|
28
|
+
applyToNewConnection(_pc: RTCPeerConnection): void;
|
|
29
|
+
private tick;
|
|
30
|
+
private switchProfile;
|
|
31
|
+
private applyVideo;
|
|
32
|
+
buildOpusFmtp(payloadType: string): string;
|
|
33
|
+
private collectStats;
|
|
34
|
+
private classify;
|
|
35
|
+
private resolved;
|
|
36
|
+
private rank;
|
|
37
|
+
private stepUp;
|
|
38
|
+
getCurrentProfile(): NetworkProfile;
|
|
39
|
+
getCurrentResolved(): ResolvedConfig;
|
|
40
|
+
}
|