Merge branch 'voip/improve-ice-connect-speed' into 'main'

Improve ice connection speed.

See merge request famedly/company/frontend/famedlysdk!1136
This commit is contained in:
td 2022-09-23 20:02:09 +00:00
commit ddb7cf8e30
1 changed files with 46 additions and 10 deletions

View File

@ -18,6 +18,7 @@
import 'dart:async';
import 'dart:core';
import 'dart:math';
import 'package:webrtc_interface/webrtc_interface.dart';
@ -327,6 +328,7 @@ class CallSession {
CallSession? successor;
bool waitForLocalAVStream = false;
int toDeviceSeq = 0;
int candidateSendTries = 0;
final CachedStreamController<CallSession> onCallStreamsChanged =
CachedStreamController();
@ -1084,23 +1086,36 @@ class CallSession {
pc!.onRenegotiationNeeded = onNegotiationNeeded;
pc!.onIceCandidate = (RTCIceCandidate candidate) async {
if (callHasEnded) return;
//Logs().v('[VOIP] onIceCandidate => ${candidate.toMap().toString()}');
localCandidates.add(candidate);
if (state == CallState.kRinging || !inviteOrAnswerSent) return;
// MSC2746 recommends these values (can be quite long when calling because the
// callee will need a while to answer the call)
final delay = direction == CallDirection.kIncoming ? 500 : 2000;
if (candidateSendTries == 0) {
Timer(Duration(milliseconds: delay), () {
_sendCandidateQueue();
});
}
};
pc!.onIceGatheringState = (RTCIceGatheringState state) async {
Logs().v('[VOIP] IceGatheringState => ${state.toString()}');
if (state == RTCIceGatheringState.RTCIceGatheringStateGathering) {
Timer(Duration(seconds: 3), () async {
if (!iceGatheringFinished) {
iceGatheringFinished = true;
await _candidateReady();
await _sendCandidateQueue();
}
});
}
if (state == RTCIceGatheringState.RTCIceGatheringStateComplete) {
if (!iceGatheringFinished) {
iceGatheringFinished = true;
await _candidateReady();
await _sendCandidateQueue();
}
}
};
@ -1277,22 +1292,43 @@ class CallSession {
};
}
Future<void> _candidateReady() async {
Future<void> _sendCandidateQueue() async {
if (callHasEnded) return;
/*
Currently, trickle-ice is not supported, so it will take a
long time to wait to collect all the canidates, set the
timeout for collection canidates to speed up the connection.
*/
final candidatesQueue = localCandidates;
try {
if (candidatesQueue.isNotEmpty) {
final candidates = <Map<String, dynamic>>[];
localCandidates.forEach((element) {
candidatesQueue.forEach((element) {
candidates.add(element.toMap());
});
final res =
await sendCallCandidates(opts.room, callId, localPartyId, candidates);
localCandidates = [];
final res = await sendCallCandidates(
opts.room, callId, localPartyId, candidates);
Logs().v('[VOIP] sendCallCandidates res => $res');
}
} catch (e) {
Logs().v('[VOIP] sendCallCandidates e => ${e.toString()}');
candidateSendTries++;
localCandidates = candidatesQueue;
if (candidateSendTries > 5) {
Logs().d(
'Failed to send candidates on attempt $candidateSendTries Giving up on this call.');
lastError =
CallError(CallErrorCode.SignallingFailed, 'Signalling failed', e);
await hangup(CallErrorCode.SignallingFailed, true);
return;
}
final delay = 500 * pow(2, candidateSendTries);
Timer(Duration(milliseconds: delay as int), () {
_sendCandidateQueue();
});
}
}