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:async';
import 'dart:core'; import 'dart:core';
import 'dart:math';
import 'package:webrtc_interface/webrtc_interface.dart'; import 'package:webrtc_interface/webrtc_interface.dart';
@ -327,6 +328,7 @@ class CallSession {
CallSession? successor; CallSession? successor;
bool waitForLocalAVStream = false; bool waitForLocalAVStream = false;
int toDeviceSeq = 0; int toDeviceSeq = 0;
int candidateSendTries = 0;
final CachedStreamController<CallSession> onCallStreamsChanged = final CachedStreamController<CallSession> onCallStreamsChanged =
CachedStreamController(); CachedStreamController();
@ -1084,23 +1086,36 @@ class CallSession {
pc!.onRenegotiationNeeded = onNegotiationNeeded; pc!.onRenegotiationNeeded = onNegotiationNeeded;
pc!.onIceCandidate = (RTCIceCandidate candidate) async { pc!.onIceCandidate = (RTCIceCandidate candidate) async {
if (callHasEnded) return;
//Logs().v('[VOIP] onIceCandidate => ${candidate.toMap().toString()}'); //Logs().v('[VOIP] onIceCandidate => ${candidate.toMap().toString()}');
localCandidates.add(candidate); 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 { pc!.onIceGatheringState = (RTCIceGatheringState state) async {
Logs().v('[VOIP] IceGatheringState => ${state.toString()}'); Logs().v('[VOIP] IceGatheringState => ${state.toString()}');
if (state == RTCIceGatheringState.RTCIceGatheringStateGathering) { if (state == RTCIceGatheringState.RTCIceGatheringStateGathering) {
Timer(Duration(seconds: 3), () async { Timer(Duration(seconds: 3), () async {
if (!iceGatheringFinished) { if (!iceGatheringFinished) {
iceGatheringFinished = true; iceGatheringFinished = true;
await _candidateReady(); await _sendCandidateQueue();
} }
}); });
} }
if (state == RTCIceGatheringState.RTCIceGatheringStateComplete) { if (state == RTCIceGatheringState.RTCIceGatheringStateComplete) {
if (!iceGatheringFinished) { if (!iceGatheringFinished) {
iceGatheringFinished = true; 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 Currently, trickle-ice is not supported, so it will take a
long time to wait to collect all the canidates, set the long time to wait to collect all the canidates, set the
timeout for collection canidates to speed up the connection. timeout for collection canidates to speed up the connection.
*/ */
final candidatesQueue = localCandidates;
try { try {
if (candidatesQueue.isNotEmpty) {
final candidates = <Map<String, dynamic>>[]; final candidates = <Map<String, dynamic>>[];
localCandidates.forEach((element) { candidatesQueue.forEach((element) {
candidates.add(element.toMap()); candidates.add(element.toMap());
}); });
final res = localCandidates = [];
await sendCallCandidates(opts.room, callId, localPartyId, candidates); final res = await sendCallCandidates(
opts.room, callId, localPartyId, candidates);
Logs().v('[VOIP] sendCallCandidates res => $res'); Logs().v('[VOIP] sendCallCandidates res => $res');
}
} catch (e) { } catch (e) {
Logs().v('[VOIP] sendCallCandidates e => ${e.toString()}'); 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();
});
} }
} }